mfplat: Read queue subscriber within the critical section.
[wine/zf.git] / dlls / crypt32 / tests / encode.c
blob7c72eba1b9b2e03ea9789bbcd9355404b282d7bd
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>
26 #include <snmp.h>
28 #include "wine/test.h"
31 static BOOL (WINAPI *pCryptDecodeObjectEx)(DWORD,LPCSTR,const BYTE*,DWORD,DWORD,PCRYPT_DECODE_PARA,void*,DWORD*);
32 static BOOL (WINAPI *pCryptEncodeObjectEx)(DWORD,LPCSTR,const void*,DWORD,PCRYPT_ENCODE_PARA,void*,DWORD*);
33 static DWORD (WINAPI *pBCryptDestroyKey)(BCRYPT_KEY_HANDLE);
35 struct encodedInt
37 int val;
38 const BYTE *encoded;
41 static const BYTE bin1[] = {0x02,0x01,0x01};
42 static const BYTE bin2[] = {0x02,0x01,0x7f};
43 static const BYTE bin3[] = {0x02,0x02,0x00,0x80};
44 static const BYTE bin4[] = {0x02,0x02,0x01,0x00};
45 static const BYTE bin5[] = {0x02,0x01,0x80};
46 static const BYTE bin6[] = {0x02,0x02,0xff,0x7f};
47 static const BYTE bin7[] = {0x02,0x04,0xba,0xdd,0xf0,0x0d};
49 static const struct encodedInt ints[] = {
50 { 1, bin1 },
51 { 127, bin2 },
52 { 128, bin3 },
53 { 256, bin4 },
54 { -128, bin5 },
55 { -129, bin6 },
56 { 0xbaddf00d, bin7 },
59 struct encodedBigInt
61 const BYTE *val;
62 const BYTE *encoded;
63 const BYTE *decoded;
66 static const BYTE bin8[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
67 static const BYTE bin9[] = {0x02,0x0a,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0};
68 static const BYTE bin10[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
70 static const BYTE bin11[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0xff,0};
71 static const BYTE bin12[] = {0x02,0x09,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
72 static const BYTE bin13[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0};
74 static const struct encodedBigInt bigInts[] = {
75 { bin8, bin9, bin10 },
76 { bin11, bin12, bin13 },
79 static const BYTE bin14[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
80 static const BYTE bin15[] = {0x02,0x0a,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0};
81 static const BYTE bin16[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0xff,0};
82 static const BYTE bin17[] = {0x02,0x0c,0x00,0xff,0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
84 /* Decoded is the same as original, so don't bother storing a separate copy */
85 static const struct encodedBigInt bigUInts[] = {
86 { bin14, bin15, NULL },
87 { bin16, bin17, NULL },
90 static void test_encodeInt(DWORD dwEncoding)
92 DWORD bufSize = 0;
93 int i;
94 BOOL ret;
95 CRYPT_INTEGER_BLOB blob;
96 BYTE *buf = NULL;
98 /* CryptEncodeObjectEx with NULL bufSize crashes..
99 ret = pCryptEncodeObjectEx(3, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
100 NULL);
102 /* check bogus encoding */
103 ret = pCryptEncodeObjectEx(0, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
104 &bufSize);
105 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
106 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
107 if (0)
109 /* check with NULL integer buffer. Windows XP incorrectly returns an
110 * NTSTATUS (crashes on win9x).
112 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, NULL, 0, NULL, NULL,
113 &bufSize);
114 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
115 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
117 for (i = 0; i < ARRAY_SIZE(ints); i++)
119 /* encode as normal integer */
120 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, &ints[i].val, 0,
121 NULL, NULL, &bufSize);
122 ok(ret, "Expected success, got %d\n", GetLastError());
123 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, &ints[i].val,
124 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
125 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
126 if (ret)
128 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
129 buf[0]);
130 ok(buf[1] == ints[i].encoded[1], "Got length %d, expected %d\n",
131 buf[1], ints[i].encoded[1]);
132 ok(!memcmp(buf + 1, ints[i].encoded + 1, ints[i].encoded[1] + 1),
133 "Encoded value of 0x%08x didn't match expected\n", ints[i].val);
134 LocalFree(buf);
136 /* encode as multibyte integer */
137 blob.cbData = sizeof(ints[i].val);
138 blob.pbData = (BYTE *)&ints[i].val;
139 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
140 0, NULL, NULL, &bufSize);
141 ok(ret, "Expected success, got %d\n", GetLastError());
142 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
143 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
144 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
145 if (ret)
147 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
148 buf[0]);
149 ok(buf[1] == ints[i].encoded[1], "Got length %d, expected %d\n",
150 buf[1], ints[i].encoded[1]);
151 ok(!memcmp(buf + 1, ints[i].encoded + 1, ints[i].encoded[1] + 1),
152 "Encoded value of 0x%08x didn't match expected\n", ints[i].val);
153 LocalFree(buf);
156 /* encode a couple bigger ints, just to show it's little-endian and leading
157 * sign bytes are dropped
159 for (i = 0; i < ARRAY_SIZE(bigInts); i++)
161 blob.cbData = strlen((const char*)bigInts[i].val);
162 blob.pbData = (BYTE *)bigInts[i].val;
163 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
164 0, NULL, NULL, &bufSize);
165 ok(ret, "Expected success, got %d\n", GetLastError());
166 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
167 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
168 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
169 if (ret)
171 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
172 buf[0]);
173 ok(buf[1] == bigInts[i].encoded[1], "Got length %d, expected %d\n",
174 buf[1], bigInts[i].encoded[1]);
175 ok(!memcmp(buf + 1, bigInts[i].encoded + 1,
176 bigInts[i].encoded[1] + 1),
177 "Encoded value didn't match expected\n");
178 LocalFree(buf);
181 /* and, encode some uints */
182 for (i = 0; i < ARRAY_SIZE(bigUInts); i++)
184 blob.cbData = strlen((const char*)bigUInts[i].val);
185 blob.pbData = (BYTE*)bigUInts[i].val;
186 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, &blob,
187 0, NULL, NULL, &bufSize);
188 ok(ret, "Expected success, got %d\n", GetLastError());
189 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, &blob,
190 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
191 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
192 if (ret)
194 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
195 buf[0]);
196 ok(buf[1] == bigUInts[i].encoded[1], "Got length %d, expected %d\n",
197 buf[1], bigUInts[i].encoded[1]);
198 ok(!memcmp(buf + 1, bigUInts[i].encoded + 1,
199 bigUInts[i].encoded[1] + 1),
200 "Encoded value didn't match expected\n");
201 LocalFree(buf);
206 static void test_decodeInt(DWORD dwEncoding)
208 static const BYTE bigInt[] = { 2, 5, 0xff, 0xfe, 0xff, 0xfe, 0xff };
209 static const BYTE testStr[] = { 0x16, 4, 't', 'e', 's', 't' };
210 static const BYTE longForm[] = { 2, 0x81, 0x01, 0x01 };
211 static const BYTE bigBogus[] = { 0x02, 0x84, 0x01, 0xff, 0xff, 0xf9 };
212 static const BYTE extraBytes[] = { 2, 1, 1, 0, 0, 0, 0 };
213 BYTE *buf = NULL;
214 DWORD bufSize = 0;
215 int i;
216 BOOL ret;
218 /* CryptDecodeObjectEx with NULL bufSize crashes..
219 ret = pCryptDecodeObjectEx(3, X509_INTEGER, &ints[0].encoded,
220 ints[0].encoded[1] + 2, 0, NULL, NULL, NULL);
222 /* check bogus encoding */
223 ret = pCryptDecodeObjectEx(3, X509_INTEGER, (BYTE *)&ints[0].encoded,
224 ints[0].encoded[1] + 2, 0, NULL, NULL, &bufSize);
225 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
226 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
227 /* check with NULL integer buffer */
228 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, NULL, 0, 0, NULL, NULL,
229 &bufSize);
230 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
231 GetLastError() == OSS_BAD_ARG /* Win9x */),
232 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
233 /* check with a valid, but too large, integer */
234 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, bigInt, bigInt[1] + 2,
235 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
236 ok((!ret && GetLastError() == CRYPT_E_ASN1_LARGE) ||
237 broken(ret) /* Win9x */,
238 "Expected CRYPT_E_ASN1_LARGE, got %d\n", GetLastError());
239 /* check with a DER-encoded string */
240 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, testStr, testStr[1] + 2,
241 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
242 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
243 GetLastError() == OSS_PDU_MISMATCH /* Win9x */ ),
244 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %08x\n",
245 GetLastError());
246 for (i = 0; i < ARRAY_SIZE(ints); i++)
248 /* When the output buffer is NULL, this always succeeds */
249 SetLastError(0xdeadbeef);
250 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER,
251 ints[i].encoded, ints[i].encoded[1] + 2, 0, NULL, NULL,
252 &bufSize);
253 ok(ret && GetLastError() == NOERROR,
254 "Expected success and NOERROR, got %d\n", GetLastError());
255 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER,
256 ints[i].encoded, ints[i].encoded[1] + 2,
257 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
258 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
259 ok(bufSize == sizeof(int), "Wrong size %d\n", bufSize);
260 ok(buf != NULL, "Expected allocated buffer\n");
261 if (ret)
263 ok(!memcmp(buf, &ints[i].val, bufSize), "Expected %d, got %d\n",
264 ints[i].val, *(int *)buf);
265 LocalFree(buf);
268 for (i = 0; i < ARRAY_SIZE(bigInts); i++)
270 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER,
271 bigInts[i].encoded, bigInts[i].encoded[1] + 2, 0, NULL, NULL,
272 &bufSize);
273 ok(ret && GetLastError() == NOERROR,
274 "Expected success and NOERROR, got %d\n", GetLastError());
275 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER,
276 bigInts[i].encoded, bigInts[i].encoded[1] + 2,
277 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
278 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
279 ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %d\n", bufSize);
280 ok(buf != NULL, "Expected allocated buffer\n");
281 if (ret)
283 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
285 ok(blob->cbData == strlen((const char*)bigInts[i].decoded),
286 "Expected len %d, got %d\n", lstrlenA((const char*)bigInts[i].decoded),
287 blob->cbData);
288 ok(!memcmp(blob->pbData, bigInts[i].decoded, blob->cbData),
289 "Unexpected value\n");
290 LocalFree(buf);
293 for (i = 0; i < ARRAY_SIZE(bigUInts); i++)
295 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT,
296 bigUInts[i].encoded, bigUInts[i].encoded[1] + 2, 0, NULL, NULL,
297 &bufSize);
298 ok(ret && GetLastError() == NOERROR,
299 "Expected success and NOERROR, got %d\n", GetLastError());
300 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT,
301 bigUInts[i].encoded, bigUInts[i].encoded[1] + 2,
302 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
303 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
304 ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %d\n", bufSize);
305 ok(buf != NULL, "Expected allocated buffer\n");
306 if (ret)
308 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
310 ok(blob->cbData == strlen((const char*)bigUInts[i].val),
311 "Expected len %d, got %d\n", lstrlenA((const char*)bigUInts[i].val),
312 blob->cbData);
313 ok(!memcmp(blob->pbData, bigUInts[i].val, blob->cbData),
314 "Unexpected value\n");
315 LocalFree(buf);
318 /* Decode the value 1 with long-form length */
319 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, longForm,
320 sizeof(longForm), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
321 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
322 if (ret)
324 ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf);
325 LocalFree(buf);
327 /* check with extra bytes at the end */
328 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, extraBytes,
329 sizeof(extraBytes), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
330 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
331 if (ret)
333 ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf);
334 LocalFree(buf);
336 /* Try to decode some bogus large items */
337 /* The buffer size is smaller than the encoded length, so this should fail
338 * with CRYPT_E_ASN1_EOD if it's being decoded.
339 * Under XP it fails with CRYPT_E_ASN1_LARGE, which means there's a limit
340 * on the size decoded, but in ME it fails with CRYPT_E_ASN1_EOD or crashes.
341 * So this test unfortunately isn't useful.
342 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, tooBig,
343 0x7fffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
344 ok(!ret && GetLastError() == CRYPT_E_ASN1_LARGE,
345 "Expected CRYPT_E_ASN1_LARGE, got %08x\n", GetLastError());
347 /* This will try to decode the buffer and overflow it, check that it's
348 * caught.
350 if (0)
352 /* a large buffer isn't guaranteed to crash, it depends on memory allocation order */
353 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, bigBogus,
354 0x01ffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
355 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
356 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
360 static const BYTE bin18[] = {0x0a,0x01,0x01};
361 static const BYTE bin19[] = {0x0a,0x05,0x00,0xff,0xff,0xff,0x80};
363 /* These are always encoded unsigned, and aren't constrained to be any
364 * particular value
366 static const struct encodedInt enums[] = {
367 { 1, bin18 },
368 { -128, bin19 },
371 /* X509_CRL_REASON_CODE is also an enumerated type, but it's #defined to
372 * X509_ENUMERATED.
374 static const LPCSTR enumeratedTypes[] = { X509_ENUMERATED,
375 szOID_CRL_REASON_CODE };
377 static void test_encodeEnumerated(DWORD dwEncoding)
379 DWORD i, j;
381 for (i = 0; i < ARRAY_SIZE(enumeratedTypes); i++)
383 for (j = 0; j < ARRAY_SIZE(enums); j++)
385 BOOL ret;
386 BYTE *buf = NULL;
387 DWORD bufSize = 0;
389 ret = pCryptEncodeObjectEx(dwEncoding, enumeratedTypes[i],
390 &enums[j].val, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf,
391 &bufSize);
392 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
393 if (ret)
395 ok(buf[0] == 0xa,
396 "Got unexpected type %d for enumerated (expected 0xa)\n",
397 buf[0]);
398 ok(buf[1] == enums[j].encoded[1],
399 "Got length %d, expected %d\n", buf[1], enums[j].encoded[1]);
400 ok(!memcmp(buf + 1, enums[j].encoded + 1,
401 enums[j].encoded[1] + 1),
402 "Encoded value of 0x%08x didn't match expected\n",
403 enums[j].val);
404 LocalFree(buf);
410 static void test_decodeEnumerated(DWORD dwEncoding)
412 DWORD i, j;
414 for (i = 0; i < ARRAY_SIZE(enumeratedTypes); i++)
416 for (j = 0; j < ARRAY_SIZE(enums); j++)
418 BOOL ret;
419 DWORD bufSize = sizeof(int);
420 int val;
422 ret = pCryptDecodeObjectEx(dwEncoding, enumeratedTypes[i],
423 enums[j].encoded, enums[j].encoded[1] + 2, 0, NULL,
424 &val, &bufSize);
425 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
426 ok(bufSize == sizeof(int),
427 "Got unexpected size %d for enumerated\n", bufSize);
428 ok(val == enums[j].val, "Unexpected value %d, expected %d\n",
429 val, enums[j].val);
434 struct encodedFiletime
436 SYSTEMTIME sysTime;
437 const BYTE *encodedTime;
440 static void testTimeEncoding(DWORD dwEncoding, LPCSTR structType,
441 const struct encodedFiletime *time)
443 FILETIME ft = { 0 };
444 BYTE *buf = NULL;
445 DWORD bufSize = 0;
446 BOOL ret;
448 ret = SystemTimeToFileTime(&time->sysTime, &ft);
449 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
450 ret = pCryptEncodeObjectEx(dwEncoding, structType, &ft,
451 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
452 /* years other than 1950-2050 are not allowed for encodings other than
453 * X509_CHOICE_OF_TIME.
455 if (structType == X509_CHOICE_OF_TIME ||
456 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050))
458 ok(ret, "CryptEncodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
459 GetLastError());
460 ok(buf != NULL, "Expected an allocated buffer\n");
461 if (ret)
463 ok(buf[0] == time->encodedTime[0],
464 "Expected type 0x%02x, got 0x%02x\n", time->encodedTime[0],
465 buf[0]);
466 ok(buf[1] == time->encodedTime[1], "Expected %d bytes, got %d\n",
467 time->encodedTime[1], bufSize);
468 ok(!memcmp(time->encodedTime + 2, buf + 2, time->encodedTime[1]),
469 "Got unexpected value for time encoding\n");
470 LocalFree(buf);
473 else
474 ok((!ret && GetLastError() == CRYPT_E_BAD_ENCODE) ||
475 broken(GetLastError() == ERROR_SUCCESS),
476 "Expected CRYPT_E_BAD_ENCODE, got 0x%08x\n", GetLastError());
479 static const char *printSystemTime(const SYSTEMTIME *st)
481 static char buf[64];
483 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st->wMonth, st->wDay,
484 st->wYear, st->wHour, st->wMinute, st->wSecond, st->wMilliseconds);
485 return buf;
488 static const char *printFileTime(const FILETIME *ft)
490 static char buf[64];
491 SYSTEMTIME st;
493 FileTimeToSystemTime(ft, &st);
494 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st.wMonth, st.wDay,
495 st.wYear, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
496 return buf;
499 static void compareTime(const SYSTEMTIME *expected, const FILETIME *got)
501 SYSTEMTIME st;
503 FileTimeToSystemTime(got, &st);
504 ok((expected->wYear == st.wYear &&
505 expected->wMonth == st.wMonth &&
506 expected->wDay == st.wDay &&
507 expected->wHour == st.wHour &&
508 expected->wMinute == st.wMinute &&
509 expected->wSecond == st.wSecond &&
510 abs(expected->wMilliseconds - st.wMilliseconds) <= 1) ||
511 /* Some Windows systems only seem to be accurate in their time decoding to
512 * within about an hour.
514 broken(expected->wYear == st.wYear &&
515 expected->wMonth == st.wMonth &&
516 expected->wDay == st.wDay &&
517 abs(expected->wHour - st.wHour) <= 1),
518 "Got unexpected value for time decoding:\nexpected %s, got %s\n",
519 printSystemTime(expected), printFileTime(got));
522 static void testTimeDecoding(DWORD dwEncoding, LPCSTR structType,
523 const struct encodedFiletime *time)
525 FILETIME ft = { 0 };
526 DWORD size = sizeof(ft);
527 BOOL ret;
529 ret = pCryptDecodeObjectEx(dwEncoding, structType, time->encodedTime,
530 time->encodedTime[1] + 2, 0, NULL, &ft, &size);
531 /* years other than 1950-2050 are not allowed for encodings other than
532 * X509_CHOICE_OF_TIME.
534 if (structType == X509_CHOICE_OF_TIME ||
535 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050))
537 ok(ret || broken(GetLastError() == OSS_DATA_ERROR),
538 "CryptDecodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
539 GetLastError());
540 if (ret)
541 compareTime(&time->sysTime, &ft);
543 else
544 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
545 GetLastError() == OSS_PDU_MISMATCH /* Win9x */ ),
546 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %08x\n",
547 GetLastError());
550 static const BYTE bin20[] = {
551 0x17,0x0d,'0','5','0','6','0','6','1','6','1','0','0','0','Z'};
552 static const BYTE bin21[] = {
553 0x18,0x0f,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
554 static const BYTE bin22[] = {
555 0x18,0x0f,'2','1','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
557 static const struct encodedFiletime times[] = {
558 { { 2005, 6, 1, 6, 16, 10, 0, 0 }, bin20 },
559 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin21 },
560 { { 2145, 6, 1, 6, 16, 10, 0, 0 }, bin22 },
563 static void test_encodeFiletime(DWORD dwEncoding)
565 DWORD i;
567 for (i = 0; i < ARRAY_SIZE(times); i++)
569 testTimeEncoding(dwEncoding, X509_CHOICE_OF_TIME, &times[i]);
570 testTimeEncoding(dwEncoding, PKCS_UTC_TIME, &times[i]);
571 testTimeEncoding(dwEncoding, szOID_RSA_signingTime, &times[i]);
575 static const BYTE bin23[] = {
576 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','0','0','0','Z'};
577 static const BYTE bin24[] = {
578 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','9','9','9','Z'};
579 static const BYTE bin25[] = {
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 bin26[] = {
582 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','0','0'};
583 static const BYTE bin27[] = {
584 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','1','5'};
585 static const BYTE bin28[] = {
586 0x18,0x0a,'2','1','4','5','0','6','0','6','1','6'};
587 static const BYTE bin29[] = {
588 0x17,0x0a,'4','5','0','6','0','6','1','6','1','0'};
589 static const BYTE bin30[] = {
590 0x17,0x0b,'4','5','0','6','0','6','1','6','1','0','Z'};
591 static const BYTE bin31[] = {
592 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','+','0','1'};
593 static const BYTE bin32[] = {
594 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','-','0','1'};
595 static const BYTE bin33[] = {
596 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','+','0','1','0','0'};
597 static const BYTE bin34[] = {
598 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','-','0','1','0','0'};
599 static const BYTE bin35[] = {
600 0x17,0x08, '4','5','0','6','0','6','1','6'};
601 static const BYTE bin36[] = {
602 0x18,0x0f, 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','Z'};
603 static const BYTE bin37[] = {
604 0x18,0x04, '2','1','4','5'};
605 static const BYTE bin38[] = {
606 0x18,0x08, '2','1','4','5','0','6','0','6'};
608 static void test_decodeFiletime(DWORD dwEncoding)
610 static const struct encodedFiletime otherTimes[] = {
611 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin23 },
612 { { 1945, 6, 1, 6, 16, 10, 0, 999 }, bin24 },
613 { { 1945, 6, 1, 6, 17, 10, 0, 0 }, bin25 },
614 { { 1945, 6, 1, 6, 15, 10, 0, 0 }, bin26 },
615 { { 1945, 6, 1, 6, 14, 55, 0, 0 }, bin27 },
616 { { 2145, 6, 1, 6, 16, 0, 0, 0 }, bin28 },
617 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin29 },
618 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin30 },
619 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin31 },
620 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin32 },
621 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin33 },
622 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin34 },
624 /* An oddball case that succeeds in Windows, but doesn't seem correct
625 { { 2145, 6, 1, 2, 11, 31, 0, 0 }, "\x18" "\x13" "21450606161000-9999" },
627 static const unsigned char *bogusTimes[] = {
628 /* oddly, this succeeds on Windows, with year 2765
629 "\x18" "\x0f" "21r50606161000Z",
631 bin35,
632 bin36,
633 bin37,
634 bin38,
636 DWORD i, size;
637 FILETIME ft1 = { 0 }, ft2 = { 0 };
638 BOOL ret;
640 /* Check bogus length with non-NULL buffer */
641 ret = SystemTimeToFileTime(&times[0].sysTime, &ft1);
642 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
643 size = 1;
644 ret = pCryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
645 times[0].encodedTime, times[0].encodedTime[1] + 2, 0, NULL, &ft2, &size);
646 ok(!ret && GetLastError() == ERROR_MORE_DATA,
647 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
648 /* Normal tests */
649 for (i = 0; i < ARRAY_SIZE(times); i++)
651 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &times[i]);
652 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &times[i]);
653 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &times[i]);
655 for (i = 0; i < ARRAY_SIZE(otherTimes); i++)
657 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &otherTimes[i]);
658 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &otherTimes[i]);
659 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &otherTimes[i]);
661 for (i = 0; i < ARRAY_SIZE(bogusTimes); i++)
663 size = sizeof(ft1);
664 ret = pCryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
665 bogusTimes[i], bogusTimes[i][1] + 2, 0, NULL, &ft1, &size);
666 ok((!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
667 GetLastError() == OSS_DATA_ERROR /* Win9x */)) ||
668 broken(ret), /* Win9x and NT4 for bin38 */
669 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
670 GetLastError());
674 static const char commonName[] = "Juan Lang";
675 static const char surName[] = "Lang";
677 static const BYTE emptySequence[] = { 0x30, 0 };
678 static const BYTE emptyRDNs[] = { 0x30, 0x02, 0x31, 0 };
679 static const BYTE twoRDNs[] = {
680 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
681 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
682 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0};
683 static const BYTE encodedTwoRDNs[] = {
684 0x30,0x2e,0x31,0x2c,0x30,0x2a,0x06,0x03,0x55,0x04,0x03,0x30,0x23,0x31,0x21,
685 0x30,0x0c,0x06,0x03,0x55,0x04,0x04,0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,
686 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
687 0x6e,0x67,0x00,
690 static const BYTE us[] = { 0x55, 0x53 };
691 static const BYTE minnesota[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x73, 0x6f,
692 0x74, 0x61 };
693 static const BYTE minneapolis[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x61, 0x70,
694 0x6f, 0x6c, 0x69, 0x73 };
695 static const BYTE codeweavers[] = { 0x43, 0x6f, 0x64, 0x65, 0x57, 0x65, 0x61,
696 0x76, 0x65, 0x72, 0x73 };
697 static const BYTE wine[] = { 0x57, 0x69, 0x6e, 0x65, 0x20, 0x44, 0x65, 0x76,
698 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74 };
699 static const BYTE localhostAttr[] = { 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
700 0x73, 0x74 };
701 static const BYTE aric[] = { 0x61, 0x72, 0x69, 0x63, 0x40, 0x63, 0x6f, 0x64,
702 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d };
704 #define RDNA(arr) oid_ ## arr, CERT_RDN_PRINTABLE_STRING, { sizeof(arr), (LPBYTE)arr }
705 #define RDNIA5(arr) oid_ ## arr, CERT_RDN_IA5_STRING, { sizeof(arr), (LPBYTE)arr }
707 static CHAR oid_us[] = "2.5.4.6",
708 oid_minnesota[] = "2.5.4.8",
709 oid_minneapolis[] = "2.5.4.7",
710 oid_codeweavers[] = "2.5.4.10",
711 oid_wine[] = "2.5.4.11",
712 oid_localhostAttr[] = "2.5.4.3",
713 oid_aric[] = "1.2.840.113549.1.9.1";
714 static CERT_RDN_ATTR rdnAttrs[] = { { RDNA(us) },
715 { RDNA(minnesota) },
716 { RDNA(minneapolis) },
717 { RDNA(codeweavers) },
718 { RDNA(wine) },
719 { RDNA(localhostAttr) },
720 { RDNIA5(aric) } };
721 static CERT_RDN_ATTR decodedRdnAttrs[] = { { RDNA(us) },
722 { RDNA(localhostAttr) },
723 { RDNA(minnesota) },
724 { RDNA(minneapolis) },
725 { RDNA(codeweavers) },
726 { RDNA(wine) },
727 { RDNIA5(aric) } };
729 #undef RDNIA5
730 #undef RDNA
732 static const BYTE encodedRDNAttrs[] = {
733 0x30,0x81,0x96,0x31,0x81,0x93,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
734 0x53,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x68,
735 0x6f,0x73,0x74,0x30,0x10,0x06,0x03,0x55,0x04,0x08,0x13,0x09,0x4d,0x69,0x6e,0x6e,
736 0x65,0x73,0x6f,0x74,0x61,0x30,0x12,0x06,0x03,0x55,0x04,0x07,0x13,0x0b,0x4d,0x69,
737 0x6e,0x6e,0x65,0x61,0x70,0x6f,0x6c,0x69,0x73,0x30,0x12,0x06,0x03,0x55,0x04,0x0a,
738 0x13,0x0b,0x43,0x6f,0x64,0x65,0x57,0x65,0x61,0x76,0x65,0x72,0x73,0x30,0x17,0x06,
739 0x03,0x55,0x04,0x0b,0x13,0x10,0x57,0x69,0x6e,0x65,0x20,0x44,0x65,0x76,0x65,0x6c,
740 0x6f,0x70,0x6d,0x65,0x6e,0x74,0x30,0x21,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
741 0x01,0x09,0x01,0x16,0x14,0x61,0x72,0x69,0x63,0x40,0x63,0x6f,0x64,0x65,0x77,0x65,
742 0x61,0x76,0x65,0x72,0x73,0x2e,0x63,0x6f,0x6d
745 static void test_encodeName(DWORD dwEncoding)
747 CERT_RDN_ATTR attrs[2];
748 CERT_RDN rdn;
749 CERT_NAME_INFO info;
750 static CHAR oid_common_name[] = szOID_COMMON_NAME,
751 oid_sur_name[] = szOID_SUR_NAME;
752 BYTE *buf = NULL;
753 DWORD size = 0;
754 BOOL ret;
756 if (0)
758 /* Test with NULL pvStructInfo (crashes on win9x) */
759 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, NULL,
760 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
761 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
762 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
764 /* Test with empty CERT_NAME_INFO */
765 info.cRDN = 0;
766 info.rgRDN = NULL;
767 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
768 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
769 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
770 if (ret)
772 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
773 "Got unexpected encoding for empty name\n");
774 LocalFree(buf);
776 if (0)
778 /* Test with bogus CERT_RDN (crashes on win9x) */
779 info.cRDN = 1;
780 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
781 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
782 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
783 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
785 /* Test with empty CERT_RDN */
786 rdn.cRDNAttr = 0;
787 rdn.rgRDNAttr = NULL;
788 info.cRDN = 1;
789 info.rgRDN = &rdn;
790 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
791 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
792 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
793 if (ret)
795 ok(!memcmp(buf, emptyRDNs, sizeof(emptyRDNs)),
796 "Got unexpected encoding for empty RDN array\n");
797 LocalFree(buf);
799 if (0)
801 /* Test with bogus attr array (crashes on win9x) */
802 rdn.cRDNAttr = 1;
803 rdn.rgRDNAttr = NULL;
804 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
805 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
806 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
807 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
809 /* oddly, a bogus OID is accepted by Windows XP; not testing.
810 attrs[0].pszObjId = "bogus";
811 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
812 attrs[0].Value.cbData = sizeof(commonName);
813 attrs[0].Value.pbData = commonName;
814 rdn.cRDNAttr = 1;
815 rdn.rgRDNAttr = attrs;
816 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
817 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
818 ok(!ret, "Expected failure, got success\n");
820 /* Check with two CERT_RDN_ATTRs. Note DER encoding forces the order of
821 * the encoded attributes to be swapped.
823 attrs[0].pszObjId = oid_common_name;
824 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
825 attrs[0].Value.cbData = sizeof(commonName);
826 attrs[0].Value.pbData = (BYTE *)commonName;
827 attrs[1].pszObjId = oid_sur_name;
828 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
829 attrs[1].Value.cbData = sizeof(surName);
830 attrs[1].Value.pbData = (BYTE *)surName;
831 rdn.cRDNAttr = 2;
832 rdn.rgRDNAttr = attrs;
833 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
834 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
835 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
836 if (ret)
838 ok(!memcmp(buf, twoRDNs, sizeof(twoRDNs)),
839 "Got unexpected encoding for two RDN array\n");
840 LocalFree(buf);
842 /* A name can be "encoded" with previously encoded RDN attrs. */
843 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
844 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
845 attrs[0].Value.cbData = sizeof(twoRDNs);
846 rdn.cRDNAttr = 1;
847 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
848 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
849 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
850 if (ret)
852 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
853 ok(!memcmp(buf, encodedTwoRDNs, size),
854 "Unexpected value for re-encoded two RDN array\n");
855 LocalFree(buf);
857 /* CERT_RDN_ANY_TYPE is too vague for X509_NAMEs, check the return */
858 rdn.cRDNAttr = 1;
859 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
860 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
861 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
862 ok(!ret && GetLastError() == E_INVALIDARG,
863 "Expected E_INVALIDARG, got %08x\n", GetLastError());
864 /* Test a more complex name */
865 rdn.cRDNAttr = ARRAY_SIZE(rdnAttrs);
866 rdn.rgRDNAttr = rdnAttrs;
867 info.cRDN = 1;
868 info.rgRDN = &rdn;
869 buf = NULL;
870 size = 0;
871 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, X509_NAME, &info,
872 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
873 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
874 if (ret)
876 ok(size == sizeof(encodedRDNAttrs), "Wrong size %d\n", size);
877 ok(!memcmp(buf, encodedRDNAttrs, size), "Unexpected value\n");
878 LocalFree(buf);
882 static WCHAR commonNameW[] = { 'J','u','a','n',' ','L','a','n','g',0 };
883 static WCHAR surNameW[] = { 'L','a','n','g',0 };
885 static const BYTE twoRDNsNoNull[] = {
886 0x30,0x21,0x31,0x1f,0x30,0x0b,0x06,0x03,0x55,0x04,0x04,0x13,0x04,0x4c,0x61,
887 0x6e,0x67,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,
888 0x20,0x4c,0x61,0x6e,0x67 };
889 static const BYTE anyType[] = {
890 0x30,0x2f,0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x1e,0x24,0x23,0x30,
891 0x21,0x31,0x0c,0x30,0x03,0x06,0x04,0x55,0x13,0x04,0x4c,0x05,0x6e,0x61,0x00,
892 0x67,0x11,0x30,0x03,0x06,0x04,0x55,0x13,0x03,0x4a,0x0a,0x61,0x75,0x20,0x6e,
893 0x61,0x4c,0x67,0x6e };
895 static void test_encodeUnicodeName(DWORD dwEncoding)
897 CERT_RDN_ATTR attrs[2];
898 CERT_RDN rdn;
899 CERT_NAME_INFO info;
900 static CHAR oid_common_name[] = szOID_COMMON_NAME,
901 oid_sur_name[] = szOID_SUR_NAME;
902 BYTE *buf = NULL;
903 DWORD size = 0;
904 BOOL ret;
906 if (0)
908 /* Test with NULL pvStructInfo (crashes on win9x) */
909 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, NULL,
910 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
911 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
912 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
914 /* Test with empty CERT_NAME_INFO */
915 info.cRDN = 0;
916 info.rgRDN = NULL;
917 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
918 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
919 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
920 if (ret)
922 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
923 "Got unexpected encoding for empty name\n");
924 LocalFree(buf);
926 /* Check with one CERT_RDN_ATTR, that has an invalid character for the
927 * encoding (the NULL).
929 attrs[0].pszObjId = oid_common_name;
930 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
931 attrs[0].Value.cbData = sizeof(commonNameW);
932 attrs[0].Value.pbData = (BYTE *)commonNameW;
933 rdn.cRDNAttr = 1;
934 rdn.rgRDNAttr = attrs;
935 info.cRDN = 1;
936 info.rgRDN = &rdn;
937 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
938 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
939 ok(!ret && GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING,
940 "Expected CRYPT_E_INVALID_PRINTABLE_STRING, got %08x\n", GetLastError());
941 ok(size == 9, "Unexpected error index %08x\n", size);
942 /* Check with two NULL-terminated CERT_RDN_ATTRs. Note DER encoding
943 * forces the order of the encoded attributes to be swapped.
945 attrs[0].pszObjId = oid_common_name;
946 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
947 attrs[0].Value.cbData = 0;
948 attrs[0].Value.pbData = (BYTE *)commonNameW;
949 attrs[1].pszObjId = oid_sur_name;
950 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
951 attrs[1].Value.cbData = 0;
952 attrs[1].Value.pbData = (BYTE *)surNameW;
953 rdn.cRDNAttr = 2;
954 rdn.rgRDNAttr = attrs;
955 info.cRDN = 1;
956 info.rgRDN = &rdn;
957 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
958 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
959 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
960 if (ret)
962 ok(!memcmp(buf, twoRDNsNoNull, sizeof(twoRDNsNoNull)),
963 "Got unexpected encoding for two RDN array\n");
964 LocalFree(buf);
966 /* A name can be "encoded" with previously encoded RDN attrs. */
967 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
968 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
969 attrs[0].Value.cbData = sizeof(twoRDNs);
970 rdn.cRDNAttr = 1;
971 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
972 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
973 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
974 if (ret)
976 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
977 ok(!memcmp(buf, encodedTwoRDNs, size),
978 "Unexpected value for re-encoded two RDN array\n");
979 LocalFree(buf);
981 /* Unicode names infer the type for CERT_RDN_ANY_TYPE */
982 rdn.cRDNAttr = 1;
983 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
984 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
985 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
986 todo_wine ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
987 if (ret)
989 ok(size == sizeof(anyType), "Unexpected size %d\n", size);
990 ok(!memcmp(buf, anyType, size), "Unexpected value\n");
991 LocalFree(buf);
995 static void compareNameValues(const CERT_NAME_VALUE *expected,
996 const CERT_NAME_VALUE *got)
998 if (expected->dwValueType == CERT_RDN_UTF8_STRING &&
999 got->dwValueType == CERT_RDN_ENCODED_BLOB)
1001 win_skip("Can't handle CERT_RDN_UTF8_STRING\n");
1002 return;
1005 ok(got->dwValueType == expected->dwValueType,
1006 "Expected string type %d, got %d\n", expected->dwValueType,
1007 got->dwValueType);
1008 ok(got->Value.cbData == expected->Value.cbData ||
1009 got->Value.cbData == expected->Value.cbData - sizeof(WCHAR) /* Win8 */,
1010 "String type %d: unexpected data size, got %d, expected %d\n",
1011 expected->dwValueType, got->Value.cbData, expected->Value.cbData);
1012 if (got->Value.cbData && got->Value.pbData)
1013 ok(!memcmp(got->Value.pbData, expected->Value.pbData,
1014 min(got->Value.cbData, expected->Value.cbData)),
1015 "String type %d: unexpected value\n", expected->dwValueType);
1018 static void compareRDNAttrs(const CERT_RDN_ATTR *expected,
1019 const CERT_RDN_ATTR *got)
1021 if (expected->pszObjId && *expected->pszObjId)
1023 ok(got->pszObjId != NULL, "Expected OID %s, got NULL\n",
1024 expected->pszObjId);
1025 if (got->pszObjId)
1027 ok(!strcmp(got->pszObjId, expected->pszObjId),
1028 "Got unexpected OID %s, expected %s\n", got->pszObjId,
1029 expected->pszObjId);
1032 compareNameValues((const CERT_NAME_VALUE *)&expected->dwValueType,
1033 (const CERT_NAME_VALUE *)&got->dwValueType);
1036 static void compareRDNs(const CERT_RDN *expected, const CERT_RDN *got)
1038 ok(got->cRDNAttr == expected->cRDNAttr,
1039 "Expected %d RDN attrs, got %d\n", expected->cRDNAttr, got->cRDNAttr);
1040 if (got->cRDNAttr)
1042 DWORD i;
1044 for (i = 0; i < got->cRDNAttr; i++)
1045 compareRDNAttrs(&expected->rgRDNAttr[i], &got->rgRDNAttr[i]);
1049 static void compareNames(const CERT_NAME_INFO *expected,
1050 const CERT_NAME_INFO *got)
1052 ok(got->cRDN == expected->cRDN, "Expected %d RDNs, got %d\n",
1053 expected->cRDN, got->cRDN);
1054 if (got->cRDN)
1056 DWORD i;
1058 for (i = 0; i < got->cRDN; i++)
1059 compareRDNs(&expected->rgRDN[i], &got->rgRDN[i]);
1063 static const BYTE emptyIndefiniteSequence[] = { 0x30,0x80,0x00,0x00 };
1064 static const BYTE twoRDNsExtraBytes[] = {
1065 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
1066 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1067 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0,0,0,0,0,0};
1069 static void test_decodeName(DWORD dwEncoding)
1071 BYTE *buf = NULL;
1072 DWORD bufSize = 0;
1073 BOOL ret;
1074 CERT_RDN rdn;
1075 CERT_NAME_INFO info = { 1, &rdn };
1077 /* test empty name */
1078 bufSize = 0;
1079 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptySequence,
1080 emptySequence[1] + 2,
1081 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1082 &buf, &bufSize);
1083 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1084 /* Interestingly, in Windows, if cRDN is 0, rgRGN may not be NULL. My
1085 * decoder works the same way, so only test the count.
1087 if (ret)
1089 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1090 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1091 "Expected 0 RDNs in empty info, got %d\n",
1092 ((CERT_NAME_INFO *)buf)->cRDN);
1093 LocalFree(buf);
1095 /* test empty name with indefinite-length encoding */
1096 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyIndefiniteSequence,
1097 sizeof(emptyIndefiniteSequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
1098 &buf, &bufSize);
1099 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1100 if (ret)
1102 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1103 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1104 "Expected 0 RDNs in empty info, got %d\n",
1105 ((CERT_NAME_INFO *)buf)->cRDN);
1106 LocalFree(buf);
1108 /* test empty RDN */
1109 bufSize = 0;
1110 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyRDNs,
1111 emptyRDNs[1] + 2,
1112 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1113 &buf, &bufSize);
1114 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1115 if (ret)
1117 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1119 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1120 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1121 "Got unexpected value for empty RDN\n");
1122 LocalFree(buf);
1124 /* test two RDN attrs */
1125 bufSize = 0;
1126 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNs,
1127 twoRDNs[1] + 2,
1128 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1129 &buf, &bufSize);
1130 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1131 if (ret)
1133 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1134 oid_common_name[] = szOID_COMMON_NAME;
1136 CERT_RDN_ATTR attrs[] = {
1137 { oid_sur_name, CERT_RDN_PRINTABLE_STRING, { sizeof(surName),
1138 (BYTE *)surName } },
1139 { oid_common_name, CERT_RDN_PRINTABLE_STRING, { sizeof(commonName),
1140 (BYTE *)commonName } },
1143 rdn.cRDNAttr = ARRAY_SIZE(attrs);
1144 rdn.rgRDNAttr = attrs;
1145 compareNames(&info, (CERT_NAME_INFO *)buf);
1146 LocalFree(buf);
1148 /* test that two RDN attrs with extra bytes succeeds */
1149 bufSize = 0;
1150 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNsExtraBytes,
1151 sizeof(twoRDNsExtraBytes), 0, NULL, NULL, &bufSize);
1152 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1153 /* And, a slightly more complicated name */
1154 buf = NULL;
1155 bufSize = 0;
1156 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME, encodedRDNAttrs,
1157 sizeof(encodedRDNAttrs), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1158 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1159 if (ret)
1161 rdn.cRDNAttr = ARRAY_SIZE(decodedRdnAttrs);
1162 rdn.rgRDNAttr = decodedRdnAttrs;
1163 compareNames(&info, (CERT_NAME_INFO *)buf);
1164 LocalFree(buf);
1168 static void test_decodeUnicodeName(DWORD dwEncoding)
1170 BYTE *buf = NULL;
1171 DWORD bufSize = 0;
1172 BOOL ret;
1173 CERT_RDN rdn;
1174 CERT_NAME_INFO info = { 1, &rdn };
1176 /* test empty name */
1177 bufSize = 0;
1178 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptySequence,
1179 emptySequence[1] + 2,
1180 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1181 &buf, &bufSize);
1182 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1183 if (ret)
1185 ok(bufSize == sizeof(CERT_NAME_INFO),
1186 "Got wrong bufSize %d\n", bufSize);
1187 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1188 "Expected 0 RDNs in empty info, got %d\n",
1189 ((CERT_NAME_INFO *)buf)->cRDN);
1190 LocalFree(buf);
1192 /* test empty RDN */
1193 bufSize = 0;
1194 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptyRDNs,
1195 emptyRDNs[1] + 2,
1196 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1197 &buf, &bufSize);
1198 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1199 if (ret)
1201 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1203 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1204 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1205 "Got unexpected value for empty RDN\n");
1206 LocalFree(buf);
1208 /* test two RDN attrs */
1209 bufSize = 0;
1210 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, twoRDNsNoNull,
1211 sizeof(twoRDNsNoNull),
1212 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1213 &buf, &bufSize);
1214 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1215 if (ret)
1217 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1218 oid_common_name[] = szOID_COMMON_NAME;
1220 CERT_RDN_ATTR attrs[] = {
1221 { oid_sur_name, CERT_RDN_PRINTABLE_STRING,
1222 { lstrlenW(surNameW) * sizeof(WCHAR), (BYTE *)surNameW } },
1223 { oid_common_name, CERT_RDN_PRINTABLE_STRING,
1224 { lstrlenW(commonNameW) * sizeof(WCHAR), (BYTE *)commonNameW } },
1227 rdn.cRDNAttr = ARRAY_SIZE(attrs);
1228 rdn.rgRDNAttr = attrs;
1229 compareNames(&info, (CERT_NAME_INFO *)buf);
1230 LocalFree(buf);
1234 struct EncodedNameValue
1236 CERT_NAME_VALUE value;
1237 const BYTE *encoded;
1238 DWORD encodedSize;
1241 static const char bogusIA5[] = "\x80";
1242 static const char bogusPrintable[] = "~";
1243 static const char bogusNumeric[] = "A";
1244 static const BYTE bin42[] = { 0x16,0x02,0x80,0x00 };
1245 static const BYTE bin43[] = { 0x13,0x02,0x7e,0x00 };
1246 static const BYTE bin44[] = { 0x12,0x02,0x41,0x00 };
1247 static BYTE octetCommonNameValue[] = {
1248 0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1249 static BYTE numericCommonNameValue[] = {
1250 0x12,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1251 static BYTE printableCommonNameValue[] = {
1252 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1253 static BYTE t61CommonNameValue[] = {
1254 0x14,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1255 static BYTE videotexCommonNameValue[] = {
1256 0x15,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1257 static BYTE ia5CommonNameValue[] = {
1258 0x16,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1259 static BYTE graphicCommonNameValue[] = {
1260 0x19,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1261 static BYTE visibleCommonNameValue[] = {
1262 0x1a,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1263 static BYTE generalCommonNameValue[] = {
1264 0x1b,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1265 static BYTE bmpCommonNameValue[] = {
1266 0x1e,0x14,0x00,0x4a,0x00,0x75,0x00,0x61,0x00,0x6e,0x00,0x20,0x00,0x4c,0x00,
1267 0x61,0x00,0x6e,0x00,0x67,0x00,0x00 };
1268 static BYTE utf8CommonNameValue[] = {
1269 0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1270 static char embedded_null[] = "foo\0com";
1271 static BYTE ia5EmbeddedNull[] = {
1272 0x16,0x07,0x66,0x6f,0x6f,0x00,0x63,0x6f,0x6d };
1274 static struct EncodedNameValue nameValues[] = {
1275 { { CERT_RDN_OCTET_STRING, { sizeof(commonName), (BYTE *)commonName } },
1276 octetCommonNameValue, sizeof(octetCommonNameValue) },
1277 { { CERT_RDN_NUMERIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1278 numericCommonNameValue, sizeof(numericCommonNameValue) },
1279 { { CERT_RDN_PRINTABLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1280 printableCommonNameValue, sizeof(printableCommonNameValue) },
1281 { { CERT_RDN_T61_STRING, { sizeof(commonName), (BYTE *)commonName } },
1282 t61CommonNameValue, sizeof(t61CommonNameValue) },
1283 { { CERT_RDN_VIDEOTEX_STRING, { sizeof(commonName), (BYTE *)commonName } },
1284 videotexCommonNameValue, sizeof(videotexCommonNameValue) },
1285 { { CERT_RDN_IA5_STRING, { sizeof(commonName), (BYTE *)commonName } },
1286 ia5CommonNameValue, sizeof(ia5CommonNameValue) },
1287 { { CERT_RDN_GRAPHIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1288 graphicCommonNameValue, sizeof(graphicCommonNameValue) },
1289 { { CERT_RDN_VISIBLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1290 visibleCommonNameValue, sizeof(visibleCommonNameValue) },
1291 { { CERT_RDN_GENERAL_STRING, { sizeof(commonName), (BYTE *)commonName } },
1292 generalCommonNameValue, sizeof(generalCommonNameValue) },
1293 { { CERT_RDN_BMP_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1294 bmpCommonNameValue, sizeof(bmpCommonNameValue) },
1295 { { CERT_RDN_UTF8_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1296 utf8CommonNameValue, sizeof(utf8CommonNameValue) },
1297 /* The following tests succeed under Windows, but really should fail,
1298 * they contain characters that are illegal for the encoding. I'm
1299 * including them to justify my lazy encoding.
1301 { { CERT_RDN_IA5_STRING, { sizeof(bogusIA5), (BYTE *)bogusIA5 } }, bin42,
1302 sizeof(bin42) },
1303 { { CERT_RDN_PRINTABLE_STRING, { sizeof(bogusPrintable),
1304 (BYTE *)bogusPrintable } }, bin43, sizeof(bin43) },
1305 { { CERT_RDN_NUMERIC_STRING, { sizeof(bogusNumeric), (BYTE *)bogusNumeric } },
1306 bin44, sizeof(bin44) },
1308 /* This is kept separate, because the decoding doesn't return to the original
1309 * value.
1311 static struct EncodedNameValue embeddedNullNameValue = {
1312 { CERT_RDN_IA5_STRING, { sizeof(embedded_null) - 1, (BYTE *)embedded_null } },
1313 ia5EmbeddedNull, sizeof(ia5EmbeddedNull) };
1315 static void test_encodeNameValue(DWORD dwEncoding)
1317 BYTE *buf = NULL;
1318 DWORD size = 0, i;
1319 BOOL ret;
1320 CERT_NAME_VALUE value = { 0, { 0, NULL } };
1322 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1323 value.Value.pbData = printableCommonNameValue;
1324 value.Value.cbData = sizeof(printableCommonNameValue);
1325 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, &value,
1326 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1327 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1328 if (ret)
1330 ok(size == sizeof(printableCommonNameValue), "Unexpected size %d\n",
1331 size);
1332 ok(!memcmp(buf, printableCommonNameValue, size),
1333 "Unexpected encoding\n");
1334 LocalFree(buf);
1336 for (i = 0; i < ARRAY_SIZE(nameValues); i++)
1338 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE,
1339 &nameValues[i].value, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1340 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH) /* NT4/Win9x */,
1341 "Type %d: CryptEncodeObjectEx failed: %08x\n",
1342 nameValues[i].value.dwValueType, GetLastError());
1343 if (ret)
1345 ok(size == nameValues[i].encodedSize,
1346 "Expected size %d, got %d\n", nameValues[i].encodedSize, size);
1347 ok(!memcmp(buf, nameValues[i].encoded, size),
1348 "Got unexpected encoding\n");
1349 LocalFree(buf);
1352 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE,
1353 &embeddedNullNameValue.value, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1354 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH) /* NT4/Win9x */,
1355 "Type %d: CryptEncodeObjectEx failed: %08x\n",
1356 embeddedNullNameValue.value.dwValueType, GetLastError());
1357 if (ret)
1359 ok(size == embeddedNullNameValue.encodedSize,
1360 "Expected size %d, got %d\n", embeddedNullNameValue.encodedSize, size);
1361 ok(!memcmp(buf, embeddedNullNameValue.encoded, size),
1362 "Got unexpected encoding\n");
1363 LocalFree(buf);
1367 static void test_decodeNameValue(DWORD dwEncoding)
1369 int i;
1370 BYTE *buf = NULL;
1371 DWORD bufSize = 0;
1372 BOOL ret;
1374 for (i = 0; i < ARRAY_SIZE(nameValues); i++)
1376 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE,
1377 nameValues[i].encoded, nameValues[i].encoded[1] + 2,
1378 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1379 &buf, &bufSize);
1380 ok(ret, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
1381 nameValues[i].value.dwValueType, GetLastError());
1382 if (ret)
1384 compareNameValues(&nameValues[i].value,
1385 (const CERT_NAME_VALUE *)buf);
1386 LocalFree(buf);
1389 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE,
1390 embeddedNullNameValue.encoded, embeddedNullNameValue.encodedSize,
1391 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1392 &buf, &bufSize);
1393 /* Some Windows versions disallow name values with embedded NULLs, so
1394 * either success or failure is acceptable.
1396 if (ret)
1398 CERT_NAME_VALUE rdnEncodedValue = { CERT_RDN_ENCODED_BLOB,
1399 { sizeof(ia5EmbeddedNull), ia5EmbeddedNull } };
1400 CERT_NAME_VALUE embeddedNullValue = { CERT_RDN_IA5_STRING,
1401 { sizeof(embedded_null) - 1, (BYTE *)embedded_null } };
1402 const CERT_NAME_VALUE *got = (const CERT_NAME_VALUE *)buf,
1403 *expected = NULL;
1405 /* Some Windows versions decode name values with embedded NULLs,
1406 * others leave them encoded, even with the same version of crypt32.
1407 * Accept either.
1409 ok(got->dwValueType == CERT_RDN_ENCODED_BLOB ||
1410 got->dwValueType == CERT_RDN_IA5_STRING,
1411 "Expected CERT_RDN_ENCODED_BLOB or CERT_RDN_IA5_STRING, got %d\n",
1412 got->dwValueType);
1413 if (got->dwValueType == CERT_RDN_ENCODED_BLOB)
1414 expected = &rdnEncodedValue;
1415 else if (got->dwValueType == CERT_RDN_IA5_STRING)
1416 expected = &embeddedNullValue;
1417 if (expected)
1419 ok(got->Value.cbData == expected->Value.cbData,
1420 "String type %d: unexpected data size, got %d, expected %d\n",
1421 got->dwValueType, got->Value.cbData, expected->Value.cbData);
1422 if (got->Value.cbData && got->Value.pbData)
1423 ok(!memcmp(got->Value.pbData, expected->Value.pbData,
1424 min(got->Value.cbData, expected->Value.cbData)),
1425 "String type %d: unexpected value\n", expected->dwValueType);
1427 LocalFree(buf);
1431 static const BYTE emptyURL[] = { 0x30, 0x02, 0x86, 0x00 };
1432 static const BYTE emptyURLExtraBytes[] = { 0x30, 0x02, 0x86, 0x00, 0, 0, 0 };
1433 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e',
1434 'h','q','.','o','r','g',0 };
1435 static const BYTE encodedURL[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74,
1436 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e,
1437 0x6f, 0x72, 0x67 };
1438 static const WCHAR nihongoURL[] = { 'h','t','t','p',':','/','/',0x226f,
1439 0x575b, 0 };
1440 static const WCHAR dnsName[] = { 'w','i','n','e','h','q','.','o','r','g',0 };
1441 static const BYTE encodedDnsName[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69,
1442 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
1443 static const BYTE localhost[] = { 127, 0, 0, 1 };
1444 static const BYTE encodedIPAddr[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00,
1445 0x01 };
1446 static const unsigned char encodedCommonName[] = {
1447 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0};
1448 static const BYTE encodedOidName[] = { 0x30,0x04,0x88,0x02,0x2a,0x03 };
1449 static const BYTE encodedDirectoryName[] = {
1450 0x30,0x19,0xa4,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1451 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1453 static void test_encodeAltName(DWORD dwEncoding)
1455 CERT_ALT_NAME_INFO info = { 0 };
1456 CERT_ALT_NAME_ENTRY entry = { 0 };
1457 BYTE *buf = NULL;
1458 DWORD size = 0;
1459 BOOL ret;
1460 char oid[] = "1.2.3";
1462 /* Test with empty info */
1463 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1464 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1465 if (ret)
1467 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
1468 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
1469 LocalFree(buf);
1471 /* Test with an empty entry */
1472 info.cAltEntry = 1;
1473 info.rgAltEntry = &entry;
1474 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1475 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1476 ok(!ret && GetLastError() == E_INVALIDARG,
1477 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1478 /* Test with an empty pointer */
1479 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
1480 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1481 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1482 if (ret)
1484 ok(size == sizeof(emptyURL), "Wrong size %d\n", size);
1485 ok(!memcmp(buf, emptyURL, size), "Unexpected value\n");
1486 LocalFree(buf);
1488 /* Test with a real URL */
1489 U(entry).pwszURL = (LPWSTR)url;
1490 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1491 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1492 if (ret)
1494 ok(size == sizeof(encodedURL), "Wrong size %d\n", size);
1495 ok(!memcmp(buf, encodedURL, size), "Unexpected value\n");
1496 LocalFree(buf);
1498 /* Now with the URL containing an invalid IA5 char */
1499 U(entry).pwszURL = (LPWSTR)nihongoURL;
1500 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1501 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1502 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
1503 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
1504 /* The first invalid character is at index 7 */
1505 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
1506 "Expected invalid char at index 7, got %d\n",
1507 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
1508 /* Now with the URL missing a scheme */
1509 U(entry).pwszURL = (LPWSTR)dnsName;
1510 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1511 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1512 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1513 if (ret)
1515 /* This succeeds, but it shouldn't, so don't worry about conforming */
1516 LocalFree(buf);
1518 /* Now with a DNS name */
1519 entry.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
1520 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1521 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1522 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1523 if (ret)
1525 ok(size == sizeof(encodedDnsName), "Wrong size %d\n", size);
1526 ok(!memcmp(buf, encodedDnsName, size), "Unexpected value\n");
1527 LocalFree(buf);
1529 /* Test with an IP address */
1530 entry.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
1531 U(entry).IPAddress.cbData = sizeof(localhost);
1532 U(entry).IPAddress.pbData = (LPBYTE)localhost;
1533 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1534 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1535 if (ret)
1537 ok(size == sizeof(encodedIPAddr), "Wrong size %d\n", size);
1538 ok(!memcmp(buf, encodedIPAddr, size), "Unexpected value\n");
1539 LocalFree(buf);
1541 /* Test with OID */
1542 entry.dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID;
1543 U(entry).pszRegisteredID = oid;
1544 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1545 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1546 if (ret)
1548 ok(size == sizeof(encodedOidName), "Wrong size %d\n", size);
1549 ok(!memcmp(buf, encodedOidName, size), "Unexpected value\n");
1550 LocalFree(buf);
1552 /* Test with directory name */
1553 entry.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
1554 U(entry).DirectoryName.cbData = sizeof(encodedCommonName);
1555 U(entry).DirectoryName.pbData = (LPBYTE)encodedCommonName;
1556 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1557 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1558 if (ret)
1560 ok(size == sizeof(encodedDirectoryName), "Wrong size %d\n", size);
1561 ok(!memcmp(buf, encodedDirectoryName, size), "Unexpected value\n");
1562 LocalFree(buf);
1566 static void test_decodeAltName(DWORD dwEncoding)
1568 static const BYTE unimplementedType[] = { 0x30, 0x06, 0x85, 0x04, 0x7f,
1569 0x00, 0x00, 0x01 };
1570 static const BYTE bogusType[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00,
1571 0x01 };
1572 static const BYTE dns_embedded_null[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f,
1573 0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 };
1574 static const BYTE dns_embedded_bell[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f,
1575 0x6f,0x2e,0x63,0x6f,0x6d,0x07,0x62,0x61,0x64,0x64,0x69,0x65 };
1576 static const BYTE url_embedded_null[] = { 0x30,0x10,0x86,0x0e,0x66,0x6f,
1577 0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 };
1578 BOOL ret;
1579 BYTE *buf = NULL;
1580 DWORD bufSize = 0;
1581 CERT_ALT_NAME_INFO *info;
1583 /* Test some bogus ones first */
1584 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1585 unimplementedType, sizeof(unimplementedType), CRYPT_DECODE_ALLOC_FLAG,
1586 NULL, &buf, &bufSize);
1587 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
1588 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1589 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
1590 GetLastError());
1591 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1592 bogusType, sizeof(bogusType), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
1593 &bufSize);
1594 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
1595 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1596 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
1597 GetLastError());
1598 /* Now expected cases */
1599 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptySequence,
1600 emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1601 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1602 if (ret)
1604 info = (CERT_ALT_NAME_INFO *)buf;
1606 ok(info->cAltEntry == 0, "Expected 0 entries, got %d\n",
1607 info->cAltEntry);
1608 LocalFree(buf);
1610 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptyURL,
1611 emptyURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1612 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1613 if (ret)
1615 info = (CERT_ALT_NAME_INFO *)buf;
1617 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1618 info->cAltEntry);
1619 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1620 "Expected CERT_ALT_NAME_URL, got %d\n",
1621 info->rgAltEntry[0].dwAltNameChoice);
1622 ok(U(info->rgAltEntry[0]).pwszURL == NULL || !*U(info->rgAltEntry[0]).pwszURL,
1623 "Expected empty URL\n");
1624 LocalFree(buf);
1626 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1627 emptyURLExtraBytes, sizeof(emptyURLExtraBytes), 0, NULL, NULL, &bufSize);
1628 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1629 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedURL,
1630 encodedURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1631 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1632 if (ret)
1634 info = (CERT_ALT_NAME_INFO *)buf;
1636 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1637 info->cAltEntry);
1638 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1639 "Expected CERT_ALT_NAME_URL, got %d\n",
1640 info->rgAltEntry[0].dwAltNameChoice);
1641 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszURL, url), "Unexpected URL\n");
1642 LocalFree(buf);
1644 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedDnsName,
1645 encodedDnsName[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1646 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1647 if (ret)
1649 info = (CERT_ALT_NAME_INFO *)buf;
1651 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1652 info->cAltEntry);
1653 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1654 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1655 info->rgAltEntry[0].dwAltNameChoice);
1656 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszDNSName, dnsName),
1657 "Unexpected DNS name\n");
1658 LocalFree(buf);
1660 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedIPAddr,
1661 encodedIPAddr[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1662 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1663 if (ret)
1665 info = (CERT_ALT_NAME_INFO *)buf;
1667 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1668 info->cAltEntry);
1669 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS,
1670 "Expected CERT_ALT_NAME_IP_ADDRESS, got %d\n",
1671 info->rgAltEntry[0].dwAltNameChoice);
1672 ok(U(info->rgAltEntry[0]).IPAddress.cbData == sizeof(localhost),
1673 "Unexpected IP address length %d\n",
1674 U(info->rgAltEntry[0]).IPAddress.cbData);
1675 ok(!memcmp(U(info->rgAltEntry[0]).IPAddress.pbData, localhost,
1676 sizeof(localhost)), "Unexpected IP address value\n");
1677 LocalFree(buf);
1679 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedOidName,
1680 sizeof(encodedOidName), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1681 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1682 if (ret)
1684 info = (CERT_ALT_NAME_INFO *)buf;
1686 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1687 info->cAltEntry);
1688 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_REGISTERED_ID,
1689 "Expected CERT_ALT_NAME_REGISTERED_ID, got %d\n",
1690 info->rgAltEntry[0].dwAltNameChoice);
1691 ok(!strcmp(U(info->rgAltEntry[0]).pszRegisteredID, "1.2.3"),
1692 "Expected OID 1.2.3, got %s\n", U(info->rgAltEntry[0]).pszRegisteredID);
1693 LocalFree(buf);
1695 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1696 encodedDirectoryName, sizeof(encodedDirectoryName),
1697 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1698 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1699 if (ret)
1701 info = (CERT_ALT_NAME_INFO *)buf;
1703 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1704 info->cAltEntry);
1705 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME,
1706 "Expected CERT_ALT_NAME_DIRECTORY_NAME, got %d\n",
1707 info->rgAltEntry[0].dwAltNameChoice);
1708 ok(U(info->rgAltEntry[0]).DirectoryName.cbData ==
1709 sizeof(encodedCommonName), "Unexpected directory name length %d\n",
1710 U(info->rgAltEntry[0]).DirectoryName.cbData);
1711 ok(!memcmp(U(info->rgAltEntry[0]).DirectoryName.pbData,
1712 encodedCommonName, sizeof(encodedCommonName)),
1713 "Unexpected directory name value\n");
1714 LocalFree(buf);
1716 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1717 dns_embedded_null, sizeof(dns_embedded_null), CRYPT_DECODE_ALLOC_FLAG,
1718 NULL, &buf, &bufSize);
1719 /* Fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned about the
1720 * particular failure, just that it doesn't decode.
1721 * It succeeds on (broken) Windows versions that haven't addressed
1722 * embedded NULLs in alternate names.
1724 ok(!ret || broken(ret), "expected failure\n");
1725 /* An embedded bell character is allowed, however. */
1726 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1727 dns_embedded_bell, sizeof(dns_embedded_bell), CRYPT_DECODE_ALLOC_FLAG,
1728 NULL, &buf, &bufSize);
1729 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1730 if (ret)
1732 info = (CERT_ALT_NAME_INFO *)buf;
1734 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1735 info->cAltEntry);
1736 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1737 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1738 info->rgAltEntry[0].dwAltNameChoice);
1739 LocalFree(buf);
1741 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1742 url_embedded_null, sizeof(dns_embedded_null), CRYPT_DECODE_ALLOC_FLAG,
1743 NULL, &buf, &bufSize);
1744 /* Again, fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned
1745 * about the particular failure, just that it doesn't decode.
1746 * It succeeds on (broken) Windows versions that haven't addressed
1747 * embedded NULLs in alternate names.
1749 ok(!ret || broken(ret), "expected failure\n");
1752 struct UnicodeExpectedError
1754 DWORD valueType;
1755 LPCWSTR str;
1756 DWORD errorIndex;
1757 DWORD error;
1760 static const WCHAR oneW[] = { '1',0 };
1761 static const WCHAR aW[] = { 'a',0 };
1762 static const WCHAR quoteW[] = { '"', 0 };
1764 static struct UnicodeExpectedError unicodeErrors[] = {
1765 { CERT_RDN_ANY_TYPE, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1766 { CERT_RDN_ENCODED_BLOB, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1767 { CERT_RDN_OCTET_STRING, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1768 { CERT_RDN_NUMERIC_STRING, aW, 0, CRYPT_E_INVALID_NUMERIC_STRING },
1769 { CERT_RDN_PRINTABLE_STRING, quoteW, 0, CRYPT_E_INVALID_PRINTABLE_STRING },
1770 { CERT_RDN_IA5_STRING, nihongoURL, 7, CRYPT_E_INVALID_IA5_STRING },
1773 struct UnicodeExpectedResult
1775 DWORD valueType;
1776 LPCWSTR str;
1777 CRYPT_DATA_BLOB encoded;
1780 static BYTE oneNumeric[] = { 0x12, 0x01, 0x31 };
1781 static BYTE onePrintable[] = { 0x13, 0x01, 0x31 };
1782 static BYTE oneTeletex[] = { 0x14, 0x01, 0x31 };
1783 static BYTE oneVideotex[] = { 0x15, 0x01, 0x31 };
1784 static BYTE oneIA5[] = { 0x16, 0x01, 0x31 };
1785 static BYTE oneGraphic[] = { 0x19, 0x01, 0x31 };
1786 static BYTE oneVisible[] = { 0x1a, 0x01, 0x31 };
1787 static BYTE oneUniversal[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 };
1788 static BYTE oneGeneral[] = { 0x1b, 0x01, 0x31 };
1789 static BYTE oneBMP[] = { 0x1e, 0x02, 0x00, 0x31 };
1790 static BYTE oneUTF8[] = { 0x0c, 0x01, 0x31 };
1791 static BYTE nihongoT61[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,
1792 0x5b };
1793 static BYTE nihongoGeneral[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1794 0x6f,0x5b };
1795 static BYTE nihongoBMP[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,
1796 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
1797 static BYTE nihongoUTF8[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1798 0xe2,0x89,0xaf,0xe5,0x9d,0x9b };
1800 static struct UnicodeExpectedResult unicodeResults[] = {
1801 { CERT_RDN_NUMERIC_STRING, oneW, { sizeof(oneNumeric), oneNumeric } },
1802 { CERT_RDN_PRINTABLE_STRING, oneW, { sizeof(onePrintable), onePrintable } },
1803 { CERT_RDN_TELETEX_STRING, oneW, { sizeof(oneTeletex), oneTeletex } },
1804 { CERT_RDN_VIDEOTEX_STRING, oneW, { sizeof(oneVideotex), oneVideotex } },
1805 { CERT_RDN_IA5_STRING, oneW, { sizeof(oneIA5), oneIA5 } },
1806 { CERT_RDN_GRAPHIC_STRING, oneW, { sizeof(oneGraphic), oneGraphic } },
1807 { CERT_RDN_VISIBLE_STRING, oneW, { sizeof(oneVisible), oneVisible } },
1808 { CERT_RDN_UNIVERSAL_STRING, oneW, { sizeof(oneUniversal), oneUniversal } },
1809 { CERT_RDN_GENERAL_STRING, oneW, { sizeof(oneGeneral), oneGeneral } },
1810 { CERT_RDN_BMP_STRING, oneW, { sizeof(oneBMP), oneBMP } },
1811 { CERT_RDN_UTF8_STRING, oneW, { sizeof(oneUTF8), oneUTF8 } },
1812 { CERT_RDN_BMP_STRING, nihongoURL, { sizeof(nihongoBMP), nihongoBMP } },
1813 { CERT_RDN_UTF8_STRING, nihongoURL, { sizeof(nihongoUTF8), nihongoUTF8 } },
1816 static struct UnicodeExpectedResult unicodeWeirdness[] = {
1817 { CERT_RDN_TELETEX_STRING, nihongoURL, { sizeof(nihongoT61), nihongoT61 } },
1818 { CERT_RDN_GENERAL_STRING, nihongoURL, { sizeof(nihongoGeneral), nihongoGeneral } },
1821 static void test_encodeUnicodeNameValue(DWORD dwEncoding)
1823 BYTE *buf = NULL;
1824 DWORD size = 0, i;
1825 BOOL ret;
1826 CERT_NAME_VALUE value;
1828 if (0)
1830 /* Crashes on win9x */
1831 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, NULL,
1832 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1833 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1834 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1836 /* Have to have a string of some sort */
1837 value.dwValueType = 0; /* aka CERT_RDN_ANY_TYPE */
1838 value.Value.pbData = NULL;
1839 value.Value.cbData = 0;
1840 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1841 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1842 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1843 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1844 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1845 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1846 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1847 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1848 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1849 value.dwValueType = CERT_RDN_ANY_TYPE;
1850 value.Value.pbData = (LPBYTE)oneW;
1851 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1852 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1853 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1854 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1855 value.Value.cbData = sizeof(oneW);
1856 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1857 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1858 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1859 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1860 /* An encoded string with specified length isn't good enough either */
1861 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1862 value.Value.pbData = oneUniversal;
1863 value.Value.cbData = sizeof(oneUniversal);
1864 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1865 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1866 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1867 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1868 /* More failure checking */
1869 value.Value.cbData = 0;
1870 for (i = 0; i < ARRAY_SIZE(unicodeErrors); i++)
1872 value.Value.pbData = (LPBYTE)unicodeErrors[i].str;
1873 value.dwValueType = unicodeErrors[i].valueType;
1874 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1875 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1876 ok(!ret && GetLastError() == unicodeErrors[i].error,
1877 "Value type %d: expected %08x, got %08x\n", value.dwValueType,
1878 unicodeErrors[i].error, GetLastError());
1879 ok(size == unicodeErrors[i].errorIndex,
1880 "Expected error index %d, got %d\n", unicodeErrors[i].errorIndex,
1881 size);
1883 /* cbData can be zero if the string is NULL-terminated */
1884 value.Value.cbData = 0;
1885 for (i = 0; i < ARRAY_SIZE(unicodeResults); i++)
1887 value.Value.pbData = (LPBYTE)unicodeResults[i].str;
1888 value.dwValueType = unicodeResults[i].valueType;
1889 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1890 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1891 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
1892 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1893 if (ret)
1895 ok(size == unicodeResults[i].encoded.cbData,
1896 "Value type %d: expected size %d, got %d\n",
1897 value.dwValueType, unicodeResults[i].encoded.cbData, size);
1898 ok(!memcmp(unicodeResults[i].encoded.pbData, buf, size),
1899 "Value type %d: unexpected value\n", value.dwValueType);
1900 LocalFree(buf);
1903 /* These "encode," but they do so by truncating each unicode character
1904 * rather than properly encoding it. Kept separate from the proper results,
1905 * because the encoded forms won't decode to their original strings.
1907 for (i = 0; i < ARRAY_SIZE(unicodeWeirdness); i++)
1909 value.Value.pbData = (LPBYTE)unicodeWeirdness[i].str;
1910 value.dwValueType = unicodeWeirdness[i].valueType;
1911 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1912 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1913 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1914 if (ret)
1916 ok(size == unicodeWeirdness[i].encoded.cbData,
1917 "Value type %d: expected size %d, got %d\n",
1918 value.dwValueType, unicodeWeirdness[i].encoded.cbData, size);
1919 ok(!memcmp(unicodeWeirdness[i].encoded.pbData, buf, size),
1920 "Value type %d: unexpected value\n", value.dwValueType);
1921 LocalFree(buf);
1926 static void test_decodeUnicodeNameValue(DWORD dwEncoding)
1928 DWORD i;
1930 for (i = 0; i < ARRAY_SIZE(unicodeResults); i++)
1932 BYTE *buf = NULL;
1933 BOOL ret;
1934 DWORD size = 0;
1936 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE,
1937 unicodeResults[i].encoded.pbData, unicodeResults[i].encoded.cbData,
1938 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
1939 ok(ret || broken(GetLastError() == CRYPT_E_NOT_CHAR_STRING /* Win9x */),
1940 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1941 if (ret && buf)
1943 PCERT_NAME_VALUE value = (PCERT_NAME_VALUE)buf;
1945 ok(value->dwValueType == unicodeResults[i].valueType,
1946 "Expected value type %d, got %d\n", unicodeResults[i].valueType,
1947 value->dwValueType);
1948 ok(!wcsncmp((LPWSTR)value->Value.pbData, unicodeResults[i].str,
1949 value->Value.cbData / sizeof(WCHAR)),
1950 "Unexpected decoded value for index %d (value type %d)\n", i,
1951 unicodeResults[i].valueType);
1952 LocalFree(buf);
1957 static const unsigned char decoded_hi_octet[] = { 'h','i' };
1958 static const unsigned char encoded_hi_octet[] = { ASN_OCTETSTRING,2,'h','i' };
1959 static const unsigned char decoded_something_long_octet[] = {
1960 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g' };
1961 static const unsigned char encoded_something_long_octet[] = {
1962 ASN_OCTETSTRING,15,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g' };
1963 static const unsigned char encoded_empty_octet[] = { ASN_OCTETSTRING,0 };
1965 static void test_encodeOctets(DWORD dwEncoding)
1967 CRYPT_DATA_BLOB blob;
1968 DWORD i;
1970 static const struct {
1971 const BYTE *decoded;
1972 UINT decoded_size;
1973 const BYTE *encoded;
1974 UINT encoded_size;
1975 } tests[] = {
1977 decoded_hi_octet, sizeof(decoded_hi_octet),
1978 encoded_hi_octet, sizeof(encoded_hi_octet)
1980 decoded_something_long_octet, sizeof(decoded_something_long_octet),
1981 encoded_something_long_octet, sizeof(encoded_something_long_octet)
1983 encoded_empty_octet, 0,
1984 encoded_empty_octet, sizeof(encoded_empty_octet)
1988 for (i = 0; i < ARRAY_SIZE(tests); i++)
1990 BYTE *buf = NULL;
1991 BOOL ret;
1992 DWORD bufSize = 0;
1994 blob.cbData = tests[i].decoded_size;
1995 blob.pbData = (BYTE*)tests[i].decoded;
1996 ret = pCryptEncodeObjectEx(dwEncoding, X509_OCTET_STRING, &blob,
1997 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1998 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
1999 if (ret)
2001 ok(bufSize == tests[i].encoded_size, "[%u] buf size %u expected %u\n",
2002 i, bufSize, tests[i].encoded_size);
2003 ok(buf[0] == 4, "Got unexpected type %d for octet string (expected 4)\n", buf[0]);
2004 ok(buf[1] == tests[i].decoded_size, "[%u] Got length %d, expected %d\n",
2005 i, buf[1], tests[i].decoded_size);
2006 ok(!memcmp(buf, tests[i].encoded, tests[i].encoded_size), "[%u] Got unexpected value\n", i);
2007 LocalFree(buf);
2012 static const unsigned char encoded_constructed_hi_octet[] =
2013 { ASN_CONSTRUCTOR|ASN_OCTETSTRING,0x80, ASN_OCTETSTRING,2,'h','i', 0,0 };
2014 static const unsigned char encoded_constructed_hi_octet2[] =
2015 { ASN_CONSTRUCTOR|ASN_OCTETSTRING,4, ASN_OCTETSTRING,2,'h','i', 1,2,3 };
2016 static const unsigned char encoded_constructed_hi_octet3[] =
2017 { ASN_CONSTRUCTOR|ASN_OCTETSTRING,8, ASN_CONSTRUCTOR|ASN_OCTETSTRING,0x80, ASN_OCTETSTRING,2,'h','i', 0,0, 0,0 };
2018 static const unsigned char encoded_constructed_hi_octet_invalid_end[] =
2019 { ASN_CONSTRUCTOR|ASN_OCTETSTRING,0x80, ASN_OCTETSTRING,2,'h','i', 0,1 };
2021 static void test_decodeOctets(DWORD dwEncoding)
2023 DWORD i;
2025 static const struct {
2026 const BYTE *encoded;
2027 UINT encoded_size;
2028 const BYTE *decoded;
2029 UINT decoded_size;
2030 DWORD error;
2031 } tests[] = {
2033 encoded_hi_octet, sizeof(encoded_hi_octet),
2034 decoded_hi_octet, sizeof(decoded_hi_octet)
2036 encoded_something_long_octet, sizeof(encoded_something_long_octet),
2037 decoded_something_long_octet, sizeof(decoded_something_long_octet)
2039 encoded_constructed_hi_octet, sizeof(encoded_constructed_hi_octet),
2040 decoded_hi_octet, sizeof(decoded_hi_octet)
2042 encoded_constructed_hi_octet2, sizeof(encoded_constructed_hi_octet2),
2043 decoded_hi_octet, sizeof(decoded_hi_octet)
2045 encoded_constructed_hi_octet3, sizeof(encoded_constructed_hi_octet3),
2046 decoded_hi_octet, sizeof(decoded_hi_octet)
2048 encoded_empty_octet, sizeof(encoded_empty_octet),
2049 encoded_empty_octet, 0
2051 encoded_hi_octet, sizeof(encoded_hi_octet) - 1,
2052 NULL, 0, CRYPT_E_ASN1_EOD
2054 encoded_constructed_hi_octet, sizeof(encoded_constructed_hi_octet) - 1,
2055 NULL, 0, CRYPT_E_ASN1_EOD
2057 encoded_constructed_hi_octet_invalid_end, sizeof(encoded_constructed_hi_octet_invalid_end),
2058 NULL, 0, CRYPT_E_ASN1_CORRUPT
2062 for (i = 0; i < ARRAY_SIZE(tests); i++)
2064 BYTE *buf = NULL;
2065 BOOL ret;
2066 DWORD bufSize = 0;
2068 ret = pCryptDecodeObjectEx(dwEncoding, X509_OCTET_STRING,
2069 tests[i].encoded, tests[i].encoded_size,
2070 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2071 if (tests[i].error)
2073 ok(!ret && GetLastError() == tests[i].error,
2074 "[%u] CryptDecodeObjectEx returned %x(%x)\n", i, ret, GetLastError());
2075 continue;
2077 ok(ret, "[%u] CryptDecodeObjectEx failed: %08x\n", i, GetLastError());
2078 ok(bufSize >= sizeof(CRYPT_DATA_BLOB) + tests[i].decoded_size,
2079 "[%u] Expected size >= %d, got %d\n", i,
2080 (int)sizeof(CRYPT_DATA_BLOB) + tests[i].decoded_size, bufSize);
2081 ok(buf != NULL, "Expected allocated buffer\n");
2082 if (ret)
2084 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)buf;
2086 ok (blob->cbData == tests[i].decoded_size, "[%u] cbData = %u\n", i, blob->cbData);
2087 if (blob->cbData)
2088 ok(!memcmp(blob->pbData, tests[i].decoded, blob->cbData),
2089 "Unexpected value\n");
2090 LocalFree(buf);
2095 static const BYTE bytesToEncode[] = { 0xff, 0xff };
2097 struct encodedBits
2099 DWORD cUnusedBits;
2100 const BYTE *encoded;
2101 DWORD cbDecoded;
2102 const BYTE *decoded;
2105 static const unsigned char bin52[] = { 0x03,0x03,0x00,0xff,0xff };
2106 static const unsigned char bin53[] = { 0xff,0xff };
2107 static const unsigned char bin54[] = { 0x03,0x03,0x01,0xff,0xfe };
2108 static const unsigned char bin55[] = { 0xff,0xfe };
2109 static const unsigned char bin56[] = { 0x03,0x02,0x01,0xfe };
2110 static const unsigned char bin57[] = { 0xfe };
2112 static const struct encodedBits bits[] = {
2113 /* normal test cases */
2114 { 0, bin52, 2, bin53 },
2115 { 1, bin54, 2, bin55 },
2116 /* strange test case, showing cUnusedBits >= 8 is allowed */
2117 { 9, bin56, 1, bin57 },
2120 static void test_encodeBits(DWORD dwEncoding)
2122 DWORD i;
2124 for (i = 0; i < ARRAY_SIZE(bits); i++)
2126 CRYPT_BIT_BLOB blob;
2127 BOOL ret;
2128 BYTE *buf = NULL;
2129 DWORD bufSize = 0;
2131 blob.cbData = sizeof(bytesToEncode);
2132 blob.pbData = (BYTE *)bytesToEncode;
2133 blob.cUnusedBits = bits[i].cUnusedBits;
2134 ret = pCryptEncodeObjectEx(dwEncoding, X509_BITS, &blob,
2135 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2136 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2137 if (ret)
2139 ok(bufSize == bits[i].encoded[1] + 2,
2140 "%d: Got unexpected size %d, expected %d\n", i, bufSize,
2141 bits[i].encoded[1] + 2);
2142 ok(!memcmp(buf, bits[i].encoded, bits[i].encoded[1] + 2),
2143 "%d: Unexpected value\n", i);
2144 LocalFree(buf);
2149 static void test_decodeBits(DWORD dwEncoding)
2151 static const BYTE ber[] = "\x03\x02\x01\xff";
2152 static const BYTE berDecoded = 0xfe;
2153 DWORD i;
2154 BOOL ret;
2155 BYTE *buf = NULL;
2156 DWORD bufSize = 0;
2158 /* normal cases */
2159 for (i = 0; i < ARRAY_SIZE(bits); i++)
2161 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, bits[i].encoded,
2162 bits[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
2163 &bufSize);
2164 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2165 if (ret)
2167 CRYPT_BIT_BLOB *blob;
2169 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + bits[i].cbDecoded,
2170 "Got unexpected size %d\n", bufSize);
2171 blob = (CRYPT_BIT_BLOB *)buf;
2172 ok(blob->cbData == bits[i].cbDecoded,
2173 "Got unexpected length %d, expected %d\n", blob->cbData,
2174 bits[i].cbDecoded);
2175 if (blob->cbData && bits[i].cbDecoded)
2176 ok(!memcmp(blob->pbData, bits[i].decoded, bits[i].cbDecoded),
2177 "Unexpected value\n");
2178 LocalFree(buf);
2181 /* special case: check that something that's valid in BER but not in DER
2182 * decodes successfully
2184 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, ber, ber[1] + 2,
2185 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2186 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2187 if (ret)
2189 CRYPT_BIT_BLOB *blob;
2191 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + sizeof(berDecoded),
2192 "Got unexpected size %d\n", bufSize);
2193 blob = (CRYPT_BIT_BLOB *)buf;
2194 ok(blob->cbData == sizeof(berDecoded),
2195 "Got unexpected length %d\n", blob->cbData);
2196 if (blob->cbData)
2197 ok(*blob->pbData == berDecoded, "Unexpected value\n");
2198 LocalFree(buf);
2202 struct Constraints2
2204 CERT_BASIC_CONSTRAINTS2_INFO info;
2205 const BYTE *encoded;
2208 static const unsigned char bin59[] = { 0x30,0x00 };
2209 static const unsigned char bin60[] = { 0x30,0x03,0x01,0x01,0xff };
2210 static const unsigned char bin61[] = { 0x30,0x03,0x02,0x01,0x00 };
2211 static const unsigned char bin62[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2212 static const struct Constraints2 constraints2[] = {
2213 /* empty constraints */
2214 { { FALSE, FALSE, 0}, bin59 },
2215 /* can be a CA */
2216 { { TRUE, FALSE, 0}, bin60 },
2217 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well,
2218 * but that's not the case
2220 { { FALSE, TRUE, 0}, bin61 },
2221 /* can be a CA and has path length constraints set */
2222 { { TRUE, TRUE, 1}, bin62 },
2225 static const BYTE emptyConstraint[] = { 0x30, 0x03, 0x03, 0x01, 0x00 };
2226 static const BYTE encodedDomainName[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11,
2227 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
2228 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
2229 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2230 static const BYTE constraintWithDomainName[] = { 0x30, 0x32, 0x03, 0x01, 0x00,
2231 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
2232 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30,
2233 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
2234 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2236 static void test_encodeBasicConstraints(DWORD dwEncoding)
2238 DWORD i, bufSize = 0;
2239 CERT_BASIC_CONSTRAINTS_INFO info = { { 0 } };
2240 CERT_NAME_BLOB nameBlob = { sizeof(encodedDomainName),
2241 (LPBYTE)encodedDomainName };
2242 BOOL ret;
2243 BYTE *buf = NULL;
2245 /* First test with the simpler info2 */
2246 for (i = 0; i < ARRAY_SIZE(constraints2); i++)
2248 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2249 &constraints2[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf,
2250 &bufSize);
2251 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2252 if (ret)
2254 ok(bufSize == constraints2[i].encoded[1] + 2,
2255 "Expected %d bytes, got %d\n", constraints2[i].encoded[1] + 2,
2256 bufSize);
2257 ok(!memcmp(buf, constraints2[i].encoded,
2258 constraints2[i].encoded[1] + 2), "Unexpected value\n");
2259 LocalFree(buf);
2262 /* Now test with more complex basic constraints */
2263 info.SubjectType.cbData = 0;
2264 info.fPathLenConstraint = FALSE;
2265 info.cSubtreesConstraint = 0;
2266 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2267 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2268 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2269 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2270 if (ret)
2272 ok(bufSize == sizeof(emptyConstraint), "Wrong size %d\n", bufSize);
2273 ok(!memcmp(buf, emptyConstraint, sizeof(emptyConstraint)),
2274 "Unexpected value\n");
2275 LocalFree(buf);
2277 /* None of the certs I examined had any subtree constraint, but I test one
2278 * anyway just in case.
2280 info.cSubtreesConstraint = 1;
2281 info.rgSubtreesConstraint = &nameBlob;
2282 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2283 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2284 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2285 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2286 if (ret)
2288 ok(bufSize == sizeof(constraintWithDomainName), "Wrong size %d\n", bufSize);
2289 ok(!memcmp(buf, constraintWithDomainName,
2290 sizeof(constraintWithDomainName)), "Unexpected value\n");
2291 LocalFree(buf);
2293 /* FIXME: test encoding with subject type. */
2296 static const unsigned char bin63[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 };
2298 static void test_decodeBasicConstraints(DWORD dwEncoding)
2300 static const BYTE inverted[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01,
2301 0xff };
2302 static const struct Constraints2 badBool = { { TRUE, TRUE, 1 }, bin63 };
2303 DWORD i;
2304 BOOL ret;
2305 BYTE *buf = NULL;
2306 DWORD bufSize = 0;
2308 /* First test with simpler info2 */
2309 for (i = 0; i < ARRAY_SIZE(constraints2); i++)
2311 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2312 constraints2[i].encoded, constraints2[i].encoded[1] + 2,
2313 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2314 ok(ret, "CryptDecodeObjectEx failed for item %d: %08x\n", i,
2315 GetLastError());
2316 if (ret)
2318 CERT_BASIC_CONSTRAINTS2_INFO *info =
2319 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2321 ok(!memcmp(info, &constraints2[i].info, sizeof(*info)),
2322 "Unexpected value for item %d\n", i);
2323 LocalFree(buf);
2326 /* Check with the order of encoded elements inverted */
2327 buf = (PBYTE)1;
2328 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2329 inverted, inverted[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
2330 &bufSize);
2331 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2332 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2333 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2334 GetLastError());
2335 ok(!buf, "Expected buf to be set to NULL\n");
2336 /* Check with a non-DER bool */
2337 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2338 badBool.encoded, badBool.encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2339 &buf, &bufSize);
2340 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2341 if (ret)
2343 CERT_BASIC_CONSTRAINTS2_INFO *info =
2344 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2346 ok(!memcmp(info, &badBool.info, sizeof(*info)), "Unexpected value\n");
2347 LocalFree(buf);
2349 /* Check with a non-basic constraints value */
2350 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2351 encodedCommonName, encodedCommonName[1] + 2,
2352 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2353 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2354 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2355 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2356 GetLastError());
2357 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */
2358 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2359 emptyConstraint, sizeof(emptyConstraint), CRYPT_DECODE_ALLOC_FLAG, NULL,
2360 &buf, &bufSize);
2361 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2362 if (ret)
2364 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2366 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2367 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2368 ok(info->cSubtreesConstraint == 0, "Expected no subtree constraints\n");
2369 LocalFree(buf);
2371 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2372 constraintWithDomainName, sizeof(constraintWithDomainName),
2373 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2374 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2375 if (ret)
2377 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2379 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2380 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2381 ok(info->cSubtreesConstraint == 1, "Expected a subtree constraint\n");
2382 if (info->cSubtreesConstraint && info->rgSubtreesConstraint)
2384 ok(info->rgSubtreesConstraint[0].cbData ==
2385 sizeof(encodedDomainName), "Wrong size %d\n",
2386 info->rgSubtreesConstraint[0].cbData);
2387 ok(!memcmp(info->rgSubtreesConstraint[0].pbData, encodedDomainName,
2388 sizeof(encodedDomainName)), "Unexpected value\n");
2390 LocalFree(buf);
2394 /* These are terrible public keys of course, I'm just testing encoding */
2395 static const BYTE modulus1[] = { 0,0,0,1,1,1,1,1 };
2396 static const BYTE modulus2[] = { 1,1,1,1,1,0,0,0 };
2397 static const BYTE modulus3[] = { 0x80,1,1,1,1,0,0,0 };
2398 static const BYTE modulus4[] = { 1,1,1,1,1,0,0,0x80 };
2399 static const BYTE mod1_encoded[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 };
2400 static const BYTE mod2_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2401 static const BYTE mod3_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 };
2402 static const BYTE mod4_encoded[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2404 struct EncodedRSAPubKey
2406 const BYTE *modulus;
2407 size_t modulusLen;
2408 const BYTE *encoded;
2409 size_t decodedModulusLen;
2412 static const struct EncodedRSAPubKey rsaPubKeys[] = {
2413 { modulus1, sizeof(modulus1), mod1_encoded, sizeof(modulus1) },
2414 { modulus2, sizeof(modulus2), mod2_encoded, 5 },
2415 { modulus3, sizeof(modulus3), mod3_encoded, 5 },
2416 { modulus4, sizeof(modulus4), mod4_encoded, 8 },
2419 static void test_encodeRsaPublicKey(DWORD dwEncoding)
2421 BYTE toEncode[sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + sizeof(modulus1)];
2422 BLOBHEADER *hdr = (BLOBHEADER *)toEncode;
2423 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(toEncode + sizeof(BLOBHEADER));
2424 BOOL ret;
2425 BYTE *buf = NULL;
2426 DWORD bufSize = 0, i;
2428 /* Try with a bogus blob type */
2429 hdr->bType = 2;
2430 hdr->bVersion = CUR_BLOB_VERSION;
2431 hdr->reserved = 0;
2432 hdr->aiKeyAlg = CALG_RSA_KEYX;
2433 rsaPubKey->magic = 0x31415352;
2434 rsaPubKey->bitlen = sizeof(modulus1) * 8;
2435 rsaPubKey->pubexp = 65537;
2436 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), modulus1,
2437 sizeof(modulus1));
2439 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2440 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2441 ok(!ret && GetLastError() == E_INVALIDARG,
2442 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2443 /* Now with a bogus reserved field */
2444 hdr->bType = PUBLICKEYBLOB;
2445 hdr->reserved = 1;
2446 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2447 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2448 if (ret)
2450 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2451 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2452 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2453 LocalFree(buf);
2455 /* Now with a bogus blob version */
2456 hdr->reserved = 0;
2457 hdr->bVersion = 0;
2458 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2459 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2460 if (ret)
2462 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2463 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2464 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2465 LocalFree(buf);
2467 /* And with a bogus alg ID */
2468 hdr->bVersion = CUR_BLOB_VERSION;
2469 hdr->aiKeyAlg = CALG_DES;
2470 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2471 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2472 if (ret)
2474 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2475 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2476 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2477 LocalFree(buf);
2479 /* Check a couple of RSA-related OIDs */
2480 hdr->aiKeyAlg = CALG_RSA_KEYX;
2481 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_RSA,
2482 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2483 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2484 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2485 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2486 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2487 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2488 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2489 /* Finally, all valid */
2490 hdr->aiKeyAlg = CALG_RSA_KEYX;
2491 for (i = 0; i < ARRAY_SIZE(rsaPubKeys); i++)
2493 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2494 rsaPubKeys[i].modulus, rsaPubKeys[i].modulusLen);
2495 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2496 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2497 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2498 if (ret)
2500 ok(bufSize == rsaPubKeys[i].encoded[1] + 2,
2501 "Expected size %d, got %d\n", rsaPubKeys[i].encoded[1] + 2,
2502 bufSize);
2503 ok(!memcmp(buf, rsaPubKeys[i].encoded, bufSize),
2504 "Unexpected value\n");
2505 LocalFree(buf);
2510 static void test_decodeRsaPublicKey(DWORD dwEncoding)
2512 DWORD i;
2513 LPBYTE buf = NULL;
2514 DWORD bufSize = 0;
2515 BOOL ret;
2517 /* Try with a bad length */
2518 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2519 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1],
2520 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2521 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
2522 GetLastError() == OSS_MORE_INPUT /* Win9x/NT4 */),
2523 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n",
2524 GetLastError());
2525 /* Try with a couple of RSA-related OIDs */
2526 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_RSA,
2527 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2528 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2529 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2530 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2531 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2532 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2533 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2534 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2535 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2536 /* Now try success cases */
2537 for (i = 0; i < ARRAY_SIZE(rsaPubKeys); i++)
2539 bufSize = 0;
2540 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2541 rsaPubKeys[i].encoded, rsaPubKeys[i].encoded[1] + 2,
2542 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2543 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2544 if (ret)
2546 BLOBHEADER *hdr = (BLOBHEADER *)buf;
2547 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER));
2549 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2550 rsaPubKeys[i].decodedModulusLen,
2551 "Wrong size %d\n", bufSize);
2552 ok(hdr->bType == PUBLICKEYBLOB,
2553 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB,
2554 hdr->bType);
2555 ok(hdr->bVersion == CUR_BLOB_VERSION,
2556 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
2557 CUR_BLOB_VERSION, hdr->bVersion);
2558 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n",
2559 hdr->reserved);
2560 ok(hdr->aiKeyAlg == CALG_RSA_KEYX,
2561 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg);
2562 ok(rsaPubKey->magic == 0x31415352,
2563 "Expected magic RSA1, got %08x\n", rsaPubKey->magic);
2564 ok(rsaPubKey->bitlen == rsaPubKeys[i].decodedModulusLen * 8,
2565 "Wrong bit len %d\n", rsaPubKey->bitlen);
2566 ok(rsaPubKey->pubexp == 65537, "Expected pubexp 65537, got %d\n",
2567 rsaPubKey->pubexp);
2568 ok(!memcmp(buf + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2569 rsaPubKeys[i].modulus, rsaPubKeys[i].decodedModulusLen),
2570 "Unexpected modulus\n");
2571 LocalFree(buf);
2576 static const BYTE intSequence[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01,
2577 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02,
2578 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2580 static const BYTE mixedSequence[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
2581 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f,
2582 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02,
2583 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2585 static void test_encodeSequenceOfAny(DWORD dwEncoding)
2587 CRYPT_DER_BLOB blobs[ARRAY_SIZE(ints)];
2588 CRYPT_SEQUENCE_OF_ANY seq;
2589 DWORD i;
2590 BOOL ret;
2591 BYTE *buf = NULL;
2592 DWORD bufSize = 0;
2594 /* Encode a homogeneous sequence */
2595 for (i = 0; i < ARRAY_SIZE(ints); i++)
2597 blobs[i].cbData = ints[i].encoded[1] + 2;
2598 blobs[i].pbData = (BYTE *)ints[i].encoded;
2600 seq.cValue = ARRAY_SIZE(ints);
2601 seq.rgValue = blobs;
2603 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2604 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2605 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2606 if (ret)
2608 ok(bufSize == sizeof(intSequence), "Wrong size %d\n", bufSize);
2609 ok(!memcmp(buf, intSequence, intSequence[1] + 2), "Unexpected value\n");
2610 LocalFree(buf);
2612 /* Change the type of the first element in the sequence, and give it
2613 * another go
2615 blobs[0].cbData = times[0].encodedTime[1] + 2;
2616 blobs[0].pbData = (BYTE *)times[0].encodedTime;
2617 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2618 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2619 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2620 if (ret)
2622 ok(bufSize == sizeof(mixedSequence), "Wrong size %d\n", bufSize);
2623 ok(!memcmp(buf, mixedSequence, mixedSequence[1] + 2),
2624 "Unexpected value\n");
2625 LocalFree(buf);
2629 static void test_decodeSequenceOfAny(DWORD dwEncoding)
2631 BOOL ret;
2632 BYTE *buf = NULL;
2633 DWORD bufSize = 0;
2635 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, intSequence,
2636 intSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2637 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2638 if (ret)
2640 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2641 DWORD i;
2643 ok(seq->cValue == ARRAY_SIZE(ints), "Wrong elements %d\n", seq->cValue);
2644 for (i = 0; i < min(seq->cValue, ARRAY_SIZE(ints)); i++)
2646 ok(seq->rgValue[i].cbData == ints[i].encoded[1] + 2,
2647 "Expected %d bytes, got %d\n", ints[i].encoded[1] + 2,
2648 seq->rgValue[i].cbData);
2649 ok(!memcmp(seq->rgValue[i].pbData, ints[i].encoded,
2650 ints[i].encoded[1] + 2), "Unexpected value\n");
2652 LocalFree(buf);
2654 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, mixedSequence,
2655 mixedSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
2656 &bufSize);
2657 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2658 if (ret)
2660 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2662 ok(seq->cValue == ARRAY_SIZE(ints), "Wrong elements %d\n", seq->cValue);
2663 /* Just check the first element since it's all that changed */
2664 ok(seq->rgValue[0].cbData == times[0].encodedTime[1] + 2,
2665 "Expected %d bytes, got %d\n", times[0].encodedTime[1] + 2,
2666 seq->rgValue[0].cbData);
2667 ok(!memcmp(seq->rgValue[0].pbData, times[0].encodedTime,
2668 times[0].encodedTime[1] + 2), "Unexpected value\n");
2669 LocalFree(buf);
2673 struct encodedExtensions
2675 CERT_EXTENSIONS exts;
2676 const BYTE *encoded;
2679 static BYTE crit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2680 static BYTE noncrit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2681 static CHAR oid_basic_constraints2[] = szOID_BASIC_CONSTRAINTS2;
2682 static CERT_EXTENSION criticalExt =
2683 { oid_basic_constraints2, TRUE, { 8, crit_ext_data } };
2684 static CERT_EXTENSION nonCriticalExt =
2685 { oid_basic_constraints2, FALSE, { 8, noncrit_ext_data } };
2686 static CHAR oid_short[] = "1.1";
2687 static CERT_EXTENSION extWithShortOid =
2688 { oid_short, FALSE, { 0, NULL } };
2690 static const BYTE ext0[] = { 0x30,0x00 };
2691 static const BYTE ext1[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2692 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2693 static const BYTE ext2[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2694 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2695 static const BYTE ext3[] = { 0x30,0x07,0x30,0x05,0x06,0x01,0x29,0x04,0x00 };
2697 static const struct encodedExtensions exts[] = {
2698 { { 0, NULL }, ext0 },
2699 { { 1, &criticalExt }, ext1 },
2700 { { 1, &nonCriticalExt }, ext2 },
2701 { { 1, &extWithShortOid }, ext3 }
2704 static void test_encodeExtensions(DWORD dwEncoding)
2706 DWORD i;
2708 for (i = 0; i < ARRAY_SIZE(exts); i++)
2710 BOOL ret;
2711 BYTE *buf = NULL;
2712 DWORD bufSize = 0;
2714 ret = pCryptEncodeObjectEx(dwEncoding, X509_EXTENSIONS, &exts[i].exts,
2715 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2716 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2717 if (ret)
2719 ok(bufSize == exts[i].encoded[1] + 2,
2720 "Expected %d bytes, got %d\n", exts[i].encoded[1] + 2, bufSize);
2721 ok(!memcmp(buf, exts[i].encoded, exts[i].encoded[1] + 2),
2722 "Unexpected value\n");
2723 LocalFree(buf);
2728 static void test_decodeExtensions(DWORD dwEncoding)
2730 DWORD i;
2732 for (i = 0; i < ARRAY_SIZE(exts); i++)
2734 BOOL ret;
2735 BYTE *buf = NULL;
2736 DWORD bufSize = 0;
2738 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS,
2739 exts[i].encoded, exts[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2740 NULL, &buf, &bufSize);
2741 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2742 if (ret)
2744 CERT_EXTENSIONS *ext = (CERT_EXTENSIONS *)buf;
2745 DWORD j;
2747 ok(ext->cExtension == exts[i].exts.cExtension,
2748 "Expected %d extensions, see %d\n", exts[i].exts.cExtension,
2749 ext->cExtension);
2750 for (j = 0; j < min(ext->cExtension, exts[i].exts.cExtension); j++)
2752 ok(!strcmp(ext->rgExtension[j].pszObjId,
2753 exts[i].exts.rgExtension[j].pszObjId),
2754 "Expected OID %s, got %s\n",
2755 exts[i].exts.rgExtension[j].pszObjId,
2756 ext->rgExtension[j].pszObjId);
2757 ok(!memcmp(ext->rgExtension[j].Value.pbData,
2758 exts[i].exts.rgExtension[j].Value.pbData,
2759 exts[i].exts.rgExtension[j].Value.cbData),
2760 "Unexpected value\n");
2762 LocalFree(buf);
2764 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS,
2765 exts[i].encoded, exts[i].encoded[1] + 2, 0, NULL, NULL, &bufSize);
2766 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2767 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bufSize);
2768 if (buf)
2770 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS,
2771 exts[i].encoded, exts[i].encoded[1] + 2, 0, NULL, buf, &bufSize);
2772 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2773 HeapFree(GetProcessHeap(), 0, buf);
2778 /* MS encodes public key info with a NULL if the algorithm identifier's
2779 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2780 * it encodes them by omitting the algorithm parameters. It accepts either
2781 * form for decoding.
2783 struct encodedPublicKey
2785 CERT_PUBLIC_KEY_INFO info;
2786 const BYTE *encoded;
2787 const BYTE *encodedNoNull;
2788 CERT_PUBLIC_KEY_INFO decoded;
2791 static const BYTE aKey[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2792 0xe, 0xf };
2793 static const BYTE params[] = { 0x02, 0x01, 0x01 };
2795 static const unsigned char bin64[] = {
2796 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2797 static const unsigned char bin65[] = {
2798 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2799 static const unsigned char bin66[] = {
2800 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2801 static const unsigned char bin67[] = {
2802 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2803 static const unsigned char bin68[] = {
2804 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01,
2805 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2806 static const unsigned char bin69[] = {
2807 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2808 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2809 static const unsigned char bin70[] = {
2810 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2811 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2812 0x0f};
2813 static const unsigned char bin71[] = {
2814 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2815 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2816 0x0f};
2817 static unsigned char bin72[] = { 0x05,0x00};
2819 static CHAR oid_bogus[] = "1.2.3",
2820 oid_rsa[] = szOID_RSA;
2822 static const struct encodedPublicKey pubKeys[] = {
2823 /* with a bogus OID */
2824 { { { oid_bogus, { 0, NULL } }, { 0, NULL, 0 } },
2825 bin64, bin65,
2826 { { oid_bogus, { 2, bin72 } }, { 0, NULL, 0 } } },
2827 /* some normal keys */
2828 { { { oid_rsa, { 0, NULL } }, { 0, NULL, 0} },
2829 bin66, bin67,
2830 { { oid_rsa, { 2, bin72 } }, { 0, NULL, 0 } } },
2831 { { { oid_rsa, { 0, NULL } }, { sizeof(aKey), (BYTE *)aKey, 0} },
2832 bin68, bin69,
2833 { { oid_rsa, { 2, bin72 } }, { sizeof(aKey), (BYTE *)aKey, 0} } },
2834 /* with add'l parameters--note they must be DER-encoded */
2835 { { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2836 (BYTE *)aKey, 0 } },
2837 bin70, bin71,
2838 { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2839 (BYTE *)aKey, 0 } } },
2842 static void test_encodePublicKeyInfo(DWORD dwEncoding)
2844 DWORD i;
2846 for (i = 0; i < ARRAY_SIZE(pubKeys); i++)
2848 BOOL ret;
2849 BYTE *buf = NULL;
2850 DWORD bufSize = 0;
2852 ret = pCryptEncodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2853 &pubKeys[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf,
2854 &bufSize);
2855 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2856 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2857 if (ret)
2859 ok(bufSize == pubKeys[i].encoded[1] + 2,
2860 "Expected %d bytes, got %d\n", pubKeys[i].encoded[1] + 2, bufSize);
2861 if (bufSize == pubKeys[i].encoded[1] + 2)
2862 ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2),
2863 "Unexpected value\n");
2864 LocalFree(buf);
2869 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO *expected,
2870 const CERT_PUBLIC_KEY_INFO *got)
2872 ok(!strcmp(expected->Algorithm.pszObjId, got->Algorithm.pszObjId),
2873 "Expected OID %s, got %s\n", expected->Algorithm.pszObjId,
2874 got->Algorithm.pszObjId);
2875 ok(expected->Algorithm.Parameters.cbData ==
2876 got->Algorithm.Parameters.cbData,
2877 "Expected parameters of %d bytes, got %d\n",
2878 expected->Algorithm.Parameters.cbData, got->Algorithm.Parameters.cbData);
2879 if (expected->Algorithm.Parameters.cbData)
2880 ok(!memcmp(expected->Algorithm.Parameters.pbData,
2881 got->Algorithm.Parameters.pbData, got->Algorithm.Parameters.cbData),
2882 "Unexpected algorithm parameters\n");
2883 ok(expected->PublicKey.cbData == got->PublicKey.cbData,
2884 "Expected public key of %d bytes, got %d\n",
2885 expected->PublicKey.cbData, got->PublicKey.cbData);
2886 if (expected->PublicKey.cbData)
2887 ok(!memcmp(expected->PublicKey.pbData, got->PublicKey.pbData,
2888 got->PublicKey.cbData), "Unexpected public key value\n");
2891 static void test_decodePublicKeyInfo(DWORD dwEncoding)
2893 static const BYTE bogusPubKeyInfo[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
2894 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
2895 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
2896 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2897 DWORD i;
2898 BOOL ret;
2899 BYTE *buf = NULL;
2900 DWORD bufSize = 0;
2902 for (i = 0; i < ARRAY_SIZE(pubKeys); i++)
2904 /* The NULL form decodes to the decoded member */
2905 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2906 pubKeys[i].encoded, pubKeys[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2907 NULL, &buf, &bufSize);
2908 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2909 if (ret)
2911 comparePublicKeyInfo(&pubKeys[i].decoded,
2912 (CERT_PUBLIC_KEY_INFO *)buf);
2913 LocalFree(buf);
2915 /* The non-NULL form decodes to the original */
2916 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2917 pubKeys[i].encodedNoNull, pubKeys[i].encodedNoNull[1] + 2,
2918 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2919 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2920 if (ret)
2922 comparePublicKeyInfo(&pubKeys[i].info, (CERT_PUBLIC_KEY_INFO *)buf);
2923 LocalFree(buf);
2926 /* Test with bogus (not valid DER) parameters */
2927 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2928 bogusPubKeyInfo, bogusPubKeyInfo[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2929 NULL, &buf, &bufSize);
2930 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2931 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2932 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2933 GetLastError());
2936 static const BYTE v1Cert[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
2937 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2938 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
2939 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
2940 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2941 static const BYTE v2Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02,
2942 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2943 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2944 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2945 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2946 static const BYTE v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2947 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2948 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2949 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2950 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2951 static const BYTE v4Cert[] = {
2952 0x30,0x38,0xa0,0x03,0x02,0x01,0x03,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,
2953 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
2954 0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
2955 0x30,0x30,0x30,0x5a,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00 };
2956 static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
2957 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2958 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2959 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2960 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2961 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2962 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2963 static const BYTE v1CertWithSerial[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
2964 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2965 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2966 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2967 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2968 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2969 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2970 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2971 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
2972 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
2973 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
2974 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
2975 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
2976 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
2977 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
2978 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
2979 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2980 static const BYTE v1CertWithPubKey[] = {
2981 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2982 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2983 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2984 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2985 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2986 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2987 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2988 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2989 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
2990 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
2991 0x01,0x01 };
2992 static const BYTE v1CertWithPubKeyNoNull[] = {
2993 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2994 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2995 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2996 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2997 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2998 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2999 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
3000 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
3001 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
3002 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3003 static const BYTE v1CertWithSubjectKeyId[] = {
3004 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
3005 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
3006 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
3007 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3008 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
3009 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
3010 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
3011 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
3012 0x4c,0x61,0x6e,0x67,0x00 };
3013 static const BYTE v1CertWithIssuerUniqueId[] = {
3014 0x30,0x38,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
3015 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
3016 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
3017 0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x81,0x02,0x00,0x01 };
3018 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueId[] = {
3019 0x30,0x81,0x99,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
3020 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
3021 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
3022 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3023 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
3024 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
3025 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
3026 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
3027 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,
3028 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
3029 0x01,0x01,0xff,0x02,0x01,0x01 };
3030 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull[] = {
3031 0x30,0x81,0x97,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
3032 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
3033 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
3034 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3035 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
3036 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
3037 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
3038 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
3039 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
3040 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
3041 0xff,0x02,0x01,0x01 };
3043 static const BYTE serialNum[] = { 0x01 };
3045 static void test_encodeCertToBeSigned(DWORD dwEncoding)
3047 BOOL ret;
3048 BYTE *buf = NULL;
3049 DWORD size = 0;
3050 CERT_INFO info = { 0 };
3051 static char oid_rsa_rsa[] = szOID_RSA_RSA;
3052 static char oid_subject_key_identifier[] = szOID_SUBJECT_KEY_IDENTIFIER;
3053 CERT_EXTENSION ext;
3055 if (0)
3057 /* Test with NULL pvStructInfo (crashes on win9x) */
3058 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL,
3059 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3060 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3061 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3063 /* Test with a V1 cert */
3064 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3065 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3066 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3067 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3068 if (ret)
3070 ok(size == v1Cert[1] + 2, "Expected size %d, got %d\n",
3071 v1Cert[1] + 2, size);
3072 ok(!memcmp(buf, v1Cert, size), "Got unexpected value\n");
3073 LocalFree(buf);
3075 /* Test v2 cert */
3076 info.dwVersion = CERT_V2;
3077 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3078 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3079 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3080 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3081 if (ret)
3083 ok(size == sizeof(v2Cert), "Wrong size %d\n", size);
3084 ok(!memcmp(buf, v2Cert, size), "Got unexpected value\n");
3085 LocalFree(buf);
3087 /* Test v3 cert */
3088 info.dwVersion = CERT_V3;
3089 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3090 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3091 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3092 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3093 if (ret)
3095 ok(size == sizeof(v3Cert), "Wrong size %d\n", size);
3096 ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n");
3097 LocalFree(buf);
3099 /* A v4 cert? */
3100 info.dwVersion = 3; /* Not a typo, CERT_V3 is 2 */
3101 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3102 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3103 if (ret)
3105 ok(size == sizeof(v4Cert), "Wrong size %d\n", size);
3106 ok(!memcmp(buf, v4Cert, size), "Unexpected value\n");
3107 LocalFree(buf);
3109 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
3110 * API doesn't prevent it)
3112 info.dwVersion = CERT_V1;
3113 info.cExtension = 1;
3114 info.rgExtension = &criticalExt;
3115 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3116 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3117 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3118 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3119 if (ret)
3121 ok(size == sizeof(v1CertWithConstraints), "Wrong size %d\n", size);
3122 ok(!memcmp(buf, v1CertWithConstraints, size), "Got unexpected value\n");
3123 LocalFree(buf);
3125 /* test v1 cert with a serial number */
3126 info.SerialNumber.cbData = sizeof(serialNum);
3127 info.SerialNumber.pbData = (BYTE *)serialNum;
3128 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3129 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3130 if (ret)
3132 ok(size == sizeof(v1CertWithSerial), "Wrong size %d\n", size);
3133 ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n");
3134 LocalFree(buf);
3136 /* Test v1 cert with an issuer name, serial number, and issuer unique id */
3137 info.dwVersion = CERT_V1;
3138 info.cExtension = 0;
3139 info.IssuerUniqueId.cbData = sizeof(serialNum);
3140 info.IssuerUniqueId.pbData = (BYTE *)serialNum;
3141 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3142 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3143 ok(ret || broken(GetLastError() == OSS_BAD_PTR /* Win98 */),
3144 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3145 if (ret)
3147 ok(size == sizeof(v1CertWithIssuerUniqueId), "Wrong size %d\n", size);
3148 ok(!memcmp(buf, v1CertWithIssuerUniqueId, size),
3149 "Got unexpected value\n");
3150 LocalFree(buf);
3152 /* Test v1 cert with an issuer name, a subject name, and a serial number */
3153 info.IssuerUniqueId.cbData = 0;
3154 info.IssuerUniqueId.pbData = NULL;
3155 info.cExtension = 1;
3156 info.rgExtension = &criticalExt;
3157 info.Issuer.cbData = sizeof(encodedCommonName);
3158 info.Issuer.pbData = (BYTE *)encodedCommonName;
3159 info.Subject.cbData = sizeof(encodedCommonName);
3160 info.Subject.pbData = (BYTE *)encodedCommonName;
3161 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3162 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3163 if (ret)
3165 ok(size == sizeof(bigCert), "Wrong size %d\n", size);
3166 ok(!memcmp(buf, bigCert, size), "Got unexpected value\n");
3167 LocalFree(buf);
3169 /* Add a public key */
3170 info.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3171 info.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
3172 info.SubjectPublicKeyInfo.PublicKey.pbData = (LPBYTE)aKey;
3173 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3174 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3175 if (ret)
3177 ok(size == sizeof(v1CertWithPubKey) ||
3178 size == sizeof(v1CertWithPubKeyNoNull), "Wrong size %d\n", size);
3179 if (size == sizeof(v1CertWithPubKey))
3180 ok(!memcmp(buf, v1CertWithPubKey, size), "Got unexpected value\n");
3181 else if (size == sizeof(v1CertWithPubKeyNoNull))
3182 ok(!memcmp(buf, v1CertWithPubKeyNoNull, size),
3183 "Got unexpected value\n");
3184 LocalFree(buf);
3186 /* Again add an issuer unique id */
3187 info.IssuerUniqueId.cbData = sizeof(serialNum);
3188 info.IssuerUniqueId.pbData = (BYTE *)serialNum;
3189 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3190 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3191 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3192 if (ret)
3194 ok(size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId) ||
3195 size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull),
3196 "Wrong size %d\n", size);
3197 if (size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId))
3198 ok(!memcmp(buf, v1CertWithSubjectIssuerSerialAndIssuerUniqueId,
3199 size), "unexpected value\n");
3200 else if (size ==
3201 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull))
3202 ok(!memcmp(buf,
3203 v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull, size),
3204 "unexpected value\n");
3205 LocalFree(buf);
3207 /* Remove the public key, and add a subject key identifier extension */
3208 info.IssuerUniqueId.cbData = 0;
3209 info.IssuerUniqueId.pbData = NULL;
3210 info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
3211 info.SubjectPublicKeyInfo.PublicKey.cbData = 0;
3212 info.SubjectPublicKeyInfo.PublicKey.pbData = NULL;
3213 ext.pszObjId = oid_subject_key_identifier;
3214 ext.fCritical = FALSE;
3215 ext.Value.cbData = sizeof(octetCommonNameValue);
3216 ext.Value.pbData = octetCommonNameValue;
3217 info.cExtension = 1;
3218 info.rgExtension = &ext;
3219 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3220 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3221 if (ret)
3223 ok(size == sizeof(v1CertWithSubjectKeyId), "Wrong size %d\n", size);
3224 ok(!memcmp(buf, v1CertWithSubjectKeyId, size), "Unexpected value\n");
3225 LocalFree(buf);
3229 static void test_decodeCertToBeSigned(DWORD dwEncoding)
3231 static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert, v4Cert,
3232 v1CertWithConstraints, v1CertWithSerial, v1CertWithIssuerUniqueId };
3233 BOOL ret;
3234 BYTE *buf = NULL;
3235 DWORD size = 0, i;
3237 /* Test with NULL pbEncoded */
3238 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 0,
3239 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3240 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
3241 GetLastError() == OSS_BAD_ARG /* Win9x */),
3242 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
3243 if (0)
3245 /* Crashes on win9x */
3246 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 1,
3247 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3248 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3249 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3251 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT or
3252 * CRYPT_E_ASN1_BADTAG, because at a minimum a cert must have a non-zero
3253 * serial number, an issuer, a subject, and a public key.
3255 for (i = 0; i < ARRAY_SIZE(corruptCerts); i++)
3257 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3258 corruptCerts[i], corruptCerts[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3259 &buf, &size);
3260 ok(!ret, "Expected failure\n");
3262 /* The following succeeds, even though v1 certs are not allowed to have
3263 * extensions.
3265 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3266 v1CertWithSubjectKeyId, sizeof(v1CertWithSubjectKeyId),
3267 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3268 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3269 if (ret)
3271 CERT_INFO *info = (CERT_INFO *)buf;
3273 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3274 ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %d\n",
3275 info->dwVersion);
3276 ok(info->cExtension == 1, "expected 1 extension, got %d\n",
3277 info->cExtension);
3278 LocalFree(buf);
3280 /* The following also succeeds, even though V1 certs are not allowed to
3281 * have issuer unique ids.
3283 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3284 v1CertWithSubjectIssuerSerialAndIssuerUniqueId,
3285 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId),
3286 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3287 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3288 if (ret)
3290 CERT_INFO *info = (CERT_INFO *)buf;
3292 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3293 ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %d\n",
3294 info->dwVersion);
3295 ok(info->IssuerUniqueId.cbData == sizeof(serialNum),
3296 "unexpected issuer unique id size %d\n", info->IssuerUniqueId.cbData);
3297 ok(!memcmp(info->IssuerUniqueId.pbData, serialNum, sizeof(serialNum)),
3298 "unexpected issuer unique id value\n");
3299 LocalFree(buf);
3301 /* Now check with serial number, subject and issuer specified */
3302 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert,
3303 sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3304 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3305 if (ret)
3307 CERT_INFO *info = (CERT_INFO *)buf;
3309 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3310 ok(info->SerialNumber.cbData == 1,
3311 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3312 ok(*info->SerialNumber.pbData == *serialNum,
3313 "Expected serial number %d, got %d\n", *serialNum,
3314 *info->SerialNumber.pbData);
3315 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3316 "Wrong size %d\n", info->Issuer.cbData);
3317 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3318 "Unexpected issuer\n");
3319 ok(info->Subject.cbData == sizeof(encodedCommonName),
3320 "Wrong size %d\n", info->Subject.cbData);
3321 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3322 info->Subject.cbData), "Unexpected subject\n");
3323 LocalFree(buf);
3325 /* Check again with pub key specified */
3326 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3327 v1CertWithPubKey, sizeof(v1CertWithPubKey), CRYPT_DECODE_ALLOC_FLAG, NULL,
3328 &buf, &size);
3329 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3330 if (ret)
3332 CERT_INFO *info = (CERT_INFO *)buf;
3334 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3335 ok(info->SerialNumber.cbData == 1,
3336 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3337 ok(*info->SerialNumber.pbData == *serialNum,
3338 "Expected serial number %d, got %d\n", *serialNum,
3339 *info->SerialNumber.pbData);
3340 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3341 "Wrong size %d\n", info->Issuer.cbData);
3342 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3343 "Unexpected issuer\n");
3344 ok(info->Subject.cbData == sizeof(encodedCommonName),
3345 "Wrong size %d\n", info->Subject.cbData);
3346 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3347 info->Subject.cbData), "Unexpected subject\n");
3348 ok(!strcmp(info->SubjectPublicKeyInfo.Algorithm.pszObjId,
3349 szOID_RSA_RSA), "Expected szOID_RSA_RSA, got %s\n",
3350 info->SubjectPublicKeyInfo.Algorithm.pszObjId);
3351 ok(info->SubjectPublicKeyInfo.PublicKey.cbData == sizeof(aKey),
3352 "Wrong size %d\n", info->SubjectPublicKeyInfo.PublicKey.cbData);
3353 ok(!memcmp(info->SubjectPublicKeyInfo.PublicKey.pbData, aKey,
3354 sizeof(aKey)), "Unexpected public key\n");
3355 LocalFree(buf);
3359 static const BYTE hash[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
3360 0xe, 0xf };
3362 static const BYTE signedBigCert[] = {
3363 ASN_SEQUENCE,0x81,147,
3364 ASN_SEQUENCE,122,
3365 ASN_INTEGER,1, 0x01,
3366 ASN_SEQUENCE,2,
3367 ASN_OBJECTIDENTIFIER,0,
3368 ASN_SEQUENCE,21,
3369 0x31,19,
3370 ASN_SEQUENCE,17,
3371 ASN_OBJECTIDENTIFIER,3, 0x55,0x04,0x03,
3372 0x13,10, 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
3373 ASN_SEQUENCE,34,
3374 0x18,15, 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
3375 0x18,15, 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
3376 ASN_SEQUENCE,21,
3377 0x31,19,
3378 ASN_SEQUENCE,17,
3379 ASN_OBJECTIDENTIFIER,3, 0x55,0x04,0x03,
3380 0x13,10, 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
3381 ASN_SEQUENCE,7,
3382 ASN_SEQUENCE,2,
3383 ASN_OBJECTIDENTIFIER,0,
3384 ASN_BITS,1, 0x00,
3385 0xa3,22,
3386 ASN_SEQUENCE,20,
3387 ASN_SEQUENCE,18,
3388 ASN_OBJECTIDENTIFIER,3, 0x55,0x1d,0x13,
3389 0x01,1, 0xff,
3390 ASN_OCTETSTRING,8, 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,
3391 ASN_SEQUENCE,2,
3392 ASN_OBJECTIDENTIFIER,0,
3393 ASN_BITS,17, 0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,
3394 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00
3397 static const BYTE signedBigCertWithIndefiniteSeq[] = {
3398 ASN_SEQUENCE,0x81,151,
3399 ASN_SEQUENCE,126,
3400 ASN_INTEGER,1, 0x01,
3401 ASN_SEQUENCE,2,
3402 ASN_OBJECTIDENTIFIER,0,
3403 ASN_SEQUENCE,21,
3404 0x31,19,
3405 ASN_SEQUENCE,17,
3406 ASN_OBJECTIDENTIFIER,3, 0x55,0x04,0x03,
3407 0x13,10, 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
3408 ASN_SEQUENCE,0x80,
3409 0x18,15, 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
3410 0x18,15, 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
3411 0,0,
3412 ASN_SEQUENCE,21,
3413 0x31,19,
3414 ASN_SEQUENCE,17,
3415 ASN_OBJECTIDENTIFIER,3, 0x55,0x04,0x03,
3416 0x13,10, 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
3417 ASN_SEQUENCE,0x80,
3418 ASN_SEQUENCE,2,
3419 ASN_OBJECTIDENTIFIER,0,
3420 ASN_BITS,1, 0x00,
3421 0,0,
3422 0xa3,22,
3423 ASN_SEQUENCE,20,
3424 ASN_SEQUENCE,18,
3425 ASN_OBJECTIDENTIFIER,3, 0x55,0x1d,0x13,
3426 0x01,1, 0xff,
3427 ASN_OCTETSTRING,8, 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,
3428 ASN_SEQUENCE,2,
3429 ASN_OBJECTIDENTIFIER,0,
3430 ASN_BITS,17, 0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,
3431 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00
3434 static void test_encodeCert(DWORD dwEncoding)
3436 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
3437 * also that bigCert is a NULL-terminated string, so don't count its
3438 * last byte (otherwise the signed cert won't decode.)
3440 CERT_SIGNED_CONTENT_INFO info = { { sizeof(bigCert), (BYTE *)bigCert },
3441 { NULL, { 0, NULL } }, { sizeof(hash), (BYTE *)hash, 0 } };
3442 BOOL ret;
3443 BYTE *buf = NULL;
3444 DWORD bufSize = 0;
3446 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT, &info,
3447 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
3448 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3449 if (ret)
3451 ok(bufSize == sizeof(signedBigCert), "Wrong size %d\n", bufSize);
3452 ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n");
3453 LocalFree(buf);
3457 static void test_decodeCert(DWORD dwEncoding)
3459 BOOL ret;
3460 BYTE *buf = NULL;
3461 DWORD size = 0;
3463 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert,
3464 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3465 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3466 if (ret)
3468 CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf;
3470 ok(info->ToBeSigned.cbData == sizeof(bigCert),
3471 "Wrong cert size %d\n", info->ToBeSigned.cbData);
3472 ok(!memcmp(info->ToBeSigned.pbData, bigCert, info->ToBeSigned.cbData),
3473 "Unexpected cert\n");
3474 ok(info->Signature.cbData == sizeof(hash),
3475 "Wrong signature size %d\n", info->Signature.cbData);
3476 ok(!memcmp(info->Signature.pbData, hash, info->Signature.cbData),
3477 "Unexpected signature\n");
3478 LocalFree(buf);
3480 /* A signed cert decodes as a CERT_INFO too */
3481 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCert,
3482 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3483 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3484 if (ret)
3486 CERT_INFO *info = (CERT_INFO *)buf;
3488 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3489 ok(info->SerialNumber.cbData == 1,
3490 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3491 ok(*info->SerialNumber.pbData == *serialNum,
3492 "Expected serial number %d, got %d\n", *serialNum,
3493 *info->SerialNumber.pbData);
3494 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3495 "Wrong size %d\n", info->Issuer.cbData);
3496 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3497 "Unexpected issuer\n");
3498 ok(info->Subject.cbData == sizeof(encodedCommonName),
3499 "Wrong size %d\n", info->Subject.cbData);
3500 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3501 info->Subject.cbData), "Unexpected subject\n");
3502 LocalFree(buf);
3504 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCertWithIndefiniteSeq,
3505 sizeof(signedBigCertWithIndefiniteSeq), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3506 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3507 if (ret)
3509 CERT_INFO *info = (CERT_INFO *)buf;
3511 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3512 ok(info->SerialNumber.cbData == 1,
3513 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3514 ok(*info->SerialNumber.pbData == *serialNum,
3515 "Expected serial number %d, got %d\n", *serialNum,
3516 *info->SerialNumber.pbData);
3517 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3518 "Wrong size %d\n", info->Issuer.cbData);
3519 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3520 "Unexpected issuer\n");
3521 ok(info->Subject.cbData == sizeof(encodedCommonName),
3522 "Wrong size %d\n", info->Subject.cbData);
3523 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3524 info->Subject.cbData), "Unexpected subject\n");
3525 LocalFree(buf);
3529 static const BYTE emptyDistPoint[] = { 0x30, 0x02, 0x30, 0x00 };
3530 static const BYTE distPointWithUrl[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3531 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3532 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3533 static const BYTE distPointWithReason[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3534 0x00, 0x03 };
3535 static const BYTE distPointWithIssuer[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3536 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3537 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3538 static const BYTE distPointWithUrlAndIssuer[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3539 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3540 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3541 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3542 0x2e, 0x6f, 0x72, 0x67 };
3543 static const BYTE crlReason = CRL_REASON_KEY_COMPROMISE |
3544 CRL_REASON_AFFILIATION_CHANGED;
3546 static void test_encodeCRLDistPoints(DWORD dwEncoding)
3548 CRL_DIST_POINTS_INFO info = { 0 };
3549 CRL_DIST_POINT point = { { 0 } };
3550 CERT_ALT_NAME_ENTRY entry = { 0 };
3551 BOOL ret;
3552 BYTE *buf = NULL;
3553 DWORD size = 0;
3555 /* Test with an empty info */
3556 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3557 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3558 ok(!ret && GetLastError() == E_INVALIDARG,
3559 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3560 /* Test with one empty dist point */
3561 info.cDistPoint = 1;
3562 info.rgDistPoint = &point;
3563 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3564 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3565 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3566 if (ret)
3568 ok(size == sizeof(emptyDistPoint), "Wrong size %d\n", size);
3569 ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n");
3570 LocalFree(buf);
3572 /* A dist point with an invalid name */
3573 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3574 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3575 U(entry).pwszURL = (LPWSTR)nihongoURL;
3576 U(point.DistPointName).FullName.cAltEntry = 1;
3577 U(point.DistPointName).FullName.rgAltEntry = &entry;
3578 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3579 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3580 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
3581 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
3582 /* The first invalid character is at index 7 */
3583 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
3584 "Expected invalid char at index 7, got %d\n",
3585 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
3586 /* A dist point with (just) a valid name */
3587 U(entry).pwszURL = (LPWSTR)url;
3588 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3589 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3590 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3591 if (ret)
3593 ok(size == sizeof(distPointWithUrl), "Wrong size %d\n", size);
3594 ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n");
3595 LocalFree(buf);
3597 /* A dist point with (just) reason flags */
3598 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3599 point.ReasonFlags.cbData = sizeof(crlReason);
3600 point.ReasonFlags.pbData = (LPBYTE)&crlReason;
3601 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3602 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3603 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3604 if (ret)
3606 ok(size == sizeof(distPointWithReason), "Wrong size %d\n", size);
3607 ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n");
3608 LocalFree(buf);
3610 /* A dist point with just an issuer */
3611 point.ReasonFlags.cbData = 0;
3612 point.CRLIssuer.cAltEntry = 1;
3613 point.CRLIssuer.rgAltEntry = &entry;
3614 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3615 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3616 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3617 if (ret)
3619 ok(size == sizeof(distPointWithIssuer), "Wrong size %d\n", size);
3620 ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n");
3621 LocalFree(buf);
3623 /* A dist point with both a name and an issuer */
3624 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3625 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3626 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3627 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3628 if (ret)
3630 ok(size == sizeof(distPointWithUrlAndIssuer),
3631 "Wrong size %d\n", size);
3632 ok(!memcmp(buf, distPointWithUrlAndIssuer, size), "Unexpected value\n");
3633 LocalFree(buf);
3637 static void test_decodeCRLDistPoints(DWORD dwEncoding)
3639 BOOL ret;
3640 BYTE *buf = NULL;
3641 DWORD size = 0;
3642 PCRL_DIST_POINTS_INFO info;
3643 PCRL_DIST_POINT point;
3644 PCERT_ALT_NAME_ENTRY entry;
3646 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3647 emptyDistPoint, emptyDistPoint[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3648 &buf, &size);
3649 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3650 if (ret)
3652 info = (PCRL_DIST_POINTS_INFO)buf;
3653 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3654 "Wrong size %d\n", size);
3655 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3656 info->cDistPoint);
3657 point = info->rgDistPoint;
3658 ok(point->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_NO_NAME,
3659 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3660 point->DistPointName.dwDistPointNameChoice);
3661 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3662 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3663 LocalFree(buf);
3665 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3666 distPointWithUrl, distPointWithUrl[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3667 &buf, &size);
3668 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3669 if (ret)
3671 info = (PCRL_DIST_POINTS_INFO)buf;
3672 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3673 "Wrong size %d\n", size);
3674 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3675 info->cDistPoint);
3676 point = info->rgDistPoint;
3677 ok(point->DistPointName.dwDistPointNameChoice ==
3678 CRL_DIST_POINT_FULL_NAME,
3679 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3680 point->DistPointName.dwDistPointNameChoice);
3681 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3682 "Expected 1 name entry, got %d\n",
3683 U(point->DistPointName).FullName.cAltEntry);
3684 entry = U(point->DistPointName).FullName.rgAltEntry;
3685 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3686 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3687 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3688 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3689 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3690 LocalFree(buf);
3692 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3693 distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
3694 NULL, &buf, &size);
3695 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3696 if (ret)
3698 info = (PCRL_DIST_POINTS_INFO)buf;
3699 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3700 "Wrong size %d\n", size);
3701 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3702 info->cDistPoint);
3703 point = info->rgDistPoint;
3704 ok(point->DistPointName.dwDistPointNameChoice ==
3705 CRL_DIST_POINT_NO_NAME,
3706 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3707 point->DistPointName.dwDistPointNameChoice);
3708 ok(point->ReasonFlags.cbData == sizeof(crlReason),
3709 "Expected reason length\n");
3710 ok(!memcmp(point->ReasonFlags.pbData, &crlReason, sizeof(crlReason)),
3711 "Unexpected reason\n");
3712 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3713 LocalFree(buf);
3715 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3716 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2,
3717 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3718 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3719 if (ret)
3721 info = (PCRL_DIST_POINTS_INFO)buf;
3722 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3723 "Wrong size %d\n", size);
3724 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3725 info->cDistPoint);
3726 point = info->rgDistPoint;
3727 ok(point->DistPointName.dwDistPointNameChoice ==
3728 CRL_DIST_POINT_FULL_NAME,
3729 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3730 point->DistPointName.dwDistPointNameChoice);
3731 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3732 "Expected 1 name entry, got %d\n",
3733 U(point->DistPointName).FullName.cAltEntry);
3734 entry = U(point->DistPointName).FullName.rgAltEntry;
3735 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3736 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3737 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3738 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3739 ok(point->CRLIssuer.cAltEntry == 1,
3740 "Expected 1 issuer entry, got %d\n", point->CRLIssuer.cAltEntry);
3741 entry = point->CRLIssuer.rgAltEntry;
3742 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3743 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3744 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3745 LocalFree(buf);
3747 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3748 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2, 0,
3749 NULL, NULL, &size);
3750 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3751 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
3752 if (buf)
3754 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3755 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2, 0,
3756 NULL, buf, &size);
3757 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3758 HeapFree(GetProcessHeap(), 0, buf);
3762 static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3763 static const BYTE emptyNameIDP[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3764 static const BYTE urlIDP[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3765 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3766 0x67 };
3768 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding)
3770 BOOL ret;
3771 BYTE *buf = NULL;
3772 DWORD size = 0;
3773 CRL_ISSUING_DIST_POINT point = { { 0 } };
3774 CERT_ALT_NAME_ENTRY entry;
3776 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, NULL,
3777 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3778 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3780 skip("no X509_ISSUING_DIST_POINT encode support\n");
3781 return;
3783 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3784 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3785 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3786 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3787 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3788 if (ret)
3790 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
3791 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
3792 LocalFree(buf);
3794 /* nonsensical flags */
3795 point.fOnlyContainsUserCerts = TRUE;
3796 point.fOnlyContainsCACerts = TRUE;
3797 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3798 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3799 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3800 if (ret)
3802 ok(size == sizeof(badFlagsIDP), "Unexpected size %d\n", size);
3803 ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n");
3804 LocalFree(buf);
3806 /* unimplemented name type */
3807 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3808 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_ISSUER_RDN_NAME;
3809 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3810 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3811 ok(!ret && GetLastError() == E_INVALIDARG,
3812 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3813 /* empty name */
3814 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3815 U(point.DistPointName).FullName.cAltEntry = 0;
3816 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3817 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3818 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3819 if (ret)
3821 ok(size == sizeof(emptyNameIDP), "Unexpected size %d\n", size);
3822 ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n");
3823 LocalFree(buf);
3825 /* name with URL entry */
3826 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3827 U(entry).pwszURL = (LPWSTR)url;
3828 U(point.DistPointName).FullName.cAltEntry = 1;
3829 U(point.DistPointName).FullName.rgAltEntry = &entry;
3830 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3831 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3832 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3833 if (ret)
3835 ok(size == sizeof(urlIDP), "Unexpected size %d\n", size);
3836 ok(!memcmp(buf, urlIDP, size), "Unexpected value\n");
3837 LocalFree(buf);
3841 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY *expected,
3842 const CERT_ALT_NAME_ENTRY *got)
3844 ok(expected->dwAltNameChoice == got->dwAltNameChoice,
3845 "Expected name choice %d, got %d\n", expected->dwAltNameChoice,
3846 got->dwAltNameChoice);
3847 if (expected->dwAltNameChoice == got->dwAltNameChoice)
3849 switch (got->dwAltNameChoice)
3851 case CERT_ALT_NAME_RFC822_NAME:
3852 case CERT_ALT_NAME_DNS_NAME:
3853 case CERT_ALT_NAME_EDI_PARTY_NAME:
3854 case CERT_ALT_NAME_URL:
3855 case CERT_ALT_NAME_REGISTERED_ID:
3856 ok((!U(*expected).pwszURL && !U(*got).pwszURL) ||
3857 (!U(*expected).pwszURL && !lstrlenW(U(*got).pwszURL)) ||
3858 (!U(*got).pwszURL && !lstrlenW(U(*expected).pwszURL)) ||
3859 !lstrcmpW(U(*expected).pwszURL, U(*got).pwszURL),
3860 "Unexpected name\n");
3861 break;
3862 case CERT_ALT_NAME_X400_ADDRESS:
3863 case CERT_ALT_NAME_DIRECTORY_NAME:
3864 case CERT_ALT_NAME_IP_ADDRESS:
3865 ok(U(*got).IPAddress.cbData == U(*expected).IPAddress.cbData,
3866 "Unexpected IP address length %d\n", U(*got).IPAddress.cbData);
3867 ok(!memcmp(U(*got).IPAddress.pbData, U(*expected).IPAddress.pbData,
3868 U(*got).IPAddress.cbData), "Unexpected value\n");
3869 break;
3874 static void compareAltNameInfo(const CERT_ALT_NAME_INFO *expected,
3875 const CERT_ALT_NAME_INFO *got)
3877 DWORD i;
3879 ok(expected->cAltEntry == got->cAltEntry, "Expected %d entries, got %d\n",
3880 expected->cAltEntry, got->cAltEntry);
3881 for (i = 0; i < min(expected->cAltEntry, got->cAltEntry); i++)
3882 compareAltNameEntry(&expected->rgAltEntry[i], &got->rgAltEntry[i]);
3885 static void compareDistPointName(const CRL_DIST_POINT_NAME *expected,
3886 const CRL_DIST_POINT_NAME *got)
3888 ok(got->dwDistPointNameChoice == expected->dwDistPointNameChoice,
3889 "Unexpected name choice %d\n", got->dwDistPointNameChoice);
3890 if (got->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME)
3891 compareAltNameInfo(&(U(*expected).FullName), &(U(*got).FullName));
3894 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT *expected,
3895 const CRL_ISSUING_DIST_POINT *got)
3897 compareDistPointName(&expected->DistPointName, &got->DistPointName);
3898 ok(got->fOnlyContainsUserCerts == expected->fOnlyContainsUserCerts,
3899 "Unexpected fOnlyContainsUserCerts\n");
3900 ok(got->fOnlyContainsCACerts == expected->fOnlyContainsCACerts,
3901 "Unexpected fOnlyContainsCACerts\n");
3902 ok(got->OnlySomeReasonFlags.cbData == expected->OnlySomeReasonFlags.cbData,
3903 "Unexpected reason flags\n");
3904 ok(got->fIndirectCRL == expected->fIndirectCRL,
3905 "Unexpected fIndirectCRL\n");
3908 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding)
3910 BOOL ret;
3911 BYTE *buf = NULL;
3912 DWORD size = 0;
3913 CRL_ISSUING_DIST_POINT point = { { 0 } };
3915 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3916 emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3917 &buf, &size);
3918 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3920 skip("no X509_ISSUING_DIST_POINT decode support\n");
3921 return;
3923 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3924 if (ret)
3926 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3927 LocalFree(buf);
3929 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3930 badFlagsIDP, badFlagsIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3931 &buf, &size);
3932 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3933 if (ret)
3935 point.fOnlyContainsUserCerts = point.fOnlyContainsCACerts = TRUE;
3936 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3937 LocalFree(buf);
3939 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3940 emptyNameIDP, emptyNameIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3941 &buf, &size);
3942 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3943 if (ret)
3945 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3946 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3947 U(point.DistPointName).FullName.cAltEntry = 0;
3948 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3949 LocalFree(buf);
3951 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3952 urlIDP, urlIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3953 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3954 if (ret)
3956 CERT_ALT_NAME_ENTRY entry;
3958 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3959 U(entry).pwszURL = (LPWSTR)url;
3960 U(point.DistPointName).FullName.cAltEntry = 1;
3961 U(point.DistPointName).FullName.rgAltEntry = &entry;
3962 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3963 LocalFree(buf);
3967 static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3968 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3969 0x30, 0x5a };
3970 static const BYTE v2CRL[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3971 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3972 0x30, 0x30, 0x30, 0x30, 0x5a };
3973 static const BYTE v1CRLWithIssuer[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3974 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3975 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3976 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3977 0x5a };
3978 static const BYTE v1CRLWithIssuerAndEmptyEntry[] = { 0x30, 0x43, 0x30, 0x02,
3979 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3980 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3981 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3982 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3983 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3984 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3985 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3986 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3987 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3988 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3989 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3990 static const BYTE v1CRLWithEntryExt[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3991 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3992 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3993 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3994 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3995 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3996 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3997 static const BYTE v1CRLWithExt[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3998 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3999 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
4000 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
4001 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
4002 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
4003 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
4004 static const BYTE v2CRLWithExt[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
4005 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
4006 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
4007 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
4008 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
4009 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
4010 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
4012 static void test_encodeCRLToBeSigned(DWORD dwEncoding)
4014 BOOL ret;
4015 BYTE *buf = NULL;
4016 DWORD size = 0;
4017 CRL_INFO info = { 0 };
4018 CRL_ENTRY entry = { { 0 }, { 0 }, 0, 0 };
4020 /* Test with a V1 CRL */
4021 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
4022 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4023 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
4024 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4025 if (ret)
4027 ok(size == sizeof(v1CRL), "Wrong size %d\n", size);
4028 ok(!memcmp(buf, v1CRL, size), "Got unexpected value\n");
4029 LocalFree(buf);
4031 /* Test v2 CRL */
4032 info.dwVersion = CRL_V2;
4033 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
4034 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4035 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
4036 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4037 if (ret)
4039 ok(size == v2CRL[1] + 2, "Expected size %d, got %d\n",
4040 v2CRL[1] + 2, size);
4041 ok(!memcmp(buf, v2CRL, size), "Got unexpected value\n");
4042 LocalFree(buf);
4044 /* v1 CRL with a name */
4045 info.dwVersion = CRL_V1;
4046 info.Issuer.cbData = sizeof(encodedCommonName);
4047 info.Issuer.pbData = (BYTE *)encodedCommonName;
4048 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
4049 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4050 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4051 if (ret)
4053 ok(size == sizeof(v1CRLWithIssuer), "Wrong size %d\n", size);
4054 ok(!memcmp(buf, v1CRLWithIssuer, size), "Got unexpected value\n");
4055 LocalFree(buf);
4057 if (0)
4059 /* v1 CRL with a name and a NULL entry pointer (crashes on win9x) */
4060 info.cCRLEntry = 1;
4061 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
4062 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4063 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
4064 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
4066 /* now set an empty entry */
4067 info.cCRLEntry = 1;
4068 info.rgCRLEntry = &entry;
4069 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
4070 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4071 if (ret)
4073 ok(size == sizeof(v1CRLWithIssuerAndEmptyEntry),
4074 "Wrong size %d\n", size);
4075 ok(!memcmp(buf, v1CRLWithIssuerAndEmptyEntry, size),
4076 "Got unexpected value\n");
4077 LocalFree(buf);
4079 /* an entry with a serial number */
4080 entry.SerialNumber.cbData = sizeof(serialNum);
4081 entry.SerialNumber.pbData = (BYTE *)serialNum;
4082 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
4083 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4084 if (ret)
4086 ok(size == sizeof(v1CRLWithIssuerAndEntry),
4087 "Wrong size %d\n", size);
4088 ok(!memcmp(buf, v1CRLWithIssuerAndEntry, size),
4089 "Got unexpected value\n");
4090 LocalFree(buf);
4092 /* an entry with an extension */
4093 entry.cExtension = 1;
4094 entry.rgExtension = &criticalExt;
4095 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
4096 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4097 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4098 if (ret)
4100 ok(size == sizeof(v1CRLWithEntryExt), "Wrong size %d\n", size);
4101 ok(!memcmp(buf, v1CRLWithEntryExt, size), "Got unexpected value\n");
4102 LocalFree(buf);
4104 /* a CRL with an extension */
4105 entry.cExtension = 0;
4106 info.cExtension = 1;
4107 info.rgExtension = &criticalExt;
4108 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
4109 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4110 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4111 if (ret)
4113 ok(size == sizeof(v1CRLWithExt), "Wrong size %d\n", size);
4114 ok(!memcmp(buf, v1CRLWithExt, size), "Got unexpected value\n");
4115 LocalFree(buf);
4117 /* a v2 CRL with an extension, this time non-critical */
4118 info.dwVersion = CRL_V2;
4119 info.rgExtension = &nonCriticalExt;
4120 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
4121 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4122 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4123 if (ret)
4125 ok(size == sizeof(v2CRLWithExt), "Wrong size %d\n", size);
4126 ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n");
4127 LocalFree(buf);
4131 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
4132 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
4133 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
4134 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
4135 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
4136 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
4137 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
4138 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
4139 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
4140 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
4141 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
4142 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
4143 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
4144 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
4145 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
4146 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
4147 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
4148 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
4149 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
4150 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
4151 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
4152 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
4153 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
4154 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
4155 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
4156 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
4157 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
4158 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
4159 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
4160 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
4161 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
4162 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
4163 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
4164 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
4165 0xcd };
4166 static const BYTE verisignCRLWithLotsOfEntries[] = {
4167 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
4168 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
4169 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
4170 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
4171 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
4172 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
4173 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
4174 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
4175 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
4176 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
4177 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
4178 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
4179 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
4180 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
4181 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
4182 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
4183 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
4184 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
4185 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
4186 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
4187 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
4188 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
4189 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
4190 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
4191 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
4192 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
4193 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
4194 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
4195 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
4196 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
4197 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
4198 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
4199 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
4200 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
4201 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
4202 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
4203 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
4204 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
4205 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
4206 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
4207 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
4208 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
4209 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
4210 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
4211 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
4212 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
4213 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
4214 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
4215 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
4216 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
4217 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
4218 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
4219 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
4220 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
4221 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
4222 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
4223 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
4224 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
4225 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
4226 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
4227 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
4228 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
4229 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
4230 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
4231 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
4232 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
4233 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
4234 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
4235 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
4236 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
4237 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
4238 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
4239 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
4240 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
4241 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
4242 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
4243 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
4244 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
4245 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
4246 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
4247 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
4248 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
4249 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
4250 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
4251 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
4252 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
4253 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
4254 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
4255 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
4256 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
4257 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
4258 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
4259 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
4260 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
4261 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
4262 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
4263 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
4264 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
4265 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
4266 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
4267 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
4268 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
4269 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
4270 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
4271 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
4272 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
4273 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
4274 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
4275 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
4276 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
4277 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
4278 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
4279 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
4280 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
4281 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
4282 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
4283 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
4284 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
4285 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
4286 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
4287 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
4288 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
4289 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
4290 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
4291 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
4292 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
4293 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
4294 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
4295 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
4296 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
4297 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
4298 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
4299 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
4300 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
4301 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
4302 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
4303 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
4304 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
4305 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
4306 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
4307 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
4308 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
4309 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
4310 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
4311 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
4312 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
4313 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
4314 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
4315 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
4316 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
4317 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
4318 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
4319 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
4320 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
4321 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
4322 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
4323 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
4324 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
4325 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
4326 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
4327 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
4328 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
4329 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
4330 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
4331 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
4332 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
4333 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
4334 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
4335 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
4336 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
4337 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
4338 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
4339 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
4340 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
4341 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
4342 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
4343 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
4344 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
4345 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
4346 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
4347 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
4348 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
4349 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
4350 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
4351 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
4352 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
4353 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
4354 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
4355 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
4356 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
4357 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
4358 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
4359 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
4360 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
4361 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
4362 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
4363 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
4364 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
4365 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
4366 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
4367 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
4368 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
4369 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
4370 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
4371 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
4372 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
4373 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
4374 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
4375 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
4376 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
4377 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
4378 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
4379 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
4380 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
4381 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
4382 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
4383 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
4384 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
4385 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
4386 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
4387 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
4388 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
4389 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
4390 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
4391 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
4392 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
4393 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
4394 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
4395 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
4396 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
4397 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
4398 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
4399 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
4400 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
4401 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
4402 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
4403 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
4404 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
4405 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
4406 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
4407 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
4408 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
4409 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
4410 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
4411 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
4412 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
4413 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
4414 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
4415 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
4416 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
4417 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
4418 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
4419 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
4420 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
4421 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
4422 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
4423 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
4424 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
4425 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
4426 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
4427 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
4428 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
4429 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
4430 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
4431 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
4432 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
4433 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
4434 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
4435 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
4436 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
4437 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
4438 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
4439 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
4440 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
4441 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
4442 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
4443 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
4444 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
4445 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
4446 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
4447 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
4448 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
4449 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
4450 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
4451 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
4452 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
4453 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
4454 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
4455 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
4456 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
4457 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
4458 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
4459 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
4460 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
4461 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
4462 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
4463 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
4464 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
4465 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
4466 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
4467 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
4468 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
4469 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
4470 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4471 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4472 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4473 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4474 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4475 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4476 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4477 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4478 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4479 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4480 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4481 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4482 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4483 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4484 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4485 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4486 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4487 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4488 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4489 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4490 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4491 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4492 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4493 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4494 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4495 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4496 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4497 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4498 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4499 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4500 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4501 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4502 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4503 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4504 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4505 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4506 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4507 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4508 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4509 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4510 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4511 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4512 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4513 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4514 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4515 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4516 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4517 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4518 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4519 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4520 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4521 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4522 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4523 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4524 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4525 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4526 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4527 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4528 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4529 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4530 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4531 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4532 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4533 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4534 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4535 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4536 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4537 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4538 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4539 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4540 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4541 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4542 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4543 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4544 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4545 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4546 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4547 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4548 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4549 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4550 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4551 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4552 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4553 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4554 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4555 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4556 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4557 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4558 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4559 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4560 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4561 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4562 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4563 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4564 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4565 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4566 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4567 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4568 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4569 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4570 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4571 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4572 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4573 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4574 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4575 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4576 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4577 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4578 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4579 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4580 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4581 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4582 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4583 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4584 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4585 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4586 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4587 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4588 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4589 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4590 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4591 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4592 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4593 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4594 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4595 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4596 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4597 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4598 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4599 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4600 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4601 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4602 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4603 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4604 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4605 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4606 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4607 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4608 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4609 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4610 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4611 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4612 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4613 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4614 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4615 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4616 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4617 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4618 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4619 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4620 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4621 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4622 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4623 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4624 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4625 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4626 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4627 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4628 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4629 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4630 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4631 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4632 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4633 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4634 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4635 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4636 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4637 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4638 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4639 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4640 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4641 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4642 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4643 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4644 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4645 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4646 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4647 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4648 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4649 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4650 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4651 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4652 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4653 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4654 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4655 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4656 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4657 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4658 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4659 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4660 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4661 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4662 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4663 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4664 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4665 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4666 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4667 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4668 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4669 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4670 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4671 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4672 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4673 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4674 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4676 static void test_decodeCRLToBeSigned(DWORD dwEncoding)
4678 static const BYTE *corruptCRLs[] = { v1CRL, v2CRL };
4679 BOOL ret;
4680 BYTE *buf = NULL;
4681 DWORD size = 0, i;
4683 for (i = 0; i < ARRAY_SIZE(corruptCRLs); i++)
4685 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4686 corruptCRLs[i], corruptCRLs[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4687 &buf, &size);
4688 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4689 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4690 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4691 GetLastError());
4693 /* at a minimum, a CRL must contain an issuer: */
4694 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4695 v1CRLWithIssuer, v1CRLWithIssuer[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4696 &buf, &size);
4697 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4698 if (ret)
4700 CRL_INFO *info = (CRL_INFO *)buf;
4702 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4703 ok(info->cCRLEntry == 0, "Expected 0 CRL entries, got %d\n",
4704 info->cCRLEntry);
4705 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4706 "Wrong issuer size %d\n", info->Issuer.cbData);
4707 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4708 "Unexpected issuer\n");
4709 LocalFree(buf);
4711 /* check decoding with an empty CRL entry */
4712 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4713 v1CRLWithIssuerAndEmptyEntry, v1CRLWithIssuerAndEmptyEntry[1] + 2,
4714 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4715 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4716 GetLastError() == OSS_DATA_ERROR /* Win9x */ ||
4717 GetLastError() == CRYPT_E_BAD_ENCODE /* Win8 */),
4718 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4719 GetLastError());
4720 /* with a real CRL entry */
4721 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4722 v1CRLWithIssuerAndEntry, v1CRLWithIssuerAndEntry[1] + 2,
4723 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4724 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4725 if (ret)
4727 CRL_INFO *info = (CRL_INFO *)buf;
4728 CRL_ENTRY *entry;
4730 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4731 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4732 info->cCRLEntry);
4733 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4734 entry = info->rgCRLEntry;
4735 ok(entry->SerialNumber.cbData == 1,
4736 "Expected serial number size 1, got %d\n",
4737 entry->SerialNumber.cbData);
4738 ok(*entry->SerialNumber.pbData == *serialNum,
4739 "Expected serial number %d, got %d\n", *serialNum,
4740 *entry->SerialNumber.pbData);
4741 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4742 "Wrong issuer size %d\n", info->Issuer.cbData);
4743 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4744 "Unexpected issuer\n");
4745 LocalFree(buf);
4747 /* a real CRL from verisign that has extensions */
4748 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4749 verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG,
4750 NULL, &buf, &size);
4751 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4752 if (ret)
4754 CRL_INFO *info = (CRL_INFO *)buf;
4756 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4757 ok(info->cCRLEntry == 3, "Expected 3 CRL entries, got %d\n",
4758 info->cCRLEntry);
4759 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4760 ok(info->cExtension == 2, "Expected 2 extensions, got %d\n",
4761 info->cExtension);
4762 LocalFree(buf);
4764 /* another real CRL from verisign that has lots of entries */
4765 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4766 verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries),
4767 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4768 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4769 if (ret)
4771 CRL_INFO *info = (CRL_INFO *)buf;
4773 ok(size >= sizeof(CRL_INFO), "Got size %d\n", size);
4774 ok(info->cCRLEntry == 209, "Expected 209 CRL entries, got %d\n",
4775 info->cCRLEntry);
4776 ok(info->cExtension == 0, "Expected 0 extensions, got %d\n",
4777 info->cExtension);
4778 LocalFree(buf);
4780 /* and finally, with an extension */
4781 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4782 v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4783 NULL, &buf, &size);
4784 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4785 if (ret)
4787 CRL_INFO *info = (CRL_INFO *)buf;
4788 CRL_ENTRY *entry;
4790 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4791 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4792 info->cCRLEntry);
4793 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4794 entry = info->rgCRLEntry;
4795 ok(entry->SerialNumber.cbData == 1,
4796 "Expected serial number size 1, got %d\n",
4797 entry->SerialNumber.cbData);
4798 ok(*entry->SerialNumber.pbData == *serialNum,
4799 "Expected serial number %d, got %d\n", *serialNum,
4800 *entry->SerialNumber.pbData);
4801 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4802 "Wrong issuer size %d\n", info->Issuer.cbData);
4803 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4804 "Unexpected issuer\n");
4805 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4806 info->cExtension);
4807 LocalFree(buf);
4809 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4810 v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4811 NULL, &buf, &size);
4812 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4813 if (ret)
4815 CRL_INFO *info = (CRL_INFO *)buf;
4817 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4818 info->cExtension);
4819 LocalFree(buf);
4823 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
4824 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
4825 static const BYTE encodedUsage[] = {
4826 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4827 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4828 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4830 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding)
4832 BOOL ret;
4833 BYTE *buf = NULL;
4834 DWORD size = 0;
4835 CERT_ENHKEY_USAGE usage;
4837 /* Test with empty usage */
4838 usage.cUsageIdentifier = 0;
4839 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4840 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4841 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4842 if (ret)
4844 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
4845 ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n");
4846 LocalFree(buf);
4848 /* Test with a few usages */
4849 usage.cUsageIdentifier = ARRAY_SIZE(keyUsages);
4850 usage.rgpszUsageIdentifier = (LPSTR *)keyUsages;
4851 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4852 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4853 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4854 if (ret)
4856 ok(size == sizeof(encodedUsage), "Wrong size %d\n", size);
4857 ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n");
4858 LocalFree(buf);
4862 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding)
4864 BOOL ret;
4865 LPBYTE buf = NULL;
4866 DWORD size = 0;
4868 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4869 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4870 &buf, &size);
4871 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4872 if (ret)
4874 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4876 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4877 "Wrong size %d\n", size);
4878 ok(usage->cUsageIdentifier == 0, "Expected 0 CRL entries, got %d\n",
4879 usage->cUsageIdentifier);
4880 LocalFree(buf);
4882 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4883 encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL,
4884 &buf, &size);
4885 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4886 if (ret)
4888 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4889 DWORD i;
4891 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4892 "Wrong size %d\n", size);
4893 ok(usage->cUsageIdentifier == ARRAY_SIZE(keyUsages),
4894 "Wrong CRL entries count %d\n", usage->cUsageIdentifier);
4895 for (i = 0; i < usage->cUsageIdentifier; i++)
4896 ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]),
4897 "Expected OID %s, got %s\n", keyUsages[i],
4898 usage->rgpszUsageIdentifier[i]);
4899 LocalFree(buf);
4901 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4902 encodedUsage, sizeof(encodedUsage), 0, NULL, NULL, &size);
4903 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4904 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
4905 if (buf)
4907 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4908 encodedUsage, sizeof(encodedUsage), 0, NULL, buf, &size);
4909 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4910 HeapFree(GetProcessHeap(), 0, buf);
4914 static BYTE keyId[] = { 1,2,3,4 };
4915 static const BYTE authorityKeyIdWithId[] = {
4916 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4917 static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4918 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4919 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4920 static const BYTE authorityKeyIdWithSerial[] = { 0x30,0x03,0x82,0x01,0x01 };
4922 static void test_encodeAuthorityKeyId(DWORD dwEncoding)
4924 CERT_AUTHORITY_KEY_ID_INFO info = { { 0 } };
4925 BOOL ret;
4926 BYTE *buf = NULL;
4927 DWORD size = 0;
4929 /* Test with empty id */
4930 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4931 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4932 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4933 if (ret)
4935 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4936 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4937 LocalFree(buf);
4939 /* With just a key id */
4940 info.KeyId.cbData = sizeof(keyId);
4941 info.KeyId.pbData = keyId;
4942 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4943 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4944 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4945 if (ret)
4947 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", size);
4948 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4949 LocalFree(buf);
4951 /* With just an issuer */
4952 info.KeyId.cbData = 0;
4953 info.CertIssuer.cbData = sizeof(encodedCommonName);
4954 info.CertIssuer.pbData = (BYTE *)encodedCommonName;
4955 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4956 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4957 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4958 if (ret)
4960 ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %d\n",
4961 size);
4962 ok(!memcmp(buf, authorityKeyIdWithIssuer, size), "Unexpected value\n");
4963 LocalFree(buf);
4965 /* With just a serial number */
4966 info.CertIssuer.cbData = 0;
4967 info.CertSerialNumber.cbData = sizeof(serialNum);
4968 info.CertSerialNumber.pbData = (BYTE *)serialNum;
4969 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4970 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4971 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4972 if (ret)
4974 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4975 size);
4976 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4977 LocalFree(buf);
4981 static void test_decodeAuthorityKeyId(DWORD dwEncoding)
4983 BOOL ret;
4984 LPBYTE buf = NULL;
4985 DWORD size = 0;
4987 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4988 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4989 &buf, &size);
4990 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4991 if (ret)
4993 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4995 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4996 size);
4997 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4998 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4999 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
5000 LocalFree(buf);
5002 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
5003 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
5004 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5005 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5006 if (ret)
5008 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
5010 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
5011 size);
5012 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
5013 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
5014 "Unexpected key id\n");
5015 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
5016 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
5017 LocalFree(buf);
5019 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
5020 authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer),
5021 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5022 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5023 if (ret)
5025 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
5027 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
5028 size);
5029 ok(info->KeyId.cbData == 0, "Expected no key id\n");
5030 ok(info->CertIssuer.cbData == sizeof(encodedCommonName),
5031 "Unexpected issuer len\n");
5032 ok(!memcmp(info->CertIssuer.pbData, encodedCommonName,
5033 sizeof(encodedCommonName)), "Unexpected issuer\n");
5034 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
5035 LocalFree(buf);
5037 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
5038 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
5039 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5040 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5041 if (ret)
5043 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
5045 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
5046 size);
5047 ok(info->KeyId.cbData == 0, "Expected no key id\n");
5048 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
5049 ok(info->CertSerialNumber.cbData == sizeof(serialNum),
5050 "Unexpected serial number len\n");
5051 ok(!memcmp(info->CertSerialNumber.pbData, serialNum, sizeof(serialNum)),
5052 "Unexpected serial number\n");
5053 LocalFree(buf);
5057 static const BYTE authorityKeyIdWithIssuerUrl[] = { 0x30,0x15,0xa1,0x13,0x86,
5058 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
5059 0x6f,0x72,0x67 };
5061 static void test_encodeAuthorityKeyId2(DWORD dwEncoding)
5063 CERT_AUTHORITY_KEY_ID2_INFO info = { { 0 } };
5064 CERT_ALT_NAME_ENTRY entry = { 0 };
5065 BOOL ret;
5066 BYTE *buf = NULL;
5067 DWORD size = 0;
5069 /* Test with empty id */
5070 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
5071 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5072 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5073 if (ret)
5075 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
5076 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
5077 LocalFree(buf);
5079 /* With just a key id */
5080 info.KeyId.cbData = sizeof(keyId);
5081 info.KeyId.pbData = keyId;
5082 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
5083 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5084 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5085 if (ret)
5087 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n",
5088 size);
5089 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
5090 LocalFree(buf);
5092 /* With a bogus issuer name */
5093 info.KeyId.cbData = 0;
5094 info.AuthorityCertIssuer.cAltEntry = 1;
5095 info.AuthorityCertIssuer.rgAltEntry = &entry;
5096 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
5097 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5098 ok(!ret && GetLastError() == E_INVALIDARG,
5099 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5100 /* With an issuer name */
5101 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
5102 U(entry).pwszURL = (LPWSTR)url;
5103 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
5104 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5105 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5106 if (ret)
5108 ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %d\n",
5109 size);
5110 ok(!memcmp(buf, authorityKeyIdWithIssuerUrl, size),
5111 "Unexpected value\n");
5112 LocalFree(buf);
5114 /* With just a serial number */
5115 info.AuthorityCertIssuer.cAltEntry = 0;
5116 info.AuthorityCertSerialNumber.cbData = sizeof(serialNum);
5117 info.AuthorityCertSerialNumber.pbData = (BYTE *)serialNum;
5118 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
5119 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5120 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5121 if (ret)
5123 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
5124 size);
5125 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
5126 LocalFree(buf);
5130 static void test_decodeAuthorityKeyId2(DWORD dwEncoding)
5132 BOOL ret;
5133 LPBYTE buf = NULL;
5134 DWORD size = 0;
5136 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
5137 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
5138 &buf, &size);
5139 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5140 if (ret)
5142 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
5144 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
5145 size);
5146 ok(info->KeyId.cbData == 0, "Expected no key id\n");
5147 ok(info->AuthorityCertIssuer.cAltEntry == 0,
5148 "Expected no issuer name entries\n");
5149 ok(info->AuthorityCertSerialNumber.cbData == 0,
5150 "Expected no serial number\n");
5151 LocalFree(buf);
5153 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
5154 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
5155 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5156 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5157 if (ret)
5159 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
5161 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
5162 size);
5163 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
5164 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
5165 "Unexpected key id\n");
5166 ok(info->AuthorityCertIssuer.cAltEntry == 0,
5167 "Expected no issuer name entries\n");
5168 ok(info->AuthorityCertSerialNumber.cbData == 0,
5169 "Expected no serial number\n");
5170 LocalFree(buf);
5172 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
5173 authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl),
5174 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5175 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5176 if (ret)
5178 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
5180 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
5181 size);
5182 ok(info->KeyId.cbData == 0, "Expected no key id\n");
5183 ok(info->AuthorityCertIssuer.cAltEntry == 1,
5184 "Expected 1 issuer entry, got %d\n",
5185 info->AuthorityCertIssuer.cAltEntry);
5186 ok(info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice ==
5187 CERT_ALT_NAME_URL, "Expected CERT_ALT_NAME_URL, got %d\n",
5188 info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice);
5189 ok(!lstrcmpW(U(info->AuthorityCertIssuer.rgAltEntry[0]).pwszURL,
5190 url), "Unexpected URL\n");
5191 ok(info->AuthorityCertSerialNumber.cbData == 0,
5192 "Expected no serial number\n");
5193 LocalFree(buf);
5195 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
5196 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
5197 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5198 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5199 if (ret)
5201 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
5203 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
5204 size);
5205 ok(info->KeyId.cbData == 0, "Expected no key id\n");
5206 ok(info->AuthorityCertIssuer.cAltEntry == 0,
5207 "Expected no issuer name entries\n");
5208 ok(info->AuthorityCertSerialNumber.cbData == sizeof(serialNum),
5209 "Unexpected serial number len\n");
5210 ok(!memcmp(info->AuthorityCertSerialNumber.pbData, serialNum,
5211 sizeof(serialNum)), "Unexpected serial number\n");
5212 LocalFree(buf);
5216 static const BYTE authorityInfoAccessWithUrl[] = {
5217 0x30,0x19,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
5218 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5219 static const BYTE authorityInfoAccessWithUrlAndIPAddr[] = {
5220 0x30,0x29,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
5221 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x0e,0x06,
5222 0x02,0x2d,0x06,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5224 static void test_encodeAuthorityInfoAccess(DWORD dwEncoding)
5226 static char oid1[] = "1.2.3";
5227 static char oid2[] = "1.5.6";
5228 BOOL ret;
5229 BYTE *buf = NULL;
5230 DWORD size = 0;
5231 CERT_ACCESS_DESCRIPTION accessDescription[2];
5232 CERT_AUTHORITY_INFO_ACCESS aia;
5234 memset(accessDescription, 0, sizeof(accessDescription));
5235 aia.cAccDescr = 0;
5236 aia.rgAccDescr = NULL;
5237 /* Having no access descriptions is allowed */
5238 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5239 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5240 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5241 if (ret)
5243 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
5244 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
5245 LocalFree(buf);
5246 buf = NULL;
5248 /* It can't have an empty access method */
5249 aia.cAccDescr = 1;
5250 aia.rgAccDescr = accessDescription;
5251 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5252 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5253 ok(!ret && (GetLastError() == E_INVALIDARG ||
5254 GetLastError() == OSS_LIMITED /* Win9x */),
5255 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
5256 /* It can't have an empty location */
5257 accessDescription[0].pszAccessMethod = oid1;
5258 SetLastError(0xdeadbeef);
5259 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5260 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5261 ok(!ret && GetLastError() == E_INVALIDARG,
5262 "expected E_INVALIDARG, got %08x\n", GetLastError());
5263 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5264 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
5265 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5266 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5267 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5268 if (ret)
5270 ok(size == sizeof(authorityInfoAccessWithUrl), "unexpected size %d\n",
5271 size);
5272 ok(!memcmp(buf, authorityInfoAccessWithUrl, size),
5273 "unexpected value\n");
5274 LocalFree(buf);
5275 buf = NULL;
5277 accessDescription[1].pszAccessMethod = oid2;
5278 accessDescription[1].AccessLocation.dwAltNameChoice =
5279 CERT_ALT_NAME_IP_ADDRESS;
5280 U(accessDescription[1].AccessLocation).IPAddress.cbData =
5281 sizeof(encodedIPAddr);
5282 U(accessDescription[1].AccessLocation).IPAddress.pbData =
5283 (LPBYTE)encodedIPAddr;
5284 aia.cAccDescr = 2;
5285 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5286 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5287 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5288 if (ret)
5290 ok(size == sizeof(authorityInfoAccessWithUrlAndIPAddr),
5291 "unexpected size %d\n", size);
5292 ok(!memcmp(buf, authorityInfoAccessWithUrlAndIPAddr, size),
5293 "unexpected value\n");
5294 LocalFree(buf);
5295 buf = NULL;
5299 static void compareAuthorityInfoAccess(LPCSTR header,
5300 const CERT_AUTHORITY_INFO_ACCESS *expected,
5301 const CERT_AUTHORITY_INFO_ACCESS *got)
5303 DWORD i;
5305 ok(expected->cAccDescr == got->cAccDescr,
5306 "%s: expected %d access descriptions, got %d\n", header,
5307 expected->cAccDescr, got->cAccDescr);
5308 for (i = 0; i < expected->cAccDescr; i++)
5310 ok(!strcmp(expected->rgAccDescr[i].pszAccessMethod,
5311 got->rgAccDescr[i].pszAccessMethod), "%s[%d]: expected %s, got %s\n",
5312 header, i, expected->rgAccDescr[i].pszAccessMethod,
5313 got->rgAccDescr[i].pszAccessMethod);
5314 compareAltNameEntry(&expected->rgAccDescr[i].AccessLocation,
5315 &got->rgAccDescr[i].AccessLocation);
5319 static void test_decodeAuthorityInfoAccess(DWORD dwEncoding)
5321 static char oid1[] = "1.2.3";
5322 static char oid2[] = "1.5.6";
5323 BOOL ret;
5324 LPBYTE buf = NULL;
5325 DWORD size = 0;
5327 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5328 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
5329 &buf, &size);
5330 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5331 if (ret)
5333 CERT_AUTHORITY_INFO_ACCESS aia = { 0, NULL };
5335 compareAuthorityInfoAccess("empty AIA", &aia,
5336 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5337 LocalFree(buf);
5338 buf = NULL;
5340 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5341 authorityInfoAccessWithUrl, sizeof(authorityInfoAccessWithUrl),
5342 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5343 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5344 if (ret)
5346 CERT_ACCESS_DESCRIPTION accessDescription;
5347 CERT_AUTHORITY_INFO_ACCESS aia;
5349 accessDescription.pszAccessMethod = oid1;
5350 accessDescription.AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5351 U(accessDescription.AccessLocation).pwszURL = (LPWSTR)url;
5352 aia.cAccDescr = 1;
5353 aia.rgAccDescr = &accessDescription;
5354 compareAuthorityInfoAccess("AIA with URL", &aia,
5355 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5356 LocalFree(buf);
5357 buf = NULL;
5359 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5360 authorityInfoAccessWithUrlAndIPAddr,
5361 sizeof(authorityInfoAccessWithUrlAndIPAddr), CRYPT_DECODE_ALLOC_FLAG,
5362 NULL, &buf, &size);
5363 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5364 if (ret)
5366 CERT_ACCESS_DESCRIPTION accessDescription[2];
5367 CERT_AUTHORITY_INFO_ACCESS aia;
5369 accessDescription[0].pszAccessMethod = oid1;
5370 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5371 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
5372 accessDescription[1].pszAccessMethod = oid2;
5373 accessDescription[1].AccessLocation.dwAltNameChoice =
5374 CERT_ALT_NAME_IP_ADDRESS;
5375 U(accessDescription[1].AccessLocation).IPAddress.cbData =
5376 sizeof(encodedIPAddr);
5377 U(accessDescription[1].AccessLocation).IPAddress.pbData =
5378 (LPBYTE)encodedIPAddr;
5379 aia.cAccDescr = 2;
5380 aia.rgAccDescr = accessDescription;
5381 compareAuthorityInfoAccess("AIA with URL and IP addr", &aia,
5382 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5383 LocalFree(buf);
5384 buf = NULL;
5386 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5387 authorityInfoAccessWithUrlAndIPAddr,
5388 sizeof(authorityInfoAccessWithUrlAndIPAddr), 0, NULL, NULL, &size);
5389 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5390 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
5391 if (buf)
5393 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5394 authorityInfoAccessWithUrlAndIPAddr,
5395 sizeof(authorityInfoAccessWithUrlAndIPAddr), 0, NULL, buf, &size);
5396 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5397 HeapFree(GetProcessHeap(), 0, buf);
5401 static const BYTE emptyCTL[] = {
5402 0x30,0x17,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5403 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5404 static const BYTE emptyCTLWithVersion1[] = {
5405 0x30,0x1a,0x02,0x01,0x01,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5406 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5407 static const BYTE ctlWithUsageIdentifier[] = {
5408 0x30,0x1b,0x30,0x04,0x06,0x02,0x2a,0x03,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
5409 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5410 static const BYTE ctlWithListIdentifier[] = {
5411 0x30,0x1a,0x30,0x00,0x04,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5412 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5413 static const BYTE ctlWithSequenceNumber[] = {
5414 0x30,0x1a,0x30,0x00,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5415 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5416 static const BYTE ctlWithThisUpdate[] = {
5417 0x30,0x15,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5418 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5419 static const BYTE ctlWithThisAndNextUpdate[] = {
5420 0x30,0x24,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5421 0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5422 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5423 static const BYTE ctlWithAlgId[] = {
5424 0x30,0x1b,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5425 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5426 static const BYTE ctlWithBogusEntry[] = {
5427 0x30,0x29,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5428 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x10,0x30,0x0e,0x04,
5429 0x01,0x01,0x31,0x09,0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,0x01 };
5430 static const BYTE ctlWithOneEntry[] = {
5431 0x30,0x2a,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5432 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x11,0x30,0x0f,0x04,
5433 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00 };
5434 static const BYTE ctlWithTwoEntries[] = {
5435 0x30,0x41,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5436 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x28,0x30,0x0f,0x04,
5437 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00,0x30,
5438 0x15,0x04,0x01,0x01,0x31,0x10,0x30,0x0e,0x06,0x02,0x2d,0x06,0x31,0x08,0x30,
5439 0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5441 static void test_encodeCTL(DWORD dwEncoding)
5443 static char oid1[] = "1.2.3";
5444 static char oid2[] = "1.5.6";
5445 char *pOid1 = oid1;
5446 BOOL ret;
5447 BYTE *buf = NULL;
5448 DWORD size = 0;
5449 CTL_INFO info;
5450 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5451 CTL_ENTRY ctlEntry[2];
5452 CRYPT_ATTRIBUTE attr1, attr2;
5453 CRYPT_ATTR_BLOB value1, value2;
5455 memset(&info, 0, sizeof(info));
5456 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5457 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5458 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5459 if (ret)
5461 ok(size == sizeof(emptyCTL), "unexpected size %d\n", size);
5462 ok(!memcmp(buf, emptyCTL, size), "unexpected value\n");
5463 LocalFree(buf);
5464 buf = NULL;
5466 info.dwVersion = 1;
5467 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5468 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5469 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5470 if (ret)
5472 ok(size == sizeof(emptyCTLWithVersion1), "unexpected size %d\n", size);
5473 ok(!memcmp(buf, emptyCTLWithVersion1, size), "unexpected value\n");
5474 LocalFree(buf);
5475 buf = NULL;
5477 info.dwVersion = 0;
5478 info.SubjectUsage.cUsageIdentifier = 1;
5479 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5480 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5481 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5482 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5483 if (ret)
5485 ok(size == sizeof(ctlWithUsageIdentifier), "unexpected size %d\n",
5486 size);
5487 ok(!memcmp(buf, ctlWithUsageIdentifier, size), "unexpected value\n");
5488 LocalFree(buf);
5489 buf = NULL;
5491 info.SubjectUsage.cUsageIdentifier = 0;
5492 info.ListIdentifier.cbData = sizeof(serialNum);
5493 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5494 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5495 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5496 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5497 if (ret)
5499 ok(size == sizeof(ctlWithListIdentifier), "unexpected size %d\n", size);
5500 ok(!memcmp(buf, ctlWithListIdentifier, size), "unexpected value\n");
5501 LocalFree(buf);
5502 buf = NULL;
5504 info.ListIdentifier.cbData = 0;
5505 info.SequenceNumber.cbData = sizeof(serialNum);
5506 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5507 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5508 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5509 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5510 if (ret)
5512 ok(size == sizeof(ctlWithSequenceNumber), "unexpected size %d\n",
5513 size);
5514 ok(!memcmp(buf, ctlWithSequenceNumber, size), "unexpected value\n");
5515 LocalFree(buf);
5516 buf = NULL;
5518 info.SequenceNumber.cbData = 0;
5519 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5520 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5521 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5522 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5523 if (ret)
5525 ok(size == sizeof(ctlWithThisUpdate), "unexpected size %d\n", size);
5526 ok(!memcmp(buf, ctlWithThisUpdate, size), "unexpected value\n");
5527 LocalFree(buf);
5528 buf = NULL;
5530 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5531 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5532 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5533 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5534 if (ret)
5536 ok(size == sizeof(ctlWithThisAndNextUpdate), "unexpected size %d\n",
5537 size);
5538 ok(!memcmp(buf, ctlWithThisAndNextUpdate, size), "unexpected value\n");
5539 LocalFree(buf);
5540 buf = NULL;
5542 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5543 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5544 info.SubjectAlgorithm.pszObjId = oid2;
5545 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5546 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5547 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5548 if (ret)
5550 ok(size == sizeof(ctlWithAlgId), "unexpected size %d\n", size);
5551 ok(!memcmp(buf, ctlWithAlgId, size), "unexpected value\n");
5552 LocalFree(buf);
5553 buf = NULL;
5555 /* The value is supposed to be asn.1 encoded, so this'll fail to decode
5556 * (see tests below) but it'll encode fine.
5558 info.SubjectAlgorithm.pszObjId = NULL;
5559 value1.cbData = sizeof(serialNum);
5560 value1.pbData = (LPBYTE)serialNum;
5561 attr1.pszObjId = oid1;
5562 attr1.cValue = 1;
5563 attr1.rgValue = &value1;
5564 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5565 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5566 ctlEntry[0].cAttribute = 1;
5567 ctlEntry[0].rgAttribute = &attr1;
5568 info.cCTLEntry = 1;
5569 info.rgCTLEntry = ctlEntry;
5570 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5571 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5572 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5573 if (ret)
5575 ok(size == sizeof(ctlWithBogusEntry), "unexpected size %d\n", size);
5576 ok(!memcmp(buf, ctlWithBogusEntry, size), "unexpected value\n");
5577 LocalFree(buf);
5578 buf = NULL;
5580 value1.cbData = sizeof(emptySequence);
5581 value1.pbData = (LPBYTE)emptySequence;
5582 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5583 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5584 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5585 if (ret)
5587 ok(size == sizeof(ctlWithOneEntry), "unexpected size %d\n", size);
5588 ok(!memcmp(buf, ctlWithOneEntry, size), "unexpected value\n");
5589 LocalFree(buf);
5590 buf = NULL;
5592 value2.cbData = sizeof(encodedIPAddr);
5593 value2.pbData = (LPBYTE)encodedIPAddr;
5594 attr2.pszObjId = oid2;
5595 attr2.cValue = 1;
5596 attr2.rgValue = &value2;
5597 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5598 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5599 ctlEntry[1].cAttribute = 1;
5600 ctlEntry[1].rgAttribute = &attr2;
5601 info.cCTLEntry = 2;
5602 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5603 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5604 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5605 if (ret)
5607 ok(size == sizeof(ctlWithTwoEntries), "unexpected size %d\n", size);
5608 ok(!memcmp(buf, ctlWithTwoEntries, size), "unexpected value\n");
5609 LocalFree(buf);
5610 buf = NULL;
5614 static void compareCTLInfo(LPCSTR header, const CTL_INFO *expected,
5615 const CTL_INFO *got)
5617 DWORD i, j, k;
5619 ok(expected->dwVersion == got->dwVersion,
5620 "%s: expected version %d, got %d\n", header, expected->dwVersion,
5621 got->dwVersion);
5622 ok(expected->SubjectUsage.cUsageIdentifier ==
5623 got->SubjectUsage.cUsageIdentifier,
5624 "%s: expected %d usage identifiers, got %d\n", header,
5625 expected->SubjectUsage.cUsageIdentifier,
5626 got->SubjectUsage.cUsageIdentifier);
5627 for (i = 0; i < expected->SubjectUsage.cUsageIdentifier; i++)
5628 ok(!strcmp(expected->SubjectUsage.rgpszUsageIdentifier[i],
5629 got->SubjectUsage.rgpszUsageIdentifier[i]),
5630 "%s[%d]: expected %s, got %s\n", header, i,
5631 expected->SubjectUsage.rgpszUsageIdentifier[i],
5632 got->SubjectUsage.rgpszUsageIdentifier[i]);
5633 ok(expected->ListIdentifier.cbData == got->ListIdentifier.cbData,
5634 "%s: expected list identifier of %d bytes, got %d\n", header,
5635 expected->ListIdentifier.cbData, got->ListIdentifier.cbData);
5636 if (expected->ListIdentifier.cbData)
5637 ok(!memcmp(expected->ListIdentifier.pbData, got->ListIdentifier.pbData,
5638 expected->ListIdentifier.cbData),
5639 "%s: unexpected list identifier value\n", header);
5640 ok(expected->SequenceNumber.cbData == got->SequenceNumber.cbData,
5641 "%s: expected sequence number of %d bytes, got %d\n", header,
5642 expected->SequenceNumber.cbData, got->SequenceNumber.cbData);
5643 if (expected->SequenceNumber.cbData)
5644 ok(!memcmp(expected->SequenceNumber.pbData, got->SequenceNumber.pbData,
5645 expected->SequenceNumber.cbData),
5646 "%s: unexpected sequence number value\n", header);
5647 ok(!memcmp(&expected->ThisUpdate, &got->ThisUpdate, sizeof(FILETIME)),
5648 "%s: expected this update = (%d, %d), got (%d, %d)\n", header,
5649 expected->ThisUpdate.dwLowDateTime, expected->ThisUpdate.dwHighDateTime,
5650 got->ThisUpdate.dwLowDateTime, got->ThisUpdate.dwHighDateTime);
5651 ok(!memcmp(&expected->NextUpdate, &got->NextUpdate, sizeof(FILETIME)),
5652 "%s: expected next update = (%d, %d), got (%d, %d)\n", header,
5653 expected->NextUpdate.dwLowDateTime, expected->NextUpdate.dwHighDateTime,
5654 got->NextUpdate.dwLowDateTime, got->NextUpdate.dwHighDateTime);
5655 if (expected->SubjectAlgorithm.pszObjId &&
5656 *expected->SubjectAlgorithm.pszObjId && !got->SubjectAlgorithm.pszObjId)
5657 ok(0, "%s: expected subject algorithm %s, got NULL\n", header,
5658 expected->SubjectAlgorithm.pszObjId);
5659 if (expected->SubjectAlgorithm.pszObjId && got->SubjectAlgorithm.pszObjId)
5660 ok(!strcmp(expected->SubjectAlgorithm.pszObjId,
5661 got->SubjectAlgorithm.pszObjId),
5662 "%s: expected subject algorithm %s, got %s\n", header,
5663 expected->SubjectAlgorithm.pszObjId, got->SubjectAlgorithm.pszObjId);
5664 ok(expected->SubjectAlgorithm.Parameters.cbData ==
5665 got->SubjectAlgorithm.Parameters.cbData,
5666 "%s: expected subject algorithm parameters of %d bytes, got %d\n", header,
5667 expected->SubjectAlgorithm.Parameters.cbData,
5668 got->SubjectAlgorithm.Parameters.cbData);
5669 if (expected->SubjectAlgorithm.Parameters.cbData)
5670 ok(!memcmp(expected->SubjectAlgorithm.Parameters.pbData,
5671 got->SubjectAlgorithm.Parameters.pbData,
5672 expected->SubjectAlgorithm.Parameters.cbData),
5673 "%s: unexpected subject algorithm parameter value\n", header);
5674 ok(expected->cCTLEntry == got->cCTLEntry,
5675 "%s: expected %d CTL entries, got %d\n", header, expected->cCTLEntry,
5676 got->cCTLEntry);
5677 for (i = 0; i < expected->cCTLEntry; i++)
5679 ok(expected->rgCTLEntry[i].SubjectIdentifier.cbData ==
5680 got->rgCTLEntry[i].SubjectIdentifier.cbData,
5681 "%s[%d]: expected subject identifier of %d bytes, got %d\n",
5682 header, i, expected->rgCTLEntry[i].SubjectIdentifier.cbData,
5683 got->rgCTLEntry[i].SubjectIdentifier.cbData);
5684 if (expected->rgCTLEntry[i].SubjectIdentifier.cbData)
5685 ok(!memcmp(expected->rgCTLEntry[i].SubjectIdentifier.pbData,
5686 got->rgCTLEntry[i].SubjectIdentifier.pbData,
5687 expected->rgCTLEntry[i].SubjectIdentifier.cbData),
5688 "%s[%d]: unexpected subject identifier value\n",
5689 header, i);
5690 for (j = 0; j < expected->rgCTLEntry[i].cAttribute; j++)
5692 ok(!strcmp(expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5693 got->rgCTLEntry[i].rgAttribute[j].pszObjId),
5694 "%s[%d][%d]: expected attribute OID %s, got %s\n", header, i, j,
5695 expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5696 got->rgCTLEntry[i].rgAttribute[j].pszObjId);
5697 for (k = 0; k < expected->rgCTLEntry[i].rgAttribute[j].cValue; k++)
5699 ok(expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData ==
5700 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5701 "%s[%d][%d][%d]: expected value of %d bytes, got %d\n",
5702 header, i, j, k,
5703 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5704 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData);
5705 if (expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData)
5706 ok(!memcmp(
5707 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5708 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5709 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData),
5710 "%s[%d][%d][%d]: unexpected value\n",
5711 header, i, j, k);
5715 ok(expected->cExtension == got->cExtension,
5716 "%s: expected %d extensions, got %d\n", header, expected->cExtension,
5717 got->cExtension);
5718 for (i = 0; i < expected->cExtension; i++)
5720 ok(!strcmp(expected->rgExtension[i].pszObjId,
5721 got->rgExtension[i].pszObjId), "%s[%d]: expected %s, got %s\n",
5722 header, i, expected->rgExtension[i].pszObjId,
5723 got->rgExtension[i].pszObjId);
5724 ok(expected->rgExtension[i].fCritical == got->rgExtension[i].fCritical,
5725 "%s[%d]: expected fCritical = %d, got %d\n", header, i,
5726 expected->rgExtension[i].fCritical, got->rgExtension[i].fCritical);
5727 ok(expected->rgExtension[i].Value.cbData ==
5728 got->rgExtension[i].Value.cbData,
5729 "%s[%d]: expected extension value to have %d bytes, got %d\n",
5730 header, i, expected->rgExtension[i].Value.cbData,
5731 got->rgExtension[i].Value.cbData);
5732 if (expected->rgExtension[i].Value.cbData)
5733 ok(!memcmp(expected->rgExtension[i].Value.pbData,
5734 got->rgExtension[i].Value.pbData,
5735 expected->rgExtension[i].Value.cbData),
5736 "%s[%d]: unexpected extension value\n", header, i);
5740 static const BYTE signedCTL[] = {
5741 0x30,0x81,0xc7,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
5742 0x81,0xb9,0x30,0x81,0xb6,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
5743 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x28,0x06,0x09,0x2a,0x86,
5744 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x1b,0x04,0x19,0x30,0x17,0x30,0x00,
5745 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5746 0x30,0x5a,0x30,0x02,0x06,0x00,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
5747 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
5748 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
5749 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5750 0x00,0x04,0x40,0xca,0xd8,0x32,0xd1,0xbd,0x97,0x61,0x54,0xd6,0x80,0xcf,0x0d,
5751 0xbd,0xa2,0x42,0xc7,0xca,0x37,0x91,0x7d,0x9d,0xac,0x8c,0xdf,0x05,0x8a,0x39,
5752 0xc6,0x07,0xc1,0x37,0xe6,0xb9,0xd1,0x0d,0x26,0xec,0xa5,0xb0,0x8a,0x51,0x26,
5753 0x2b,0x4f,0x73,0x44,0x86,0x83,0x5e,0x2b,0x6e,0xcc,0xf8,0x1b,0x85,0x53,0xe9,
5754 0x7a,0x80,0x8f,0x6b,0x42,0x19,0x93 };
5755 static const BYTE signedCTLWithCTLInnerContent[] = {
5756 0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
5757 0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
5758 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
5759 0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
5760 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5761 0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
5762 0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
5763 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
5764 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
5765 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
5766 0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
5767 0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
5768 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
5769 0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5770 0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
5771 0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
5772 0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
5773 0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
5774 0x57,0x6c,0x0b,0x47,0xb8 };
5776 static void test_decodeCTL(DWORD dwEncoding)
5778 static char oid1[] = "1.2.3";
5779 static char oid2[] = "1.5.6";
5780 static BYTE nullData[] = { 5,0 };
5781 char *pOid1 = oid1;
5782 BOOL ret;
5783 BYTE *buf = NULL;
5784 DWORD size = 0;
5785 CTL_INFO info;
5786 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5787 CTL_ENTRY ctlEntry[2];
5788 CRYPT_ATTRIBUTE attr1, attr2;
5789 CRYPT_ATTR_BLOB value1, value2;
5791 memset(&info, 0, sizeof(info));
5792 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTL, sizeof(emptyCTL),
5793 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5794 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5795 if (ret)
5797 compareCTLInfo("empty CTL", &info, (CTL_INFO *)buf);
5798 LocalFree(buf);
5799 buf = NULL;
5801 info.dwVersion = 1;
5802 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTLWithVersion1,
5803 sizeof(emptyCTLWithVersion1), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
5804 &size);
5805 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5806 if (ret)
5808 compareCTLInfo("v1 CTL", &info, (CTL_INFO *)buf);
5809 LocalFree(buf);
5810 buf = NULL;
5812 info.dwVersion = 0;
5813 info.SubjectUsage.cUsageIdentifier = 1;
5814 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5815 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithUsageIdentifier,
5816 sizeof(ctlWithUsageIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5817 &buf, &size);
5818 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5819 if (ret)
5821 compareCTLInfo("CTL with usage identifier", &info, (CTL_INFO *)buf);
5822 LocalFree(buf);
5823 buf = NULL;
5825 info.SubjectUsage.cUsageIdentifier = 0;
5826 info.ListIdentifier.cbData = sizeof(serialNum);
5827 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5828 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithListIdentifier,
5829 sizeof(ctlWithListIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5830 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5831 if (ret)
5833 compareCTLInfo("CTL with list identifier", &info, (CTL_INFO *)buf);
5834 LocalFree(buf);
5835 buf = NULL;
5837 info.ListIdentifier.cbData = 0;
5838 info.SequenceNumber.cbData = sizeof(serialNum);
5839 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5840 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithSequenceNumber,
5841 sizeof(ctlWithSequenceNumber), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5842 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5843 if (ret)
5845 compareCTLInfo("CTL with sequence number", &info, (CTL_INFO *)buf);
5846 LocalFree(buf);
5847 buf = NULL;
5849 info.SequenceNumber.cbData = 0;
5850 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5851 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisUpdate,
5852 sizeof(ctlWithThisUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5853 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5854 if (ret)
5856 compareCTLInfo("CTL with this update", &info, (CTL_INFO *)buf);
5857 LocalFree(buf);
5858 buf = NULL;
5860 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5861 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisAndNextUpdate,
5862 sizeof(ctlWithThisAndNextUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5863 &buf, &size);
5864 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5865 if (ret)
5867 compareCTLInfo("CTL with this and next update", &info, (CTL_INFO *)buf);
5868 LocalFree(buf);
5869 buf = NULL;
5871 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5872 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5873 info.SubjectAlgorithm.pszObjId = oid2;
5874 info.SubjectAlgorithm.Parameters.cbData = sizeof(nullData);
5875 info.SubjectAlgorithm.Parameters.pbData = nullData;
5876 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithAlgId,
5877 sizeof(ctlWithAlgId), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5878 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5879 if (ret)
5881 compareCTLInfo("CTL with algorithm identifier", &info, (CTL_INFO *)buf);
5882 LocalFree(buf);
5883 buf = NULL;
5885 SetLastError(0xdeadbeef);
5886 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithBogusEntry,
5887 sizeof(ctlWithBogusEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5888 ok(!ret &&
5889 (GetLastError() == CRYPT_E_ASN1_EOD ||
5890 GetLastError() == CRYPT_E_ASN1_CORRUPT ||
5891 GetLastError() == OSS_MORE_INPUT), /* Win9x */
5892 "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n",
5893 GetLastError());
5894 info.SubjectAlgorithm.Parameters.cbData = 0;
5895 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5896 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5897 info.SubjectAlgorithm.pszObjId = NULL;
5898 value1.cbData = sizeof(emptySequence);
5899 value1.pbData = (LPBYTE)emptySequence;
5900 attr1.pszObjId = oid1;
5901 attr1.cValue = 1;
5902 attr1.rgValue = &value1;
5903 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5904 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5905 ctlEntry[0].cAttribute = 1;
5906 ctlEntry[0].rgAttribute = &attr1;
5907 info.cCTLEntry = 1;
5908 info.rgCTLEntry = ctlEntry;
5909 SetLastError(0xdeadbeef);
5910 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithOneEntry,
5911 sizeof(ctlWithOneEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5912 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5913 if (ret)
5915 compareCTLInfo("CTL with one entry", &info, (CTL_INFO *)buf);
5916 LocalFree(buf);
5917 buf = NULL;
5919 value2.cbData = sizeof(encodedIPAddr);
5920 value2.pbData = (LPBYTE)encodedIPAddr;
5921 attr2.pszObjId = oid2;
5922 attr2.cValue = 1;
5923 attr2.rgValue = &value2;
5924 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5925 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5926 ctlEntry[1].cAttribute = 1;
5927 ctlEntry[1].rgAttribute = &attr2;
5928 info.cCTLEntry = 2;
5929 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithTwoEntries,
5930 sizeof(ctlWithTwoEntries), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5931 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5932 if (ret)
5934 compareCTLInfo("CTL with two entries", &info, (CTL_INFO *)buf);
5935 LocalFree(buf);
5936 buf = NULL;
5938 /* A signed CTL isn't decodable, even if the inner content is a CTL */
5939 SetLastError(0xdeadbeef);
5940 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, signedCTL,
5941 sizeof(signedCTL), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5942 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5943 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5944 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5945 GetLastError());
5946 SetLastError(0xdeadbeef);
5947 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL,
5948 signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent),
5949 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5950 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5951 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5952 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5953 GetLastError());
5956 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
5957 static const BYTE emptyPKCSContentInfoExtraBytes[] = { 0x30,0x04,0x06,0x02,0x2a,
5958 0x03,0,0,0,0,0,0 };
5959 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
5960 0xa0,0x01,0x01 };
5961 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
5962 0x03,0x02,0x01,0x01 };
5963 static BYTE bogusDER[] = { 1 };
5965 static void test_encodePKCSContentInfo(DWORD dwEncoding)
5967 BOOL ret;
5968 BYTE *buf = NULL;
5969 DWORD size = 0;
5970 CRYPT_CONTENT_INFO info = { 0 };
5971 char oid1[] = "1.2.3";
5973 if (0)
5975 /* Crashes on win9x */
5976 SetLastError(0xdeadbeef);
5977 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL,
5978 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5979 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5980 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5982 SetLastError(0xdeadbeef);
5983 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5984 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5985 ok(!ret && (GetLastError() == E_INVALIDARG ||
5986 GetLastError() == OSS_LIMITED /* Win9x */),
5987 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5988 info.pszObjId = oid1;
5989 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5990 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5991 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5992 if (ret)
5994 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size);
5995 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n");
5996 LocalFree(buf);
5998 info.Content.pbData = bogusDER;
5999 info.Content.cbData = sizeof(bogusDER);
6000 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
6001 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6002 ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError());
6003 if (ret)
6005 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size);
6006 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n");
6007 LocalFree(buf);
6009 info.Content.pbData = (BYTE *)ints[0].encoded;
6010 info.Content.cbData = ints[0].encoded[1] + 2;
6011 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
6012 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6013 if (ret)
6015 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size);
6016 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n");
6017 LocalFree(buf);
6021 static const BYTE indefiniteSignedPKCSContent[] = {
6022 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
6023 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
6024 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
6025 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
6026 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
6027 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
6028 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
6029 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
6030 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
6031 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
6032 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
6033 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
6034 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
6035 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
6036 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
6037 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
6038 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
6039 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
6040 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
6041 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
6042 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
6043 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
6044 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
6045 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
6046 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
6047 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
6048 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
6049 0x00,0x00,0x00,0x00,0x00,0x00 };
6051 static const BYTE content_abcd[] = {
6052 ASN_SEQUENCE, 0x80,
6053 ASN_OBJECTIDENTIFIER, 2, 42,3,
6054 ASN_CONTEXT|ASN_CONSTRUCTOR, 0x80,
6055 ASN_OCTETSTRING, 4, 'a','b','c','d',
6056 0,0,
6057 0,0,
6060 static const BYTE encoded_abcd[] = {
6061 ASN_OCTETSTRING, 4, 'a','b','c','d',
6064 static const BYTE content_constructed_abcd[] = {
6065 ASN_SEQUENCE, 0x80,
6066 ASN_OBJECTIDENTIFIER, 2, 42,3,
6067 ASN_CONTEXT|ASN_CONSTRUCTOR, 0x80,
6068 ASN_CONSTRUCTOR|ASN_OCTETSTRING,0x80,
6069 ASN_OCTETSTRING, 4, 'a','b','0','0',
6070 0,0,
6071 0,0,
6072 0,0,
6073 1,2,3,4,5,6,7 /* extra garbage */
6076 static void test_decodePKCSContentInfo(DWORD dwEncoding)
6078 BOOL ret;
6079 LPBYTE buf = NULL;
6080 DWORD size = 0, i;
6081 CRYPT_CONTENT_INFO *info;
6083 const struct {
6084 const BYTE *encoded;
6085 UINT encoded_size;
6086 const char *obj_id;
6087 const BYTE *content;
6088 UINT content_size;
6089 } tests[] = {
6090 { emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo),
6091 "1.2.3", NULL, 0 },
6092 { emptyPKCSContentInfoExtraBytes, sizeof(emptyPKCSContentInfoExtraBytes),
6093 "1.2.3", NULL, 0 },
6094 { intPKCSContentInfo, sizeof(intPKCSContentInfo),
6095 "1.2.3", ints[0].encoded, ints[0].encoded[1] + 2 },
6096 { indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent),
6097 "1.2.840.113549.1.7.2", NULL, 392 },
6098 { content_abcd, sizeof(content_abcd),
6099 "1.2.3", encoded_abcd, 6 },
6100 { content_constructed_abcd, sizeof(content_constructed_abcd),
6101 "1.2.3", content_constructed_abcd + 8, 10 }
6104 for (i = 0; i < ARRAY_SIZE(tests); i++)
6106 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, tests[i].encoded,
6107 tests[i].encoded_size, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6108 ok(ret, "[%u] CryptDecodeObjectEx failed: %x\n", i, GetLastError());
6109 if (!ret) continue;
6111 info = (CRYPT_CONTENT_INFO *)buf;
6113 ok(!strcmp(info->pszObjId, tests[i].obj_id), "[%u] Expected %s, got %s\n",
6114 i, tests[i].obj_id, info->pszObjId);
6115 ok(info->Content.cbData == tests[i].content_size,
6116 "[%u] Unexpected size %d expected %d\n", i, info->Content.cbData,
6117 tests[i].content_size);
6118 if (tests[i].content)
6119 ok(!memcmp(info->Content.pbData, tests[i].content, tests[i].content_size),
6120 "[%u] Unexpected value\n", i);
6121 LocalFree(buf);
6124 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
6125 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo),
6126 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6127 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
6128 * I doubt an app depends on that.
6130 ok((!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
6131 GetLastError() == CRYPT_E_ASN1_CORRUPT)) || broken(ret),
6132 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
6133 GetLastError());
6136 static const BYTE emptyPKCSAttr[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
6137 0x00 };
6138 static const BYTE bogusPKCSAttr[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
6139 0x01 };
6140 static const BYTE intPKCSAttr[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
6141 0x02,0x01,0x01 };
6143 static void test_encodePKCSAttribute(DWORD dwEncoding)
6145 CRYPT_ATTRIBUTE attr = { 0 };
6146 BOOL ret;
6147 LPBYTE buf = NULL;
6148 DWORD size = 0;
6149 CRYPT_ATTR_BLOB blob;
6150 char oid[] = "1.2.3";
6152 if (0)
6154 /* Crashes on win9x */
6155 SetLastError(0xdeadbeef);
6156 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, NULL,
6157 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6158 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
6159 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
6161 SetLastError(0xdeadbeef);
6162 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
6163 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6164 ok(!ret && (GetLastError() == E_INVALIDARG ||
6165 GetLastError() == OSS_LIMITED /* Win9x */),
6166 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
6167 attr.pszObjId = oid;
6168 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
6169 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6170 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6171 if (ret)
6173 ok(size == sizeof(emptyPKCSAttr), "Unexpected size %d\n", size);
6174 ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n");
6175 LocalFree(buf);
6177 blob.cbData = sizeof(bogusDER);
6178 blob.pbData = bogusDER;
6179 attr.cValue = 1;
6180 attr.rgValue = &blob;
6181 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
6182 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6183 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6184 if (ret)
6186 ok(size == sizeof(bogusPKCSAttr), "Unexpected size %d\n", size);
6187 ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n");
6188 LocalFree(buf);
6190 blob.pbData = (BYTE *)ints[0].encoded;
6191 blob.cbData = ints[0].encoded[1] + 2;
6192 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
6193 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6194 if (ret)
6196 ok(size == sizeof(intPKCSAttr), "Unexpected size %d\n", size);
6197 ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n");
6198 LocalFree(buf);
6202 static void test_decodePKCSAttribute(DWORD dwEncoding)
6204 BOOL ret;
6205 LPBYTE buf = NULL;
6206 DWORD size = 0;
6207 CRYPT_ATTRIBUTE *attr;
6209 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
6210 emptyPKCSAttr, sizeof(emptyPKCSAttr),
6211 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6212 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6213 if (ret)
6215 attr = (CRYPT_ATTRIBUTE *)buf;
6217 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
6218 attr->pszObjId);
6219 ok(attr->cValue == 0, "Expected no value, got %d\n", attr->cValue);
6220 LocalFree(buf);
6222 SetLastError(0xdeadbeef);
6223 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
6224 bogusPKCSAttr, sizeof(bogusPKCSAttr),
6225 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6226 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
6227 * I doubt an app depends on that.
6229 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
6230 GetLastError() == CRYPT_E_ASN1_CORRUPT ||
6231 GetLastError() == OSS_MORE_INPUT /* Win9x */),
6232 "Expected CRYPT_E_ASN1_EOD, CRYPT_E_ASN1_CORRUPT, or OSS_MORE_INPUT, got %x\n",
6233 GetLastError());
6234 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
6235 intPKCSAttr, sizeof(intPKCSAttr),
6236 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6237 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6238 if (ret)
6240 attr = (CRYPT_ATTRIBUTE *)buf;
6242 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
6243 attr->pszObjId);
6244 ok(attr->cValue == 1, "Expected 1 value, got %d\n", attr->cValue);
6245 ok(attr->rgValue[0].cbData == ints[0].encoded[1] + 2,
6246 "Unexpected size %d\n", attr->rgValue[0].cbData);
6247 ok(!memcmp(attr->rgValue[0].pbData, ints[0].encoded,
6248 attr->rgValue[0].cbData), "Unexpected value\n");
6249 LocalFree(buf);
6253 static const BYTE emptyPKCSAttributes[] = { 0x31,0x00 };
6254 static const BYTE singlePKCSAttributes[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
6255 0x2a,0x03,0x31,0x00 };
6256 static const BYTE doublePKCSAttributes[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
6257 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
6259 static void test_encodePKCSAttributes(DWORD dwEncoding)
6261 CRYPT_ATTRIBUTES attributes = { 0 };
6262 CRYPT_ATTRIBUTE attr[2] = { { 0 } };
6263 CRYPT_ATTR_BLOB blob;
6264 BOOL ret;
6265 LPBYTE buf = NULL;
6266 DWORD size = 0;
6267 char oid1[] = "1.2.3", oid2[] = "1.5.6";
6269 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6270 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6271 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6272 if (ret)
6274 ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %d\n", size);
6275 ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n");
6276 LocalFree(buf);
6278 attributes.cAttr = 1;
6279 attributes.rgAttr = attr;
6280 SetLastError(0xdeadbeef);
6281 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6282 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6283 ok(!ret && (GetLastError() == E_INVALIDARG ||
6284 GetLastError() == OSS_LIMITED /* Win9x */),
6285 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6286 attr[0].pszObjId = oid1;
6287 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6288 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6289 if (ret)
6291 ok(size == sizeof(singlePKCSAttributes), "Unexpected size %d\n", size);
6292 ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n");
6293 LocalFree(buf);
6295 attr[1].pszObjId = oid2;
6296 attr[1].cValue = 1;
6297 attr[1].rgValue = &blob;
6298 blob.pbData = (BYTE *)ints[0].encoded;
6299 blob.cbData = ints[0].encoded[1] + 2;
6300 attributes.cAttr = 2;
6301 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6302 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6303 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6304 if (ret)
6306 ok(size == sizeof(doublePKCSAttributes), "Unexpected size %d\n", size);
6307 ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n");
6308 LocalFree(buf);
6312 static void test_decodePKCSAttributes(DWORD dwEncoding)
6314 BOOL ret;
6315 LPBYTE buf = NULL;
6316 DWORD size = 0;
6317 CRYPT_ATTRIBUTES *attributes;
6319 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6320 emptyPKCSAttributes, sizeof(emptyPKCSAttributes),
6321 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6322 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6323 if (ret)
6325 attributes = (CRYPT_ATTRIBUTES *)buf;
6326 ok(attributes->cAttr == 0, "Expected no attributes, got %d\n",
6327 attributes->cAttr);
6328 LocalFree(buf);
6330 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6331 singlePKCSAttributes, sizeof(singlePKCSAttributes),
6332 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6333 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6334 if (ret)
6336 attributes = (CRYPT_ATTRIBUTES *)buf;
6337 ok(attributes->cAttr == 1, "Expected 1 attribute, got %d\n",
6338 attributes->cAttr);
6339 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
6340 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
6341 ok(attributes->rgAttr[0].cValue == 0,
6342 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
6343 LocalFree(buf);
6345 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6346 doublePKCSAttributes, sizeof(doublePKCSAttributes),
6347 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6348 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6349 if (ret)
6351 attributes = (CRYPT_ATTRIBUTES *)buf;
6352 ok(attributes->cAttr == 2, "Expected 2 attributes, got %d\n",
6353 attributes->cAttr);
6354 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
6355 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
6356 ok(attributes->rgAttr[0].cValue == 0,
6357 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
6358 ok(!strcmp(attributes->rgAttr[1].pszObjId, "1.5.6"),
6359 "Expected 1.5.6, got %s\n", attributes->rgAttr[1].pszObjId);
6360 ok(attributes->rgAttr[1].cValue == 1,
6361 "Expected 1 attribute, got %d\n", attributes->rgAttr[1].cValue);
6362 ok(attributes->rgAttr[1].rgValue[0].cbData == ints[0].encoded[1] + 2,
6363 "Unexpected size %d\n", attributes->rgAttr[1].rgValue[0].cbData);
6364 ok(!memcmp(attributes->rgAttr[1].rgValue[0].pbData, ints[0].encoded,
6365 attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n");
6366 LocalFree(buf);
6368 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6369 doublePKCSAttributes, sizeof(doublePKCSAttributes), 0, NULL, NULL, &size);
6370 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6371 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
6372 if (buf)
6374 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6375 doublePKCSAttributes, sizeof(doublePKCSAttributes), 0, NULL, buf, &size);
6376 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6377 HeapFree(GetProcessHeap(), 0, buf);
6381 static const BYTE singleCapability[] = {
6382 0x30,0x06,0x30,0x04,0x06,0x02,0x2d,0x06 };
6383 static const BYTE twoCapabilities[] = {
6384 0x30,0x0c,0x30,0x04,0x06,0x02,0x2d,0x06,0x30,0x04,0x06,0x02,0x2a,0x03 };
6385 static const BYTE singleCapabilitywithNULL[] = {
6386 0x30,0x08,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
6388 static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding)
6390 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6391 BOOL ret;
6392 LPBYTE buf = NULL;
6393 DWORD size = 0;
6394 CRYPT_SMIME_CAPABILITY capability[2];
6395 CRYPT_SMIME_CAPABILITIES capabilities;
6397 /* An empty capabilities is allowed */
6398 capabilities.cCapability = 0;
6399 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6400 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6401 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6402 if (ret)
6404 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
6405 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
6406 LocalFree(buf);
6408 /* A non-empty capabilities with an empty capability (lacking an OID) is
6409 * not allowed
6411 capability[0].pszObjId = NULL;
6412 capability[0].Parameters.cbData = 0;
6413 capabilities.cCapability = 1;
6414 capabilities.rgCapability = capability;
6415 SetLastError(0xdeadbeef);
6416 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6417 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6418 ok(!ret && (GetLastError() == E_INVALIDARG ||
6419 GetLastError() == OSS_LIMITED /* Win9x */),
6420 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6421 capability[0].pszObjId = oid1;
6422 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6423 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6424 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6425 if (ret)
6427 ok(size == sizeof(singleCapability), "unexpected size %d\n", size);
6428 ok(!memcmp(buf, singleCapability, size), "unexpected value\n");
6429 LocalFree(buf);
6431 capability[1].pszObjId = oid2;
6432 capability[1].Parameters.cbData = 0;
6433 capabilities.cCapability = 2;
6434 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6435 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6436 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6437 if (ret)
6439 ok(size == sizeof(twoCapabilities), "unexpected size %d\n", size);
6440 ok(!memcmp(buf, twoCapabilities, size), "unexpected value\n");
6441 LocalFree(buf);
6445 static void compareSMimeCapabilities(LPCSTR header,
6446 const CRYPT_SMIME_CAPABILITIES *expected, const CRYPT_SMIME_CAPABILITIES *got)
6448 DWORD i;
6450 ok(got->cCapability == expected->cCapability,
6451 "%s: expected %d capabilities, got %d\n", header, expected->cCapability,
6452 got->cCapability);
6453 for (i = 0; i < expected->cCapability; i++)
6455 ok(!strcmp(expected->rgCapability[i].pszObjId,
6456 got->rgCapability[i].pszObjId), "%s[%d]: expected %s, got %s\n",
6457 header, i, expected->rgCapability[i].pszObjId,
6458 got->rgCapability[i].pszObjId);
6459 ok(expected->rgCapability[i].Parameters.cbData ==
6460 got->rgCapability[i].Parameters.cbData,
6461 "%s[%d]: expected %d bytes, got %d\n", header, i,
6462 expected->rgCapability[i].Parameters.cbData,
6463 got->rgCapability[i].Parameters.cbData);
6464 if (expected->rgCapability[i].Parameters.cbData)
6465 ok(!memcmp(expected->rgCapability[i].Parameters.pbData,
6466 got->rgCapability[i].Parameters.pbData,
6467 expected->rgCapability[i].Parameters.cbData),
6468 "%s[%d]: unexpected value\n", header, i);
6472 static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding)
6474 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6475 BOOL ret;
6476 DWORD size = 0;
6477 CRYPT_SMIME_CAPABILITY capability[2];
6478 CRYPT_SMIME_CAPABILITIES capabilities, *ptr;
6480 SetLastError(0xdeadbeef);
6481 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6482 emptySequence, sizeof(emptySequence),
6483 CRYPT_DECODE_ALLOC_FLAG, NULL, &ptr, &size);
6484 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6485 if (ret)
6487 capabilities.cCapability = 0;
6488 compareSMimeCapabilities("empty capabilities", &capabilities, ptr);
6489 LocalFree(ptr);
6491 SetLastError(0xdeadbeef);
6492 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6493 singleCapability, sizeof(singleCapability), CRYPT_DECODE_ALLOC_FLAG, NULL,
6494 &ptr, &size);
6495 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6496 if (ret)
6498 capability[0].pszObjId = oid1;
6499 capability[0].Parameters.cbData = 0;
6500 capabilities.cCapability = 1;
6501 capabilities.rgCapability = capability;
6502 compareSMimeCapabilities("single capability", &capabilities, ptr);
6503 LocalFree(ptr);
6505 SetLastError(0xdeadbeef);
6506 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6507 singleCapabilitywithNULL, sizeof(singleCapabilitywithNULL),
6508 CRYPT_DECODE_ALLOC_FLAG, NULL, &ptr, &size);
6509 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6510 if (ret)
6512 BYTE NULLparam[] = {0x05, 0x00};
6513 capability[0].pszObjId = oid1;
6514 capability[0].Parameters.cbData = 2;
6515 capability[0].Parameters.pbData = NULLparam;
6516 capabilities.cCapability = 1;
6517 capabilities.rgCapability = capability;
6518 compareSMimeCapabilities("single capability with NULL", &capabilities,
6519 ptr);
6520 LocalFree(ptr);
6522 SetLastError(0xdeadbeef);
6523 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6524 twoCapabilities, sizeof(twoCapabilities), CRYPT_DECODE_ALLOC_FLAG, NULL,
6525 &ptr, &size);
6526 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6527 if (ret)
6529 capability[0].Parameters.cbData = 0;
6530 capability[1].pszObjId = oid2;
6531 capability[1].Parameters.cbData = 0;
6532 capabilities.cCapability = 2;
6533 compareSMimeCapabilities("two capabilities", &capabilities, ptr);
6534 LocalFree(ptr);
6536 SetLastError(0xdeadbeef);
6537 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6538 twoCapabilities, sizeof(twoCapabilities), 0, NULL, NULL, &size);
6539 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6540 ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
6541 if (ptr)
6543 SetLastError(0xdeadbeef);
6544 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6545 twoCapabilities, sizeof(twoCapabilities), 0, NULL, ptr, &size);
6546 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6547 HeapFree(GetProcessHeap(), 0, ptr);
6551 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
6552 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
6553 0x67 };
6554 static const BYTE minimalPKCSSigner[] = {
6555 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6556 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6557 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6558 static const BYTE PKCSSignerWithSerial[] = {
6559 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6560 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6561 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
6562 0x00 };
6563 static const BYTE PKCSSignerWithHashAlgo[] = {
6564 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6565 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6566 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
6567 0x00,0x04,0x00 };
6568 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = {
6569 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6570 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6571 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6572 0x06,0x05,0x00,0x04,0x00 };
6573 static const BYTE PKCSSignerWithHash[] = {
6574 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6575 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6576 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6577 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
6578 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6579 static const BYTE PKCSSignerWithAuthAttr[] = {
6580 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6581 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6582 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
6583 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
6584 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
6585 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
6586 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6588 static void test_encodePKCSSignerInfo(DWORD dwEncoding)
6590 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6591 BOOL ret;
6592 LPBYTE buf = NULL;
6593 DWORD size = 0;
6594 CMSG_SIGNER_INFO info = { 0 };
6595 char oid_common_name[] = szOID_COMMON_NAME;
6596 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
6597 (LPBYTE)encodedCommonName };
6598 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
6600 SetLastError(0xdeadbeef);
6601 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6602 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6603 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6605 skip("no PKCS7_SIGNER_INFO encode support\n");
6606 return;
6608 ok(!ret && (GetLastError() == E_INVALIDARG ||
6609 GetLastError() == OSS_LIMITED /* Win9x */),
6610 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6611 /* To be encoded, a signer must have an issuer at least, and the encoding
6612 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
6613 * see decoding tests.)
6615 info.Issuer.cbData = sizeof(encodedCommonNameNoNull);
6616 info.Issuer.pbData = encodedCommonNameNoNull;
6617 SetLastError(0xdeadbeef);
6618 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6619 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6620 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6621 ok(!ret && GetLastError() == E_INVALIDARG,
6622 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6623 else
6625 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6626 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6627 if (ret)
6629 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6630 if (size == sizeof(minimalPKCSSigner))
6631 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6632 else
6633 ok(0, "Unexpected value\n");
6634 LocalFree(buf);
6637 info.SerialNumber.cbData = sizeof(serialNum);
6638 info.SerialNumber.pbData = (BYTE *)serialNum;
6639 SetLastError(0xdeadbeef);
6640 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6641 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6642 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6643 ok(!ret && GetLastError() == E_INVALIDARG,
6644 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6645 else
6647 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6648 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6649 if (ret)
6651 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6652 size);
6653 if (size == sizeof(PKCSSignerWithSerial))
6654 ok(!memcmp(buf, PKCSSignerWithSerial, size),
6655 "Unexpected value\n");
6656 else
6657 ok(0, "Unexpected value\n");
6658 LocalFree(buf);
6661 info.HashAlgorithm.pszObjId = oid1;
6662 SetLastError(0xdeadbeef);
6663 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6664 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6665 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6666 ok(!ret && GetLastError() == E_INVALIDARG,
6667 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6668 else
6670 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6671 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6672 if (ret)
6674 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6675 size);
6676 if (size == sizeof(PKCSSignerWithHashAlgo))
6677 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6678 "Unexpected value\n");
6679 else
6680 ok(0, "Unexpected value\n");
6681 LocalFree(buf);
6684 info.HashEncryptionAlgorithm.pszObjId = oid2;
6685 SetLastError(0xdeadbeef);
6686 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6687 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6688 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6689 ok(!ret && GetLastError() == E_INVALIDARG,
6690 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6691 else
6693 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6694 if (ret)
6696 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6697 "Unexpected size %d\n", size);
6698 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo))
6699 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6700 "Unexpected value\n");
6701 else
6702 ok(0, "Unexpected value\n");
6703 LocalFree(buf);
6706 info.EncryptedHash.cbData = sizeof(hash);
6707 info.EncryptedHash.pbData = (BYTE *)hash;
6708 SetLastError(0xdeadbeef);
6709 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6710 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6711 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6712 ok(!ret && GetLastError() == E_INVALIDARG,
6713 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6714 else
6716 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6717 if (ret)
6719 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6720 size);
6721 if (size == sizeof(PKCSSignerWithHash))
6722 ok(!memcmp(buf, PKCSSignerWithHash, size),
6723 "Unexpected value\n");
6724 else
6725 ok(0, "Unexpected value\n");
6726 LocalFree(buf);
6729 info.AuthAttrs.cAttr = 1;
6730 info.AuthAttrs.rgAttr = &attr;
6731 SetLastError(0xdeadbeef);
6732 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6733 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6734 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6735 ok(!ret && GetLastError() == E_INVALIDARG,
6736 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6737 else
6739 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6740 if (ret)
6742 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
6743 size);
6744 if (size == sizeof(PKCSSignerWithAuthAttr))
6745 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
6746 "Unexpected value\n");
6747 else
6748 ok(0, "Unexpected value\n");
6749 LocalFree(buf);
6754 static void test_decodePKCSSignerInfo(DWORD dwEncoding)
6756 BOOL ret;
6757 LPBYTE buf = NULL;
6758 DWORD size = 0;
6759 CMSG_SIGNER_INFO *info;
6761 /* A PKCS signer can't be decoded without a serial number. */
6762 SetLastError(0xdeadbeef);
6763 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6764 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6765 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6766 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
6767 GetLastError() == OSS_DATA_ERROR /* Win9x */),
6768 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %x\n",
6769 GetLastError());
6770 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6771 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6772 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6773 ok(ret || broken(GetLastError() == OSS_DATA_ERROR),
6774 "CryptDecodeObjectEx failed: %x\n", GetLastError());
6775 if (ret)
6777 info = (CMSG_SIGNER_INFO *)buf;
6778 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6779 info->dwVersion);
6780 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6781 "Unexpected size %d\n", info->Issuer.cbData);
6782 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6783 info->Issuer.cbData), "Unexpected value\n");
6784 ok(info->SerialNumber.cbData == sizeof(serialNum),
6785 "Unexpected size %d\n", info->SerialNumber.cbData);
6786 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6787 "Unexpected value\n");
6788 LocalFree(buf);
6790 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6791 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6792 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6793 if (ret)
6795 info = (CMSG_SIGNER_INFO *)buf;
6796 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6797 info->dwVersion);
6798 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6799 "Unexpected size %d\n", info->Issuer.cbData);
6800 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6801 info->Issuer.cbData), "Unexpected value\n");
6802 ok(info->SerialNumber.cbData == sizeof(serialNum),
6803 "Unexpected size %d\n", info->SerialNumber.cbData);
6804 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6805 "Unexpected value\n");
6806 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6807 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6808 LocalFree(buf);
6810 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6811 PKCSSignerWithHashAndEncryptionAlgo,
6812 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6813 NULL, &buf, &size);
6814 if (ret)
6816 info = (CMSG_SIGNER_INFO *)buf;
6817 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6818 info->dwVersion);
6819 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6820 "Unexpected size %d\n", info->Issuer.cbData);
6821 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6822 info->Issuer.cbData), "Unexpected value\n");
6823 ok(info->SerialNumber.cbData == sizeof(serialNum),
6824 "Unexpected size %d\n", info->SerialNumber.cbData);
6825 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6826 "Unexpected value\n");
6827 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6828 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6829 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6830 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6831 LocalFree(buf);
6833 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6834 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6835 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6836 if (ret)
6838 info = (CMSG_SIGNER_INFO *)buf;
6839 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6840 info->dwVersion);
6841 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6842 "Unexpected size %d\n", info->Issuer.cbData);
6843 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6844 info->Issuer.cbData), "Unexpected value\n");
6845 ok(info->SerialNumber.cbData == sizeof(serialNum),
6846 "Unexpected size %d\n", info->SerialNumber.cbData);
6847 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6848 "Unexpected value\n");
6849 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6850 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6851 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6852 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6853 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6854 info->EncryptedHash.cbData);
6855 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6856 "Unexpected value\n");
6857 LocalFree(buf);
6859 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6860 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
6861 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6862 if (ret)
6864 info = (CMSG_SIGNER_INFO *)buf;
6865 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n",
6866 info->AuthAttrs.cAttr);
6867 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
6868 "Expected %s, got %s\n", szOID_COMMON_NAME,
6869 info->AuthAttrs.rgAttr[0].pszObjId);
6870 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
6871 info->AuthAttrs.rgAttr[0].cValue);
6872 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
6873 sizeof(encodedCommonName), "Unexpected size %d\n",
6874 info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
6875 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
6876 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
6877 LocalFree(buf);
6881 static const BYTE CMSSignerWithKeyId[] = {
6882 0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,
6883 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6885 static void test_encodeCMSSignerInfo(DWORD dwEncoding)
6887 BOOL ret;
6888 LPBYTE buf = NULL;
6889 DWORD size = 0;
6890 CMSG_CMS_SIGNER_INFO info = { 0 };
6891 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6893 SetLastError(0xdeadbeef);
6894 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6895 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6896 ok(!ret, "Expected failure, got %d\n", ret);
6897 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6899 skip("no CMS_SIGNER_INFO encode support\n");
6900 return;
6902 ok(GetLastError() == E_INVALIDARG,
6903 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6904 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6905 SetLastError(0xdeadbeef);
6906 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6907 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6908 ok(!ret, "Expected failure, got %d\n", ret);
6909 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6911 skip("no CMS_SIGNER_INFO encode support\n");
6912 return;
6914 ok(GetLastError() == E_INVALIDARG,
6915 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6916 /* To be encoded, a signer must have a valid cert ID, where a valid ID may
6917 * be a key id or an issuer serial number with at least the issuer set, and
6918 * the encoding must include PKCS_7_ASN_ENCODING.
6919 * (That isn't enough to be decoded, see decoding tests.)
6921 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6922 sizeof(encodedCommonNameNoNull);
6923 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6924 SetLastError(0xdeadbeef);
6925 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6926 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6927 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6928 ok(!ret && GetLastError() == E_INVALIDARG,
6929 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6930 else
6932 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6933 if (ret)
6935 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6936 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6937 LocalFree(buf);
6940 U(info.SignerId).IssuerSerialNumber.SerialNumber.cbData = sizeof(serialNum);
6941 U(info.SignerId).IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
6942 SetLastError(0xdeadbeef);
6943 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6944 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6945 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6946 ok(!ret && GetLastError() == E_INVALIDARG,
6947 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6948 else
6950 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6951 if (ret)
6953 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6954 size);
6955 ok(!memcmp(buf, PKCSSignerWithSerial, size), "Unexpected value\n");
6956 LocalFree(buf);
6959 info.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
6960 U(info.SignerId).KeyId.cbData = sizeof(serialNum);
6961 U(info.SignerId).KeyId.pbData = (BYTE *)serialNum;
6962 SetLastError(0xdeadbeef);
6963 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6964 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6965 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6966 ok(!ret && GetLastError() == E_INVALIDARG,
6967 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6968 else
6970 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6971 if (ret)
6973 ok(size == sizeof(CMSSignerWithKeyId), "Unexpected size %d\n",
6974 size);
6975 ok(!memcmp(buf, CMSSignerWithKeyId, size), "Unexpected value\n");
6976 LocalFree(buf);
6979 /* While a CERT_ID can have a hash type, that's not allowed in CMS, where
6980 * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed
6981 * (see RFC 3852, section 5.3.)
6983 info.SignerId.dwIdChoice = CERT_ID_SHA1_HASH;
6984 U(info.SignerId).HashId.cbData = sizeof(hash);
6985 U(info.SignerId).HashId.pbData = (BYTE *)hash;
6986 SetLastError(0xdeadbeef);
6987 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6988 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6989 ok(!ret && GetLastError() == E_INVALIDARG,
6990 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6991 /* Now with a hash algo */
6992 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6993 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6994 sizeof(encodedCommonNameNoNull);
6995 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6996 info.HashAlgorithm.pszObjId = oid1;
6997 SetLastError(0xdeadbeef);
6998 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6999 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7000 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
7001 ok(!ret && GetLastError() == E_INVALIDARG,
7002 "Expected E_INVALIDARG, got %08x\n", GetLastError());
7003 else
7005 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
7006 if (ret)
7008 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
7009 size);
7010 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
7011 "Unexpected value\n");
7012 LocalFree(buf);
7015 info.HashEncryptionAlgorithm.pszObjId = oid2;
7016 SetLastError(0xdeadbeef);
7017 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
7018 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7019 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
7020 ok(!ret && GetLastError() == E_INVALIDARG,
7021 "Expected E_INVALIDARG, got %08x\n", GetLastError());
7022 else
7024 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
7025 if (ret)
7027 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
7028 "Unexpected size %d\n", size);
7029 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
7030 "Unexpected value\n");
7031 LocalFree(buf);
7034 info.EncryptedHash.cbData = sizeof(hash);
7035 info.EncryptedHash.pbData = (BYTE *)hash;
7036 SetLastError(0xdeadbeef);
7037 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
7038 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7039 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
7040 ok(!ret && GetLastError() == E_INVALIDARG,
7041 "Expected E_INVALIDARG, got %08x\n", GetLastError());
7042 else
7044 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
7045 if (ret)
7047 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
7048 size);
7049 ok(!memcmp(buf, PKCSSignerWithHash, size), "Unexpected value\n");
7050 LocalFree(buf);
7055 static void test_decodeCMSSignerInfo(DWORD dwEncoding)
7057 BOOL ret;
7058 LPBYTE buf = NULL;
7059 DWORD size = 0;
7060 CMSG_CMS_SIGNER_INFO *info;
7061 static const char oid1[] = "1.2.3", oid2[] = "1.5.6";
7063 /* A CMS signer can't be decoded without a serial number. */
7064 SetLastError(0xdeadbeef);
7065 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
7066 minimalPKCSSigner, sizeof(minimalPKCSSigner),
7067 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
7068 ok(!ret, "expected failure\n");
7069 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7071 skip("no CMS_SIGNER_INFO decode support\n");
7072 return;
7074 ok(GetLastError() == CRYPT_E_ASN1_CORRUPT,
7075 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
7076 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
7077 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
7078 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
7079 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
7080 if (ret)
7082 info = (CMSG_CMS_SIGNER_INFO *)buf;
7083 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
7084 info->dwVersion);
7085 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
7086 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
7087 info->SignerId.dwIdChoice);
7088 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
7089 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
7090 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
7091 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
7092 encodedCommonNameNoNull,
7093 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
7094 "Unexpected value\n");
7095 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
7096 sizeof(serialNum), "Unexpected size %d\n",
7097 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
7098 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
7099 serialNum, sizeof(serialNum)), "Unexpected value\n");
7100 LocalFree(buf);
7102 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
7103 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
7104 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
7105 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
7106 if (ret)
7108 info = (CMSG_CMS_SIGNER_INFO *)buf;
7109 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
7110 info->dwVersion);
7111 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
7112 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
7113 info->SignerId.dwIdChoice);
7114 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
7115 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
7116 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
7117 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
7118 encodedCommonNameNoNull,
7119 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
7120 "Unexpected value\n");
7121 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
7122 sizeof(serialNum), "Unexpected size %d\n",
7123 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
7124 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
7125 serialNum, sizeof(serialNum)), "Unexpected value\n");
7126 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
7127 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
7128 LocalFree(buf);
7130 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
7131 PKCSSignerWithHashAndEncryptionAlgo,
7132 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
7133 NULL, &buf, &size);
7134 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
7135 if (ret)
7137 info = (CMSG_CMS_SIGNER_INFO *)buf;
7138 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
7139 info->dwVersion);
7140 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
7141 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
7142 info->SignerId.dwIdChoice);
7143 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
7144 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
7145 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
7146 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
7147 encodedCommonNameNoNull,
7148 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
7149 "Unexpected value\n");
7150 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
7151 sizeof(serialNum), "Unexpected size %d\n",
7152 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
7153 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
7154 serialNum, sizeof(serialNum)), "Unexpected value\n");
7155 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
7156 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
7157 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
7158 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
7159 LocalFree(buf);
7161 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
7162 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
7163 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
7164 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
7165 if (ret)
7167 info = (CMSG_CMS_SIGNER_INFO *)buf;
7168 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
7169 info->dwVersion);
7170 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
7171 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
7172 info->SignerId.dwIdChoice);
7173 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
7174 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
7175 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
7176 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
7177 encodedCommonNameNoNull,
7178 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
7179 "Unexpected value\n");
7180 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
7181 sizeof(serialNum), "Unexpected size %d\n",
7182 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
7183 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
7184 serialNum, sizeof(serialNum)), "Unexpected value\n");
7185 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
7186 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
7187 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
7188 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
7189 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
7190 info->EncryptedHash.cbData);
7191 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
7192 "Unexpected value\n");
7193 LocalFree(buf);
7195 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
7196 CMSSignerWithKeyId, sizeof(CMSSignerWithKeyId),
7197 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
7198 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
7199 if (ret)
7201 info = (CMSG_CMS_SIGNER_INFO *)buf;
7202 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
7203 info->dwVersion);
7204 ok(info->SignerId.dwIdChoice == CERT_ID_KEY_IDENTIFIER,
7205 "Expected CERT_ID_KEY_IDENTIFIER, got %d\n",
7206 info->SignerId.dwIdChoice);
7207 ok(U(info->SignerId).KeyId.cbData == sizeof(serialNum),
7208 "Unexpected size %d\n", U(info->SignerId).KeyId.cbData);
7209 ok(!memcmp(U(info->SignerId).KeyId.pbData, serialNum, sizeof(serialNum)),
7210 "Unexpected value\n");
7211 LocalFree(buf);
7215 static BYTE emptyDNSPermittedConstraints[] = {
7216 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
7217 static BYTE emptyDNSExcludedConstraints[] = {
7218 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
7219 static BYTE DNSExcludedConstraints[] = {
7220 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
7221 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7222 static BYTE permittedAndExcludedConstraints[] = {
7223 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7224 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
7225 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7226 static BYTE permittedAndExcludedWithMinConstraints[] = {
7227 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7228 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
7229 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7230 static BYTE permittedAndExcludedWithMinMaxConstraints[] = {
7231 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7232 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
7233 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7235 static void test_encodeNameConstraints(DWORD dwEncoding)
7237 BOOL ret;
7238 CERT_NAME_CONSTRAINTS_INFO constraints = { 0 };
7239 CERT_GENERAL_SUBTREE permitted = { { 0 } };
7240 CERT_GENERAL_SUBTREE excluded = { { 0 } };
7241 LPBYTE buf;
7242 DWORD size;
7244 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7245 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7246 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7248 skip("no X509_NAME_CONSTRAINTS encode support\n");
7249 return;
7251 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7252 if (ret)
7254 ok(size == sizeof(emptySequence), "Unexpected size\n");
7255 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
7256 LocalFree(buf);
7258 constraints.cPermittedSubtree = 1;
7259 constraints.rgPermittedSubtree = &permitted;
7260 SetLastError(0xdeadbeef);
7261 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7262 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7263 ok(!ret && GetLastError() == E_INVALIDARG,
7264 "Expected E_INVALIDARG, got %08x\n", GetLastError());
7265 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
7266 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7267 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7268 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7269 if (ret)
7271 ok(size == sizeof(emptyDNSPermittedConstraints), "Unexpected size\n");
7272 ok(!memcmp(buf, emptyDNSPermittedConstraints, size),
7273 "Unexpected value\n");
7274 LocalFree(buf);
7276 constraints.cPermittedSubtree = 0;
7277 constraints.cExcludedSubtree = 1;
7278 constraints.rgExcludedSubtree = &excluded;
7279 excluded.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
7280 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7281 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7282 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7283 if (ret)
7285 ok(size == sizeof(emptyDNSExcludedConstraints), "Unexpected size\n");
7286 ok(!memcmp(buf, emptyDNSExcludedConstraints, size),
7287 "Unexpected value\n");
7288 LocalFree(buf);
7290 U(excluded.Base).pwszURL = (LPWSTR)url;
7291 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7292 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7293 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7294 if (ret)
7296 ok(size == sizeof(DNSExcludedConstraints), "Unexpected size\n");
7297 ok(!memcmp(buf, DNSExcludedConstraints, size),
7298 "Unexpected value\n");
7299 LocalFree(buf);
7301 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
7302 U(permitted.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7303 U(permitted.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7304 constraints.cPermittedSubtree = 1;
7305 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7306 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7307 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7308 if (ret)
7310 ok(size == sizeof(permittedAndExcludedConstraints),
7311 "Unexpected size\n");
7312 ok(!memcmp(buf, permittedAndExcludedConstraints, size),
7313 "Unexpected value\n");
7314 LocalFree(buf);
7316 permitted.dwMinimum = 5;
7317 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7318 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7319 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7320 if (ret)
7322 ok(size == sizeof(permittedAndExcludedWithMinConstraints),
7323 "Unexpected size\n");
7324 ok(!memcmp(buf, permittedAndExcludedWithMinConstraints, size),
7325 "Unexpected value\n");
7326 LocalFree(buf);
7328 permitted.fMaximum = TRUE;
7329 permitted.dwMaximum = 3;
7330 SetLastError(0xdeadbeef);
7331 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7332 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7333 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7334 if (ret)
7336 ok(size == sizeof(permittedAndExcludedWithMinMaxConstraints),
7337 "Unexpected size\n");
7338 ok(!memcmp(buf, permittedAndExcludedWithMinMaxConstraints, size),
7339 "Unexpected value\n");
7340 LocalFree(buf);
7344 struct EncodedNameConstraints
7346 CRYPT_DATA_BLOB encoded;
7347 CERT_NAME_CONSTRAINTS_INFO constraints;
7350 static CERT_GENERAL_SUBTREE emptyDNSSubtree = {
7351 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
7352 static CERT_GENERAL_SUBTREE DNSSubtree = {
7353 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
7354 static CERT_GENERAL_SUBTREE IPAddressSubtree = {
7355 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 0 };
7356 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree = {
7357 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, 0 };
7358 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree = {
7359 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, TRUE, 3 };
7361 static const struct EncodedNameConstraints encodedNameConstraints[] = {
7362 { { sizeof(emptySequence), (LPBYTE)emptySequence }, { 0 } },
7363 { { sizeof(emptyDNSPermittedConstraints), emptyDNSPermittedConstraints },
7364 { 1, &emptyDNSSubtree, 0, NULL } },
7365 { { sizeof(emptyDNSExcludedConstraints), emptyDNSExcludedConstraints },
7366 { 0, NULL, 1, &emptyDNSSubtree } },
7367 { { sizeof(DNSExcludedConstraints), DNSExcludedConstraints },
7368 { 0, NULL, 1, &DNSSubtree } },
7369 { { sizeof(permittedAndExcludedConstraints), permittedAndExcludedConstraints },
7370 { 1, &IPAddressSubtree, 1, &DNSSubtree } },
7371 { { sizeof(permittedAndExcludedWithMinConstraints),
7372 permittedAndExcludedWithMinConstraints },
7373 { 1, &IPAddressWithMinSubtree, 1, &DNSSubtree } },
7374 { { sizeof(permittedAndExcludedWithMinMaxConstraints),
7375 permittedAndExcludedWithMinMaxConstraints },
7376 { 1, &IPAddressWithMinMaxSubtree, 1, &DNSSubtree } },
7379 static void test_decodeNameConstraints(DWORD dwEncoding)
7381 BOOL ret;
7382 DWORD i;
7383 CERT_NAME_CONSTRAINTS_INFO *constraints;
7385 U(DNSSubtree.Base).pwszURL = (LPWSTR)url;
7386 U(IPAddressSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7387 U(IPAddressSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7388 U(IPAddressWithMinSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7389 U(IPAddressWithMinSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7390 U(IPAddressWithMinMaxSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7391 U(IPAddressWithMinMaxSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7392 for (i = 0; i < ARRAY_SIZE(encodedNameConstraints); i++)
7394 DWORD size;
7396 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS,
7397 encodedNameConstraints[i].encoded.pbData,
7398 encodedNameConstraints[i].encoded.cbData,
7399 CRYPT_DECODE_ALLOC_FLAG, NULL, &constraints, &size);
7400 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7402 skip("no X509_NAME_CONSTRAINTS decode support\n");
7403 return;
7405 ok(ret, "%d: CryptDecodeObjectEx failed: %08x\n", i, GetLastError());
7406 if (ret)
7408 DWORD j;
7410 if (constraints->cPermittedSubtree !=
7411 encodedNameConstraints[i].constraints.cPermittedSubtree)
7412 fprintf(stderr, "%d: expected %u permitted, got %u\n", i,
7413 encodedNameConstraints[i].constraints.cPermittedSubtree,
7414 constraints->cPermittedSubtree);
7415 if (constraints->cPermittedSubtree ==
7416 encodedNameConstraints[i].constraints.cPermittedSubtree)
7418 for (j = 0; j < constraints->cPermittedSubtree; j++)
7420 compareAltNameEntry(&constraints->rgPermittedSubtree[j].Base,
7421 &encodedNameConstraints[i].constraints.rgPermittedSubtree[j].Base);
7424 if (constraints->cExcludedSubtree !=
7425 encodedNameConstraints[i].constraints.cExcludedSubtree)
7426 fprintf(stderr, "%d: expected %u excluded, got %u\n", i,
7427 encodedNameConstraints[i].constraints.cExcludedSubtree,
7428 constraints->cExcludedSubtree);
7429 if (constraints->cExcludedSubtree ==
7430 encodedNameConstraints[i].constraints.cExcludedSubtree)
7432 for (j = 0; j < constraints->cExcludedSubtree; j++)
7434 compareAltNameEntry(&constraints->rgExcludedSubtree[j].Base,
7435 &encodedNameConstraints[i].constraints.rgExcludedSubtree[j].Base);
7438 LocalFree(constraints);
7443 static WCHAR noticeText[] = { 'T','h','i','s',' ','i','s',' ','a',' ',
7444 'n','o','t','i','c','e',0 };
7445 static const BYTE noticeWithDisplayText[] = {
7446 0x30,0x22,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,0x00,
7447 0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,0x74,
7448 0x00,0x69,0x00,0x63,0x00,0x65
7450 static char org[] = "Wine";
7451 static int noticeNumbers[] = { 2,3 };
7452 static BYTE noticeWithReference[] = {
7453 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7454 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7455 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7456 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7459 static void test_encodePolicyQualifierUserNotice(DWORD dwEncoding)
7461 BOOL ret;
7462 LPBYTE buf;
7463 DWORD size;
7464 CERT_POLICY_QUALIFIER_USER_NOTICE notice;
7465 CERT_POLICY_QUALIFIER_NOTICE_REFERENCE reference;
7467 memset(&notice, 0, sizeof(notice));
7468 ret = pCryptEncodeObjectEx(dwEncoding,
7469 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, &notice, CRYPT_ENCODE_ALLOC_FLAG,
7470 NULL, &buf, &size);
7471 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7473 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE encode support\n");
7474 return;
7476 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7477 if (ret)
7479 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size);
7480 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
7481 LocalFree(buf);
7483 notice.pszDisplayText = noticeText;
7484 ret = pCryptEncodeObjectEx(dwEncoding,
7485 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, &notice, CRYPT_ENCODE_ALLOC_FLAG,
7486 NULL, &buf, &size);
7487 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7488 if (ret)
7490 ok(sizeof(noticeWithDisplayText) == size, "unexpected size %d\n", size);
7491 ok(!memcmp(buf, noticeWithDisplayText, size), "unexpected value\n");
7492 LocalFree(buf);
7494 reference.pszOrganization = org;
7495 reference.cNoticeNumbers = 2;
7496 reference.rgNoticeNumbers = noticeNumbers;
7497 notice.pNoticeReference = &reference;
7498 ret = pCryptEncodeObjectEx(dwEncoding,
7499 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, &notice, CRYPT_ENCODE_ALLOC_FLAG,
7500 NULL, &buf, &size);
7501 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7502 if (ret)
7504 ok(sizeof(noticeWithReference) == size, "unexpected size %d\n", size);
7505 ok(!memcmp(buf, noticeWithReference, size), "unexpected value\n");
7506 LocalFree(buf);
7510 static void test_decodePolicyQualifierUserNotice(DWORD dwEncoding)
7512 BOOL ret;
7513 CERT_POLICY_QUALIFIER_USER_NOTICE *notice;
7514 DWORD size;
7516 ret = pCryptDecodeObjectEx(dwEncoding,
7517 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7518 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7519 &notice, &size);
7520 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7522 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE decode support\n");
7523 return;
7525 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7526 if (ret)
7528 ok(notice->pszDisplayText == NULL, "unexpected display text\n");
7529 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7530 LocalFree(notice);
7532 ret = pCryptDecodeObjectEx(dwEncoding,
7533 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7534 noticeWithDisplayText, sizeof(noticeWithDisplayText),
7535 CRYPT_DECODE_ALLOC_FLAG, NULL, &notice, &size);
7536 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7537 if (ret)
7539 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7540 "unexpected display text\n");
7541 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7542 LocalFree(notice);
7544 ret = pCryptDecodeObjectEx(dwEncoding,
7545 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7546 noticeWithReference, sizeof(noticeWithReference),
7547 CRYPT_DECODE_ALLOC_FLAG, NULL, &notice, &size);
7548 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7549 if (ret)
7551 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7552 "unexpected display text\n");
7553 ok(notice->pNoticeReference != NULL, "expected a notice reference\n");
7554 if (notice->pNoticeReference)
7556 ok(!strcmp(notice->pNoticeReference->pszOrganization, org),
7557 "unexpected organization %s\n",
7558 notice->pNoticeReference->pszOrganization);
7559 ok(notice->pNoticeReference->cNoticeNumbers == 2,
7560 "expected 2 notice numbers, got %d\n",
7561 notice->pNoticeReference->cNoticeNumbers);
7562 ok(notice->pNoticeReference->rgNoticeNumbers[0] == noticeNumbers[0],
7563 "unexpected notice number %d\n",
7564 notice->pNoticeReference->rgNoticeNumbers[0]);
7565 ok(notice->pNoticeReference->rgNoticeNumbers[1] == noticeNumbers[1],
7566 "unexpected notice number %d\n",
7567 notice->pNoticeReference->rgNoticeNumbers[1]);
7569 LocalFree(notice);
7573 static char oid_any_policy[] = "2.5.29.32.0";
7574 static const BYTE policiesWithAnyPolicy[] = {
7575 0x30,0x08,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00
7577 static char oid1[] = "1.2.3";
7578 static char oid_user_notice[] = "1.3.6.1.5.5.7.2.2";
7579 static const BYTE twoPolicies[] = {
7580 0x30,0x50,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00,0x30,0x46,0x06,0x02,0x2a,
7581 0x03,0x30,0x40,0x30,0x3e,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x02,
7582 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7583 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7584 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7585 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7588 static void test_encodeCertPolicies(DWORD dwEncoding)
7590 BOOL ret;
7591 CERT_POLICIES_INFO info;
7592 CERT_POLICY_INFO policy[2];
7593 CERT_POLICY_QUALIFIER_INFO qualifier;
7594 LPBYTE buf;
7595 DWORD size;
7597 memset(&info, 0, sizeof(info));
7598 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7599 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7600 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7601 if (ret)
7603 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size);
7604 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
7605 LocalFree(buf);
7607 memset(policy, 0, sizeof(policy));
7608 info.cPolicyInfo = 1;
7609 info.rgPolicyInfo = policy;
7610 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7611 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7612 ok(!ret && (GetLastError() == E_INVALIDARG ||
7613 GetLastError() == OSS_LIMITED /* Win9x/NT4 */),
7614 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
7615 policy[0].pszPolicyIdentifier = oid_any_policy;
7616 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7617 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7618 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7619 if (ret)
7621 ok(sizeof(policiesWithAnyPolicy) == size, "unexpected size %d\n", size);
7622 ok(!memcmp(buf, policiesWithAnyPolicy, size), "unexpected value\n");
7623 LocalFree(buf);
7625 policy[1].pszPolicyIdentifier = oid1;
7626 memset(&qualifier, 0, sizeof(qualifier));
7627 qualifier.pszPolicyQualifierId = oid_user_notice;
7628 qualifier.Qualifier.cbData = sizeof(noticeWithReference);
7629 qualifier.Qualifier.pbData = noticeWithReference;
7630 policy[1].cPolicyQualifier = 1;
7631 policy[1].rgPolicyQualifier = &qualifier;
7632 info.cPolicyInfo = 2;
7633 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7634 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7635 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7636 if (ret)
7638 ok(sizeof(twoPolicies) == size, "unexpected size %d\n", size);
7639 ok(!memcmp(buf, twoPolicies, size), "unexpected value\n");
7640 LocalFree(buf);
7644 static void test_decodeCertPolicies(DWORD dwEncoding)
7646 BOOL ret;
7647 CERT_POLICIES_INFO *info;
7648 DWORD size;
7650 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7651 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7652 &info, &size);
7653 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7654 if (ret)
7656 ok(info->cPolicyInfo == 0, "unexpected policy info %d\n",
7657 info->cPolicyInfo);
7658 LocalFree(info);
7660 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7661 policiesWithAnyPolicy, sizeof(policiesWithAnyPolicy),
7662 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7663 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7664 if (ret)
7666 ok(info->cPolicyInfo == 1, "unexpected policy info %d\n",
7667 info->cPolicyInfo);
7668 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy),
7669 "unexpected policy id %s\n",
7670 info->rgPolicyInfo[0].pszPolicyIdentifier);
7671 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0,
7672 "unexpected policy qualifier count %d\n",
7673 info->rgPolicyInfo[0].cPolicyQualifier);
7674 LocalFree(info);
7676 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7677 twoPolicies, sizeof(twoPolicies),
7678 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7679 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7680 if (ret)
7682 ok(info->cPolicyInfo == 2, "unexpected policy info %d\n",
7683 info->cPolicyInfo);
7684 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy),
7685 "unexpected policy id %s\n",
7686 info->rgPolicyInfo[0].pszPolicyIdentifier);
7687 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0,
7688 "unexpected policy qualifier count %d\n",
7689 info->rgPolicyInfo[0].cPolicyQualifier);
7690 ok(!strcmp(info->rgPolicyInfo[1].pszPolicyIdentifier, oid1),
7691 "unexpected policy id %s\n",
7692 info->rgPolicyInfo[1].pszPolicyIdentifier);
7693 ok(info->rgPolicyInfo[1].cPolicyQualifier == 1,
7694 "unexpected policy qualifier count %d\n",
7695 info->rgPolicyInfo[1].cPolicyQualifier);
7696 ok(!strcmp(
7697 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId,
7698 oid_user_notice), "unexpected policy qualifier id %s\n",
7699 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId);
7700 ok(info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData ==
7701 sizeof(noticeWithReference), "unexpected qualifier size %d\n",
7702 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData);
7703 ok(!memcmp(
7704 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.pbData,
7705 noticeWithReference, sizeof(noticeWithReference)),
7706 "unexpected qualifier value\n");
7707 LocalFree(info);
7709 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7710 twoPolicies, sizeof(twoPolicies), 0, NULL, NULL, &size);
7711 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7712 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
7713 if (info)
7715 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7716 twoPolicies, sizeof(twoPolicies), 0, NULL, info, &size);
7717 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7718 HeapFree(GetProcessHeap(), 0, info);
7722 static const BYTE policyMappingWithOneMapping[] = {
7723 0x30,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04 };
7724 static const BYTE policyMappingWithTwoMappings[] = {
7725 0x30,0x14,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04,0x30,0x08,0x06,
7726 0x02,0x2b,0x04,0x06,0x02,0x55,0x06 };
7727 static const LPCSTR mappingOids[] = { X509_POLICY_MAPPINGS,
7728 szOID_POLICY_MAPPINGS, szOID_LEGACY_POLICY_MAPPINGS };
7730 static void test_encodeCertPolicyMappings(DWORD dwEncoding)
7732 static char oid2[] = "2.3.4";
7733 static char oid3[] = "1.3.4";
7734 static char oid4[] = "2.5.6";
7735 BOOL ret;
7736 CERT_POLICY_MAPPINGS_INFO info = { 0 };
7737 CERT_POLICY_MAPPING mapping[2];
7738 LPBYTE buf;
7739 DWORD size, i;
7741 /* Each of the mapping OIDs is equivalent, so check with all of them */
7742 for (i = 0; i < ARRAY_SIZE(mappingOids); i++)
7744 memset(&info, 0, sizeof(info));
7745 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7746 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7747 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
7748 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7749 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7751 win_skip("no policy mappings support\n");
7752 return;
7754 if (ret)
7756 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
7757 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
7758 "unexpected value\n");
7759 LocalFree(buf);
7761 mapping[0].pszIssuerDomainPolicy = NULL;
7762 mapping[0].pszSubjectDomainPolicy = NULL;
7763 info.cPolicyMapping = 1;
7764 info.rgPolicyMapping = mapping;
7765 SetLastError(0xdeadbeef);
7766 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7767 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7768 ok(!ret && GetLastError() == E_INVALIDARG,
7769 "expected E_INVALIDARG, got %08x\n", GetLastError());
7770 mapping[0].pszIssuerDomainPolicy = oid1;
7771 mapping[0].pszSubjectDomainPolicy = oid2;
7772 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7773 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7774 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7775 if (ret)
7777 ok(size == sizeof(policyMappingWithOneMapping),
7778 "unexpected size %d\n", size);
7779 ok(!memcmp(buf, policyMappingWithOneMapping, size),
7780 "unexpected value\n");
7781 LocalFree(buf);
7783 mapping[1].pszIssuerDomainPolicy = oid3;
7784 mapping[1].pszSubjectDomainPolicy = oid4;
7785 info.cPolicyMapping = 2;
7786 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7787 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7788 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7789 if (ret)
7791 ok(size == sizeof(policyMappingWithTwoMappings),
7792 "unexpected size %d\n", size);
7793 ok(!memcmp(buf, policyMappingWithTwoMappings, size),
7794 "unexpected value\n");
7795 LocalFree(buf);
7800 static void test_decodeCertPolicyMappings(DWORD dwEncoding)
7802 DWORD size, i;
7803 CERT_POLICY_MAPPINGS_INFO *info;
7804 BOOL ret;
7806 /* Each of the mapping OIDs is equivalent, so check with all of them */
7807 for (i = 0; i < ARRAY_SIZE(mappingOids); i++)
7809 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7810 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7811 &info, &size);
7812 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
7813 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7814 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7816 win_skip("no policy mappings support\n");
7817 return;
7819 if (ret)
7821 ok(info->cPolicyMapping == 0,
7822 "expected 0 policy mappings, got %d\n", info->cPolicyMapping);
7823 LocalFree(info);
7825 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7826 policyMappingWithOneMapping, sizeof(policyMappingWithOneMapping),
7827 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7828 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7829 if (ret)
7831 ok(info->cPolicyMapping == 1,
7832 "expected 1 policy mappings, got %d\n", info->cPolicyMapping);
7833 ok(!strcmp(info->rgPolicyMapping[0].pszIssuerDomainPolicy, "1.2.3"),
7834 "unexpected issuer policy %s\n",
7835 info->rgPolicyMapping[0].pszIssuerDomainPolicy);
7836 ok(!strcmp(info->rgPolicyMapping[0].pszSubjectDomainPolicy,
7837 "2.3.4"), "unexpected subject policy %s\n",
7838 info->rgPolicyMapping[0].pszSubjectDomainPolicy);
7839 LocalFree(info);
7841 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7842 policyMappingWithTwoMappings, sizeof(policyMappingWithTwoMappings),
7843 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7844 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7845 if (ret)
7847 ok(info->cPolicyMapping == 2,
7848 "expected 2 policy mappings, got %d\n", info->cPolicyMapping);
7849 ok(!strcmp(info->rgPolicyMapping[0].pszIssuerDomainPolicy, "1.2.3"),
7850 "unexpected issuer policy %s\n",
7851 info->rgPolicyMapping[0].pszIssuerDomainPolicy);
7852 ok(!strcmp(info->rgPolicyMapping[0].pszSubjectDomainPolicy,
7853 "2.3.4"), "unexpected subject policy %s\n",
7854 info->rgPolicyMapping[0].pszSubjectDomainPolicy);
7855 ok(!strcmp(info->rgPolicyMapping[1].pszIssuerDomainPolicy, "1.3.4"),
7856 "unexpected issuer policy %s\n",
7857 info->rgPolicyMapping[1].pszIssuerDomainPolicy);
7858 ok(!strcmp(info->rgPolicyMapping[1].pszSubjectDomainPolicy,
7859 "2.5.6"), "unexpected subject policy %s\n",
7860 info->rgPolicyMapping[1].pszSubjectDomainPolicy);
7861 LocalFree(info);
7863 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7864 policyMappingWithTwoMappings, sizeof(policyMappingWithTwoMappings), 0,
7865 NULL, NULL, &size);
7866 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7867 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
7868 if (info)
7870 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7871 policyMappingWithTwoMappings, sizeof(policyMappingWithTwoMappings), 0,
7872 NULL, info, &size);
7873 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7874 HeapFree(GetProcessHeap(), 0, info);
7879 static const BYTE policyConstraintsWithRequireExplicit[] = {
7880 0x30,0x03,0x80,0x01,0x00 };
7881 static const BYTE policyConstraintsWithInhibitMapping[] = {
7882 0x30,0x03,0x81,0x01,0x01 };
7883 static const BYTE policyConstraintsWithBoth[] = {
7884 0x30,0x06,0x80,0x01,0x01,0x81,0x01,0x01 };
7886 static void test_encodeCertPolicyConstraints(DWORD dwEncoding)
7888 CERT_POLICY_CONSTRAINTS_INFO info = { 0 };
7889 LPBYTE buf;
7890 DWORD size;
7891 BOOL ret;
7893 /* Even though RFC 5280 explicitly states CAs must not issue empty
7894 * policy constraints (section 4.2.1.11), the API doesn't prevent it.
7896 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7897 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7898 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
7899 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7900 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7902 win_skip("no policy constraints support\n");
7903 return;
7905 if (ret)
7907 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
7908 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
7909 "unexpected value\n");
7910 LocalFree(buf);
7912 /* If fRequireExplicitPolicy is set but dwRequireExplicitPolicySkipCerts
7913 * is not, then a skip of 0 is encoded.
7915 info.fRequireExplicitPolicy = TRUE;
7916 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7917 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7918 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7919 if (ret)
7921 ok(size == sizeof(policyConstraintsWithRequireExplicit),
7922 "unexpected size %d\n", size);
7923 ok(!memcmp(buf, policyConstraintsWithRequireExplicit,
7924 sizeof(policyConstraintsWithRequireExplicit)), "unexpected value\n");
7925 LocalFree(buf);
7927 /* With inhibit policy mapping */
7928 info.fRequireExplicitPolicy = FALSE;
7929 info.dwRequireExplicitPolicySkipCerts = 0;
7930 info.fInhibitPolicyMapping = TRUE;
7931 info.dwInhibitPolicyMappingSkipCerts = 1;
7932 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7933 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7934 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7935 if (ret)
7937 ok(size == sizeof(policyConstraintsWithInhibitMapping),
7938 "unexpected size %d\n", size);
7939 ok(!memcmp(buf, policyConstraintsWithInhibitMapping,
7940 sizeof(policyConstraintsWithInhibitMapping)), "unexpected value\n");
7941 LocalFree(buf);
7943 /* And with both */
7944 info.fRequireExplicitPolicy = TRUE;
7945 info.dwRequireExplicitPolicySkipCerts = 1;
7946 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7947 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7948 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7949 if (ret)
7951 ok(size == sizeof(policyConstraintsWithBoth), "unexpected size %d\n",
7952 size);
7953 ok(!memcmp(buf, policyConstraintsWithBoth,
7954 sizeof(policyConstraintsWithBoth)), "unexpected value\n");
7955 LocalFree(buf);
7959 static void test_decodeCertPolicyConstraints(DWORD dwEncoding)
7961 CERT_POLICY_CONSTRAINTS_INFO *info;
7962 DWORD size;
7963 BOOL ret;
7965 /* Again, even though CAs must not issue such constraints, they can be
7966 * decoded.
7968 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7969 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7970 &info, &size);
7971 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
7972 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7973 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7975 win_skip("no policy mappings support\n");
7976 return;
7978 if (ret)
7980 ok(!info->fRequireExplicitPolicy,
7981 "expected require explicit = FALSE\n");
7982 ok(!info->fInhibitPolicyMapping,
7983 "expected implicit mapping = FALSE\n");
7984 LocalFree(info);
7986 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7987 policyConstraintsWithRequireExplicit,
7988 sizeof(policyConstraintsWithRequireExplicit), CRYPT_DECODE_ALLOC_FLAG,
7989 NULL, &info, &size);
7990 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7991 if (ret)
7993 ok(info->fRequireExplicitPolicy,
7994 "expected require explicit = TRUE\n");
7995 ok(info->dwRequireExplicitPolicySkipCerts == 0, "expected 0, got %d\n",
7996 info->dwRequireExplicitPolicySkipCerts);
7997 ok(!info->fInhibitPolicyMapping,
7998 "expected implicit mapping = FALSE\n");
7999 LocalFree(info);
8001 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
8002 policyConstraintsWithInhibitMapping,
8003 sizeof(policyConstraintsWithInhibitMapping), CRYPT_DECODE_ALLOC_FLAG,
8004 NULL, &info, &size);
8005 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
8006 if (ret)
8008 ok(!info->fRequireExplicitPolicy,
8009 "expected require explicit = FALSE\n");
8010 ok(info->fInhibitPolicyMapping,
8011 "expected implicit mapping = TRUE\n");
8012 ok(info->dwInhibitPolicyMappingSkipCerts == 1, "expected 1, got %d\n",
8013 info->dwInhibitPolicyMappingSkipCerts);
8014 LocalFree(info);
8016 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
8017 policyConstraintsWithBoth, sizeof(policyConstraintsWithBoth),
8018 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
8019 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
8020 if (ret)
8022 ok(info->fRequireExplicitPolicy,
8023 "expected require explicit = TRUE\n");
8024 ok(info->dwRequireExplicitPolicySkipCerts == 1, "expected 1, got %d\n",
8025 info->dwRequireExplicitPolicySkipCerts);
8026 ok(info->fInhibitPolicyMapping,
8027 "expected implicit mapping = TRUE\n");
8028 ok(info->dwInhibitPolicyMappingSkipCerts == 1, "expected 1, got %d\n",
8029 info->dwInhibitPolicyMappingSkipCerts);
8030 LocalFree(info);
8034 static const BYTE rsaPrivKeyDer[] = {
8035 0x30,0x82,0x04,0xa5,0x02,0x01,0x00,0x02,0x82,0x01,0x01,0x00,
8036 0xae,0xba,0x3c,0x41,0xeb,0x25,0x41,0xb0,0x1c,0x41,0xd4,0x26,
8037 0xf9,0xf8,0x31,0x64,0x7e,0x97,0x65,0x54,0x9c,0x90,0xdf,0x34,
8038 0x07,0xfb,0xb0,0x69,0x99,0x3b,0x45,0x39,0x06,0xe4,0x3a,0x7a,
8039 0x01,0xe0,0xeb,0x3f,0xe1,0xd5,0x91,0xe0,0x16,0xe0,0xf2,0x35,
8040 0x59,0xdf,0x32,0x2d,0x69,0x3a,0x4a,0xbc,0xd1,0xba,0x1b,0x3b,
8041 0x7a,0x55,0x76,0xba,0x11,0xdd,0x2f,0xc7,0x58,0x66,0xf2,0x6c,
8042 0xd1,0x68,0x27,0x6c,0x85,0x74,0x0b,0xc9,0x7b,0x1a,0xde,0x3c,
8043 0x62,0x73,0xe2,0x9e,0x36,0x3a,0x29,0x3b,0x91,0x85,0x3d,0xd2,
8044 0xe1,0xe5,0x61,0x84,0x1e,0x28,0xfd,0xb7,0x97,0x68,0xc1,0xbb,
8045 0x0f,0x93,0x14,0xc2,0x03,0x60,0x41,0x11,0x7a,0xda,0x76,0x01,
8046 0x65,0x08,0xe6,0x0c,0xf6,0xfc,0x1d,0x64,0x12,0x7b,0x42,0xb0,
8047 0xb8,0xfe,0x61,0xe5,0xe2,0xe5,0x61,0x44,0xcc,0x94,0xe8,0xc0,
8048 0x4f,0x58,0x9a,0xea,0x99,0xaf,0x9c,0xa4,0xf2,0xd7,0x2b,0x31,
8049 0x90,0x3b,0x41,0x2e,0x4a,0x74,0x7c,0x1a,0xfc,0x42,0xa9,0x17,
8050 0xff,0x53,0x20,0x76,0xa7,0xf0,0x2c,0xb9,0xd5,0x1f,0xa9,0x8a,
8051 0x77,0xa8,0x09,0x5c,0x0e,0xd1,0x54,0xc5,0xf2,0x86,0xf1,0x2f,
8052 0x23,0xd6,0x63,0xba,0xe9,0x2b,0x73,0xf9,0xf0,0xdc,0xcb,0xf9,
8053 0xcb,0xe8,0x40,0x62,0x47,0x09,0x85,0xe1,0x9c,0xfd,0xcf,0x75,
8054 0x5a,0x65,0xfd,0x86,0x1c,0x50,0xfa,0x24,0x36,0x0f,0x54,0x5e,
8055 0x81,0xe7,0xf6,0x63,0x2d,0x87,0x0c,0x50,0x03,0x25,0x49,0xe7,
8056 0xc5,0x20,0xaa,0xbc,0x6c,0xf9,0xbe,0x49,0x8f,0x4f,0xb8,0x9a,
8057 0x73,0x9f,0x55,0x43,0x02,0x03,0x01,0x00,0x01,0x02,0x82,0x01,
8058 0x01,0x00,0x99,0x03,0xcd,0x5b,0x69,0x03,0x32,0x98,0x78,0xd6,
8059 0x89,0x65,0x2c,0xc9,0xd6,0xef,0x8c,0x11,0x27,0x93,0x46,0x9d,
8060 0x74,0x6a,0xcb,0x86,0xf6,0x02,0x34,0x47,0xfc,0xa2,0x29,0x4f,
8061 0xdb,0x8a,0x17,0x75,0x12,0x6f,0xda,0x65,0x3f,0x1f,0xc0,0xc9,
8062 0x74,0x33,0x96,0xa5,0xe8,0xfa,0x6d,0xc9,0xb7,0xc3,0xcd,0xe3,
8063 0x2e,0x90,0x12,0xdd,0x1f,0x61,0x69,0xdd,0x8b,0x47,0x07,0x3a,
8064 0xf8,0x98,0xa5,0x76,0x91,0xf7,0xee,0x93,0x26,0xf3,0x66,0x54,
8065 0xac,0x44,0xb3,0x6f,0x8b,0x09,0x44,0xb2,0x00,0x84,0x03,0x37,
8066 0x6d,0x61,0xed,0xa4,0x04,0x97,0x40,0x16,0x63,0xc2,0xd0,0xdc,
8067 0xd3,0xb3,0xee,0xba,0xbe,0x95,0xfd,0x80,0xe0,0xda,0xde,0xfc,
8068 0xcc,0x15,0x02,0x97,0x1d,0x68,0x43,0x2f,0x9c,0xc8,0x20,0x23,
8069 0xeb,0x00,0x4c,0x74,0x3d,0x27,0x20,0x14,0x23,0x95,0xfc,0x8c,
8070 0xb7,0x7e,0x7f,0xb0,0xdb,0xaf,0x8a,0x48,0x1b,0xfe,0x59,0xab,
8071 0x75,0xe2,0xbf,0x69,0xf2,0x73,0xe3,0xb9,0x92,0xa9,0x90,0x03,
8072 0xe5,0xd4,0x2d,0x86,0xff,0x12,0x54,0xb3,0xbb,0xe2,0xce,0x81,
8073 0x58,0x71,0xa4,0xde,0x45,0x05,0xf8,0x2d,0x45,0xf5,0xd8,0x5e,
8074 0x4c,0x5d,0x06,0x69,0x0c,0x86,0x9f,0x66,0x9f,0xb1,0x60,0xfd,
8075 0xf2,0x33,0x85,0x15,0xd5,0x18,0xf7,0xba,0x99,0x65,0x15,0x1d,
8076 0xfa,0xaa,0x76,0xdd,0x25,0xed,0xdf,0x90,0x6e,0xba,0x61,0x96,
8077 0x79,0xde,0xd2,0xda,0x66,0x03,0x74,0x3b,0x13,0x39,0x68,0xbc,
8078 0x94,0x01,0x00,0x2d,0xf8,0xf0,0x8c,0xbd,0x4c,0x9c,0x7e,0x87,
8079 0x9c,0x62,0x9f,0xb6,0x90,0x11,0x02,0x81,0x81,0x00,0xe3,0x5e,
8080 0xfe,0xdd,0xed,0x76,0xb6,0x4e,0xfc,0x5b,0xe0,0x20,0x99,0x7b,
8081 0x48,0x3b,0x1e,0x5f,0x7f,0x9f,0xa4,0x68,0xbe,0xc3,0x7f,0xb8,
8082 0x62,0x98,0xb0,0x95,0x8a,0xfa,0x0d,0xa3,0x79,0x63,0x39,0xf7,
8083 0xdb,0x76,0x3d,0x53,0x4a,0x0a,0x33,0xdf,0xe0,0x47,0x22,0xd5,
8084 0x96,0x80,0xc7,0xcd,0x24,0xef,0xac,0x49,0x46,0x37,0x6c,0x25,
8085 0xcf,0x6c,0x4d,0xe5,0x31,0xf8,0x2f,0xd2,0x59,0x74,0x00,0x38,
8086 0xdb,0xce,0xd1,0x72,0xc3,0xa8,0x30,0x70,0xd8,0x02,0x20,0xe7,
8087 0x56,0xe7,0xca,0xf0,0x3b,0x52,0x5d,0x11,0xbe,0x53,0x4e,0xd0,
8088 0xd9,0x2e,0xa6,0xb8,0xe2,0xd9,0xbf,0xb9,0x77,0xe7,0x3b,0xed,
8089 0x5e,0xd7,0x16,0x4a,0x3a,0xc5,0x86,0xd7,0x74,0x20,0xa7,0x8e,
8090 0xbf,0xb7,0x33,0xdb,0x51,0xe9,0x02,0x81,0x81,0x00,0xc4,0xba,
8091 0x57,0xf0,0x6e,0xcf,0xe8,0xce,0xce,0x9d,0x4a,0xe9,0x0f,0xe1,
8092 0xab,0x91,0x62,0xaa,0x66,0x5d,0x82,0x66,0x1c,0x72,0x18,0x6f,
8093 0x68,0x9c,0x7d,0x5e,0xfc,0xaf,0x4a,0xd6,0x8e,0xc6,0xae,0x40,
8094 0xf2,0x40,0x84,0x93,0xee,0x7c,0x87,0xa9,0xa6,0xcd,0x2b,0xc3,
8095 0xe6,0x29,0x3a,0xe2,0x4a,0xed,0xb0,0x4d,0x9f,0xc0,0xe9,0xd6,
8096 0xa3,0xca,0x97,0xee,0xac,0xab,0xa4,0x32,0x05,0x40,0x4d,0xf2,
8097 0x95,0x99,0xaf,0xa0,0xe1,0xe1,0xe7,0x3a,0x64,0xa4,0x70,0x6b,
8098 0x3d,0x1d,0x7b,0xf1,0x53,0xfa,0xb0,0xe0,0xe2,0x68,0x1a,0x61,
8099 0x2c,0x37,0xa5,0x39,0x7b,0xb2,0xcf,0xe6,0x5f,0x9b,0xc6,0x64,
8100 0xaf,0x48,0x86,0xfb,0xc1,0xf3,0x39,0x97,0x10,0x36,0xf5,0xa9,
8101 0x3d,0x08,0xa5,0x2f,0xe6,0x4b,0x02,0x81,0x81,0x00,0x86,0xe7,
8102 0x02,0x08,0xe2,0xaf,0xa0,0x93,0x54,0x9f,0x9e,0x67,0x39,0x29,
8103 0x30,0x3e,0x03,0x53,0x5e,0x01,0x76,0x26,0xbf,0xa8,0x76,0xcb,
8104 0x0b,0x94,0xd4,0x90,0xa5,0x98,0x9f,0x26,0xf3,0x0a,0xb0,0x86,
8105 0x22,0xac,0x10,0xce,0xae,0x0b,0x47,0xa3,0xf9,0x09,0xbb,0xdd,
8106 0x46,0x22,0xba,0x69,0x39,0x15,0x0a,0xff,0x9e,0xad,0x9b,0x79,
8107 0x03,0x8c,0x9a,0xda,0xf5,0xbe,0xef,0x80,0xba,0x9a,0x5c,0xd7,
8108 0x5f,0x73,0x62,0x49,0xd9,0x54,0x9d,0x09,0x16,0xe0,0x8c,0x6d,
8109 0x35,0xde,0xe9,0x45,0x87,0xac,0xe2,0x93,0x78,0x7d,0x2d,0x32,
8110 0x34,0xe9,0xbc,0xf9,0xcd,0x7e,0xac,0x86,0x7a,0x61,0xb3,0xe8,
8111 0xae,0x70,0xa7,0x44,0xfb,0x81,0xde,0xf3,0x4e,0x6f,0x61,0x7b,
8112 0x0c,0xbc,0xc2,0x03,0xca,0xa1,0x02,0x81,0x80,0x69,0x5b,0x4a,
8113 0xa1,0x4f,0x17,0x35,0x9d,0x1b,0xf6,0x0d,0x1a,0x48,0x11,0x19,
8114 0xab,0x20,0xe6,0x15,0x30,0x5b,0x17,0x88,0x80,0x6a,0x29,0xb0,
8115 0x22,0xae,0xd9,0xe2,0x05,0x96,0xd4,0xd5,0x5d,0xfe,0x10,0x76,
8116 0x2c,0xab,0x53,0xf6,0x52,0xe6,0xec,0xaa,0x92,0x12,0xb0,0x35,
8117 0x61,0x3b,0x51,0xd9,0xc2,0xf5,0xba,0x7c,0xa5,0xfa,0x15,0xa3,
8118 0x5e,0x6a,0x83,0xbe,0x21,0xa6,0x2b,0xcb,0xb8,0x26,0x86,0x96,
8119 0x2b,0xda,0x6d,0x14,0xcb,0xc0,0xe3,0xfa,0xe6,0x3d,0xf6,0x90,
8120 0xa2,0x6b,0xb0,0x50,0xc3,0x5f,0x5a,0xf0,0xa5,0xc4,0x0a,0xea,
8121 0x7d,0x5a,0x95,0x30,0x74,0x10,0xf7,0x55,0x98,0xbd,0x65,0x4a,
8122 0xa2,0x52,0xf8,0x1d,0x64,0xbf,0x20,0xf1,0xe4,0x1d,0x28,0x67,
8123 0xb1,0x6b,0x95,0xfd,0x85,0x02,0x81,0x81,0x00,0xda,0xb4,0x31,
8124 0x34,0xe1,0xec,0x9a,0x1e,0x07,0xd7,0xda,0x20,0x46,0xbf,0x6b,
8125 0xf0,0x45,0xbd,0x50,0xa2,0x0f,0x8a,0x14,0x51,0x52,0x83,0x7c,
8126 0x47,0xc8,0x9c,0x4e,0x68,0x6b,0xae,0x00,0x25,0x63,0xdd,0x13,
8127 0x2a,0x66,0x65,0xb6,0x74,0x91,0x5b,0xb6,0x47,0x3e,0x8e,0x46,
8128 0x62,0xcd,0x9d,0xc1,0xf7,0x14,0x14,0xbc,0x60,0xd6,0x3c,0x7c,
8129 0x3a,0xce,0xff,0x96,0x04,0x84,0xf6,0x44,0x1a,0xf8,0xdb,0x40,
8130 0x1c,0xf2,0xf1,0x4d,0xb2,0x68,0x3e,0xa3,0x0b,0xc6,0xb1,0xd0,
8131 0xa6,0x88,0x18,0x68,0xa1,0x05,0x2a,0xfc,0x2b,0x3a,0xa1,0xe6,
8132 0x31,0x4a,0x46,0x88,0x39,0x1e,0x44,0x11,0x6c,0xc5,0x8b,0xb6,
8133 0x8b,0xce,0x3d,0xd5,0xcb,0xbd,0xf0,0xd4,0xd9,0xfb,0x02,0x35,
8134 0x96,0x39,0x26,0x85,0xf9 };
8135 static const BYTE rsaPrivKeyModulus[] = {
8136 0x43,0x55,0x9f,0x73,0x9a,0xb8,0x4f,0x8f,0x49,0xbe,0xf9,0x6c,
8137 0xbc,0xaa,0x20,0xc5,0xe7,0x49,0x25,0x03,0x50,0x0c,0x87,0x2d,
8138 0x63,0xf6,0xe7,0x81,0x5e,0x54,0x0f,0x36,0x24,0xfa,0x50,0x1c,
8139 0x86,0xfd,0x65,0x5a,0x75,0xcf,0xfd,0x9c,0xe1,0x85,0x09,0x47,
8140 0x62,0x40,0xe8,0xcb,0xf9,0xcb,0xdc,0xf0,0xf9,0x73,0x2b,0xe9,
8141 0xba,0x63,0xd6,0x23,0x2f,0xf1,0x86,0xf2,0xc5,0x54,0xd1,0x0e,
8142 0x5c,0x09,0xa8,0x77,0x8a,0xa9,0x1f,0xd5,0xb9,0x2c,0xf0,0xa7,
8143 0x76,0x20,0x53,0xff,0x17,0xa9,0x42,0xfc,0x1a,0x7c,0x74,0x4a,
8144 0x2e,0x41,0x3b,0x90,0x31,0x2b,0xd7,0xf2,0xa4,0x9c,0xaf,0x99,
8145 0xea,0x9a,0x58,0x4f,0xc0,0xe8,0x94,0xcc,0x44,0x61,0xe5,0xe2,
8146 0xe5,0x61,0xfe,0xb8,0xb0,0x42,0x7b,0x12,0x64,0x1d,0xfc,0xf6,
8147 0x0c,0xe6,0x08,0x65,0x01,0x76,0xda,0x7a,0x11,0x41,0x60,0x03,
8148 0xc2,0x14,0x93,0x0f,0xbb,0xc1,0x68,0x97,0xb7,0xfd,0x28,0x1e,
8149 0x84,0x61,0xe5,0xe1,0xd2,0x3d,0x85,0x91,0x3b,0x29,0x3a,0x36,
8150 0x9e,0xe2,0x73,0x62,0x3c,0xde,0x1a,0x7b,0xc9,0x0b,0x74,0x85,
8151 0x6c,0x27,0x68,0xd1,0x6c,0xf2,0x66,0x58,0xc7,0x2f,0xdd,0x11,
8152 0xba,0x76,0x55,0x7a,0x3b,0x1b,0xba,0xd1,0xbc,0x4a,0x3a,0x69,
8153 0x2d,0x32,0xdf,0x59,0x35,0xf2,0xe0,0x16,0xe0,0x91,0xd5,0xe1,
8154 0x3f,0xeb,0xe0,0x01,0x7a,0x3a,0xe4,0x06,0x39,0x45,0x3b,0x99,
8155 0x69,0xb0,0xfb,0x07,0x34,0xdf,0x90,0x9c,0x54,0x65,0x97,0x7e,
8156 0x64,0x31,0xf8,0xf9,0x26,0xd4,0x41,0x1c,0xb0,0x41,0x25,0xeb,
8157 0x41,0x3c,0xba,0xae };
8158 static const BYTE rsaPrivKeyPrime1[] = {
8159 0xe9,0x51,0xdb,0x33,0xb7,0xbf,0x8e,0xa7,0x20,0x74,0xd7,0x86,
8160 0xc5,0x3a,0x4a,0x16,0xd7,0x5e,0xed,0x3b,0xe7,0x77,0xb9,0xbf,
8161 0xd9,0xe2,0xb8,0xa6,0x2e,0xd9,0xd0,0x4e,0x53,0xbe,0x11,0x5d,
8162 0x52,0x3b,0xf0,0xca,0xe7,0x56,0xe7,0x20,0x02,0xd8,0x70,0x30,
8163 0xa8,0xc3,0x72,0xd1,0xce,0xdb,0x38,0x00,0x74,0x59,0xd2,0x2f,
8164 0xf8,0x31,0xe5,0x4d,0x6c,0xcf,0x25,0x6c,0x37,0x46,0x49,0xac,
8165 0xef,0x24,0xcd,0xc7,0x80,0x96,0xd5,0x22,0x47,0xe0,0xdf,0x33,
8166 0x0a,0x4a,0x53,0x3d,0x76,0xdb,0xf7,0x39,0x63,0x79,0xa3,0x0d,
8167 0xfa,0x8a,0x95,0xb0,0x98,0x62,0xb8,0x7f,0xc3,0xbe,0x68,0xa4,
8168 0x9f,0x7f,0x5f,0x1e,0x3b,0x48,0x7b,0x99,0x20,0xe0,0x5b,0xfc,
8169 0x4e,0xb6,0x76,0xed,0xdd,0xfe,0x5e,0xe3 };
8170 static const BYTE rsaPrivKeyPrime2[] = {
8171 0x4b,0xe6,0x2f,0xa5,0x08,0x3d,0xa9,0xf5,0x36,0x10,0x97,0x39,
8172 0xf3,0xc1,0xfb,0x86,0x48,0xaf,0x64,0xc6,0x9b,0x5f,0xe6,0xcf,
8173 0xb2,0x7b,0x39,0xa5,0x37,0x2c,0x61,0x1a,0x68,0xe2,0xe0,0xb0,
8174 0xfa,0x53,0xf1,0x7b,0x1d,0x3d,0x6b,0x70,0xa4,0x64,0x3a,0xe7,
8175 0xe1,0xe1,0xa0,0xaf,0x99,0x95,0xf2,0x4d,0x40,0x05,0x32,0xa4,
8176 0xab,0xac,0xee,0x97,0xca,0xa3,0xd6,0xe9,0xc0,0x9f,0x4d,0xb0,
8177 0xed,0x4a,0xe2,0x3a,0x29,0xe6,0xc3,0x2b,0xcd,0xa6,0xa9,0x87,
8178 0x7c,0xee,0x93,0x84,0x40,0xf2,0x40,0xae,0xc6,0x8e,0xd6,0x4a,
8179 0xaf,0xfc,0x5e,0x7d,0x9c,0x68,0x6f,0x18,0x72,0x1c,0x66,0x82,
8180 0x5d,0x66,0xaa,0x62,0x91,0xab,0xe1,0x0f,0xe9,0x4a,0x9d,0xce,
8181 0xce,0xe8,0xcf,0x6e,0xf0,0x57,0xba,0xc4 };
8182 static const BYTE rsaPrivKeyExponent1[] = {
8183 0xa1,0xca,0x03,0xc2,0xbc,0x0c,0x7b,0x61,0x6f,0x4e,0xf3,0xde,
8184 0x81,0xfb,0x44,0xa7,0x70,0xae,0xe8,0xb3,0x61,0x7a,0x86,0xac,
8185 0x7e,0xcd,0xf9,0xbc,0xe9,0x34,0x32,0x2d,0x7d,0x78,0x93,0xe2,
8186 0xac,0x87,0x45,0xe9,0xde,0x35,0x6d,0x8c,0xe0,0x16,0x09,0x9d,
8187 0x54,0xd9,0x49,0x62,0x73,0x5f,0xd7,0x5c,0x9a,0xba,0x80,0xef,
8188 0xbe,0xf5,0xda,0x9a,0x8c,0x03,0x79,0x9b,0xad,0x9e,0xff,0x0a,
8189 0x15,0x39,0x69,0xba,0x22,0x46,0xdd,0xbb,0x09,0xf9,0xa3,0x47,
8190 0x0b,0xae,0xce,0x10,0xac,0x22,0x86,0xb0,0x0a,0xf3,0x26,0x9f,
8191 0x98,0xa5,0x90,0xd4,0x94,0x0b,0xcb,0x76,0xa8,0xbf,0x26,0x76,
8192 0x01,0x5e,0x53,0x03,0x3e,0x30,0x29,0x39,0x67,0x9e,0x9f,0x54,
8193 0x93,0xa0,0xaf,0xe2,0x08,0x02,0xe7,0x86 };
8194 static const BYTE rsaPrivKeyExponent2[] = {
8195 0x85,0xfd,0x95,0x6b,0xb1,0x67,0x28,0x1d,0xe4,0xf1,0x20,0xbf,
8196 0x64,0x1d,0xf8,0x52,0xa2,0x4a,0x65,0xbd,0x98,0x55,0xf7,0x10,
8197 0x74,0x30,0x95,0x5a,0x7d,0xea,0x0a,0xc4,0xa5,0xf0,0x5a,0x5f,
8198 0xc3,0x50,0xb0,0x6b,0xa2,0x90,0xf6,0x3d,0xe6,0xfa,0xe3,0xc0,
8199 0xcb,0x14,0x6d,0xda,0x2b,0x96,0x86,0x26,0xb8,0xcb,0x2b,0xa6,
8200 0x21,0xbe,0x83,0x6a,0x5e,0xa3,0x15,0xfa,0xa5,0x7c,0xba,0xf5,
8201 0xc2,0xd9,0x51,0x3b,0x61,0x35,0xb0,0x12,0x92,0xaa,0xec,0xe6,
8202 0x52,0xf6,0x53,0xab,0x2c,0x76,0x10,0xfe,0x5d,0xd5,0xd4,0x96,
8203 0x05,0xe2,0xd9,0xae,0x22,0xb0,0x29,0x6a,0x80,0x88,0x17,0x5b,
8204 0x30,0x15,0xe6,0x20,0xab,0x19,0x11,0x48,0x1a,0x0d,0xf6,0x1b,
8205 0x9d,0x35,0x17,0x4f,0xa1,0x4a,0x5b,0x69 };
8206 static const BYTE rsaPrivKeyCoefficient[] = {
8207 0xf9,0x85,0x26,0x39,0x96,0x35,0x02,0xfb,0xd9,0xd4,0xf0,0xbd,
8208 0xcb,0xd5,0x3d,0xce,0x8b,0xb6,0x8b,0xc5,0x6c,0x11,0x44,0x1e,
8209 0x39,0x88,0x46,0x4a,0x31,0xe6,0xa1,0x3a,0x2b,0xfc,0x2a,0x05,
8210 0xa1,0x68,0x18,0x88,0xa6,0xd0,0xb1,0xc6,0x0b,0xa3,0x3e,0x68,
8211 0xb2,0x4d,0xf1,0xf2,0x1c,0x40,0xdb,0xf8,0x1a,0x44,0xf6,0x84,
8212 0x04,0x96,0xff,0xce,0x3a,0x7c,0x3c,0xd6,0x60,0xbc,0x14,0x14,
8213 0xf7,0xc1,0x9d,0xcd,0x62,0x46,0x8e,0x3e,0x47,0xb6,0x5b,0x91,
8214 0x74,0xb6,0x65,0x66,0x2a,0x13,0xdd,0x63,0x25,0x00,0xae,0x6b,
8215 0x68,0x4e,0x9c,0xc8,0x47,0x7c,0x83,0x52,0x51,0x14,0x8a,0x0f,
8216 0xa2,0x50,0xbd,0x45,0xf0,0x6b,0xbf,0x46,0x20,0xda,0xd7,0x07,
8217 0x1e,0x9a,0xec,0xe1,0x34,0x31,0xb4,0xda };
8218 static const BYTE rsaPrivKeyPrivateExponent[] = {
8219 0x11,0x90,0xb6,0x9f,0x62,0x9c,0x87,0x7e,0x9c,0x4c,0xbd,0x8c,
8220 0xf0,0xf8,0x2d,0x00,0x01,0x94,0xbc,0x68,0x39,0x13,0x3b,0x74,
8221 0x03,0x66,0xda,0xd2,0xde,0x79,0x96,0x61,0xba,0x6e,0x90,0xdf,
8222 0xed,0x25,0xdd,0x76,0xaa,0xfa,0x1d,0x15,0x65,0x99,0xba,0xf7,
8223 0x18,0xd5,0x15,0x85,0x33,0xf2,0xfd,0x60,0xb1,0x9f,0x66,0x9f,
8224 0x86,0x0c,0x69,0x06,0x5d,0x4c,0x5e,0xd8,0xf5,0x45,0x2d,0xf8,
8225 0x05,0x45,0xde,0xa4,0x71,0x58,0x81,0xce,0xe2,0xbb,0xb3,0x54,
8226 0x12,0xff,0x86,0x2d,0xd4,0xe5,0x03,0x90,0xa9,0x92,0xb9,0xe3,
8227 0x73,0xf2,0x69,0xbf,0xe2,0x75,0xab,0x59,0xfe,0x1b,0x48,0x8a,
8228 0xaf,0xdb,0xb0,0x7f,0x7e,0xb7,0x8c,0xfc,0x95,0x23,0x14,0x20,
8229 0x27,0x3d,0x74,0x4c,0x00,0xeb,0x23,0x20,0xc8,0x9c,0x2f,0x43,
8230 0x68,0x1d,0x97,0x02,0x15,0xcc,0xfc,0xde,0xda,0xe0,0x80,0xfd,
8231 0x95,0xbe,0xba,0xee,0xb3,0xd3,0xdc,0xd0,0xc2,0x63,0x16,0x40,
8232 0x97,0x04,0xa4,0xed,0x61,0x6d,0x37,0x03,0x84,0x00,0xb2,0x44,
8233 0x09,0x8b,0x6f,0xb3,0x44,0xac,0x54,0x66,0xf3,0x26,0x93,0xee,
8234 0xf7,0x91,0x76,0xa5,0x98,0xf8,0x3a,0x07,0x47,0x8b,0xdd,0x69,
8235 0x61,0x1f,0xdd,0x12,0x90,0x2e,0xe3,0xcd,0xc3,0xb7,0xc9,0x6d,
8236 0xfa,0xe8,0xa5,0x96,0x33,0x74,0xc9,0xc0,0x1f,0x3f,0x65,0xda,
8237 0x6f,0x12,0x75,0x17,0x8a,0xdb,0x4f,0x29,0xa2,0xfc,0x47,0x34,
8238 0x02,0xf6,0x86,0xcb,0x6a,0x74,0x9d,0x46,0x93,0x27,0x11,0x8c,
8239 0xef,0xd6,0xc9,0x2c,0x65,0x89,0xd6,0x78,0x98,0x32,0x03,0x69,
8240 0x5b,0xcd,0x03,0x99 };
8242 static void test_decodeRsaPrivateKey(DWORD dwEncoding)
8244 LPBYTE buf = NULL;
8245 DWORD bufSize = 0;
8246 BOOL ret;
8248 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_RSA_PRIVATE_KEY,
8249 rsaPrivKeyDer, sizeof(rsaPrivKeyDer)-10,
8250 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
8251 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD),
8252 "Expected CRYPT_E_ASN1_EOD, got %08x\n",
8253 GetLastError());
8255 buf = NULL;
8256 bufSize = 0;
8257 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_RSA_PRIVATE_KEY,
8258 rsaPrivKeyDer, sizeof(rsaPrivKeyDer),
8259 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
8260 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
8262 if (ret)
8264 BLOBHEADER *hdr = (BLOBHEADER *)buf;
8265 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER));
8266 static const int bitlen = 2048;
8267 BYTE *modulus = (BYTE*)(rsaPubKey + 1);
8268 BYTE *prime1 = modulus + bitlen/8;
8269 BYTE *prime2 = prime1 + bitlen/16;
8270 BYTE *exponent1 = prime2 + bitlen/16;
8271 BYTE *exponent2 = exponent1 + bitlen/16;
8272 BYTE *coefficient = exponent2 + bitlen/16;
8273 BYTE *privateExponent = coefficient + bitlen/16;
8275 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
8276 (bitlen * 9 / 16),
8277 "Wrong size %d\n", bufSize);
8279 ok(hdr->bType == PRIVATEKEYBLOB,
8280 "Expected type PRIVATEKEYBLOB (%d), got %d\n", PRIVATEKEYBLOB,
8281 hdr->bType);
8282 ok(hdr->bVersion == CUR_BLOB_VERSION,
8283 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
8284 CUR_BLOB_VERSION, hdr->bVersion);
8285 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n",
8286 hdr->reserved);
8287 ok(hdr->aiKeyAlg == CALG_RSA_KEYX,
8288 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg);
8290 ok(rsaPubKey->magic == 0x32415352,
8291 "Expected magic 0x32415352, got 0x%x\n", rsaPubKey->magic);
8292 ok(rsaPubKey->bitlen == bitlen,
8293 "Expected bitlen %d, got %d\n", bitlen, rsaPubKey->bitlen);
8294 ok(rsaPubKey->pubexp == 65537,
8295 "Expected pubexp 65537, got %d\n", rsaPubKey->pubexp);
8297 ok(!memcmp(modulus, rsaPrivKeyModulus, bitlen/8),
8298 "unexpected modulus\n");
8299 ok(!memcmp(prime1, rsaPrivKeyPrime1, bitlen/16),
8300 "unexpected prime1\n");
8301 ok(!memcmp(prime2, rsaPrivKeyPrime2, bitlen/16),
8302 "unexpected prime2\n");
8303 ok(!memcmp(exponent1, rsaPrivKeyExponent1, bitlen/16),
8304 "unexpected exponent1\n");
8305 ok(!memcmp(exponent2, rsaPrivKeyExponent2, bitlen/16),
8306 "unexpected exponent2\n");
8307 ok(!memcmp(coefficient, rsaPrivKeyCoefficient, bitlen/16),
8308 "unexpected coefficient\n");
8309 ok(!memcmp(privateExponent, rsaPrivKeyPrivateExponent, bitlen/8),
8310 "unexpected privateExponent\n");
8312 LocalFree(buf);
8316 /* Free *pInfo with HeapFree */
8317 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
8319 BOOL ret;
8320 DWORD size = 0;
8321 HCRYPTKEY key;
8323 /* This crashes
8324 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
8326 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size);
8327 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
8328 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
8329 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL,
8330 &size);
8331 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
8332 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
8333 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL,
8334 NULL, &size);
8335 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
8336 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
8337 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
8338 0, NULL, NULL, &size);
8339 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
8340 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
8341 /* Test with no key */
8342 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
8343 0, NULL, NULL, &size);
8344 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n",
8345 GetLastError());
8346 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
8347 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
8348 if (ret)
8350 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
8351 NULL, 0, NULL, NULL, &size);
8352 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
8353 *pInfo = HeapAlloc(GetProcessHeap(), 0, size);
8354 if (*pInfo)
8356 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
8357 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size);
8358 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n",
8359 GetLastError());
8360 if (ret)
8362 /* By default (we passed NULL as the OID) the OID is
8363 * szOID_RSA_RSA.
8365 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA),
8366 "Expected %s, got %s\n", szOID_RSA_RSA,
8367 (*pInfo)->Algorithm.pszObjId);
8371 CryptDestroyKey(key);
8374 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
8375 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
8376 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
8377 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
8378 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
8379 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
8380 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
8381 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
8382 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
8383 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
8384 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
8385 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
8386 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
8387 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
8388 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
8389 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
8390 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
8391 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
8392 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
8393 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
8394 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
8395 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
8396 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
8397 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
8398 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
8400 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info)
8402 BOOL ret;
8403 HCRYPTKEY key;
8404 BCRYPT_KEY_HANDLE key2;
8405 PCCERT_CONTEXT context;
8406 DWORD dwSize;
8407 ALG_ID ai;
8409 /* These crash
8410 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
8411 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
8412 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
8413 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
8414 NULL);
8416 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key);
8417 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
8418 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
8419 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key);
8420 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
8421 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
8422 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL,
8423 &key);
8424 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
8425 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
8427 /* Export key with standard algorithm (CALG_RSA_KEYX) */
8428 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
8429 &key);
8430 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
8432 dwSize = sizeof(ai);
8433 ret = CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
8434 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
8435 if(ret)
8437 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
8438 ok(ai == CALG_RSA_KEYX, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai);
8441 CryptDestroyKey(key);
8443 /* Repeat with forced algorithm */
8444 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, CALG_RSA_SIGN, 0, NULL,
8445 &key);
8446 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
8448 dwSize = sizeof(ai);
8449 ret = CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
8450 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
8451 if(ret)
8453 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
8454 ok(ai == CALG_RSA_SIGN, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai);
8457 CryptDestroyKey(key);
8459 /* Test importing a public key from a certificate context */
8460 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert,
8461 sizeof(expiredCert));
8462 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
8463 GetLastError());
8464 if (context)
8466 ok(!strcmp(szOID_RSA_RSA,
8467 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId),
8468 "Expected %s, got %s\n", szOID_RSA_RSA,
8469 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
8470 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING,
8471 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
8472 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
8473 CryptDestroyKey(key);
8475 ret = CryptImportPublicKeyInfoEx2(X509_ASN_ENCODING,
8476 &context->pCertInfo->SubjectPublicKeyInfo, 0, NULL, &key2);
8477 ok(ret, "CryptImportPublicKeyInfoEx2 failed: %08x\n", GetLastError());
8478 if (pBCryptDestroyKey) pBCryptDestroyKey(key2);
8480 CertFreeCertificateContext(context);
8484 static const char cspName[] = "WineCryptTemp";
8486 static void testPortPublicKeyInfo(void)
8488 HCRYPTPROV csp;
8489 BOOL ret;
8490 PCERT_PUBLIC_KEY_INFO info = NULL;
8492 /* Just in case a previous run failed, delete this thing */
8493 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV_A, PROV_RSA_FULL,
8494 CRYPT_DELETEKEYSET);
8495 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV_A, PROV_RSA_FULL,
8496 CRYPT_NEWKEYSET);
8497 ok(ret,"CryptAcquireContextA failed\n");
8499 testExportPublicKey(csp, &info);
8500 testImportPublicKey(csp, info);
8502 HeapFree(GetProcessHeap(), 0, info);
8503 CryptReleaseContext(csp, 0);
8504 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV_A, PROV_RSA_FULL,
8505 CRYPT_DELETEKEYSET);
8506 ok(ret,"CryptAcquireContextA failed\n");
8509 START_TEST(encode)
8511 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
8512 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING };
8513 HMODULE hCrypt32, hBcrypt;
8514 DWORD i;
8516 hCrypt32 = GetModuleHandleA("crypt32.dll");
8517 pCryptDecodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptDecodeObjectEx");
8518 pCryptEncodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptEncodeObjectEx");
8519 if (!pCryptDecodeObjectEx || !pCryptEncodeObjectEx)
8521 win_skip("CryptDecodeObjectEx() is not available\n");
8522 return;
8525 hBcrypt = GetModuleHandleA("bcrypt.dll");
8526 pBCryptDestroyKey = (void*)GetProcAddress(hBcrypt, "BCryptDestroyKey");
8528 for (i = 0; i < ARRAY_SIZE(encodings); i++)
8530 test_encodeInt(encodings[i]);
8531 test_decodeInt(encodings[i]);
8532 test_encodeEnumerated(encodings[i]);
8533 test_decodeEnumerated(encodings[i]);
8534 test_encodeFiletime(encodings[i]);
8535 test_decodeFiletime(encodings[i]);
8536 test_encodeName(encodings[i]);
8537 test_decodeName(encodings[i]);
8538 test_encodeUnicodeName(encodings[i]);
8539 test_decodeUnicodeName(encodings[i]);
8540 test_encodeNameValue(encodings[i]);
8541 test_decodeNameValue(encodings[i]);
8542 test_encodeUnicodeNameValue(encodings[i]);
8543 test_decodeUnicodeNameValue(encodings[i]);
8544 test_encodeAltName(encodings[i]);
8545 test_decodeAltName(encodings[i]);
8546 test_encodeOctets(encodings[i]);
8547 test_decodeOctets(encodings[i]);
8548 test_encodeBits(encodings[i]);
8549 test_decodeBits(encodings[i]);
8550 test_encodeBasicConstraints(encodings[i]);
8551 test_decodeBasicConstraints(encodings[i]);
8552 test_encodeRsaPublicKey(encodings[i]);
8553 test_decodeRsaPublicKey(encodings[i]);
8554 test_encodeSequenceOfAny(encodings[i]);
8555 test_decodeSequenceOfAny(encodings[i]);
8556 test_encodeExtensions(encodings[i]);
8557 test_decodeExtensions(encodings[i]);
8558 test_encodePublicKeyInfo(encodings[i]);
8559 test_decodePublicKeyInfo(encodings[i]);
8560 test_encodeCertToBeSigned(encodings[i]);
8561 test_decodeCertToBeSigned(encodings[i]);
8562 test_encodeCert(encodings[i]);
8563 test_decodeCert(encodings[i]);
8564 test_encodeCRLDistPoints(encodings[i]);
8565 test_decodeCRLDistPoints(encodings[i]);
8566 test_encodeCRLIssuingDistPoint(encodings[i]);
8567 test_decodeCRLIssuingDistPoint(encodings[i]);
8568 test_encodeCRLToBeSigned(encodings[i]);
8569 test_decodeCRLToBeSigned(encodings[i]);
8570 test_encodeEnhancedKeyUsage(encodings[i]);
8571 test_decodeEnhancedKeyUsage(encodings[i]);
8572 test_encodeAuthorityKeyId(encodings[i]);
8573 test_decodeAuthorityKeyId(encodings[i]);
8574 test_encodeAuthorityKeyId2(encodings[i]);
8575 test_decodeAuthorityKeyId2(encodings[i]);
8576 test_encodeAuthorityInfoAccess(encodings[i]);
8577 test_decodeAuthorityInfoAccess(encodings[i]);
8578 test_encodeCTL(encodings[i]);
8579 test_decodeCTL(encodings[i]);
8580 test_encodePKCSContentInfo(encodings[i]);
8581 test_decodePKCSContentInfo(encodings[i]);
8582 test_encodePKCSAttribute(encodings[i]);
8583 test_decodePKCSAttribute(encodings[i]);
8584 test_encodePKCSAttributes(encodings[i]);
8585 test_decodePKCSAttributes(encodings[i]);
8586 test_encodePKCSSMimeCapabilities(encodings[i]);
8587 test_decodePKCSSMimeCapabilities(encodings[i]);
8588 test_encodePKCSSignerInfo(encodings[i]);
8589 test_decodePKCSSignerInfo(encodings[i]);
8590 test_encodeCMSSignerInfo(encodings[i]);
8591 test_decodeCMSSignerInfo(encodings[i]);
8592 test_encodeNameConstraints(encodings[i]);
8593 test_decodeNameConstraints(encodings[i]);
8594 test_encodePolicyQualifierUserNotice(encodings[i]);
8595 test_decodePolicyQualifierUserNotice(encodings[i]);
8596 test_encodeCertPolicies(encodings[i]);
8597 test_decodeCertPolicies(encodings[i]);
8598 test_encodeCertPolicyMappings(encodings[i]);
8599 test_decodeCertPolicyMappings(encodings[i]);
8600 test_encodeCertPolicyConstraints(encodings[i]);
8601 test_decodeCertPolicyConstraints(encodings[i]);
8602 test_decodeRsaPrivateKey(encodings[i]);
8604 testPortPublicKeyInfo();