crypt32: Add partial support for decoding OCSP_BASIC_RESPONSE_INFO structures.
[wine.git] / dlls / crypt32 / tests / encode.c
blobb6325efd51892910c6cd135f2724723375d4d843
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*);
34 void CRYPT_CopyReversed(BYTE *dst, const BYTE *src, size_t len)
36 DWORD i;
37 for (i = 0; i < len; i++) {
38 dst[len - i - 1] = src[i];
42 struct encodedInt
44 int val;
45 const BYTE *encoded;
48 static const BYTE bin1[] = {0x02,0x01,0x01};
49 static const BYTE bin2[] = {0x02,0x01,0x7f};
50 static const BYTE bin3[] = {0x02,0x02,0x00,0x80};
51 static const BYTE bin4[] = {0x02,0x02,0x01,0x00};
52 static const BYTE bin5[] = {0x02,0x01,0x80};
53 static const BYTE bin6[] = {0x02,0x02,0xff,0x7f};
54 static const BYTE bin7[] = {0x02,0x04,0xba,0xdd,0xf0,0x0d};
56 static const struct encodedInt ints[] = {
57 { 1, bin1 },
58 { 127, bin2 },
59 { 128, bin3 },
60 { 256, bin4 },
61 { -128, bin5 },
62 { -129, bin6 },
63 { 0xbaddf00d, bin7 },
66 struct encodedBigInt
68 const BYTE *val;
69 const BYTE *encoded;
70 const BYTE *decoded;
73 static const BYTE bin8[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
74 static const BYTE bin9[] = {0x02,0x0a,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0};
75 static const BYTE bin10[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
77 static const BYTE bin11[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0xff,0};
78 static const BYTE bin12[] = {0x02,0x09,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
79 static const BYTE bin13[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0};
81 static const struct encodedBigInt bigInts[] = {
82 { bin8, bin9, bin10 },
83 { bin11, bin12, bin13 },
86 static const BYTE bin14[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
87 static const BYTE bin15[] = {0x02,0x0a,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0};
88 static const BYTE bin16[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0xff,0};
89 static const BYTE bin17[] = {0x02,0x0c,0x00,0xff,0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
91 /* Decoded is the same as original, so don't bother storing a separate copy */
92 static const struct encodedBigInt bigUInts[] = {
93 { bin14, bin15, NULL },
94 { bin16, bin17, NULL },
97 static void test_encodeInt(DWORD dwEncoding)
99 DWORD bufSize = 0;
100 int i;
101 BOOL ret;
102 CRYPT_INTEGER_BLOB blob;
103 BYTE *buf = NULL;
105 /* CryptEncodeObjectEx with NULL bufSize crashes..
106 ret = pCryptEncodeObjectEx(3, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
107 NULL);
109 /* check bogus encoding */
110 ret = pCryptEncodeObjectEx(0, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
111 &bufSize);
112 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
113 "Expected ERROR_FILE_NOT_FOUND, got %ld\n", GetLastError());
114 if (0)
116 /* check with NULL integer buffer. Windows XP incorrectly returns an
117 * NTSTATUS (crashes on win9x).
119 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, NULL, 0, NULL, NULL,
120 &bufSize);
121 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
122 "Expected STATUS_ACCESS_VIOLATION, got %08lx\n", GetLastError());
124 for (i = 0; i < ARRAY_SIZE(ints); i++)
126 /* encode as normal integer */
127 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, &ints[i].val, 0,
128 NULL, NULL, &bufSize);
129 ok(ret, "Expected success, got %ld\n", GetLastError());
130 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, &ints[i].val,
131 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
132 ok(ret, "CryptEncodeObjectEx failed: %ld\n", GetLastError());
133 if (ret)
135 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
136 buf[0]);
137 ok(buf[1] == ints[i].encoded[1], "Got length %d, expected %d\n",
138 buf[1], ints[i].encoded[1]);
139 ok(!memcmp(buf + 1, ints[i].encoded + 1, ints[i].encoded[1] + 1),
140 "Encoded value of 0x%08x didn't match expected\n", ints[i].val);
141 LocalFree(buf);
143 /* encode as multibyte integer */
144 blob.cbData = sizeof(ints[i].val);
145 blob.pbData = (BYTE *)&ints[i].val;
146 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
147 0, NULL, NULL, &bufSize);
148 ok(ret, "Expected success, got %ld\n", GetLastError());
149 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
150 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
151 ok(ret, "CryptEncodeObjectEx failed: %ld\n", GetLastError());
152 if (ret)
154 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
155 buf[0]);
156 ok(buf[1] == ints[i].encoded[1], "Got length %d, expected %d\n",
157 buf[1], ints[i].encoded[1]);
158 ok(!memcmp(buf + 1, ints[i].encoded + 1, ints[i].encoded[1] + 1),
159 "Encoded value of 0x%08x didn't match expected\n", ints[i].val);
160 LocalFree(buf);
163 /* encode a couple bigger ints, just to show it's little-endian and leading
164 * sign bytes are dropped
166 for (i = 0; i < ARRAY_SIZE(bigInts); i++)
168 blob.cbData = strlen((const char*)bigInts[i].val);
169 blob.pbData = (BYTE *)bigInts[i].val;
170 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
171 0, NULL, NULL, &bufSize);
172 ok(ret, "Expected success, got %ld\n", GetLastError());
173 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
174 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
175 ok(ret, "CryptEncodeObjectEx failed: %ld\n", GetLastError());
176 if (ret)
178 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
179 buf[0]);
180 ok(buf[1] == bigInts[i].encoded[1], "Got length %d, expected %d\n",
181 buf[1], bigInts[i].encoded[1]);
182 ok(!memcmp(buf + 1, bigInts[i].encoded + 1,
183 bigInts[i].encoded[1] + 1),
184 "Encoded value didn't match expected\n");
185 LocalFree(buf);
188 /* and, encode some uints */
189 for (i = 0; i < ARRAY_SIZE(bigUInts); i++)
191 blob.cbData = strlen((const char*)bigUInts[i].val);
192 blob.pbData = (BYTE*)bigUInts[i].val;
193 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, &blob,
194 0, NULL, NULL, &bufSize);
195 ok(ret, "Expected success, got %ld\n", GetLastError());
196 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, &blob,
197 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
198 ok(ret, "CryptEncodeObjectEx failed: %ld\n", GetLastError());
199 if (ret)
201 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
202 buf[0]);
203 ok(buf[1] == bigUInts[i].encoded[1], "Got length %d, expected %d\n",
204 buf[1], bigUInts[i].encoded[1]);
205 ok(!memcmp(buf + 1, bigUInts[i].encoded + 1,
206 bigUInts[i].encoded[1] + 1),
207 "Encoded value didn't match expected\n");
208 LocalFree(buf);
213 static void test_decodeInt(DWORD dwEncoding)
215 static const BYTE bigInt[] = { 2, 5, 0xff, 0xfe, 0xff, 0xfe, 0xff };
216 static const BYTE testStr[] = { 0x16, 4, 't', 'e', 's', 't' };
217 static const BYTE longForm[] = { 2, 0x81, 0x01, 0x01 };
218 static const BYTE bigBogus[] = { 0x02, 0x84, 0x01, 0xff, 0xff, 0xf9 };
219 static const BYTE extraBytes[] = { 2, 1, 1, 0, 0, 0, 0 };
220 BYTE *buf = NULL;
221 DWORD bufSize = 0;
222 int i;
223 BOOL ret;
225 /* CryptDecodeObjectEx with NULL bufSize crashes..
226 ret = pCryptDecodeObjectEx(3, X509_INTEGER, &ints[0].encoded,
227 ints[0].encoded[1] + 2, 0, NULL, NULL, NULL);
229 /* check bogus encoding */
230 ret = pCryptDecodeObjectEx(3, X509_INTEGER, (BYTE *)&ints[0].encoded,
231 ints[0].encoded[1] + 2, 0, NULL, NULL, &bufSize);
232 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
233 "Expected ERROR_FILE_NOT_FOUND, got %ld\n", GetLastError());
234 /* check with NULL integer buffer */
235 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, NULL, 0, 0, NULL, NULL,
236 &bufSize);
237 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
238 GetLastError() == OSS_BAD_ARG /* Win9x */),
239 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08lx\n", GetLastError());
240 /* check with a valid, but too large, integer */
241 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, bigInt, bigInt[1] + 2,
242 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
243 ok((!ret && GetLastError() == CRYPT_E_ASN1_LARGE) ||
244 broken(ret) /* Win9x */,
245 "Expected CRYPT_E_ASN1_LARGE, got %ld\n", GetLastError());
246 /* check with a DER-encoded string */
247 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, testStr, testStr[1] + 2,
248 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
249 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
250 GetLastError() == OSS_PDU_MISMATCH /* Win9x */ ),
251 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %08lx\n",
252 GetLastError());
253 for (i = 0; i < ARRAY_SIZE(ints); i++)
255 /* When the output buffer is NULL, this always succeeds */
256 SetLastError(0xdeadbeef);
257 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER,
258 ints[i].encoded, ints[i].encoded[1] + 2, 0, NULL, NULL,
259 &bufSize);
260 ok(ret && GetLastError() == NOERROR,
261 "Expected success and NOERROR, got %ld\n", GetLastError());
262 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER,
263 ints[i].encoded, ints[i].encoded[1] + 2,
264 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
265 ok(ret, "CryptDecodeObjectEx failed: %ld\n", GetLastError());
266 ok(bufSize == sizeof(int), "Wrong size %ld\n", bufSize);
267 ok(buf != NULL, "Expected allocated buffer\n");
268 if (ret)
270 ok(!memcmp(buf, &ints[i].val, bufSize), "Expected %d, got %d\n",
271 ints[i].val, *(int *)buf);
272 LocalFree(buf);
275 for (i = 0; i < ARRAY_SIZE(bigInts); i++)
277 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER,
278 bigInts[i].encoded, bigInts[i].encoded[1] + 2, 0, NULL, NULL,
279 &bufSize);
280 ok(ret && GetLastError() == NOERROR,
281 "Expected success and NOERROR, got %ld\n", GetLastError());
282 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER,
283 bigInts[i].encoded, bigInts[i].encoded[1] + 2,
284 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
285 ok(ret, "CryptDecodeObjectEx failed: %ld\n", GetLastError());
286 ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %ld\n", bufSize);
287 ok(buf != NULL, "Expected allocated buffer\n");
288 if (ret)
290 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
292 ok(blob->cbData == strlen((const char*)bigInts[i].decoded),
293 "Expected len %d, got %ld\n", lstrlenA((const char*)bigInts[i].decoded),
294 blob->cbData);
295 ok(!memcmp(blob->pbData, bigInts[i].decoded, blob->cbData),
296 "Unexpected value\n");
297 LocalFree(buf);
300 for (i = 0; i < ARRAY_SIZE(bigUInts); i++)
302 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT,
303 bigUInts[i].encoded, bigUInts[i].encoded[1] + 2, 0, NULL, NULL,
304 &bufSize);
305 ok(ret && GetLastError() == NOERROR,
306 "Expected success and NOERROR, got %ld\n", GetLastError());
307 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT,
308 bigUInts[i].encoded, bigUInts[i].encoded[1] + 2,
309 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
310 ok(ret, "CryptDecodeObjectEx failed: %ld\n", GetLastError());
311 ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %ld\n", bufSize);
312 ok(buf != NULL, "Expected allocated buffer\n");
313 if (ret)
315 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
317 ok(blob->cbData == strlen((const char*)bigUInts[i].val),
318 "Expected len %d, got %ld\n", lstrlenA((const char*)bigUInts[i].val),
319 blob->cbData);
320 ok(!memcmp(blob->pbData, bigUInts[i].val, blob->cbData),
321 "Unexpected value\n");
322 LocalFree(buf);
325 /* Decode the value 1 with long-form length */
326 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, longForm,
327 sizeof(longForm), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
328 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
329 if (ret)
331 ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf);
332 LocalFree(buf);
334 /* check with extra bytes at the end */
335 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, extraBytes,
336 sizeof(extraBytes), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
337 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
338 if (ret)
340 ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf);
341 LocalFree(buf);
343 /* Try to decode some bogus large items */
344 /* The buffer size is smaller than the encoded length, so this should fail
345 * with CRYPT_E_ASN1_EOD if it's being decoded.
346 * Under XP it fails with CRYPT_E_ASN1_LARGE, which means there's a limit
347 * on the size decoded, but in ME it fails with CRYPT_E_ASN1_EOD or crashes.
348 * So this test unfortunately isn't useful.
349 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, tooBig,
350 0x7fffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
351 ok(!ret && GetLastError() == CRYPT_E_ASN1_LARGE,
352 "Expected CRYPT_E_ASN1_LARGE, got %08x\n", GetLastError());
354 /* This will try to decode the buffer and overflow it, check that it's
355 * caught.
357 if (0)
359 /* a large buffer isn't guaranteed to crash, it depends on memory allocation order */
360 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, bigBogus,
361 0x01ffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
362 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
363 "Expected STATUS_ACCESS_VIOLATION, got %08lx\n", GetLastError());
367 static const BYTE bin18[] = {0x0a,0x01,0x01};
368 static const BYTE bin19[] = {0x0a,0x05,0x00,0xff,0xff,0xff,0x80};
370 /* These are always encoded unsigned, and aren't constrained to be any
371 * particular value
373 static const struct encodedInt enums[] = {
374 { 1, bin18 },
375 { -128, bin19 },
378 /* X509_CRL_REASON_CODE is also an enumerated type, but it's #defined to
379 * X509_ENUMERATED.
381 static const LPCSTR enumeratedTypes[] = { X509_ENUMERATED,
382 szOID_CRL_REASON_CODE };
384 static void test_encodeEnumerated(DWORD dwEncoding)
386 DWORD i, j;
388 for (i = 0; i < ARRAY_SIZE(enumeratedTypes); i++)
390 for (j = 0; j < ARRAY_SIZE(enums); j++)
392 BOOL ret;
393 BYTE *buf = NULL;
394 DWORD bufSize = 0;
396 ret = pCryptEncodeObjectEx(dwEncoding, enumeratedTypes[i],
397 &enums[j].val, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf,
398 &bufSize);
399 ok(ret, "CryptEncodeObjectEx failed: %ld\n", GetLastError());
400 if (ret)
402 ok(buf[0] == 0xa,
403 "Got unexpected type %d for enumerated (expected 0xa)\n",
404 buf[0]);
405 ok(buf[1] == enums[j].encoded[1],
406 "Got length %d, expected %d\n", buf[1], enums[j].encoded[1]);
407 ok(!memcmp(buf + 1, enums[j].encoded + 1,
408 enums[j].encoded[1] + 1),
409 "Encoded value of 0x%08x didn't match expected\n",
410 enums[j].val);
411 LocalFree(buf);
417 static void test_decodeEnumerated(DWORD dwEncoding)
419 DWORD i, j;
421 for (i = 0; i < ARRAY_SIZE(enumeratedTypes); i++)
423 for (j = 0; j < ARRAY_SIZE(enums); j++)
425 BOOL ret;
426 DWORD bufSize = sizeof(int);
427 int val;
429 ret = pCryptDecodeObjectEx(dwEncoding, enumeratedTypes[i],
430 enums[j].encoded, enums[j].encoded[1] + 2, 0, NULL,
431 &val, &bufSize);
432 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
433 ok(bufSize == sizeof(int),
434 "Got unexpected size %ld for enumerated\n", bufSize);
435 ok(val == enums[j].val, "Unexpected value %d, expected %d\n",
436 val, enums[j].val);
441 struct encodedFiletime
443 SYSTEMTIME sysTime;
444 const BYTE *encodedTime;
447 static void testTimeEncoding(DWORD dwEncoding, LPCSTR structType,
448 const struct encodedFiletime *time)
450 FILETIME ft = { 0 };
451 BYTE *buf = NULL;
452 DWORD bufSize = 0;
453 BOOL ret;
455 ret = SystemTimeToFileTime(&time->sysTime, &ft);
456 ok(ret, "SystemTimeToFileTime failed: %ld\n", GetLastError());
457 ret = pCryptEncodeObjectEx(dwEncoding, structType, &ft,
458 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
459 /* years other than 1950-2050 are not allowed for encodings other than
460 * X509_CHOICE_OF_TIME.
462 if (structType == X509_CHOICE_OF_TIME ||
463 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050))
465 ok(ret, "CryptEncodeObjectEx failed: %ld (0x%08lx)\n", GetLastError(),
466 GetLastError());
467 ok(buf != NULL, "Expected an allocated buffer\n");
468 if (ret)
470 ok(buf[0] == time->encodedTime[0],
471 "Expected type 0x%02x, got 0x%02x\n", time->encodedTime[0],
472 buf[0]);
473 ok(buf[1] == time->encodedTime[1], "Expected %d bytes, got %ld\n",
474 time->encodedTime[1], bufSize);
475 ok(!memcmp(time->encodedTime + 2, buf + 2, time->encodedTime[1]),
476 "Got unexpected value for time encoding\n");
477 LocalFree(buf);
480 else
481 ok((!ret && GetLastError() == CRYPT_E_BAD_ENCODE) ||
482 broken(GetLastError() == ERROR_SUCCESS),
483 "Expected CRYPT_E_BAD_ENCODE, got 0x%08lx\n", GetLastError());
486 static const char *printSystemTime(const SYSTEMTIME *st)
488 static char buf[64];
490 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st->wMonth, st->wDay,
491 st->wYear, st->wHour, st->wMinute, st->wSecond, st->wMilliseconds);
492 return buf;
495 static const char *printFileTime(const FILETIME *ft)
497 static char buf[64];
498 SYSTEMTIME st;
500 FileTimeToSystemTime(ft, &st);
501 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st.wMonth, st.wDay,
502 st.wYear, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
503 return buf;
506 static void compareTime(const SYSTEMTIME *expected, const FILETIME *got)
508 SYSTEMTIME st;
510 FileTimeToSystemTime(got, &st);
511 ok((expected->wYear == st.wYear &&
512 expected->wMonth == st.wMonth &&
513 expected->wDay == st.wDay &&
514 expected->wHour == st.wHour &&
515 expected->wMinute == st.wMinute &&
516 expected->wSecond == st.wSecond &&
517 abs(expected->wMilliseconds - st.wMilliseconds) <= 1) ||
518 /* Some Windows systems only seem to be accurate in their time decoding to
519 * within about an hour.
521 broken(expected->wYear == st.wYear &&
522 expected->wMonth == st.wMonth &&
523 expected->wDay == st.wDay &&
524 abs(expected->wHour - st.wHour) <= 1),
525 "Got unexpected value for time decoding:\nexpected %s, got %s\n",
526 printSystemTime(expected), printFileTime(got));
529 static void testTimeDecoding(DWORD dwEncoding, LPCSTR structType,
530 const struct encodedFiletime *time)
532 FILETIME ft = { 0 };
533 DWORD size = sizeof(ft);
534 BOOL ret;
536 ret = pCryptDecodeObjectEx(dwEncoding, structType, time->encodedTime,
537 time->encodedTime[1] + 2, 0, NULL, &ft, &size);
538 /* years other than 1950-2050 are not allowed for encodings other than
539 * X509_CHOICE_OF_TIME.
541 if (structType == X509_CHOICE_OF_TIME ||
542 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050))
544 ok(ret || broken(GetLastError() == OSS_DATA_ERROR),
545 "CryptDecodeObjectEx failed: %ld (0x%08lx)\n", GetLastError(),
546 GetLastError());
547 if (ret)
548 compareTime(&time->sysTime, &ft);
550 else
551 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
552 GetLastError() == OSS_PDU_MISMATCH /* Win9x */ ),
553 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %08lx\n",
554 GetLastError());
557 static const BYTE bin20[] = {
558 0x17,0x0d,'0','5','0','6','0','6','1','6','1','0','0','0','Z'};
559 static const BYTE bin21[] = {
560 0x18,0x0f,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
561 static const BYTE bin22[] = {
562 0x18,0x0f,'2','1','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
564 static const struct encodedFiletime times[] = {
565 { { 2005, 6, 1, 6, 16, 10, 0, 0 }, bin20 },
566 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin21 },
567 { { 2145, 6, 1, 6, 16, 10, 0, 0 }, bin22 },
570 static void test_encodeFiletime(DWORD dwEncoding)
572 DWORD i;
574 for (i = 0; i < ARRAY_SIZE(times); i++)
576 testTimeEncoding(dwEncoding, X509_CHOICE_OF_TIME, &times[i]);
577 testTimeEncoding(dwEncoding, PKCS_UTC_TIME, &times[i]);
578 testTimeEncoding(dwEncoding, szOID_RSA_signingTime, &times[i]);
582 static const BYTE bin23[] = {
583 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','0','0','0','Z'};
584 static const BYTE bin24[] = {
585 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','9','9','9','Z'};
586 static const BYTE bin25[] = {
587 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','+','0','1','0','0'};
588 static const BYTE bin26[] = {
589 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','0','0'};
590 static const BYTE bin27[] = {
591 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','1','5'};
592 static const BYTE bin28[] = {
593 0x18,0x0a,'2','1','4','5','0','6','0','6','1','6'};
594 static const BYTE bin29[] = {
595 0x17,0x0a,'4','5','0','6','0','6','1','6','1','0'};
596 static const BYTE bin30[] = {
597 0x17,0x0b,'4','5','0','6','0','6','1','6','1','0','Z'};
598 static const BYTE bin31[] = {
599 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','+','0','1'};
600 static const BYTE bin32[] = {
601 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','-','0','1'};
602 static const BYTE bin33[] = {
603 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','+','0','1','0','0'};
604 static const BYTE bin34[] = {
605 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','-','0','1','0','0'};
606 static const BYTE bin35[] = {
607 0x17,0x08, '4','5','0','6','0','6','1','6'};
608 static const BYTE bin36[] = {
609 0x18,0x0f, 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','Z'};
610 static const BYTE bin37[] = {
611 0x18,0x04, '2','1','4','5'};
612 static const BYTE bin38[] = {
613 0x18,0x08, '2','1','4','5','0','6','0','6'};
615 static void test_decodeFiletime(DWORD dwEncoding)
617 static const struct encodedFiletime otherTimes[] = {
618 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin23 },
619 { { 1945, 6, 1, 6, 16, 10, 0, 999 }, bin24 },
620 { { 1945, 6, 1, 6, 17, 10, 0, 0 }, bin25 },
621 { { 1945, 6, 1, 6, 15, 10, 0, 0 }, bin26 },
622 { { 1945, 6, 1, 6, 14, 55, 0, 0 }, bin27 },
623 { { 2145, 6, 1, 6, 16, 0, 0, 0 }, bin28 },
624 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin29 },
625 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin30 },
626 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin31 },
627 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin32 },
628 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin33 },
629 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin34 },
631 /* An oddball case that succeeds in Windows, but doesn't seem correct
632 { { 2145, 6, 1, 2, 11, 31, 0, 0 }, "\x18" "\x13" "21450606161000-9999" },
634 static const unsigned char *bogusTimes[] = {
635 /* oddly, this succeeds on Windows, with year 2765
636 "\x18" "\x0f" "21r50606161000Z",
638 bin35,
639 bin36,
640 bin37,
641 bin38,
643 DWORD i, size;
644 FILETIME ft1 = { 0 }, ft2 = { 0 };
645 BOOL ret;
647 /* Check bogus length with non-NULL buffer */
648 ret = SystemTimeToFileTime(&times[0].sysTime, &ft1);
649 ok(ret, "SystemTimeToFileTime failed: %ld\n", GetLastError());
650 size = 1;
651 ret = pCryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
652 times[0].encodedTime, times[0].encodedTime[1] + 2, 0, NULL, &ft2, &size);
653 ok(!ret && GetLastError() == ERROR_MORE_DATA,
654 "Expected ERROR_MORE_DATA, got %ld\n", GetLastError());
655 /* Normal tests */
656 for (i = 0; i < ARRAY_SIZE(times); i++)
658 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &times[i]);
659 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &times[i]);
660 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &times[i]);
662 for (i = 0; i < ARRAY_SIZE(otherTimes); i++)
664 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &otherTimes[i]);
665 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &otherTimes[i]);
666 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &otherTimes[i]);
668 for (i = 0; i < ARRAY_SIZE(bogusTimes); i++)
670 size = sizeof(ft1);
671 ret = pCryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
672 bogusTimes[i], bogusTimes[i][1] + 2, 0, NULL, &ft1, &size);
673 ok((!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
674 GetLastError() == OSS_DATA_ERROR /* Win9x */)) ||
675 broken(ret), /* Win9x and NT4 for bin38 */
676 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08lx\n",
677 GetLastError());
681 static const char commonName[] = "Juan Lang";
682 static const char surName[] = "Lang";
684 static const BYTE emptySequence[] = { 0x30, 0 };
685 static const BYTE emptyRDNs[] = { 0x30, 0x02, 0x31, 0 };
686 static const BYTE twoRDNs[] = {
687 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
688 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
689 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0};
690 static const BYTE encodedTwoRDNs[] = {
691 0x30,0x2e,0x31,0x2c,0x30,0x2a,0x06,0x03,0x55,0x04,0x03,0x30,0x23,0x31,0x21,
692 0x30,0x0c,0x06,0x03,0x55,0x04,0x04,0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,
693 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
694 0x6e,0x67,0x00,
697 static const BYTE us[] = { 0x55, 0x53 };
698 static const BYTE minnesota[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x73, 0x6f,
699 0x74, 0x61 };
700 static const BYTE minneapolis[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x61, 0x70,
701 0x6f, 0x6c, 0x69, 0x73 };
702 static const BYTE codeweavers[] = { 0x43, 0x6f, 0x64, 0x65, 0x57, 0x65, 0x61,
703 0x76, 0x65, 0x72, 0x73 };
704 static const BYTE wine[] = { 0x57, 0x69, 0x6e, 0x65, 0x20, 0x44, 0x65, 0x76,
705 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74 };
706 static const BYTE localhostAttr[] = { 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
707 0x73, 0x74 };
708 static const BYTE aric[] = { 0x61, 0x72, 0x69, 0x63, 0x40, 0x63, 0x6f, 0x64,
709 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d };
711 #define RDNA(arr) oid_ ## arr, CERT_RDN_PRINTABLE_STRING, { sizeof(arr), (LPBYTE)arr }
712 #define RDNIA5(arr) oid_ ## arr, CERT_RDN_IA5_STRING, { sizeof(arr), (LPBYTE)arr }
714 static CHAR oid_us[] = "2.5.4.6",
715 oid_minnesota[] = "2.5.4.8",
716 oid_minneapolis[] = "2.5.4.7",
717 oid_codeweavers[] = "2.5.4.10",
718 oid_wine[] = "2.5.4.11",
719 oid_localhostAttr[] = "2.5.4.3",
720 oid_aric[] = "1.2.840.113549.1.9.1";
721 static CERT_RDN_ATTR rdnAttrs[] = { { RDNA(us) },
722 { RDNA(minnesota) },
723 { RDNA(minneapolis) },
724 { RDNA(codeweavers) },
725 { RDNA(wine) },
726 { RDNA(localhostAttr) },
727 { RDNIA5(aric) } };
728 static CERT_RDN_ATTR decodedRdnAttrs[] = { { RDNA(us) },
729 { RDNA(localhostAttr) },
730 { RDNA(minnesota) },
731 { RDNA(minneapolis) },
732 { RDNA(codeweavers) },
733 { RDNA(wine) },
734 { RDNIA5(aric) } };
736 #undef RDNIA5
737 #undef RDNA
739 static const BYTE encodedRDNAttrs[] = {
740 0x30,0x81,0x96,0x31,0x81,0x93,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
741 0x53,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x68,
742 0x6f,0x73,0x74,0x30,0x10,0x06,0x03,0x55,0x04,0x08,0x13,0x09,0x4d,0x69,0x6e,0x6e,
743 0x65,0x73,0x6f,0x74,0x61,0x30,0x12,0x06,0x03,0x55,0x04,0x07,0x13,0x0b,0x4d,0x69,
744 0x6e,0x6e,0x65,0x61,0x70,0x6f,0x6c,0x69,0x73,0x30,0x12,0x06,0x03,0x55,0x04,0x0a,
745 0x13,0x0b,0x43,0x6f,0x64,0x65,0x57,0x65,0x61,0x76,0x65,0x72,0x73,0x30,0x17,0x06,
746 0x03,0x55,0x04,0x0b,0x13,0x10,0x57,0x69,0x6e,0x65,0x20,0x44,0x65,0x76,0x65,0x6c,
747 0x6f,0x70,0x6d,0x65,0x6e,0x74,0x30,0x21,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
748 0x01,0x09,0x01,0x16,0x14,0x61,0x72,0x69,0x63,0x40,0x63,0x6f,0x64,0x65,0x77,0x65,
749 0x61,0x76,0x65,0x72,0x73,0x2e,0x63,0x6f,0x6d
752 static void test_encodeName(DWORD dwEncoding)
754 CERT_RDN_ATTR attrs[2];
755 CERT_RDN rdn;
756 CERT_NAME_INFO info;
757 static CHAR oid_common_name[] = szOID_COMMON_NAME,
758 oid_sur_name[] = szOID_SUR_NAME;
759 BYTE *buf = NULL;
760 DWORD size = 0;
761 BOOL ret;
763 if (0)
765 /* Test with NULL pvStructInfo (crashes on win9x) */
766 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, NULL,
767 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
768 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
769 "Expected STATUS_ACCESS_VIOLATION, got %08lx\n", GetLastError());
771 /* Test with empty CERT_NAME_INFO */
772 info.cRDN = 0;
773 info.rgRDN = NULL;
774 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
775 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
776 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
777 if (ret)
779 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
780 "Got unexpected encoding for empty name\n");
781 LocalFree(buf);
783 if (0)
785 /* Test with bogus CERT_RDN (crashes on win9x) */
786 info.cRDN = 1;
787 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
788 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
789 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
790 "Expected STATUS_ACCESS_VIOLATION, got %08lx\n", GetLastError());
792 /* Test with empty CERT_RDN */
793 rdn.cRDNAttr = 0;
794 rdn.rgRDNAttr = NULL;
795 info.cRDN = 1;
796 info.rgRDN = &rdn;
797 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
798 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
799 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
800 if (ret)
802 ok(!memcmp(buf, emptyRDNs, sizeof(emptyRDNs)),
803 "Got unexpected encoding for empty RDN array\n");
804 LocalFree(buf);
806 if (0)
808 /* Test with bogus attr array (crashes on win9x) */
809 rdn.cRDNAttr = 1;
810 rdn.rgRDNAttr = NULL;
811 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
812 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
813 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
814 "Expected STATUS_ACCESS_VIOLATION, got %08lx\n", GetLastError());
816 /* oddly, a bogus OID is accepted by Windows XP; not testing.
817 attrs[0].pszObjId = "bogus";
818 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
819 attrs[0].Value.cbData = sizeof(commonName);
820 attrs[0].Value.pbData = commonName;
821 rdn.cRDNAttr = 1;
822 rdn.rgRDNAttr = attrs;
823 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
824 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
825 ok(!ret, "Expected failure, got success\n");
827 /* Check with two CERT_RDN_ATTRs. Note DER encoding forces the order of
828 * the encoded attributes to be swapped.
830 attrs[0].pszObjId = oid_common_name;
831 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
832 attrs[0].Value.cbData = sizeof(commonName);
833 attrs[0].Value.pbData = (BYTE *)commonName;
834 attrs[1].pszObjId = oid_sur_name;
835 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
836 attrs[1].Value.cbData = sizeof(surName);
837 attrs[1].Value.pbData = (BYTE *)surName;
838 rdn.cRDNAttr = 2;
839 rdn.rgRDNAttr = attrs;
840 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
841 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
842 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
843 if (ret)
845 ok(!memcmp(buf, twoRDNs, sizeof(twoRDNs)),
846 "Got unexpected encoding for two RDN array\n");
847 LocalFree(buf);
849 /* A name can be "encoded" with previously encoded RDN attrs. */
850 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
851 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
852 attrs[0].Value.cbData = sizeof(twoRDNs);
853 rdn.cRDNAttr = 1;
854 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
855 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
856 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
857 if (ret)
859 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %ld\n", size);
860 ok(!memcmp(buf, encodedTwoRDNs, size),
861 "Unexpected value for re-encoded two RDN array\n");
862 LocalFree(buf);
864 /* CERT_RDN_ANY_TYPE is too vague for X509_NAMEs, check the return */
865 rdn.cRDNAttr = 1;
866 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
867 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
868 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
869 ok(!ret && GetLastError() == E_INVALIDARG,
870 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
871 /* Test a more complex name */
872 rdn.cRDNAttr = ARRAY_SIZE(rdnAttrs);
873 rdn.rgRDNAttr = rdnAttrs;
874 info.cRDN = 1;
875 info.rgRDN = &rdn;
876 buf = NULL;
877 size = 0;
878 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, X509_NAME, &info,
879 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
880 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
881 if (ret)
883 ok(size == sizeof(encodedRDNAttrs), "Wrong size %ld\n", size);
884 ok(!memcmp(buf, encodedRDNAttrs, size), "Unexpected value\n");
885 LocalFree(buf);
889 static WCHAR commonNameW[] = { 'J','u','a','n',' ','L','a','n','g',0 };
890 static WCHAR surNameW[] = { 'L','a','n','g',0 };
892 static const BYTE twoRDNsNoNull[] = {
893 0x30,0x21,0x31,0x1f,0x30,0x0b,0x06,0x03,0x55,0x04,0x04,0x13,0x04,0x4c,0x61,
894 0x6e,0x67,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,
895 0x20,0x4c,0x61,0x6e,0x67 };
896 static const BYTE anyType[] = {
897 0x30,0x2f,0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x1e,0x24,0x23,0x30,
898 0x21,0x31,0x0c,0x30,0x03,0x06,0x04,0x55,0x13,0x04,0x4c,0x05,0x6e,0x61,0x00,
899 0x67,0x11,0x30,0x03,0x06,0x04,0x55,0x13,0x03,0x4a,0x0a,0x61,0x75,0x20,0x6e,
900 0x61,0x4c,0x67,0x6e };
902 static void test_encodeUnicodeName(DWORD dwEncoding)
904 CERT_RDN_ATTR attrs[2];
905 CERT_RDN rdn;
906 CERT_NAME_INFO info;
907 static CHAR oid_common_name[] = szOID_COMMON_NAME,
908 oid_sur_name[] = szOID_SUR_NAME;
909 BYTE *buf = NULL;
910 DWORD size = 0;
911 BOOL ret;
913 if (0)
915 /* Test with NULL pvStructInfo (crashes on win9x) */
916 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, NULL,
917 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
918 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
919 "Expected STATUS_ACCESS_VIOLATION, got %08lx\n", GetLastError());
921 /* Test with empty CERT_NAME_INFO */
922 info.cRDN = 0;
923 info.rgRDN = NULL;
924 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
925 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
926 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
927 if (ret)
929 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
930 "Got unexpected encoding for empty name\n");
931 LocalFree(buf);
933 /* Check with one CERT_RDN_ATTR, that has an invalid character for the
934 * encoding (the NULL).
936 attrs[0].pszObjId = oid_common_name;
937 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
938 attrs[0].Value.cbData = sizeof(commonNameW);
939 attrs[0].Value.pbData = (BYTE *)commonNameW;
940 rdn.cRDNAttr = 1;
941 rdn.rgRDNAttr = attrs;
942 info.cRDN = 1;
943 info.rgRDN = &rdn;
944 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
945 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
946 ok(!ret && GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING,
947 "Expected CRYPT_E_INVALID_PRINTABLE_STRING, got %08lx\n", GetLastError());
948 ok(size == 9, "Unexpected error index %08lx\n", size);
949 /* Check with two NULL-terminated CERT_RDN_ATTRs. Note DER encoding
950 * forces the order of the encoded attributes to be swapped.
952 attrs[0].pszObjId = oid_common_name;
953 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
954 attrs[0].Value.cbData = 0;
955 attrs[0].Value.pbData = (BYTE *)commonNameW;
956 attrs[1].pszObjId = oid_sur_name;
957 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
958 attrs[1].Value.cbData = 0;
959 attrs[1].Value.pbData = (BYTE *)surNameW;
960 rdn.cRDNAttr = 2;
961 rdn.rgRDNAttr = attrs;
962 info.cRDN = 1;
963 info.rgRDN = &rdn;
964 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
965 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
966 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
967 if (ret)
969 ok(!memcmp(buf, twoRDNsNoNull, sizeof(twoRDNsNoNull)),
970 "Got unexpected encoding for two RDN array\n");
971 LocalFree(buf);
973 /* A name can be "encoded" with previously encoded RDN attrs. */
974 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
975 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
976 attrs[0].Value.cbData = sizeof(twoRDNs);
977 rdn.cRDNAttr = 1;
978 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
979 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
980 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
981 if (ret)
983 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %ld\n", size);
984 ok(!memcmp(buf, encodedTwoRDNs, size),
985 "Unexpected value for re-encoded two RDN array\n");
986 LocalFree(buf);
988 /* Unicode names infer the type for CERT_RDN_ANY_TYPE */
989 rdn.cRDNAttr = 1;
990 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
991 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
992 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
993 todo_wine ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
994 if (ret)
996 ok(size == sizeof(anyType), "Unexpected size %ld\n", size);
997 ok(!memcmp(buf, anyType, size), "Unexpected value\n");
998 LocalFree(buf);
1002 static void compareNameValues(const CERT_NAME_VALUE *expected,
1003 const CERT_NAME_VALUE *got)
1005 if (expected->dwValueType == CERT_RDN_UTF8_STRING &&
1006 got->dwValueType == CERT_RDN_ENCODED_BLOB)
1008 win_skip("Can't handle CERT_RDN_UTF8_STRING\n");
1009 return;
1012 ok(got->dwValueType == expected->dwValueType,
1013 "Expected string type %ld, got %ld\n", expected->dwValueType,
1014 got->dwValueType);
1015 ok(got->Value.cbData == expected->Value.cbData ||
1016 got->Value.cbData == expected->Value.cbData - sizeof(WCHAR) /* Win8 */,
1017 "String type %ld: unexpected data size, got %ld, expected %ld\n",
1018 expected->dwValueType, got->Value.cbData, expected->Value.cbData);
1019 if (got->Value.cbData && got->Value.pbData)
1020 ok(!memcmp(got->Value.pbData, expected->Value.pbData,
1021 min(got->Value.cbData, expected->Value.cbData)),
1022 "String type %ld: unexpected value\n", expected->dwValueType);
1025 static void compareRDNAttrs(const CERT_RDN_ATTR *expected,
1026 const CERT_RDN_ATTR *got)
1028 if (expected->pszObjId && *expected->pszObjId)
1030 ok(got->pszObjId != NULL, "Expected OID %s, got NULL\n",
1031 expected->pszObjId);
1032 if (got->pszObjId)
1034 ok(!strcmp(got->pszObjId, expected->pszObjId),
1035 "Got unexpected OID %s, expected %s\n", got->pszObjId,
1036 expected->pszObjId);
1039 compareNameValues((const CERT_NAME_VALUE *)&expected->dwValueType,
1040 (const CERT_NAME_VALUE *)&got->dwValueType);
1043 static void compareRDNs(const CERT_RDN *expected, const CERT_RDN *got)
1045 ok(got->cRDNAttr == expected->cRDNAttr,
1046 "Expected %ld RDN attrs, got %ld\n", expected->cRDNAttr, got->cRDNAttr);
1047 if (got->cRDNAttr)
1049 DWORD i;
1051 for (i = 0; i < got->cRDNAttr; i++)
1052 compareRDNAttrs(&expected->rgRDNAttr[i], &got->rgRDNAttr[i]);
1056 static void compareNames(const CERT_NAME_INFO *expected,
1057 const CERT_NAME_INFO *got)
1059 ok(got->cRDN == expected->cRDN, "Expected %ld RDNs, got %ld\n",
1060 expected->cRDN, got->cRDN);
1061 if (got->cRDN)
1063 DWORD i;
1065 for (i = 0; i < got->cRDN; i++)
1066 compareRDNs(&expected->rgRDN[i], &got->rgRDN[i]);
1070 static const BYTE emptyIndefiniteSequence[] = { 0x30,0x80,0x00,0x00 };
1071 static const BYTE twoRDNsExtraBytes[] = {
1072 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
1073 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1074 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0,0,0,0,0,0};
1076 static void test_decodeName(DWORD dwEncoding)
1078 BYTE *buf = NULL;
1079 DWORD bufSize = 0;
1080 BOOL ret;
1081 CERT_RDN rdn;
1082 CERT_NAME_INFO info = { 1, &rdn };
1084 /* test empty name */
1085 bufSize = 0;
1086 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptySequence,
1087 emptySequence[1] + 2,
1088 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1089 &buf, &bufSize);
1090 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
1091 /* Interestingly, in Windows, if cRDN is 0, rgRGN may not be NULL. My
1092 * decoder works the same way, so only test the count.
1094 if (ret)
1096 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %ld\n", bufSize);
1097 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1098 "Expected 0 RDNs in empty info, got %ld\n",
1099 ((CERT_NAME_INFO *)buf)->cRDN);
1100 LocalFree(buf);
1102 /* test empty name with indefinite-length encoding */
1103 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyIndefiniteSequence,
1104 sizeof(emptyIndefiniteSequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
1105 &buf, &bufSize);
1106 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
1107 if (ret)
1109 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %ld\n", bufSize);
1110 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1111 "Expected 0 RDNs in empty info, got %ld\n",
1112 ((CERT_NAME_INFO *)buf)->cRDN);
1113 LocalFree(buf);
1115 /* test empty RDN */
1116 bufSize = 0;
1117 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyRDNs,
1118 emptyRDNs[1] + 2,
1119 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1120 &buf, &bufSize);
1121 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
1122 if (ret)
1124 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1126 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1127 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1128 "Got unexpected value for empty RDN\n");
1129 LocalFree(buf);
1131 /* test two RDN attrs */
1132 bufSize = 0;
1133 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNs,
1134 twoRDNs[1] + 2,
1135 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1136 &buf, &bufSize);
1137 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
1138 if (ret)
1140 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1141 oid_common_name[] = szOID_COMMON_NAME;
1143 CERT_RDN_ATTR attrs[] = {
1144 { oid_sur_name, CERT_RDN_PRINTABLE_STRING, { sizeof(surName),
1145 (BYTE *)surName } },
1146 { oid_common_name, CERT_RDN_PRINTABLE_STRING, { sizeof(commonName),
1147 (BYTE *)commonName } },
1150 rdn.cRDNAttr = ARRAY_SIZE(attrs);
1151 rdn.rgRDNAttr = attrs;
1152 compareNames(&info, (CERT_NAME_INFO *)buf);
1153 LocalFree(buf);
1155 /* test that two RDN attrs with extra bytes succeeds */
1156 bufSize = 0;
1157 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNsExtraBytes,
1158 sizeof(twoRDNsExtraBytes), 0, NULL, NULL, &bufSize);
1159 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
1160 /* And, a slightly more complicated name */
1161 buf = NULL;
1162 bufSize = 0;
1163 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME, encodedRDNAttrs,
1164 sizeof(encodedRDNAttrs), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1165 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
1166 if (ret)
1168 rdn.cRDNAttr = ARRAY_SIZE(decodedRdnAttrs);
1169 rdn.rgRDNAttr = decodedRdnAttrs;
1170 compareNames(&info, (CERT_NAME_INFO *)buf);
1171 LocalFree(buf);
1175 static void test_decodeUnicodeName(DWORD dwEncoding)
1177 BYTE *buf = NULL;
1178 DWORD bufSize = 0;
1179 BOOL ret;
1180 CERT_RDN rdn;
1181 CERT_NAME_INFO info = { 1, &rdn };
1183 /* test empty name */
1184 bufSize = 0;
1185 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptySequence,
1186 emptySequence[1] + 2,
1187 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1188 &buf, &bufSize);
1189 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
1190 if (ret)
1192 ok(bufSize == sizeof(CERT_NAME_INFO),
1193 "Got wrong bufSize %ld\n", bufSize);
1194 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1195 "Expected 0 RDNs in empty info, got %ld\n",
1196 ((CERT_NAME_INFO *)buf)->cRDN);
1197 LocalFree(buf);
1199 /* test empty RDN */
1200 bufSize = 0;
1201 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptyRDNs,
1202 emptyRDNs[1] + 2,
1203 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1204 &buf, &bufSize);
1205 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
1206 if (ret)
1208 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1210 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1211 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1212 "Got unexpected value for empty RDN\n");
1213 LocalFree(buf);
1215 /* test two RDN attrs */
1216 bufSize = 0;
1217 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, twoRDNsNoNull,
1218 sizeof(twoRDNsNoNull),
1219 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1220 &buf, &bufSize);
1221 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
1222 if (ret)
1224 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1225 oid_common_name[] = szOID_COMMON_NAME;
1227 CERT_RDN_ATTR attrs[] = {
1228 { oid_sur_name, CERT_RDN_PRINTABLE_STRING,
1229 { lstrlenW(surNameW) * sizeof(WCHAR), (BYTE *)surNameW } },
1230 { oid_common_name, CERT_RDN_PRINTABLE_STRING,
1231 { lstrlenW(commonNameW) * sizeof(WCHAR), (BYTE *)commonNameW } },
1234 rdn.cRDNAttr = ARRAY_SIZE(attrs);
1235 rdn.rgRDNAttr = attrs;
1236 compareNames(&info, (CERT_NAME_INFO *)buf);
1237 LocalFree(buf);
1241 struct EncodedNameValue
1243 CERT_NAME_VALUE value;
1244 const BYTE *encoded;
1245 DWORD encodedSize;
1248 static const char bogusIA5[] = "\x80";
1249 static const char bogusPrintable[] = "~";
1250 static const char bogusNumeric[] = "A";
1251 static const BYTE bin42[] = { 0x16,0x02,0x80,0x00 };
1252 static const BYTE bin43[] = { 0x13,0x02,0x7e,0x00 };
1253 static const BYTE bin44[] = { 0x12,0x02,0x41,0x00 };
1254 static BYTE octetCommonNameValue[] = {
1255 0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1256 static BYTE numericCommonNameValue[] = {
1257 0x12,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1258 static BYTE printableCommonNameValue[] = {
1259 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1260 static BYTE t61CommonNameValue[] = {
1261 0x14,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1262 static BYTE videotexCommonNameValue[] = {
1263 0x15,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1264 static BYTE ia5CommonNameValue[] = {
1265 0x16,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1266 static BYTE graphicCommonNameValue[] = {
1267 0x19,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1268 static BYTE visibleCommonNameValue[] = {
1269 0x1a,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1270 static BYTE generalCommonNameValue[] = {
1271 0x1b,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1272 static BYTE bmpCommonNameValue[] = {
1273 0x1e,0x14,0x00,0x4a,0x00,0x75,0x00,0x61,0x00,0x6e,0x00,0x20,0x00,0x4c,0x00,
1274 0x61,0x00,0x6e,0x00,0x67,0x00,0x00 };
1275 static BYTE utf8CommonNameValue[] = {
1276 0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1277 static char embedded_null[] = "foo\0com";
1278 static BYTE ia5EmbeddedNull[] = {
1279 0x16,0x07,0x66,0x6f,0x6f,0x00,0x63,0x6f,0x6d };
1281 static struct EncodedNameValue nameValues[] = {
1282 { { CERT_RDN_OCTET_STRING, { sizeof(commonName), (BYTE *)commonName } },
1283 octetCommonNameValue, sizeof(octetCommonNameValue) },
1284 { { CERT_RDN_NUMERIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1285 numericCommonNameValue, sizeof(numericCommonNameValue) },
1286 { { CERT_RDN_PRINTABLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1287 printableCommonNameValue, sizeof(printableCommonNameValue) },
1288 { { CERT_RDN_T61_STRING, { sizeof(commonName), (BYTE *)commonName } },
1289 t61CommonNameValue, sizeof(t61CommonNameValue) },
1290 { { CERT_RDN_VIDEOTEX_STRING, { sizeof(commonName), (BYTE *)commonName } },
1291 videotexCommonNameValue, sizeof(videotexCommonNameValue) },
1292 { { CERT_RDN_IA5_STRING, { sizeof(commonName), (BYTE *)commonName } },
1293 ia5CommonNameValue, sizeof(ia5CommonNameValue) },
1294 { { CERT_RDN_GRAPHIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1295 graphicCommonNameValue, sizeof(graphicCommonNameValue) },
1296 { { CERT_RDN_VISIBLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1297 visibleCommonNameValue, sizeof(visibleCommonNameValue) },
1298 { { CERT_RDN_GENERAL_STRING, { sizeof(commonName), (BYTE *)commonName } },
1299 generalCommonNameValue, sizeof(generalCommonNameValue) },
1300 { { CERT_RDN_BMP_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1301 bmpCommonNameValue, sizeof(bmpCommonNameValue) },
1302 { { CERT_RDN_UTF8_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1303 utf8CommonNameValue, sizeof(utf8CommonNameValue) },
1304 /* The following tests succeed under Windows, but really should fail,
1305 * they contain characters that are illegal for the encoding. I'm
1306 * including them to justify my lazy encoding.
1308 { { CERT_RDN_IA5_STRING, { sizeof(bogusIA5), (BYTE *)bogusIA5 } }, bin42,
1309 sizeof(bin42) },
1310 { { CERT_RDN_PRINTABLE_STRING, { sizeof(bogusPrintable),
1311 (BYTE *)bogusPrintable } }, bin43, sizeof(bin43) },
1312 { { CERT_RDN_NUMERIC_STRING, { sizeof(bogusNumeric), (BYTE *)bogusNumeric } },
1313 bin44, sizeof(bin44) },
1315 /* This is kept separate, because the decoding doesn't return to the original
1316 * value.
1318 static struct EncodedNameValue embeddedNullNameValue = {
1319 { CERT_RDN_IA5_STRING, { sizeof(embedded_null) - 1, (BYTE *)embedded_null } },
1320 ia5EmbeddedNull, sizeof(ia5EmbeddedNull) };
1322 static void test_encodeNameValue(DWORD dwEncoding)
1324 BYTE *buf = NULL;
1325 DWORD size = 0, i;
1326 BOOL ret;
1327 CERT_NAME_VALUE value = { 0, { 0, NULL } };
1329 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1330 value.Value.pbData = printableCommonNameValue;
1331 value.Value.cbData = sizeof(printableCommonNameValue);
1332 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, &value,
1333 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1334 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
1335 if (ret)
1337 ok(size == sizeof(printableCommonNameValue), "Unexpected size %ld\n",
1338 size);
1339 ok(!memcmp(buf, printableCommonNameValue, size),
1340 "Unexpected encoding\n");
1341 LocalFree(buf);
1343 for (i = 0; i < ARRAY_SIZE(nameValues); i++)
1345 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE,
1346 &nameValues[i].value, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1347 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH) /* NT4/Win9x */,
1348 "Type %ld: CryptEncodeObjectEx failed: %08lx\n",
1349 nameValues[i].value.dwValueType, GetLastError());
1350 if (ret)
1352 ok(size == nameValues[i].encodedSize,
1353 "Expected size %ld, got %ld\n", nameValues[i].encodedSize, size);
1354 ok(!memcmp(buf, nameValues[i].encoded, size),
1355 "Got unexpected encoding\n");
1356 LocalFree(buf);
1359 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE,
1360 &embeddedNullNameValue.value, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1361 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH) /* NT4/Win9x */,
1362 "Type %ld: CryptEncodeObjectEx failed: %08lx\n",
1363 embeddedNullNameValue.value.dwValueType, GetLastError());
1364 if (ret)
1366 ok(size == embeddedNullNameValue.encodedSize,
1367 "Expected size %ld, got %ld\n", embeddedNullNameValue.encodedSize, size);
1368 ok(!memcmp(buf, embeddedNullNameValue.encoded, size),
1369 "Got unexpected encoding\n");
1370 LocalFree(buf);
1374 static void test_decodeNameValue(DWORD dwEncoding)
1376 int i;
1377 BYTE *buf = NULL;
1378 DWORD bufSize = 0;
1379 BOOL ret;
1381 for (i = 0; i < ARRAY_SIZE(nameValues); i++)
1383 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE,
1384 nameValues[i].encoded, nameValues[i].encoded[1] + 2,
1385 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1386 &buf, &bufSize);
1387 ok(ret, "Value type %ld: CryptDecodeObjectEx failed: %08lx\n",
1388 nameValues[i].value.dwValueType, GetLastError());
1389 if (ret)
1391 compareNameValues(&nameValues[i].value,
1392 (const CERT_NAME_VALUE *)buf);
1393 LocalFree(buf);
1396 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE,
1397 embeddedNullNameValue.encoded, embeddedNullNameValue.encodedSize,
1398 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1399 &buf, &bufSize);
1400 /* Some Windows versions disallow name values with embedded NULLs, so
1401 * either success or failure is acceptable.
1403 if (ret)
1405 CERT_NAME_VALUE rdnEncodedValue = { CERT_RDN_ENCODED_BLOB,
1406 { sizeof(ia5EmbeddedNull), ia5EmbeddedNull } };
1407 CERT_NAME_VALUE embeddedNullValue = { CERT_RDN_IA5_STRING,
1408 { sizeof(embedded_null) - 1, (BYTE *)embedded_null } };
1409 const CERT_NAME_VALUE *got = (const CERT_NAME_VALUE *)buf,
1410 *expected = NULL;
1412 /* Some Windows versions decode name values with embedded NULLs,
1413 * others leave them encoded, even with the same version of crypt32.
1414 * Accept either.
1416 ok(got->dwValueType == CERT_RDN_ENCODED_BLOB ||
1417 got->dwValueType == CERT_RDN_IA5_STRING,
1418 "Expected CERT_RDN_ENCODED_BLOB or CERT_RDN_IA5_STRING, got %ld\n",
1419 got->dwValueType);
1420 if (got->dwValueType == CERT_RDN_ENCODED_BLOB)
1421 expected = &rdnEncodedValue;
1422 else if (got->dwValueType == CERT_RDN_IA5_STRING)
1423 expected = &embeddedNullValue;
1424 if (expected)
1426 ok(got->Value.cbData == expected->Value.cbData,
1427 "String type %ld: unexpected data size, got %ld, expected %ld\n",
1428 got->dwValueType, got->Value.cbData, expected->Value.cbData);
1429 if (got->Value.cbData && got->Value.pbData)
1430 ok(!memcmp(got->Value.pbData, expected->Value.pbData,
1431 min(got->Value.cbData, expected->Value.cbData)),
1432 "String type %ld: unexpected value\n", expected->dwValueType);
1434 LocalFree(buf);
1438 static const BYTE emptyURL[] = { 0x30, 0x02, 0x86, 0x00 };
1439 static const BYTE emptyURLExtraBytes[] = { 0x30, 0x02, 0x86, 0x00, 0, 0, 0 };
1440 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e',
1441 'h','q','.','o','r','g',0 };
1442 static const BYTE encodedURL[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74,
1443 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e,
1444 0x6f, 0x72, 0x67 };
1445 static const WCHAR nihongoURL[] = { 'h','t','t','p',':','/','/',0x226f,
1446 0x575b, 0 };
1447 static const WCHAR dnsName[] = { 'w','i','n','e','h','q','.','o','r','g',0 };
1448 static const BYTE encodedDnsName[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69,
1449 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
1450 static const BYTE localhost[] = { 127, 0, 0, 1 };
1451 static const BYTE encodedIPAddr[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00,
1452 0x01 };
1453 static const unsigned char encodedCommonName[] = {
1454 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0};
1455 static const BYTE encodedOidName[] = { 0x30,0x04,0x88,0x02,0x2a,0x03 };
1456 static const BYTE encodedDirectoryName[] = {
1457 0x30,0x19,0xa4,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1458 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1460 static void test_encodeAltName(DWORD dwEncoding)
1462 CERT_ALT_NAME_INFO info = { 0 };
1463 CERT_ALT_NAME_ENTRY entry = { 0 };
1464 BYTE *buf = NULL;
1465 DWORD size = 0;
1466 BOOL ret;
1467 char oid[] = "1.2.3";
1469 /* Test with empty info */
1470 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1471 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1472 if (ret)
1474 ok(size == sizeof(emptySequence), "Wrong size %ld\n", size);
1475 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
1476 LocalFree(buf);
1478 /* Test with an empty entry */
1479 info.cAltEntry = 1;
1480 info.rgAltEntry = &entry;
1481 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1482 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1483 ok(!ret && GetLastError() == E_INVALIDARG,
1484 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
1485 /* Test with an empty pointer */
1486 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
1487 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1488 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1489 if (ret)
1491 ok(size == sizeof(emptyURL), "Wrong size %ld\n", size);
1492 ok(!memcmp(buf, emptyURL, size), "Unexpected value\n");
1493 LocalFree(buf);
1495 /* Test with a real URL */
1496 U(entry).pwszURL = (LPWSTR)url;
1497 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1498 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1499 if (ret)
1501 ok(size == sizeof(encodedURL), "Wrong size %ld\n", size);
1502 ok(!memcmp(buf, encodedURL, size), "Unexpected value\n");
1503 LocalFree(buf);
1505 /* Now with the URL containing an invalid IA5 char */
1506 U(entry).pwszURL = (LPWSTR)nihongoURL;
1507 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1508 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1509 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
1510 "Expected CRYPT_E_INVALID_IA5_STRING, got %08lx\n", GetLastError());
1511 /* The first invalid character is at index 7 */
1512 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
1513 "Expected invalid char at index 7, got %ld\n",
1514 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
1515 /* Now with the URL missing a scheme */
1516 U(entry).pwszURL = (LPWSTR)dnsName;
1517 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1518 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1519 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
1520 if (ret)
1522 /* This succeeds, but it shouldn't, so don't worry about conforming */
1523 LocalFree(buf);
1525 /* Now with a DNS name */
1526 entry.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
1527 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1528 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1529 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
1530 if (ret)
1532 ok(size == sizeof(encodedDnsName), "Wrong size %ld\n", size);
1533 ok(!memcmp(buf, encodedDnsName, size), "Unexpected value\n");
1534 LocalFree(buf);
1536 /* Test with an IP address */
1537 entry.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
1538 U(entry).IPAddress.cbData = sizeof(localhost);
1539 U(entry).IPAddress.pbData = (LPBYTE)localhost;
1540 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1541 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1542 if (ret)
1544 ok(size == sizeof(encodedIPAddr), "Wrong size %ld\n", size);
1545 ok(!memcmp(buf, encodedIPAddr, size), "Unexpected value\n");
1546 LocalFree(buf);
1548 /* Test with OID */
1549 entry.dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID;
1550 U(entry).pszRegisteredID = oid;
1551 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1552 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1553 if (ret)
1555 ok(size == sizeof(encodedOidName), "Wrong size %ld\n", size);
1556 ok(!memcmp(buf, encodedOidName, size), "Unexpected value\n");
1557 LocalFree(buf);
1559 /* Test with directory name */
1560 entry.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
1561 U(entry).DirectoryName.cbData = sizeof(encodedCommonName);
1562 U(entry).DirectoryName.pbData = (LPBYTE)encodedCommonName;
1563 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1564 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1565 if (ret)
1567 ok(size == sizeof(encodedDirectoryName), "Wrong size %ld\n", size);
1568 ok(!memcmp(buf, encodedDirectoryName, size), "Unexpected value\n");
1569 LocalFree(buf);
1573 static void test_decodeAltName(DWORD dwEncoding)
1575 static const BYTE unimplementedType[] = { 0x30, 0x06, 0x85, 0x04, 0x7f,
1576 0x00, 0x00, 0x01 };
1577 static const BYTE bogusType[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00,
1578 0x01 };
1579 static const BYTE dns_embedded_null[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f,
1580 0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 };
1581 static const BYTE dns_embedded_bell[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f,
1582 0x6f,0x2e,0x63,0x6f,0x6d,0x07,0x62,0x61,0x64,0x64,0x69,0x65 };
1583 static const BYTE url_embedded_null[] = { 0x30,0x10,0x86,0x0e,0x66,0x6f,
1584 0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 };
1585 BOOL ret;
1586 BYTE *buf = NULL;
1587 DWORD bufSize = 0;
1588 CERT_ALT_NAME_INFO *info;
1590 /* Test some bogus ones first */
1591 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1592 unimplementedType, sizeof(unimplementedType), CRYPT_DECODE_ALLOC_FLAG,
1593 NULL, &buf, &bufSize);
1594 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
1595 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1596 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08lx\n",
1597 GetLastError());
1598 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1599 bogusType, sizeof(bogusType), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
1600 &bufSize);
1601 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
1602 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1603 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08lx\n",
1604 GetLastError());
1605 /* Now expected cases */
1606 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptySequence,
1607 emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1608 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
1609 if (ret)
1611 info = (CERT_ALT_NAME_INFO *)buf;
1613 ok(info->cAltEntry == 0, "Expected 0 entries, got %ld\n",
1614 info->cAltEntry);
1615 LocalFree(buf);
1617 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptyURL,
1618 emptyURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1619 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
1620 if (ret)
1622 info = (CERT_ALT_NAME_INFO *)buf;
1624 ok(info->cAltEntry == 1, "Expected 1 entries, got %ld\n",
1625 info->cAltEntry);
1626 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1627 "Expected CERT_ALT_NAME_URL, got %ld\n",
1628 info->rgAltEntry[0].dwAltNameChoice);
1629 ok(U(info->rgAltEntry[0]).pwszURL == NULL || !*U(info->rgAltEntry[0]).pwszURL,
1630 "Expected empty URL\n");
1631 LocalFree(buf);
1633 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1634 emptyURLExtraBytes, sizeof(emptyURLExtraBytes), 0, NULL, NULL, &bufSize);
1635 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
1636 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedURL,
1637 encodedURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1638 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
1639 if (ret)
1641 info = (CERT_ALT_NAME_INFO *)buf;
1643 ok(info->cAltEntry == 1, "Expected 1 entries, got %ld\n",
1644 info->cAltEntry);
1645 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1646 "Expected CERT_ALT_NAME_URL, got %ld\n",
1647 info->rgAltEntry[0].dwAltNameChoice);
1648 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszURL, url), "Unexpected URL\n");
1649 LocalFree(buf);
1651 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedDnsName,
1652 encodedDnsName[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1653 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
1654 if (ret)
1656 info = (CERT_ALT_NAME_INFO *)buf;
1658 ok(info->cAltEntry == 1, "Expected 1 entries, got %ld\n",
1659 info->cAltEntry);
1660 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1661 "Expected CERT_ALT_NAME_DNS_NAME, got %ld\n",
1662 info->rgAltEntry[0].dwAltNameChoice);
1663 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszDNSName, dnsName),
1664 "Unexpected DNS name\n");
1665 LocalFree(buf);
1667 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedIPAddr,
1668 encodedIPAddr[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1669 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
1670 if (ret)
1672 info = (CERT_ALT_NAME_INFO *)buf;
1674 ok(info->cAltEntry == 1, "Expected 1 entries, got %ld\n",
1675 info->cAltEntry);
1676 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS,
1677 "Expected CERT_ALT_NAME_IP_ADDRESS, got %ld\n",
1678 info->rgAltEntry[0].dwAltNameChoice);
1679 ok(U(info->rgAltEntry[0]).IPAddress.cbData == sizeof(localhost),
1680 "Unexpected IP address length %ld\n",
1681 U(info->rgAltEntry[0]).IPAddress.cbData);
1682 ok(!memcmp(U(info->rgAltEntry[0]).IPAddress.pbData, localhost,
1683 sizeof(localhost)), "Unexpected IP address value\n");
1684 LocalFree(buf);
1686 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedOidName,
1687 sizeof(encodedOidName), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1688 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
1689 if (ret)
1691 info = (CERT_ALT_NAME_INFO *)buf;
1693 ok(info->cAltEntry == 1, "Expected 1 entries, got %ld\n",
1694 info->cAltEntry);
1695 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_REGISTERED_ID,
1696 "Expected CERT_ALT_NAME_REGISTERED_ID, got %ld\n",
1697 info->rgAltEntry[0].dwAltNameChoice);
1698 ok(!strcmp(U(info->rgAltEntry[0]).pszRegisteredID, "1.2.3"),
1699 "Expected OID 1.2.3, got %s\n", U(info->rgAltEntry[0]).pszRegisteredID);
1700 LocalFree(buf);
1702 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1703 encodedDirectoryName, sizeof(encodedDirectoryName),
1704 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1705 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
1706 if (ret)
1708 info = (CERT_ALT_NAME_INFO *)buf;
1710 ok(info->cAltEntry == 1, "Expected 1 entries, got %ld\n",
1711 info->cAltEntry);
1712 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME,
1713 "Expected CERT_ALT_NAME_DIRECTORY_NAME, got %ld\n",
1714 info->rgAltEntry[0].dwAltNameChoice);
1715 ok(U(info->rgAltEntry[0]).DirectoryName.cbData ==
1716 sizeof(encodedCommonName), "Unexpected directory name length %ld\n",
1717 U(info->rgAltEntry[0]).DirectoryName.cbData);
1718 ok(!memcmp(U(info->rgAltEntry[0]).DirectoryName.pbData,
1719 encodedCommonName, sizeof(encodedCommonName)),
1720 "Unexpected directory name value\n");
1721 LocalFree(buf);
1723 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1724 dns_embedded_null, sizeof(dns_embedded_null), CRYPT_DECODE_ALLOC_FLAG,
1725 NULL, &buf, &bufSize);
1726 /* Fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned about the
1727 * particular failure, just that it doesn't decode.
1728 * It succeeds on (broken) Windows versions that haven't addressed
1729 * embedded NULLs in alternate names.
1731 ok(!ret || broken(ret), "expected failure\n");
1732 /* An embedded bell character is allowed, however. */
1733 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1734 dns_embedded_bell, sizeof(dns_embedded_bell), CRYPT_DECODE_ALLOC_FLAG,
1735 NULL, &buf, &bufSize);
1736 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
1737 if (ret)
1739 info = (CERT_ALT_NAME_INFO *)buf;
1741 ok(info->cAltEntry == 1, "Expected 1 entries, got %ld\n",
1742 info->cAltEntry);
1743 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1744 "Expected CERT_ALT_NAME_DNS_NAME, got %ld\n",
1745 info->rgAltEntry[0].dwAltNameChoice);
1746 LocalFree(buf);
1748 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1749 url_embedded_null, sizeof(dns_embedded_null), CRYPT_DECODE_ALLOC_FLAG,
1750 NULL, &buf, &bufSize);
1751 /* Again, fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned
1752 * about the particular failure, just that it doesn't decode.
1753 * It succeeds on (broken) Windows versions that haven't addressed
1754 * embedded NULLs in alternate names.
1756 ok(!ret || broken(ret), "expected failure\n");
1759 struct UnicodeExpectedError
1761 DWORD valueType;
1762 LPCWSTR str;
1763 DWORD errorIndex;
1764 DWORD error;
1767 static const WCHAR oneW[] = { '1',0 };
1768 static const WCHAR aW[] = { 'a',0 };
1769 static const WCHAR quoteW[] = { '"', 0 };
1771 static struct UnicodeExpectedError unicodeErrors[] = {
1772 { CERT_RDN_ANY_TYPE, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1773 { CERT_RDN_ENCODED_BLOB, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1774 { CERT_RDN_OCTET_STRING, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1775 { CERT_RDN_NUMERIC_STRING, aW, 0, CRYPT_E_INVALID_NUMERIC_STRING },
1776 { CERT_RDN_PRINTABLE_STRING, quoteW, 0, CRYPT_E_INVALID_PRINTABLE_STRING },
1777 { CERT_RDN_IA5_STRING, nihongoURL, 7, CRYPT_E_INVALID_IA5_STRING },
1780 struct UnicodeExpectedResult
1782 DWORD valueType;
1783 LPCWSTR str;
1784 CRYPT_DATA_BLOB encoded;
1787 static BYTE oneNumeric[] = { 0x12, 0x01, 0x31 };
1788 static BYTE onePrintable[] = { 0x13, 0x01, 0x31 };
1789 static BYTE oneTeletex[] = { 0x14, 0x01, 0x31 };
1790 static BYTE oneVideotex[] = { 0x15, 0x01, 0x31 };
1791 static BYTE oneIA5[] = { 0x16, 0x01, 0x31 };
1792 static BYTE oneGraphic[] = { 0x19, 0x01, 0x31 };
1793 static BYTE oneVisible[] = { 0x1a, 0x01, 0x31 };
1794 static BYTE oneUniversal[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 };
1795 static BYTE oneGeneral[] = { 0x1b, 0x01, 0x31 };
1796 static BYTE oneBMP[] = { 0x1e, 0x02, 0x00, 0x31 };
1797 static BYTE oneUTF8[] = { 0x0c, 0x01, 0x31 };
1798 static BYTE nihongoT61[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,
1799 0x5b };
1800 static BYTE nihongoGeneral[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1801 0x6f,0x5b };
1802 static BYTE nihongoBMP[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,
1803 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
1804 static BYTE nihongoUTF8[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1805 0xe2,0x89,0xaf,0xe5,0x9d,0x9b };
1807 static struct UnicodeExpectedResult unicodeResults[] = {
1808 { CERT_RDN_NUMERIC_STRING, oneW, { sizeof(oneNumeric), oneNumeric } },
1809 { CERT_RDN_PRINTABLE_STRING, oneW, { sizeof(onePrintable), onePrintable } },
1810 { CERT_RDN_TELETEX_STRING, oneW, { sizeof(oneTeletex), oneTeletex } },
1811 { CERT_RDN_VIDEOTEX_STRING, oneW, { sizeof(oneVideotex), oneVideotex } },
1812 { CERT_RDN_IA5_STRING, oneW, { sizeof(oneIA5), oneIA5 } },
1813 { CERT_RDN_GRAPHIC_STRING, oneW, { sizeof(oneGraphic), oneGraphic } },
1814 { CERT_RDN_VISIBLE_STRING, oneW, { sizeof(oneVisible), oneVisible } },
1815 { CERT_RDN_UNIVERSAL_STRING, oneW, { sizeof(oneUniversal), oneUniversal } },
1816 { CERT_RDN_GENERAL_STRING, oneW, { sizeof(oneGeneral), oneGeneral } },
1817 { CERT_RDN_BMP_STRING, oneW, { sizeof(oneBMP), oneBMP } },
1818 { CERT_RDN_UTF8_STRING, oneW, { sizeof(oneUTF8), oneUTF8 } },
1819 { CERT_RDN_BMP_STRING, nihongoURL, { sizeof(nihongoBMP), nihongoBMP } },
1820 { CERT_RDN_UTF8_STRING, nihongoURL, { sizeof(nihongoUTF8), nihongoUTF8 } },
1823 static struct UnicodeExpectedResult unicodeWeirdness[] = {
1824 { CERT_RDN_TELETEX_STRING, nihongoURL, { sizeof(nihongoT61), nihongoT61 } },
1825 { CERT_RDN_GENERAL_STRING, nihongoURL, { sizeof(nihongoGeneral), nihongoGeneral } },
1828 static void test_encodeUnicodeNameValue(DWORD dwEncoding)
1830 BYTE *buf = NULL;
1831 DWORD size = 0, i;
1832 BOOL ret;
1833 CERT_NAME_VALUE value;
1835 if (0)
1837 /* Crashes on win9x */
1838 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, NULL,
1839 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1840 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1841 "Expected STATUS_ACCESS_VIOLATION, got %08lx\n", GetLastError());
1843 /* Have to have a string of some sort */
1844 value.dwValueType = 0; /* aka CERT_RDN_ANY_TYPE */
1845 value.Value.pbData = NULL;
1846 value.Value.cbData = 0;
1847 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1848 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1849 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1850 "Expected CRYPT_E_NOT_CHAR_STRING, got %08lx\n", GetLastError());
1851 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1852 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1853 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1854 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1855 "Expected CRYPT_E_NOT_CHAR_STRING, got %08lx\n", GetLastError());
1856 value.dwValueType = CERT_RDN_ANY_TYPE;
1857 value.Value.pbData = (LPBYTE)oneW;
1858 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1859 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1860 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1861 "Expected CRYPT_E_NOT_CHAR_STRING, got %08lx\n", GetLastError());
1862 value.Value.cbData = sizeof(oneW);
1863 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1864 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1865 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1866 "Expected CRYPT_E_NOT_CHAR_STRING, got %08lx\n", GetLastError());
1867 /* An encoded string with specified length isn't good enough either */
1868 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1869 value.Value.pbData = oneUniversal;
1870 value.Value.cbData = sizeof(oneUniversal);
1871 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1872 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1873 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1874 "Expected CRYPT_E_NOT_CHAR_STRING, got %08lx\n", GetLastError());
1875 /* More failure checking */
1876 value.Value.cbData = 0;
1877 for (i = 0; i < ARRAY_SIZE(unicodeErrors); i++)
1879 value.Value.pbData = (LPBYTE)unicodeErrors[i].str;
1880 value.dwValueType = unicodeErrors[i].valueType;
1881 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1882 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1883 ok(!ret && GetLastError() == unicodeErrors[i].error,
1884 "Value type %ld: expected %08lx, got %08lx\n", value.dwValueType,
1885 unicodeErrors[i].error, GetLastError());
1886 ok(size == unicodeErrors[i].errorIndex,
1887 "Expected error index %ld, got %ld\n", unicodeErrors[i].errorIndex,
1888 size);
1890 /* cbData can be zero if the string is NULL-terminated */
1891 value.Value.cbData = 0;
1892 for (i = 0; i < ARRAY_SIZE(unicodeResults); i++)
1894 value.Value.pbData = (LPBYTE)unicodeResults[i].str;
1895 value.dwValueType = unicodeResults[i].valueType;
1896 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1897 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1898 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
1899 "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
1900 if (ret)
1902 ok(size == unicodeResults[i].encoded.cbData,
1903 "Value type %ld: expected size %ld, got %ld\n",
1904 value.dwValueType, unicodeResults[i].encoded.cbData, size);
1905 ok(!memcmp(unicodeResults[i].encoded.pbData, buf, size),
1906 "Value type %ld: unexpected value\n", value.dwValueType);
1907 LocalFree(buf);
1910 /* These "encode," but they do so by truncating each unicode character
1911 * rather than properly encoding it. Kept separate from the proper results,
1912 * because the encoded forms won't decode to their original strings.
1914 for (i = 0; i < ARRAY_SIZE(unicodeWeirdness); i++)
1916 value.Value.pbData = (LPBYTE)unicodeWeirdness[i].str;
1917 value.dwValueType = unicodeWeirdness[i].valueType;
1918 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1919 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1920 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
1921 if (ret)
1923 ok(size == unicodeWeirdness[i].encoded.cbData,
1924 "Value type %ld: expected size %ld, got %ld\n",
1925 value.dwValueType, unicodeWeirdness[i].encoded.cbData, size);
1926 ok(!memcmp(unicodeWeirdness[i].encoded.pbData, buf, size),
1927 "Value type %ld: unexpected value\n", value.dwValueType);
1928 LocalFree(buf);
1933 static void test_decodeUnicodeNameValue(DWORD dwEncoding)
1935 DWORD i;
1937 for (i = 0; i < ARRAY_SIZE(unicodeResults); i++)
1939 BYTE *buf = NULL;
1940 BOOL ret;
1941 DWORD size = 0;
1943 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE,
1944 unicodeResults[i].encoded.pbData, unicodeResults[i].encoded.cbData,
1945 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
1946 ok(ret || broken(GetLastError() == CRYPT_E_NOT_CHAR_STRING /* Win9x */),
1947 "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
1948 if (ret && buf)
1950 PCERT_NAME_VALUE value = (PCERT_NAME_VALUE)buf;
1952 ok(value->dwValueType == unicodeResults[i].valueType,
1953 "Expected value type %ld, got %ld\n", unicodeResults[i].valueType,
1954 value->dwValueType);
1955 ok(!wcsncmp((LPWSTR)value->Value.pbData, unicodeResults[i].str,
1956 value->Value.cbData / sizeof(WCHAR)),
1957 "Unexpected decoded value for index %ld (value type %ld)\n", i,
1958 unicodeResults[i].valueType);
1959 LocalFree(buf);
1964 static const unsigned char decoded_hi_octet[] = { 'h','i' };
1965 static const unsigned char encoded_hi_octet[] = { ASN_OCTETSTRING,2,'h','i' };
1966 static const unsigned char decoded_something_long_octet[] = {
1967 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g' };
1968 static const unsigned char encoded_something_long_octet[] = {
1969 ASN_OCTETSTRING,15,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g' };
1970 static const unsigned char encoded_empty_octet[] = { ASN_OCTETSTRING,0 };
1972 static void test_encodeOctets(DWORD dwEncoding)
1974 CRYPT_DATA_BLOB blob;
1975 DWORD i;
1977 static const struct {
1978 const BYTE *decoded;
1979 UINT decoded_size;
1980 const BYTE *encoded;
1981 UINT encoded_size;
1982 } tests[] = {
1984 decoded_hi_octet, sizeof(decoded_hi_octet),
1985 encoded_hi_octet, sizeof(encoded_hi_octet)
1987 decoded_something_long_octet, sizeof(decoded_something_long_octet),
1988 encoded_something_long_octet, sizeof(encoded_something_long_octet)
1990 encoded_empty_octet, 0,
1991 encoded_empty_octet, sizeof(encoded_empty_octet)
1995 for (i = 0; i < ARRAY_SIZE(tests); i++)
1997 BYTE *buf = NULL;
1998 BOOL ret;
1999 DWORD bufSize = 0;
2001 blob.cbData = tests[i].decoded_size;
2002 blob.pbData = (BYTE*)tests[i].decoded;
2003 ret = pCryptEncodeObjectEx(dwEncoding, X509_OCTET_STRING, &blob,
2004 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2005 ok(ret, "CryptEncodeObjectEx failed: %ld\n", GetLastError());
2006 if (ret)
2008 ok(bufSize == tests[i].encoded_size, "[%lu] buf size %lu expected %u\n",
2009 i, bufSize, tests[i].encoded_size);
2010 ok(buf[0] == 4, "Got unexpected type %d for octet string (expected 4)\n", buf[0]);
2011 ok(buf[1] == tests[i].decoded_size, "[%lu] Got length %d, expected %d\n",
2012 i, buf[1], tests[i].decoded_size);
2013 ok(!memcmp(buf, tests[i].encoded, tests[i].encoded_size), "[%lu] Got unexpected value\n", i);
2014 LocalFree(buf);
2019 static const unsigned char encoded_constructed_hi_octet[] =
2020 { ASN_CONSTRUCTOR|ASN_OCTETSTRING,0x80, ASN_OCTETSTRING,2,'h','i', 0,0 };
2021 static const unsigned char encoded_constructed_hi_octet2[] =
2022 { ASN_CONSTRUCTOR|ASN_OCTETSTRING,4, ASN_OCTETSTRING,2,'h','i', 1,2,3 };
2023 static const unsigned char encoded_constructed_hi_octet3[] =
2024 { ASN_CONSTRUCTOR|ASN_OCTETSTRING,8, ASN_CONSTRUCTOR|ASN_OCTETSTRING,0x80, ASN_OCTETSTRING,2,'h','i', 0,0, 0,0 };
2025 static const unsigned char encoded_constructed_hi_octet_invalid_end[] =
2026 { ASN_CONSTRUCTOR|ASN_OCTETSTRING,0x80, ASN_OCTETSTRING,2,'h','i', 0,1 };
2028 static void test_decodeOctets(DWORD dwEncoding)
2030 DWORD i;
2032 static const struct {
2033 const BYTE *encoded;
2034 UINT encoded_size;
2035 const BYTE *decoded;
2036 UINT decoded_size;
2037 DWORD error;
2038 } tests[] = {
2040 encoded_hi_octet, sizeof(encoded_hi_octet),
2041 decoded_hi_octet, sizeof(decoded_hi_octet)
2043 encoded_something_long_octet, sizeof(encoded_something_long_octet),
2044 decoded_something_long_octet, sizeof(decoded_something_long_octet)
2046 encoded_constructed_hi_octet, sizeof(encoded_constructed_hi_octet),
2047 decoded_hi_octet, sizeof(decoded_hi_octet)
2049 encoded_constructed_hi_octet2, sizeof(encoded_constructed_hi_octet2),
2050 decoded_hi_octet, sizeof(decoded_hi_octet)
2052 encoded_constructed_hi_octet3, sizeof(encoded_constructed_hi_octet3),
2053 decoded_hi_octet, sizeof(decoded_hi_octet)
2055 encoded_empty_octet, sizeof(encoded_empty_octet),
2056 encoded_empty_octet, 0
2058 encoded_hi_octet, sizeof(encoded_hi_octet) - 1,
2059 NULL, 0, CRYPT_E_ASN1_EOD
2061 encoded_constructed_hi_octet, sizeof(encoded_constructed_hi_octet) - 1,
2062 NULL, 0, CRYPT_E_ASN1_EOD
2064 encoded_constructed_hi_octet_invalid_end, sizeof(encoded_constructed_hi_octet_invalid_end),
2065 NULL, 0, CRYPT_E_ASN1_CORRUPT
2069 for (i = 0; i < ARRAY_SIZE(tests); i++)
2071 BYTE *buf = NULL;
2072 BOOL ret;
2073 DWORD bufSize = 0;
2075 ret = pCryptDecodeObjectEx(dwEncoding, X509_OCTET_STRING,
2076 tests[i].encoded, tests[i].encoded_size,
2077 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2078 if (tests[i].error)
2080 ok(!ret && GetLastError() == tests[i].error,
2081 "[%lu] CryptDecodeObjectEx returned %x(%lx)\n", i, ret, GetLastError());
2082 continue;
2084 ok(ret, "[%lu] CryptDecodeObjectEx failed: %08lx\n", i, GetLastError());
2085 ok(bufSize >= sizeof(CRYPT_DATA_BLOB) + tests[i].decoded_size,
2086 "[%lu] Expected size >= %d, got %ld\n", i,
2087 (int)sizeof(CRYPT_DATA_BLOB) + tests[i].decoded_size, bufSize);
2088 ok(buf != NULL, "Expected allocated buffer\n");
2089 if (ret)
2091 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)buf;
2093 ok (blob->cbData == tests[i].decoded_size, "[%lu] cbData = %lu\n", i, blob->cbData);
2094 if (blob->cbData)
2095 ok(!memcmp(blob->pbData, tests[i].decoded, blob->cbData),
2096 "Unexpected value\n");
2097 LocalFree(buf);
2102 static const BYTE bytesToEncode[] = { 0xff, 0xff };
2104 struct encodedBits
2106 DWORD cUnusedBits;
2107 const BYTE *encoded;
2108 DWORD cbDecoded;
2109 const BYTE *decoded;
2112 static const unsigned char bin52[] = { 0x03,0x03,0x00,0xff,0xff };
2113 static const unsigned char bin53[] = { 0xff,0xff };
2114 static const unsigned char bin54[] = { 0x03,0x03,0x01,0xff,0xfe };
2115 static const unsigned char bin55[] = { 0xff,0xfe };
2116 static const unsigned char bin56[] = { 0x03,0x02,0x01,0xfe };
2117 static const unsigned char bin57[] = { 0xfe };
2119 static const struct encodedBits bits[] = {
2120 /* normal test cases */
2121 { 0, bin52, 2, bin53 },
2122 { 1, bin54, 2, bin55 },
2123 /* strange test case, showing cUnusedBits >= 8 is allowed */
2124 { 9, bin56, 1, bin57 },
2127 static void test_encodeBits(DWORD dwEncoding)
2129 DWORD i;
2131 for (i = 0; i < ARRAY_SIZE(bits); i++)
2133 CRYPT_BIT_BLOB blob;
2134 BOOL ret;
2135 BYTE *buf = NULL;
2136 DWORD bufSize = 0;
2138 blob.cbData = sizeof(bytesToEncode);
2139 blob.pbData = (BYTE *)bytesToEncode;
2140 blob.cUnusedBits = bits[i].cUnusedBits;
2141 ret = pCryptEncodeObjectEx(dwEncoding, X509_BITS, &blob,
2142 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2143 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
2144 if (ret)
2146 ok(bufSize == bits[i].encoded[1] + 2,
2147 "%ld: Got unexpected size %ld, expected %d\n", i, bufSize,
2148 bits[i].encoded[1] + 2);
2149 ok(!memcmp(buf, bits[i].encoded, bits[i].encoded[1] + 2),
2150 "%ld: Unexpected value\n", i);
2151 LocalFree(buf);
2156 static void test_decodeBits(DWORD dwEncoding)
2158 static const BYTE ber[] = "\x03\x02\x01\xff";
2159 static const BYTE berDecoded = 0xfe;
2160 DWORD i;
2161 BOOL ret;
2162 BYTE *buf = NULL;
2163 DWORD bufSize = 0;
2165 /* normal cases */
2166 for (i = 0; i < ARRAY_SIZE(bits); i++)
2168 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, bits[i].encoded,
2169 bits[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
2170 &bufSize);
2171 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
2172 if (ret)
2174 CRYPT_BIT_BLOB *blob;
2176 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + bits[i].cbDecoded,
2177 "Got unexpected size %ld\n", bufSize);
2178 blob = (CRYPT_BIT_BLOB *)buf;
2179 ok(blob->cbData == bits[i].cbDecoded,
2180 "Got unexpected length %ld, expected %ld\n", blob->cbData,
2181 bits[i].cbDecoded);
2182 if (blob->cbData && bits[i].cbDecoded)
2183 ok(!memcmp(blob->pbData, bits[i].decoded, bits[i].cbDecoded),
2184 "Unexpected value\n");
2185 LocalFree(buf);
2188 /* special case: check that something that's valid in BER but not in DER
2189 * decodes successfully
2191 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, ber, ber[1] + 2,
2192 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2193 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
2194 if (ret)
2196 CRYPT_BIT_BLOB *blob;
2198 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + sizeof(berDecoded),
2199 "Got unexpected size %ld\n", bufSize);
2200 blob = (CRYPT_BIT_BLOB *)buf;
2201 ok(blob->cbData == sizeof(berDecoded),
2202 "Got unexpected length %ld\n", blob->cbData);
2203 if (blob->cbData)
2204 ok(*blob->pbData == berDecoded, "Unexpected value\n");
2205 LocalFree(buf);
2209 struct Constraints2
2211 CERT_BASIC_CONSTRAINTS2_INFO info;
2212 const BYTE *encoded;
2215 static const unsigned char bin59[] = { 0x30,0x00 };
2216 static const unsigned char bin60[] = { 0x30,0x03,0x01,0x01,0xff };
2217 static const unsigned char bin61[] = { 0x30,0x03,0x02,0x01,0x00 };
2218 static const unsigned char bin62[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2219 static const struct Constraints2 constraints2[] = {
2220 /* empty constraints */
2221 { { FALSE, FALSE, 0}, bin59 },
2222 /* can be a CA */
2223 { { TRUE, FALSE, 0}, bin60 },
2224 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well,
2225 * but that's not the case
2227 { { FALSE, TRUE, 0}, bin61 },
2228 /* can be a CA and has path length constraints set */
2229 { { TRUE, TRUE, 1}, bin62 },
2232 static const BYTE emptyConstraint[] = { 0x30, 0x03, 0x03, 0x01, 0x00 };
2233 static const BYTE encodedDomainName[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11,
2234 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
2235 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
2236 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2237 static const BYTE constraintWithDomainName[] = { 0x30, 0x32, 0x03, 0x01, 0x00,
2238 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
2239 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30,
2240 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
2241 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2243 static void test_encodeBasicConstraints(DWORD dwEncoding)
2245 DWORD i, bufSize = 0;
2246 CERT_BASIC_CONSTRAINTS_INFO info = { { 0 } };
2247 CERT_NAME_BLOB nameBlob = { sizeof(encodedDomainName),
2248 (LPBYTE)encodedDomainName };
2249 BOOL ret;
2250 BYTE *buf = NULL;
2252 /* First test with the simpler info2 */
2253 for (i = 0; i < ARRAY_SIZE(constraints2); i++)
2255 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2256 &constraints2[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf,
2257 &bufSize);
2258 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
2259 if (ret)
2261 ok(bufSize == constraints2[i].encoded[1] + 2,
2262 "Expected %d bytes, got %ld\n", constraints2[i].encoded[1] + 2,
2263 bufSize);
2264 ok(!memcmp(buf, constraints2[i].encoded,
2265 constraints2[i].encoded[1] + 2), "Unexpected value\n");
2266 LocalFree(buf);
2269 /* Now test with more complex basic constraints */
2270 info.SubjectType.cbData = 0;
2271 info.fPathLenConstraint = FALSE;
2272 info.cSubtreesConstraint = 0;
2273 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2274 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2275 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2276 "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
2277 if (ret)
2279 ok(bufSize == sizeof(emptyConstraint), "Wrong size %ld\n", bufSize);
2280 ok(!memcmp(buf, emptyConstraint, sizeof(emptyConstraint)),
2281 "Unexpected value\n");
2282 LocalFree(buf);
2284 /* None of the certs I examined had any subtree constraint, but I test one
2285 * anyway just in case.
2287 info.cSubtreesConstraint = 1;
2288 info.rgSubtreesConstraint = &nameBlob;
2289 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2290 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2291 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2292 "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
2293 if (ret)
2295 ok(bufSize == sizeof(constraintWithDomainName), "Wrong size %ld\n", bufSize);
2296 ok(!memcmp(buf, constraintWithDomainName,
2297 sizeof(constraintWithDomainName)), "Unexpected value\n");
2298 LocalFree(buf);
2300 /* FIXME: test encoding with subject type. */
2303 static const unsigned char bin63[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 };
2305 static void test_decodeBasicConstraints(DWORD dwEncoding)
2307 static const BYTE inverted[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01,
2308 0xff };
2309 static const struct Constraints2 badBool = { { TRUE, TRUE, 1 }, bin63 };
2310 DWORD i;
2311 BOOL ret;
2312 BYTE *buf = NULL;
2313 DWORD bufSize = 0;
2315 /* First test with simpler info2 */
2316 for (i = 0; i < ARRAY_SIZE(constraints2); i++)
2318 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2319 constraints2[i].encoded, constraints2[i].encoded[1] + 2,
2320 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2321 ok(ret, "CryptDecodeObjectEx failed for item %ld: %08lx\n", i,
2322 GetLastError());
2323 if (ret)
2325 CERT_BASIC_CONSTRAINTS2_INFO *info =
2326 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2328 ok(!memcmp(info, &constraints2[i].info, sizeof(*info)),
2329 "Unexpected value for item %ld\n", i);
2330 LocalFree(buf);
2333 /* Check with the order of encoded elements inverted */
2334 buf = (PBYTE)1;
2335 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2336 inverted, inverted[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
2337 &bufSize);
2338 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2339 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2340 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08lx\n",
2341 GetLastError());
2342 ok(!buf, "Expected buf to be set to NULL\n");
2343 /* Check with a non-DER bool */
2344 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2345 badBool.encoded, badBool.encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2346 &buf, &bufSize);
2347 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
2348 if (ret)
2350 CERT_BASIC_CONSTRAINTS2_INFO *info =
2351 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2353 ok(!memcmp(info, &badBool.info, sizeof(*info)), "Unexpected value\n");
2354 LocalFree(buf);
2356 /* Check with a non-basic constraints value */
2357 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2358 encodedCommonName, encodedCommonName[1] + 2,
2359 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2360 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2361 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2362 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08lx\n",
2363 GetLastError());
2364 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */
2365 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2366 emptyConstraint, sizeof(emptyConstraint), CRYPT_DECODE_ALLOC_FLAG, NULL,
2367 &buf, &bufSize);
2368 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
2369 if (ret)
2371 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2373 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2374 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2375 ok(info->cSubtreesConstraint == 0, "Expected no subtree constraints\n");
2376 LocalFree(buf);
2378 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2379 constraintWithDomainName, sizeof(constraintWithDomainName),
2380 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2381 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
2382 if (ret)
2384 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2386 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2387 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2388 ok(info->cSubtreesConstraint == 1, "Expected a subtree constraint\n");
2389 if (info->cSubtreesConstraint && info->rgSubtreesConstraint)
2391 ok(info->rgSubtreesConstraint[0].cbData ==
2392 sizeof(encodedDomainName), "Wrong size %ld\n",
2393 info->rgSubtreesConstraint[0].cbData);
2394 ok(!memcmp(info->rgSubtreesConstraint[0].pbData, encodedDomainName,
2395 sizeof(encodedDomainName)), "Unexpected value\n");
2397 LocalFree(buf);
2401 /* These are terrible public keys of course, I'm just testing encoding */
2402 static const BYTE modulus1[] = { 0,0,0,1,1,1,1,1 };
2403 static const BYTE modulus2[] = { 1,1,1,1,1,0,0,0 };
2404 static const BYTE modulus3[] = { 0x80,1,1,1,1,0,0,0 };
2405 static const BYTE modulus4[] = { 1,1,1,1,1,0,0,0x80 };
2406 static const BYTE mod1_encoded[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 };
2407 static const BYTE mod2_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2408 static const BYTE mod3_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 };
2409 static const BYTE mod4_encoded[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2411 struct EncodedRSAPubKey
2413 const BYTE *modulus;
2414 size_t modulusLen;
2415 const BYTE *encoded;
2416 size_t decodedModulusLen;
2419 static const struct EncodedRSAPubKey rsaPubKeys[] = {
2420 { modulus1, sizeof(modulus1), mod1_encoded, sizeof(modulus1) },
2421 { modulus2, sizeof(modulus2), mod2_encoded, 5 },
2422 { modulus3, sizeof(modulus3), mod3_encoded, 5 },
2423 { modulus4, sizeof(modulus4), mod4_encoded, 8 },
2426 static void test_encodeRsaPublicKey(DWORD dwEncoding)
2428 BYTE toEncode[sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + sizeof(modulus1)];
2429 BLOBHEADER *hdr = (BLOBHEADER *)toEncode;
2430 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(toEncode + sizeof(BLOBHEADER));
2431 BOOL ret;
2432 BYTE *buf = NULL;
2433 DWORD bufSize = 0, i;
2435 /* Try with a bogus blob type */
2436 hdr->bType = 2;
2437 hdr->bVersion = CUR_BLOB_VERSION;
2438 hdr->reserved = 0;
2439 hdr->aiKeyAlg = CALG_RSA_KEYX;
2440 rsaPubKey->magic = 0x31415352;
2441 rsaPubKey->bitlen = sizeof(modulus1) * 8;
2442 rsaPubKey->pubexp = 65537;
2443 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), modulus1,
2444 sizeof(modulus1));
2446 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2447 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2448 ok(!ret && GetLastError() == E_INVALIDARG,
2449 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
2450 /* Now with a bogus reserved field */
2451 hdr->bType = PUBLICKEYBLOB;
2452 hdr->reserved = 1;
2453 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2454 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2455 if (ret)
2457 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2458 "Expected size %d, got %ld\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2459 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2460 LocalFree(buf);
2462 /* Now with a bogus blob version */
2463 hdr->reserved = 0;
2464 hdr->bVersion = 0;
2465 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2466 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2467 if (ret)
2469 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2470 "Expected size %d, got %ld\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2471 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2472 LocalFree(buf);
2474 /* And with a bogus alg ID */
2475 hdr->bVersion = CUR_BLOB_VERSION;
2476 hdr->aiKeyAlg = CALG_DES;
2477 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2478 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2479 if (ret)
2481 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2482 "Expected size %d, got %ld\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2483 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2484 LocalFree(buf);
2486 /* Check a couple of RSA-related OIDs */
2487 hdr->aiKeyAlg = CALG_RSA_KEYX;
2488 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_RSA,
2489 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2490 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2491 "Expected ERROR_FILE_NOT_FOUND, got %08lx\n", GetLastError());
2492 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2493 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2494 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2495 "Expected ERROR_FILE_NOT_FOUND, got %08lx\n", GetLastError());
2496 /* Finally, all valid */
2497 hdr->aiKeyAlg = CALG_RSA_KEYX;
2498 for (i = 0; i < ARRAY_SIZE(rsaPubKeys); i++)
2500 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2501 rsaPubKeys[i].modulus, rsaPubKeys[i].modulusLen);
2502 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2503 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2504 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
2505 if (ret)
2507 ok(bufSize == rsaPubKeys[i].encoded[1] + 2,
2508 "Expected size %d, got %ld\n", rsaPubKeys[i].encoded[1] + 2,
2509 bufSize);
2510 ok(!memcmp(buf, rsaPubKeys[i].encoded, bufSize),
2511 "Unexpected value\n");
2512 LocalFree(buf);
2517 static void test_decodeRsaPublicKey(DWORD dwEncoding)
2519 DWORD i;
2520 LPBYTE buf = NULL;
2521 DWORD bufSize = 0;
2522 BOOL ret;
2524 /* Try with a bad length */
2525 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2526 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1],
2527 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2528 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
2529 GetLastError() == OSS_MORE_INPUT /* Win9x/NT4 */),
2530 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08lx\n",
2531 GetLastError());
2532 /* Try with a couple of RSA-related OIDs */
2533 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_RSA,
2534 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2535 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2536 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2537 "Expected ERROR_FILE_NOT_FOUND, got %08lx\n", GetLastError());
2538 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2539 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2540 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2541 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2542 "Expected ERROR_FILE_NOT_FOUND, got %08lx\n", GetLastError());
2543 /* Now try success cases */
2544 for (i = 0; i < ARRAY_SIZE(rsaPubKeys); i++)
2546 bufSize = 0;
2547 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2548 rsaPubKeys[i].encoded, rsaPubKeys[i].encoded[1] + 2,
2549 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2550 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
2551 if (ret)
2553 BLOBHEADER *hdr = (BLOBHEADER *)buf;
2554 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER));
2556 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2557 rsaPubKeys[i].decodedModulusLen,
2558 "Wrong size %ld\n", bufSize);
2559 ok(hdr->bType == PUBLICKEYBLOB,
2560 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB,
2561 hdr->bType);
2562 ok(hdr->bVersion == CUR_BLOB_VERSION,
2563 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
2564 CUR_BLOB_VERSION, hdr->bVersion);
2565 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n",
2566 hdr->reserved);
2567 ok(hdr->aiKeyAlg == CALG_RSA_KEYX,
2568 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg);
2569 ok(rsaPubKey->magic == 0x31415352,
2570 "Expected magic RSA1, got %08lx\n", rsaPubKey->magic);
2571 ok(rsaPubKey->bitlen == rsaPubKeys[i].decodedModulusLen * 8,
2572 "Wrong bit len %ld\n", rsaPubKey->bitlen);
2573 ok(rsaPubKey->pubexp == 65537, "Expected pubexp 65537, got %ld\n",
2574 rsaPubKey->pubexp);
2575 ok(!memcmp(buf + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2576 rsaPubKeys[i].modulus, rsaPubKeys[i].decodedModulusLen),
2577 "Unexpected modulus\n");
2578 LocalFree(buf);
2583 static void test_encodeRsaPublicKey_Bcrypt(DWORD dwEncoding)
2585 BYTE toEncode[sizeof(BCRYPT_RSAKEY_BLOB) + sizeof(DWORD) + sizeof(modulus1)];
2586 BCRYPT_RSAKEY_BLOB *hdr = (BCRYPT_RSAKEY_BLOB *)toEncode;
2587 BOOL ret;
2588 BYTE *buf = NULL;
2589 DWORD bufSize = 0, i;
2590 BYTE pubexp[] = {0x01,0x00,0x01,0x00}; /* 65537 */
2592 /* Verify that the Magic value doesn't matter */
2593 hdr->Magic = 1;
2594 hdr->BitLength = sizeof(modulus1) * 8;
2595 hdr->cbPublicExp = sizeof(pubexp);
2596 hdr->cbModulus = sizeof(modulus1);
2597 hdr->cbPrime1 = 0;
2598 hdr->cbPrime2 = 0;
2600 /* CNG_RSA_PUBLIC_KEY_BLOB stores the exponent and modulus
2601 * in big-endian format, so we need convert them
2602 * from little-endian format before encoding
2604 CRYPT_CopyReversed(toEncode + sizeof(BCRYPT_RSAKEY_BLOB), pubexp, sizeof(pubexp));
2605 CRYPT_CopyReversed(toEncode + sizeof(BCRYPT_RSAKEY_BLOB) + sizeof(pubexp), modulus1, sizeof(modulus1));
2607 ret = pCryptEncodeObjectEx(dwEncoding, CNG_RSA_PUBLIC_KEY_BLOB,
2608 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2609 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
2611 /* Finally, all valid */
2612 hdr->Magic = BCRYPT_RSAPUBLIC_MAGIC;
2613 for (i = 0; i < ARRAY_SIZE(rsaPubKeys); i++)
2615 hdr->BitLength = rsaPubKeys[i].modulusLen * 8;
2616 hdr->cbModulus = rsaPubKeys[i].modulusLen;
2618 CRYPT_CopyReversed(toEncode + sizeof(BCRYPT_RSAKEY_BLOB) + sizeof(DWORD),
2619 rsaPubKeys[i].modulus, rsaPubKeys[i].modulusLen);
2621 ret = pCryptEncodeObjectEx(dwEncoding, CNG_RSA_PUBLIC_KEY_BLOB,
2622 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2623 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
2624 if (ret)
2626 ok(bufSize == rsaPubKeys[i].encoded[1] + 2,
2627 "Expected size %d, got %ld\n", rsaPubKeys[i].encoded[1] + 2,
2628 bufSize);
2629 ok(!memcmp(buf, rsaPubKeys[i].encoded, bufSize),
2630 "Unexpected value\n");
2631 LocalFree(buf);
2636 static void test_decodeRsaPublicKey_Bcrypt(DWORD dwEncoding)
2638 DWORD i;
2639 LPBYTE buf = NULL;
2640 LPBYTE leModulus = NULL;
2641 DWORD bufSize = 0;
2642 BOOL ret;
2644 /* Try with a bad length */
2645 ret = pCryptDecodeObjectEx(dwEncoding, CNG_RSA_PUBLIC_KEY_BLOB,
2646 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1],
2647 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2648 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
2649 GetLastError() == OSS_MORE_INPUT /* Win9x/NT4 */),
2650 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08lx\n",
2651 GetLastError());
2652 /* Now try success cases */
2653 for (i = 0; i < ARRAY_SIZE(rsaPubKeys); i++)
2655 bufSize = 0;
2656 ret = pCryptDecodeObjectEx(dwEncoding, CNG_RSA_PUBLIC_KEY_BLOB,
2657 rsaPubKeys[i].encoded, rsaPubKeys[i].encoded[1] + 2,
2658 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2659 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
2660 if (ret)
2662 BCRYPT_RSAKEY_BLOB *hdr = (BCRYPT_RSAKEY_BLOB *)buf;
2663 BYTE pubexp[] = {0xff,0xff,0xff,0xff}, pubexp_expected[] = {0x01,0x00,0x01};
2664 /* CNG_RSA_PUBLIC_KEY_BLOB stores the exponent
2665 * in big-endian format, so we need to convert it to little-endian
2667 CRYPT_CopyReversed((BYTE *)&pubexp, buf + sizeof(BCRYPT_RSAKEY_BLOB), hdr->cbPublicExp);
2668 ok(bufSize >= sizeof(BCRYPT_RSAKEY_BLOB) +
2669 rsaPubKeys[i].decodedModulusLen,
2670 "Wrong size %ld\n", bufSize);
2671 ok(hdr->Magic == BCRYPT_RSAPUBLIC_MAGIC,
2672 "Expected magic BCRYPT_RSAPUBLIC_MAGIC (%d), got %ld\n", BCRYPT_RSAPUBLIC_MAGIC,
2673 hdr->Magic);
2674 ok(hdr->BitLength == rsaPubKeys[i].decodedModulusLen * 8,
2675 "Wrong bit len %ld\n", hdr->BitLength);
2676 /* Windows decodes the exponent to 3 bytes, since it will fit.
2677 * Our implementation currently unconditionally decodes to a DWORD (4 bytes)
2679 todo_wine ok(hdr->cbPublicExp == 3, "Expected cbPublicExp 3, got %ld\n", hdr->cbPublicExp);
2680 ok(hdr->cbModulus == rsaPubKeys[i].decodedModulusLen,
2681 "Wrong modulus len %ld\n", hdr->cbModulus);
2682 ok(hdr->cbPrime1 == 0,"Wrong cbPrime1 %ld\n", hdr->cbPrime1);
2683 ok(hdr->cbPrime2 == 0,"Wrong cbPrime2 %ld\n", hdr->cbPrime2);
2684 ok(!memcmp(pubexp, pubexp_expected, sizeof(pubexp_expected)), "Wrong exponent\n");
2685 todo_wine ok(pubexp[3] == 0xff, "Got %02x\n", pubexp[3]);
2687 leModulus = HeapAlloc(GetProcessHeap(), 0, hdr->cbModulus);
2689 * CNG_RSA_PUBLIC_KEY_BLOB stores the modulus in big-endian format,
2690 * so we need to convert it to little-endian
2692 CRYPT_CopyReversed(leModulus, buf + sizeof(BCRYPT_RSAKEY_BLOB) + hdr->cbPublicExp,
2693 hdr->cbModulus);
2694 ok(!memcmp(leModulus,
2695 rsaPubKeys[i].modulus, rsaPubKeys[i].decodedModulusLen),
2696 "Unexpected modulus\n");
2697 LocalFree(buf);
2698 LocalFree(leModulus);
2703 static const BYTE intSequence[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01,
2704 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02,
2705 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2707 static const BYTE mixedSequence[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
2708 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f,
2709 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02,
2710 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2712 static void test_encodeSequenceOfAny(DWORD dwEncoding)
2714 CRYPT_DER_BLOB blobs[ARRAY_SIZE(ints)];
2715 CRYPT_SEQUENCE_OF_ANY seq;
2716 DWORD i;
2717 BOOL ret;
2718 BYTE *buf = NULL;
2719 DWORD bufSize = 0;
2721 /* Encode a homogeneous sequence */
2722 for (i = 0; i < ARRAY_SIZE(ints); i++)
2724 blobs[i].cbData = ints[i].encoded[1] + 2;
2725 blobs[i].pbData = (BYTE *)ints[i].encoded;
2727 seq.cValue = ARRAY_SIZE(ints);
2728 seq.rgValue = blobs;
2730 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2731 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2732 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
2733 if (ret)
2735 ok(bufSize == sizeof(intSequence), "Wrong size %ld\n", bufSize);
2736 ok(!memcmp(buf, intSequence, intSequence[1] + 2), "Unexpected value\n");
2737 LocalFree(buf);
2739 /* Change the type of the first element in the sequence, and give it
2740 * another go
2742 blobs[0].cbData = times[0].encodedTime[1] + 2;
2743 blobs[0].pbData = (BYTE *)times[0].encodedTime;
2744 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2745 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2746 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
2747 if (ret)
2749 ok(bufSize == sizeof(mixedSequence), "Wrong size %ld\n", bufSize);
2750 ok(!memcmp(buf, mixedSequence, mixedSequence[1] + 2),
2751 "Unexpected value\n");
2752 LocalFree(buf);
2756 static void test_decodeSequenceOfAny(DWORD dwEncoding)
2758 BOOL ret;
2759 BYTE *buf = NULL;
2760 DWORD bufSize = 0;
2762 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, intSequence,
2763 intSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2764 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
2765 if (ret)
2767 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2768 DWORD i;
2770 ok(seq->cValue == ARRAY_SIZE(ints), "Wrong elements %ld\n", seq->cValue);
2771 for (i = 0; i < min(seq->cValue, ARRAY_SIZE(ints)); i++)
2773 ok(seq->rgValue[i].cbData == ints[i].encoded[1] + 2,
2774 "Expected %d bytes, got %ld\n", ints[i].encoded[1] + 2,
2775 seq->rgValue[i].cbData);
2776 ok(!memcmp(seq->rgValue[i].pbData, ints[i].encoded,
2777 ints[i].encoded[1] + 2), "Unexpected value\n");
2779 LocalFree(buf);
2781 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, mixedSequence,
2782 mixedSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
2783 &bufSize);
2784 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
2785 if (ret)
2787 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2789 ok(seq->cValue == ARRAY_SIZE(ints), "Wrong elements %ld\n", seq->cValue);
2790 /* Just check the first element since it's all that changed */
2791 ok(seq->rgValue[0].cbData == times[0].encodedTime[1] + 2,
2792 "Expected %d bytes, got %ld\n", times[0].encodedTime[1] + 2,
2793 seq->rgValue[0].cbData);
2794 ok(!memcmp(seq->rgValue[0].pbData, times[0].encodedTime,
2795 times[0].encodedTime[1] + 2), "Unexpected value\n");
2796 LocalFree(buf);
2800 struct encodedExtensions
2802 CERT_EXTENSIONS exts;
2803 const BYTE *encoded;
2806 static BYTE crit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2807 static BYTE noncrit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2808 static CHAR oid_basic_constraints2[] = szOID_BASIC_CONSTRAINTS2;
2809 static CERT_EXTENSION criticalExt =
2810 { oid_basic_constraints2, TRUE, { 8, crit_ext_data } };
2811 static CERT_EXTENSION nonCriticalExt =
2812 { oid_basic_constraints2, FALSE, { 8, noncrit_ext_data } };
2813 static CHAR oid_short[] = "1.1";
2814 static CERT_EXTENSION extWithShortOid =
2815 { oid_short, FALSE, { 0, NULL } };
2817 static const BYTE ext0[] = { 0x30,0x00 };
2818 static const BYTE ext1[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2819 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2820 static const BYTE ext2[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2821 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2822 static const BYTE ext3[] = { 0x30,0x07,0x30,0x05,0x06,0x01,0x29,0x04,0x00 };
2824 static const struct encodedExtensions exts[] = {
2825 { { 0, NULL }, ext0 },
2826 { { 1, &criticalExt }, ext1 },
2827 { { 1, &nonCriticalExt }, ext2 },
2828 { { 1, &extWithShortOid }, ext3 }
2831 static void test_encodeExtensions(DWORD dwEncoding)
2833 DWORD i;
2835 for (i = 0; i < ARRAY_SIZE(exts); i++)
2837 BOOL ret;
2838 BYTE *buf = NULL;
2839 DWORD bufSize = 0;
2841 ret = pCryptEncodeObjectEx(dwEncoding, X509_EXTENSIONS, &exts[i].exts,
2842 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2843 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
2844 if (ret)
2846 ok(bufSize == exts[i].encoded[1] + 2,
2847 "Expected %d bytes, got %ld\n", exts[i].encoded[1] + 2, bufSize);
2848 ok(!memcmp(buf, exts[i].encoded, exts[i].encoded[1] + 2),
2849 "Unexpected value\n");
2850 LocalFree(buf);
2855 static void test_decodeExtensions(DWORD dwEncoding)
2857 DWORD i;
2859 for (i = 0; i < ARRAY_SIZE(exts); i++)
2861 BOOL ret;
2862 BYTE *buf = NULL;
2863 DWORD bufSize = 0;
2865 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS,
2866 exts[i].encoded, exts[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2867 NULL, &buf, &bufSize);
2868 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
2869 if (ret)
2871 CERT_EXTENSIONS *ext = (CERT_EXTENSIONS *)buf;
2872 DWORD j;
2874 ok(ext->cExtension == exts[i].exts.cExtension,
2875 "Expected %ld extensions, see %ld\n", exts[i].exts.cExtension,
2876 ext->cExtension);
2877 for (j = 0; j < min(ext->cExtension, exts[i].exts.cExtension); j++)
2879 ok(!strcmp(ext->rgExtension[j].pszObjId,
2880 exts[i].exts.rgExtension[j].pszObjId),
2881 "Expected OID %s, got %s\n",
2882 exts[i].exts.rgExtension[j].pszObjId,
2883 ext->rgExtension[j].pszObjId);
2884 ok(!memcmp(ext->rgExtension[j].Value.pbData,
2885 exts[i].exts.rgExtension[j].Value.pbData,
2886 exts[i].exts.rgExtension[j].Value.cbData),
2887 "Unexpected value\n");
2889 LocalFree(buf);
2891 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS,
2892 exts[i].encoded, exts[i].encoded[1] + 2, 0, NULL, NULL, &bufSize);
2893 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
2894 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bufSize);
2895 if (buf)
2897 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS,
2898 exts[i].encoded, exts[i].encoded[1] + 2, 0, NULL, buf, &bufSize);
2899 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
2900 HeapFree(GetProcessHeap(), 0, buf);
2905 /* MS encodes public key info with a NULL if the algorithm identifier's
2906 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2907 * it encodes them by omitting the algorithm parameters. It accepts either
2908 * form for decoding.
2910 struct encodedPublicKey
2912 CERT_PUBLIC_KEY_INFO info;
2913 const BYTE *encoded;
2914 const BYTE *encodedNoNull;
2915 CERT_PUBLIC_KEY_INFO decoded;
2918 static const BYTE aKey[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2919 0xe, 0xf };
2920 static const BYTE params[] = { 0x02, 0x01, 0x01 };
2922 static const unsigned char bin64[] = {
2923 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2924 static const unsigned char bin65[] = {
2925 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2926 static const unsigned char bin66[] = {
2927 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2928 static const unsigned char bin67[] = {
2929 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2930 static const unsigned char bin68[] = {
2931 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01,
2932 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2933 static const unsigned char bin69[] = {
2934 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2935 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2936 static const unsigned char bin70[] = {
2937 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2938 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2939 0x0f};
2940 static const unsigned char bin71[] = {
2941 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2942 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2943 0x0f};
2944 static unsigned char bin72[] = { 0x05,0x00};
2946 static CHAR oid_bogus[] = "1.2.3",
2947 oid_rsa[] = szOID_RSA;
2949 static const struct encodedPublicKey pubKeys[] = {
2950 /* with a bogus OID */
2951 { { { oid_bogus, { 0, NULL } }, { 0, NULL, 0 } },
2952 bin64, bin65,
2953 { { oid_bogus, { 2, bin72 } }, { 0, NULL, 0 } } },
2954 /* some normal keys */
2955 { { { oid_rsa, { 0, NULL } }, { 0, NULL, 0} },
2956 bin66, bin67,
2957 { { oid_rsa, { 2, bin72 } }, { 0, NULL, 0 } } },
2958 { { { oid_rsa, { 0, NULL } }, { sizeof(aKey), (BYTE *)aKey, 0} },
2959 bin68, bin69,
2960 { { oid_rsa, { 2, bin72 } }, { sizeof(aKey), (BYTE *)aKey, 0} } },
2961 /* with add'l parameters--note they must be DER-encoded */
2962 { { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2963 (BYTE *)aKey, 0 } },
2964 bin70, bin71,
2965 { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2966 (BYTE *)aKey, 0 } } },
2969 static void test_encodePublicKeyInfo(DWORD dwEncoding)
2971 DWORD i;
2973 for (i = 0; i < ARRAY_SIZE(pubKeys); i++)
2975 BOOL ret;
2976 BYTE *buf = NULL;
2977 DWORD bufSize = 0;
2979 ret = pCryptEncodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2980 &pubKeys[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf,
2981 &bufSize);
2982 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2983 "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
2984 if (ret)
2986 ok(bufSize == pubKeys[i].encoded[1] + 2,
2987 "Expected %d bytes, got %ld\n", pubKeys[i].encoded[1] + 2, bufSize);
2988 if (bufSize == pubKeys[i].encoded[1] + 2)
2989 ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2),
2990 "Unexpected value\n");
2991 LocalFree(buf);
2996 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO *expected,
2997 const CERT_PUBLIC_KEY_INFO *got)
2999 ok(!strcmp(expected->Algorithm.pszObjId, got->Algorithm.pszObjId),
3000 "Expected OID %s, got %s\n", expected->Algorithm.pszObjId,
3001 got->Algorithm.pszObjId);
3002 ok(expected->Algorithm.Parameters.cbData ==
3003 got->Algorithm.Parameters.cbData,
3004 "Expected parameters of %ld bytes, got %ld\n",
3005 expected->Algorithm.Parameters.cbData, got->Algorithm.Parameters.cbData);
3006 if (expected->Algorithm.Parameters.cbData)
3007 ok(!memcmp(expected->Algorithm.Parameters.pbData,
3008 got->Algorithm.Parameters.pbData, got->Algorithm.Parameters.cbData),
3009 "Unexpected algorithm parameters\n");
3010 ok(expected->PublicKey.cbData == got->PublicKey.cbData,
3011 "Expected public key of %ld bytes, got %ld\n",
3012 expected->PublicKey.cbData, got->PublicKey.cbData);
3013 if (expected->PublicKey.cbData)
3014 ok(!memcmp(expected->PublicKey.pbData, got->PublicKey.pbData,
3015 got->PublicKey.cbData), "Unexpected public key value\n");
3018 static void test_decodePublicKeyInfo(DWORD dwEncoding)
3020 static const BYTE bogusPubKeyInfo[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
3021 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
3022 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
3023 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
3024 DWORD i;
3025 BOOL ret;
3026 BYTE *buf = NULL;
3027 DWORD bufSize = 0;
3029 for (i = 0; i < ARRAY_SIZE(pubKeys); i++)
3031 /* The NULL form decodes to the decoded member */
3032 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
3033 pubKeys[i].encoded, pubKeys[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
3034 NULL, &buf, &bufSize);
3035 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
3036 if (ret)
3038 comparePublicKeyInfo(&pubKeys[i].decoded,
3039 (CERT_PUBLIC_KEY_INFO *)buf);
3040 LocalFree(buf);
3042 /* The non-NULL form decodes to the original */
3043 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
3044 pubKeys[i].encodedNoNull, pubKeys[i].encodedNoNull[1] + 2,
3045 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
3046 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
3047 if (ret)
3049 comparePublicKeyInfo(&pubKeys[i].info, (CERT_PUBLIC_KEY_INFO *)buf);
3050 LocalFree(buf);
3053 /* Test with bogus (not valid DER) parameters */
3054 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
3055 bogusPubKeyInfo, bogusPubKeyInfo[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
3056 NULL, &buf, &bufSize);
3057 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
3058 GetLastError() == OSS_DATA_ERROR /* Win9x */),
3059 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08lx\n",
3060 GetLastError());
3063 static const BYTE v1Cert[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
3064 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
3065 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
3066 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
3067 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
3068 static const BYTE v2Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02,
3069 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
3070 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
3071 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3072 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
3073 static const BYTE v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
3074 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
3075 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
3076 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3077 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
3078 static const BYTE v4Cert[] = {
3079 0x30,0x38,0xa0,0x03,0x02,0x01,0x03,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,
3080 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3081 0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
3082 0x30,0x30,0x30,0x5a,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00 };
3083 static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
3084 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
3085 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
3086 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
3087 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
3088 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
3089 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
3090 static const BYTE v1CertWithSerial[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
3091 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
3092 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
3093 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
3094 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
3095 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
3096 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
3097 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3098 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3099 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
3100 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
3101 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
3102 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
3103 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
3104 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
3105 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
3106 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
3107 static const BYTE v1CertWithPubKey[] = {
3108 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
3109 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
3110 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
3111 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3112 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
3113 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
3114 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
3115 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
3116 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
3117 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
3118 0x01,0x01 };
3119 static const BYTE v1CertWithPubKeyNoNull[] = {
3120 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
3121 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
3122 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
3123 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3124 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
3125 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
3126 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
3127 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
3128 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
3129 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3130 static const BYTE v1CertWithSubjectKeyId[] = {
3131 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
3132 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
3133 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
3134 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3135 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
3136 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
3137 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
3138 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
3139 0x4c,0x61,0x6e,0x67,0x00 };
3140 static const BYTE v1CertWithIssuerUniqueId[] = {
3141 0x30,0x38,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
3142 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
3143 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
3144 0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x81,0x02,0x00,0x01 };
3145 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueId[] = {
3146 0x30,0x81,0x99,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
3147 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
3148 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
3149 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3150 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
3151 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
3152 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
3153 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
3154 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,
3155 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
3156 0x01,0x01,0xff,0x02,0x01,0x01 };
3157 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull[] = {
3158 0x30,0x81,0x97,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
3159 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
3160 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
3161 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3162 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
3163 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
3164 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
3165 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
3166 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
3167 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
3168 0xff,0x02,0x01,0x01 };
3170 static const BYTE serialNum[] = { 0x01 };
3172 static void test_encodeCertToBeSigned(DWORD dwEncoding)
3174 BOOL ret;
3175 BYTE *buf = NULL;
3176 DWORD size = 0;
3177 CERT_INFO info = { 0 };
3178 static char oid_rsa_rsa[] = szOID_RSA_RSA;
3179 static char oid_subject_key_identifier[] = szOID_SUBJECT_KEY_IDENTIFIER;
3180 CERT_EXTENSION ext;
3182 if (0)
3184 /* Test with NULL pvStructInfo (crashes on win9x) */
3185 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL,
3186 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3187 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3188 "Expected STATUS_ACCESS_VIOLATION, got %08lx\n", GetLastError());
3190 /* Test with a V1 cert */
3191 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3192 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3193 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3194 "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
3195 if (ret)
3197 ok(size == v1Cert[1] + 2, "Expected size %d, got %ld\n",
3198 v1Cert[1] + 2, size);
3199 ok(!memcmp(buf, v1Cert, size), "Got unexpected value\n");
3200 LocalFree(buf);
3202 /* Test v2 cert */
3203 info.dwVersion = CERT_V2;
3204 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3205 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3206 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3207 "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
3208 if (ret)
3210 ok(size == sizeof(v2Cert), "Wrong size %ld\n", size);
3211 ok(!memcmp(buf, v2Cert, size), "Got unexpected value\n");
3212 LocalFree(buf);
3214 /* Test v3 cert */
3215 info.dwVersion = CERT_V3;
3216 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3217 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3218 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3219 "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
3220 if (ret)
3222 ok(size == sizeof(v3Cert), "Wrong size %ld\n", size);
3223 ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n");
3224 LocalFree(buf);
3226 /* A v4 cert? */
3227 info.dwVersion = 3; /* Not a typo, CERT_V3 is 2 */
3228 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3229 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3230 if (ret)
3232 ok(size == sizeof(v4Cert), "Wrong size %ld\n", size);
3233 ok(!memcmp(buf, v4Cert, size), "Unexpected value\n");
3234 LocalFree(buf);
3236 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
3237 * API doesn't prevent it)
3239 info.dwVersion = CERT_V1;
3240 info.cExtension = 1;
3241 info.rgExtension = &criticalExt;
3242 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3243 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3244 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3245 "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
3246 if (ret)
3248 ok(size == sizeof(v1CertWithConstraints), "Wrong size %ld\n", size);
3249 ok(!memcmp(buf, v1CertWithConstraints, size), "Got unexpected value\n");
3250 LocalFree(buf);
3252 /* test v1 cert with a serial number */
3253 info.SerialNumber.cbData = sizeof(serialNum);
3254 info.SerialNumber.pbData = (BYTE *)serialNum;
3255 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3256 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3257 if (ret)
3259 ok(size == sizeof(v1CertWithSerial), "Wrong size %ld\n", size);
3260 ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n");
3261 LocalFree(buf);
3263 /* Test v1 cert with an issuer name, serial number, and issuer unique id */
3264 info.dwVersion = CERT_V1;
3265 info.cExtension = 0;
3266 info.IssuerUniqueId.cbData = sizeof(serialNum);
3267 info.IssuerUniqueId.pbData = (BYTE *)serialNum;
3268 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3269 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3270 ok(ret || broken(GetLastError() == OSS_BAD_PTR /* Win98 */),
3271 "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
3272 if (ret)
3274 ok(size == sizeof(v1CertWithIssuerUniqueId), "Wrong size %ld\n", size);
3275 ok(!memcmp(buf, v1CertWithIssuerUniqueId, size),
3276 "Got unexpected value\n");
3277 LocalFree(buf);
3279 /* Test v1 cert with an issuer name, a subject name, and a serial number */
3280 info.IssuerUniqueId.cbData = 0;
3281 info.IssuerUniqueId.pbData = NULL;
3282 info.cExtension = 1;
3283 info.rgExtension = &criticalExt;
3284 info.Issuer.cbData = sizeof(encodedCommonName);
3285 info.Issuer.pbData = (BYTE *)encodedCommonName;
3286 info.Subject.cbData = sizeof(encodedCommonName);
3287 info.Subject.pbData = (BYTE *)encodedCommonName;
3288 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3289 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3290 if (ret)
3292 ok(size == sizeof(bigCert), "Wrong size %ld\n", size);
3293 ok(!memcmp(buf, bigCert, size), "Got unexpected value\n");
3294 LocalFree(buf);
3296 /* Add a public key */
3297 info.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3298 info.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
3299 info.SubjectPublicKeyInfo.PublicKey.pbData = (LPBYTE)aKey;
3300 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3301 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3302 if (ret)
3304 ok(size == sizeof(v1CertWithPubKey) ||
3305 size == sizeof(v1CertWithPubKeyNoNull), "Wrong size %ld\n", size);
3306 if (size == sizeof(v1CertWithPubKey))
3307 ok(!memcmp(buf, v1CertWithPubKey, size), "Got unexpected value\n");
3308 else if (size == sizeof(v1CertWithPubKeyNoNull))
3309 ok(!memcmp(buf, v1CertWithPubKeyNoNull, size),
3310 "Got unexpected value\n");
3311 LocalFree(buf);
3313 /* Again add an issuer unique id */
3314 info.IssuerUniqueId.cbData = sizeof(serialNum);
3315 info.IssuerUniqueId.pbData = (BYTE *)serialNum;
3316 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3317 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3318 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
3319 if (ret)
3321 ok(size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId) ||
3322 size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull),
3323 "Wrong size %ld\n", size);
3324 if (size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId))
3325 ok(!memcmp(buf, v1CertWithSubjectIssuerSerialAndIssuerUniqueId,
3326 size), "unexpected value\n");
3327 else if (size ==
3328 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull))
3329 ok(!memcmp(buf,
3330 v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull, size),
3331 "unexpected value\n");
3332 LocalFree(buf);
3334 /* Remove the public key, and add a subject key identifier extension */
3335 info.IssuerUniqueId.cbData = 0;
3336 info.IssuerUniqueId.pbData = NULL;
3337 info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
3338 info.SubjectPublicKeyInfo.PublicKey.cbData = 0;
3339 info.SubjectPublicKeyInfo.PublicKey.pbData = NULL;
3340 ext.pszObjId = oid_subject_key_identifier;
3341 ext.fCritical = FALSE;
3342 ext.Value.cbData = sizeof(octetCommonNameValue);
3343 ext.Value.pbData = octetCommonNameValue;
3344 info.cExtension = 1;
3345 info.rgExtension = &ext;
3346 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3347 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3348 if (ret)
3350 ok(size == sizeof(v1CertWithSubjectKeyId), "Wrong size %ld\n", size);
3351 ok(!memcmp(buf, v1CertWithSubjectKeyId, size), "Unexpected value\n");
3352 LocalFree(buf);
3356 static void test_decodeCertToBeSigned(DWORD dwEncoding)
3358 static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert, v4Cert,
3359 v1CertWithConstraints, v1CertWithSerial, v1CertWithIssuerUniqueId };
3360 BOOL ret;
3361 BYTE *buf = NULL;
3362 DWORD size = 0, i;
3364 /* Test with NULL pbEncoded */
3365 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 0,
3366 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3367 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
3368 GetLastError() == OSS_BAD_ARG /* Win9x */),
3369 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08lx\n", GetLastError());
3370 if (0)
3372 /* Crashes on win9x */
3373 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 1,
3374 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3375 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3376 "Expected STATUS_ACCESS_VIOLATION, got %08lx\n", GetLastError());
3378 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT or
3379 * CRYPT_E_ASN1_BADTAG, because at a minimum a cert must have a non-zero
3380 * serial number, an issuer, a subject, and a public key.
3382 for (i = 0; i < ARRAY_SIZE(corruptCerts); i++)
3384 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3385 corruptCerts[i], corruptCerts[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3386 &buf, &size);
3387 ok(!ret, "Expected failure\n");
3389 /* The following succeeds, even though v1 certs are not allowed to have
3390 * extensions.
3392 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3393 v1CertWithSubjectKeyId, sizeof(v1CertWithSubjectKeyId),
3394 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3395 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
3396 if (ret)
3398 CERT_INFO *info = (CERT_INFO *)buf;
3400 ok(size >= sizeof(CERT_INFO), "Wrong size %ld\n", size);
3401 ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %ld\n",
3402 info->dwVersion);
3403 ok(info->cExtension == 1, "expected 1 extension, got %ld\n",
3404 info->cExtension);
3405 LocalFree(buf);
3407 /* The following also succeeds, even though V1 certs are not allowed to
3408 * have issuer unique ids.
3410 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3411 v1CertWithSubjectIssuerSerialAndIssuerUniqueId,
3412 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId),
3413 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3414 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
3415 if (ret)
3417 CERT_INFO *info = (CERT_INFO *)buf;
3419 ok(size >= sizeof(CERT_INFO), "Wrong size %ld\n", size);
3420 ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %ld\n",
3421 info->dwVersion);
3422 ok(info->IssuerUniqueId.cbData == sizeof(serialNum),
3423 "unexpected issuer unique id size %ld\n", info->IssuerUniqueId.cbData);
3424 ok(!memcmp(info->IssuerUniqueId.pbData, serialNum, sizeof(serialNum)),
3425 "unexpected issuer unique id value\n");
3426 LocalFree(buf);
3428 /* Now check with serial number, subject and issuer specified */
3429 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert,
3430 sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3431 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
3432 if (ret)
3434 CERT_INFO *info = (CERT_INFO *)buf;
3436 ok(size >= sizeof(CERT_INFO), "Wrong size %ld\n", size);
3437 ok(info->SerialNumber.cbData == 1,
3438 "Expected serial number size 1, got %ld\n", info->SerialNumber.cbData);
3439 ok(*info->SerialNumber.pbData == *serialNum,
3440 "Expected serial number %d, got %d\n", *serialNum,
3441 *info->SerialNumber.pbData);
3442 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3443 "Wrong size %ld\n", info->Issuer.cbData);
3444 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3445 "Unexpected issuer\n");
3446 ok(info->Subject.cbData == sizeof(encodedCommonName),
3447 "Wrong size %ld\n", info->Subject.cbData);
3448 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3449 info->Subject.cbData), "Unexpected subject\n");
3450 LocalFree(buf);
3452 /* Check again with pub key specified */
3453 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3454 v1CertWithPubKey, sizeof(v1CertWithPubKey), CRYPT_DECODE_ALLOC_FLAG, NULL,
3455 &buf, &size);
3456 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
3457 if (ret)
3459 CERT_INFO *info = (CERT_INFO *)buf;
3461 ok(size >= sizeof(CERT_INFO), "Wrong size %ld\n", size);
3462 ok(info->SerialNumber.cbData == 1,
3463 "Expected serial number size 1, got %ld\n", info->SerialNumber.cbData);
3464 ok(*info->SerialNumber.pbData == *serialNum,
3465 "Expected serial number %d, got %d\n", *serialNum,
3466 *info->SerialNumber.pbData);
3467 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3468 "Wrong size %ld\n", info->Issuer.cbData);
3469 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3470 "Unexpected issuer\n");
3471 ok(info->Subject.cbData == sizeof(encodedCommonName),
3472 "Wrong size %ld\n", info->Subject.cbData);
3473 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3474 info->Subject.cbData), "Unexpected subject\n");
3475 ok(!strcmp(info->SubjectPublicKeyInfo.Algorithm.pszObjId,
3476 szOID_RSA_RSA), "Expected szOID_RSA_RSA, got %s\n",
3477 info->SubjectPublicKeyInfo.Algorithm.pszObjId);
3478 ok(info->SubjectPublicKeyInfo.PublicKey.cbData == sizeof(aKey),
3479 "Wrong size %ld\n", info->SubjectPublicKeyInfo.PublicKey.cbData);
3480 ok(!memcmp(info->SubjectPublicKeyInfo.PublicKey.pbData, aKey,
3481 sizeof(aKey)), "Unexpected public key\n");
3482 LocalFree(buf);
3486 static const BYTE hash[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
3487 0xe, 0xf };
3489 static const BYTE signedBigCert[] = {
3490 ASN_SEQUENCE,0x81,147,
3491 ASN_SEQUENCE,122,
3492 ASN_INTEGER,1, 0x01,
3493 ASN_SEQUENCE,2,
3494 ASN_OBJECTIDENTIFIER,0,
3495 ASN_SEQUENCE,21,
3496 0x31,19,
3497 ASN_SEQUENCE,17,
3498 ASN_OBJECTIDENTIFIER,3, 0x55,0x04,0x03,
3499 0x13,10, 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
3500 ASN_SEQUENCE,34,
3501 0x18,15, 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
3502 0x18,15, 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
3503 ASN_SEQUENCE,21,
3504 0x31,19,
3505 ASN_SEQUENCE,17,
3506 ASN_OBJECTIDENTIFIER,3, 0x55,0x04,0x03,
3507 0x13,10, 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
3508 ASN_SEQUENCE,7,
3509 ASN_SEQUENCE,2,
3510 ASN_OBJECTIDENTIFIER,0,
3511 ASN_BITS,1, 0x00,
3512 0xa3,22,
3513 ASN_SEQUENCE,20,
3514 ASN_SEQUENCE,18,
3515 ASN_OBJECTIDENTIFIER,3, 0x55,0x1d,0x13,
3516 0x01,1, 0xff,
3517 ASN_OCTETSTRING,8, 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,
3518 ASN_SEQUENCE,2,
3519 ASN_OBJECTIDENTIFIER,0,
3520 ASN_BITS,17, 0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,
3521 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00
3524 static const BYTE signedBigCertWithIndefiniteSeq[] = {
3525 ASN_SEQUENCE,0x81,151,
3526 ASN_SEQUENCE,126,
3527 ASN_INTEGER,1, 0x01,
3528 ASN_SEQUENCE,2,
3529 ASN_OBJECTIDENTIFIER,0,
3530 ASN_SEQUENCE,21,
3531 0x31,19,
3532 ASN_SEQUENCE,17,
3533 ASN_OBJECTIDENTIFIER,3, 0x55,0x04,0x03,
3534 0x13,10, 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
3535 ASN_SEQUENCE,0x80,
3536 0x18,15, 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
3537 0x18,15, 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
3538 0,0,
3539 ASN_SEQUENCE,21,
3540 0x31,19,
3541 ASN_SEQUENCE,17,
3542 ASN_OBJECTIDENTIFIER,3, 0x55,0x04,0x03,
3543 0x13,10, 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
3544 ASN_SEQUENCE,0x80,
3545 ASN_SEQUENCE,2,
3546 ASN_OBJECTIDENTIFIER,0,
3547 ASN_BITS,1, 0x00,
3548 0,0,
3549 0xa3,22,
3550 ASN_SEQUENCE,20,
3551 ASN_SEQUENCE,18,
3552 ASN_OBJECTIDENTIFIER,3, 0x55,0x1d,0x13,
3553 0x01,1, 0xff,
3554 ASN_OCTETSTRING,8, 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,
3555 ASN_SEQUENCE,2,
3556 ASN_OBJECTIDENTIFIER,0,
3557 ASN_BITS,17, 0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,
3558 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00
3561 static void test_encodeCert(DWORD dwEncoding)
3563 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
3564 * also that bigCert is a NULL-terminated string, so don't count its
3565 * last byte (otherwise the signed cert won't decode.)
3567 CERT_SIGNED_CONTENT_INFO info = { { sizeof(bigCert), (BYTE *)bigCert },
3568 { NULL, { 0, NULL } }, { sizeof(hash), (BYTE *)hash, 0 } };
3569 BOOL ret;
3570 BYTE *buf = NULL;
3571 DWORD bufSize = 0;
3573 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT, &info,
3574 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
3575 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
3576 if (ret)
3578 ok(bufSize == sizeof(signedBigCert), "Wrong size %ld\n", bufSize);
3579 ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n");
3580 LocalFree(buf);
3584 static void test_decodeCert(DWORD dwEncoding)
3586 BOOL ret;
3587 BYTE *buf = NULL;
3588 DWORD size = 0;
3590 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert,
3591 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3592 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
3593 if (ret)
3595 CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf;
3597 ok(info->ToBeSigned.cbData == sizeof(bigCert),
3598 "Wrong cert size %ld\n", info->ToBeSigned.cbData);
3599 ok(!memcmp(info->ToBeSigned.pbData, bigCert, info->ToBeSigned.cbData),
3600 "Unexpected cert\n");
3601 ok(info->Signature.cbData == sizeof(hash),
3602 "Wrong signature size %ld\n", info->Signature.cbData);
3603 ok(!memcmp(info->Signature.pbData, hash, info->Signature.cbData),
3604 "Unexpected signature\n");
3605 LocalFree(buf);
3607 /* A signed cert decodes as a CERT_INFO too */
3608 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCert,
3609 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3610 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
3611 if (ret)
3613 CERT_INFO *info = (CERT_INFO *)buf;
3615 ok(size >= sizeof(CERT_INFO), "Wrong size %ld\n", size);
3616 ok(info->SerialNumber.cbData == 1,
3617 "Expected serial number size 1, got %ld\n", info->SerialNumber.cbData);
3618 ok(*info->SerialNumber.pbData == *serialNum,
3619 "Expected serial number %d, got %d\n", *serialNum,
3620 *info->SerialNumber.pbData);
3621 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3622 "Wrong size %ld\n", info->Issuer.cbData);
3623 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3624 "Unexpected issuer\n");
3625 ok(info->Subject.cbData == sizeof(encodedCommonName),
3626 "Wrong size %ld\n", info->Subject.cbData);
3627 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3628 info->Subject.cbData), "Unexpected subject\n");
3629 LocalFree(buf);
3631 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCertWithIndefiniteSeq,
3632 sizeof(signedBigCertWithIndefiniteSeq), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3633 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
3634 if (ret)
3636 CERT_INFO *info = (CERT_INFO *)buf;
3638 ok(size >= sizeof(CERT_INFO), "Wrong size %ld\n", size);
3639 ok(info->SerialNumber.cbData == 1,
3640 "Expected serial number size 1, got %ld\n", info->SerialNumber.cbData);
3641 ok(*info->SerialNumber.pbData == *serialNum,
3642 "Expected serial number %d, got %d\n", *serialNum,
3643 *info->SerialNumber.pbData);
3644 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3645 "Wrong size %ld\n", info->Issuer.cbData);
3646 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3647 "Unexpected issuer\n");
3648 ok(info->Subject.cbData == sizeof(encodedCommonName),
3649 "Wrong size %ld\n", info->Subject.cbData);
3650 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3651 info->Subject.cbData), "Unexpected subject\n");
3652 LocalFree(buf);
3656 static const BYTE emptyDistPoint[] = { 0x30, 0x02, 0x30, 0x00 };
3657 static const BYTE distPointWithUrl[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3658 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3659 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3660 static const BYTE distPointWithReason[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3661 0x00, 0x03 };
3662 static const BYTE distPointWithIssuer[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3663 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3664 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3665 static const BYTE distPointWithUrlAndIssuer[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3666 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3667 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3668 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3669 0x2e, 0x6f, 0x72, 0x67 };
3670 static const BYTE crlReason = CRL_REASON_KEY_COMPROMISE |
3671 CRL_REASON_AFFILIATION_CHANGED;
3673 static void test_encodeCRLDistPoints(DWORD dwEncoding)
3675 CRL_DIST_POINTS_INFO info = { 0 };
3676 CRL_DIST_POINT point = { { 0 } };
3677 CERT_ALT_NAME_ENTRY entry = { 0 };
3678 BOOL ret;
3679 BYTE *buf = NULL;
3680 DWORD size = 0;
3682 /* Test with an empty info */
3683 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3684 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3685 ok(!ret && GetLastError() == E_INVALIDARG,
3686 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
3687 /* Test with one empty dist point */
3688 info.cDistPoint = 1;
3689 info.rgDistPoint = &point;
3690 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3691 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3692 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
3693 if (ret)
3695 ok(size == sizeof(emptyDistPoint), "Wrong size %ld\n", size);
3696 ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n");
3697 LocalFree(buf);
3699 /* A dist point with an invalid name */
3700 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3701 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3702 U(entry).pwszURL = (LPWSTR)nihongoURL;
3703 U(point.DistPointName).FullName.cAltEntry = 1;
3704 U(point.DistPointName).FullName.rgAltEntry = &entry;
3705 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3706 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3707 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
3708 "Expected CRYPT_E_INVALID_IA5_STRING, got %08lx\n", GetLastError());
3709 /* The first invalid character is at index 7 */
3710 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
3711 "Expected invalid char at index 7, got %ld\n",
3712 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
3713 /* A dist point with (just) a valid name */
3714 U(entry).pwszURL = (LPWSTR)url;
3715 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3716 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3717 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
3718 if (ret)
3720 ok(size == sizeof(distPointWithUrl), "Wrong size %ld\n", size);
3721 ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n");
3722 LocalFree(buf);
3724 /* A dist point with (just) reason flags */
3725 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3726 point.ReasonFlags.cbData = sizeof(crlReason);
3727 point.ReasonFlags.pbData = (LPBYTE)&crlReason;
3728 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3729 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3730 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
3731 if (ret)
3733 ok(size == sizeof(distPointWithReason), "Wrong size %ld\n", size);
3734 ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n");
3735 LocalFree(buf);
3737 /* A dist point with just an issuer */
3738 point.ReasonFlags.cbData = 0;
3739 point.CRLIssuer.cAltEntry = 1;
3740 point.CRLIssuer.rgAltEntry = &entry;
3741 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3742 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3743 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
3744 if (ret)
3746 ok(size == sizeof(distPointWithIssuer), "Wrong size %ld\n", size);
3747 ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n");
3748 LocalFree(buf);
3750 /* A dist point with both a name and an issuer */
3751 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3752 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3753 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3754 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
3755 if (ret)
3757 ok(size == sizeof(distPointWithUrlAndIssuer),
3758 "Wrong size %ld\n", size);
3759 ok(!memcmp(buf, distPointWithUrlAndIssuer, size), "Unexpected value\n");
3760 LocalFree(buf);
3764 static void test_decodeCRLDistPoints(DWORD dwEncoding)
3766 BOOL ret;
3767 BYTE *buf = NULL;
3768 DWORD size = 0;
3769 PCRL_DIST_POINTS_INFO info;
3770 PCRL_DIST_POINT point;
3771 PCERT_ALT_NAME_ENTRY entry;
3773 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3774 emptyDistPoint, emptyDistPoint[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3775 &buf, &size);
3776 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
3777 if (ret)
3779 info = (PCRL_DIST_POINTS_INFO)buf;
3780 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3781 "Wrong size %ld\n", size);
3782 ok(info->cDistPoint == 1, "Expected 1 dist points, got %ld\n",
3783 info->cDistPoint);
3784 point = info->rgDistPoint;
3785 ok(point->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_NO_NAME,
3786 "Expected CRL_DIST_POINT_NO_NAME, got %ld\n",
3787 point->DistPointName.dwDistPointNameChoice);
3788 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3789 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3790 LocalFree(buf);
3792 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3793 distPointWithUrl, distPointWithUrl[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3794 &buf, &size);
3795 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
3796 if (ret)
3798 info = (PCRL_DIST_POINTS_INFO)buf;
3799 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3800 "Wrong size %ld\n", size);
3801 ok(info->cDistPoint == 1, "Expected 1 dist points, got %ld\n",
3802 info->cDistPoint);
3803 point = info->rgDistPoint;
3804 ok(point->DistPointName.dwDistPointNameChoice ==
3805 CRL_DIST_POINT_FULL_NAME,
3806 "Expected CRL_DIST_POINT_FULL_NAME, got %ld\n",
3807 point->DistPointName.dwDistPointNameChoice);
3808 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3809 "Expected 1 name entry, got %ld\n",
3810 U(point->DistPointName).FullName.cAltEntry);
3811 entry = U(point->DistPointName).FullName.rgAltEntry;
3812 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3813 "Expected CERT_ALT_NAME_URL, got %ld\n", entry->dwAltNameChoice);
3814 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3815 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3816 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3817 LocalFree(buf);
3819 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3820 distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
3821 NULL, &buf, &size);
3822 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
3823 if (ret)
3825 info = (PCRL_DIST_POINTS_INFO)buf;
3826 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3827 "Wrong size %ld\n", size);
3828 ok(info->cDistPoint == 1, "Expected 1 dist points, got %ld\n",
3829 info->cDistPoint);
3830 point = info->rgDistPoint;
3831 ok(point->DistPointName.dwDistPointNameChoice ==
3832 CRL_DIST_POINT_NO_NAME,
3833 "Expected CRL_DIST_POINT_NO_NAME, got %ld\n",
3834 point->DistPointName.dwDistPointNameChoice);
3835 ok(point->ReasonFlags.cbData == sizeof(crlReason),
3836 "Expected reason length\n");
3837 ok(!memcmp(point->ReasonFlags.pbData, &crlReason, sizeof(crlReason)),
3838 "Unexpected reason\n");
3839 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3840 LocalFree(buf);
3842 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3843 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2,
3844 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3845 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
3846 if (ret)
3848 info = (PCRL_DIST_POINTS_INFO)buf;
3849 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3850 "Wrong size %ld\n", size);
3851 ok(info->cDistPoint == 1, "Expected 1 dist points, got %ld\n",
3852 info->cDistPoint);
3853 point = info->rgDistPoint;
3854 ok(point->DistPointName.dwDistPointNameChoice ==
3855 CRL_DIST_POINT_FULL_NAME,
3856 "Expected CRL_DIST_POINT_FULL_NAME, got %ld\n",
3857 point->DistPointName.dwDistPointNameChoice);
3858 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3859 "Expected 1 name entry, got %ld\n",
3860 U(point->DistPointName).FullName.cAltEntry);
3861 entry = U(point->DistPointName).FullName.rgAltEntry;
3862 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3863 "Expected CERT_ALT_NAME_URL, got %ld\n", entry->dwAltNameChoice);
3864 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3865 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3866 ok(point->CRLIssuer.cAltEntry == 1,
3867 "Expected 1 issuer entry, got %ld\n", point->CRLIssuer.cAltEntry);
3868 entry = point->CRLIssuer.rgAltEntry;
3869 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3870 "Expected CERT_ALT_NAME_URL, got %ld\n", entry->dwAltNameChoice);
3871 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3872 LocalFree(buf);
3874 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3875 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2, 0,
3876 NULL, NULL, &size);
3877 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
3878 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
3879 if (buf)
3881 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3882 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2, 0,
3883 NULL, buf, &size);
3884 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
3885 HeapFree(GetProcessHeap(), 0, buf);
3889 static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3890 static const BYTE emptyNameIDP[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3891 static const BYTE urlIDP[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3892 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3893 0x67 };
3895 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding)
3897 BOOL ret;
3898 BYTE *buf = NULL;
3899 DWORD size = 0;
3900 CRL_ISSUING_DIST_POINT point = { { 0 } };
3901 CERT_ALT_NAME_ENTRY entry;
3903 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, NULL,
3904 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3905 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3907 skip("no X509_ISSUING_DIST_POINT encode support\n");
3908 return;
3910 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3911 "Expected STATUS_ACCESS_VIOLATION, got %08lx\n", GetLastError());
3912 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3913 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3914 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
3915 if (ret)
3917 ok(size == sizeof(emptySequence), "Unexpected size %ld\n", size);
3918 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
3919 LocalFree(buf);
3921 /* nonsensical flags */
3922 point.fOnlyContainsUserCerts = TRUE;
3923 point.fOnlyContainsCACerts = TRUE;
3924 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3925 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3926 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
3927 if (ret)
3929 ok(size == sizeof(badFlagsIDP), "Unexpected size %ld\n", size);
3930 ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n");
3931 LocalFree(buf);
3933 /* unimplemented name type */
3934 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3935 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_ISSUER_RDN_NAME;
3936 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3937 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3938 ok(!ret && GetLastError() == E_INVALIDARG,
3939 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
3940 /* empty name */
3941 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3942 U(point.DistPointName).FullName.cAltEntry = 0;
3943 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3944 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3945 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
3946 if (ret)
3948 ok(size == sizeof(emptyNameIDP), "Unexpected size %ld\n", size);
3949 ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n");
3950 LocalFree(buf);
3952 /* name with URL entry */
3953 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3954 U(entry).pwszURL = (LPWSTR)url;
3955 U(point.DistPointName).FullName.cAltEntry = 1;
3956 U(point.DistPointName).FullName.rgAltEntry = &entry;
3957 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3958 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3959 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
3960 if (ret)
3962 ok(size == sizeof(urlIDP), "Unexpected size %ld\n", size);
3963 ok(!memcmp(buf, urlIDP, size), "Unexpected value\n");
3964 LocalFree(buf);
3968 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY *expected,
3969 const CERT_ALT_NAME_ENTRY *got)
3971 ok(expected->dwAltNameChoice == got->dwAltNameChoice,
3972 "Expected name choice %ld, got %ld\n", expected->dwAltNameChoice,
3973 got->dwAltNameChoice);
3974 if (expected->dwAltNameChoice == got->dwAltNameChoice)
3976 switch (got->dwAltNameChoice)
3978 case CERT_ALT_NAME_RFC822_NAME:
3979 case CERT_ALT_NAME_DNS_NAME:
3980 case CERT_ALT_NAME_EDI_PARTY_NAME:
3981 case CERT_ALT_NAME_URL:
3982 case CERT_ALT_NAME_REGISTERED_ID:
3983 ok((!U(*expected).pwszURL && !U(*got).pwszURL) ||
3984 (!U(*expected).pwszURL && !lstrlenW(U(*got).pwszURL)) ||
3985 (!U(*got).pwszURL && !lstrlenW(U(*expected).pwszURL)) ||
3986 !lstrcmpW(U(*expected).pwszURL, U(*got).pwszURL),
3987 "Unexpected name\n");
3988 break;
3989 case CERT_ALT_NAME_X400_ADDRESS:
3990 case CERT_ALT_NAME_DIRECTORY_NAME:
3991 case CERT_ALT_NAME_IP_ADDRESS:
3992 ok(U(*got).IPAddress.cbData == U(*expected).IPAddress.cbData,
3993 "Unexpected IP address length %ld\n", U(*got).IPAddress.cbData);
3994 ok(!memcmp(U(*got).IPAddress.pbData, U(*expected).IPAddress.pbData,
3995 U(*got).IPAddress.cbData), "Unexpected value\n");
3996 break;
4001 static void compareAltNameInfo(const CERT_ALT_NAME_INFO *expected,
4002 const CERT_ALT_NAME_INFO *got)
4004 DWORD i;
4006 ok(expected->cAltEntry == got->cAltEntry, "Expected %ld entries, got %ld\n",
4007 expected->cAltEntry, got->cAltEntry);
4008 for (i = 0; i < min(expected->cAltEntry, got->cAltEntry); i++)
4009 compareAltNameEntry(&expected->rgAltEntry[i], &got->rgAltEntry[i]);
4012 static void compareDistPointName(const CRL_DIST_POINT_NAME *expected,
4013 const CRL_DIST_POINT_NAME *got)
4015 ok(got->dwDistPointNameChoice == expected->dwDistPointNameChoice,
4016 "Unexpected name choice %ld\n", got->dwDistPointNameChoice);
4017 if (got->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME)
4018 compareAltNameInfo(&(U(*expected).FullName), &(U(*got).FullName));
4021 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT *expected,
4022 const CRL_ISSUING_DIST_POINT *got)
4024 compareDistPointName(&expected->DistPointName, &got->DistPointName);
4025 ok(got->fOnlyContainsUserCerts == expected->fOnlyContainsUserCerts,
4026 "Unexpected fOnlyContainsUserCerts\n");
4027 ok(got->fOnlyContainsCACerts == expected->fOnlyContainsCACerts,
4028 "Unexpected fOnlyContainsCACerts\n");
4029 ok(got->OnlySomeReasonFlags.cbData == expected->OnlySomeReasonFlags.cbData,
4030 "Unexpected reason flags\n");
4031 ok(got->fIndirectCRL == expected->fIndirectCRL,
4032 "Unexpected fIndirectCRL\n");
4035 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding)
4037 BOOL ret;
4038 BYTE *buf = NULL;
4039 DWORD size = 0;
4040 CRL_ISSUING_DIST_POINT point = { { 0 } };
4042 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
4043 emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4044 &buf, &size);
4045 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
4047 skip("no X509_ISSUING_DIST_POINT decode support\n");
4048 return;
4050 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
4051 if (ret)
4053 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
4054 LocalFree(buf);
4056 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
4057 badFlagsIDP, badFlagsIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4058 &buf, &size);
4059 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
4060 if (ret)
4062 point.fOnlyContainsUserCerts = point.fOnlyContainsCACerts = TRUE;
4063 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
4064 LocalFree(buf);
4066 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
4067 emptyNameIDP, emptyNameIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4068 &buf, &size);
4069 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
4070 if (ret)
4072 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
4073 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
4074 U(point.DistPointName).FullName.cAltEntry = 0;
4075 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
4076 LocalFree(buf);
4078 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
4079 urlIDP, urlIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4080 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
4081 if (ret)
4083 CERT_ALT_NAME_ENTRY entry;
4085 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
4086 U(entry).pwszURL = (LPWSTR)url;
4087 U(point.DistPointName).FullName.cAltEntry = 1;
4088 U(point.DistPointName).FullName.rgAltEntry = &entry;
4089 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
4090 LocalFree(buf);
4094 static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
4095 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
4096 0x30, 0x5a };
4097 static const BYTE v2CRL[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
4098 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
4099 0x30, 0x30, 0x30, 0x30, 0x5a };
4100 static const BYTE v1CRLWithIssuer[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
4101 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
4102 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
4103 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
4104 0x5a };
4105 static const BYTE v1CRLWithIssuerAndEmptyEntry[] = { 0x30, 0x43, 0x30, 0x02,
4106 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
4107 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
4108 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
4109 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
4110 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
4111 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
4112 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
4113 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
4114 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
4115 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
4116 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
4117 static const BYTE v1CRLWithEntryExt[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
4118 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
4119 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
4120 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
4121 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
4122 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
4123 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
4124 static const BYTE v1CRLWithExt[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
4125 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4126 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
4127 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
4128 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
4129 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
4130 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
4131 static const BYTE v2CRLWithExt[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
4132 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
4133 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
4134 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
4135 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
4136 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
4137 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
4139 static void test_encodeCRLToBeSigned(DWORD dwEncoding)
4141 BOOL ret;
4142 BYTE *buf = NULL;
4143 DWORD size = 0;
4144 CRL_INFO info = { 0 };
4145 CRL_ENTRY entry = { { 0 }, { 0 }, 0, 0 };
4147 /* Test with a V1 CRL */
4148 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
4149 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4150 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
4151 "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
4152 if (ret)
4154 ok(size == sizeof(v1CRL), "Wrong size %ld\n", size);
4155 ok(!memcmp(buf, v1CRL, size), "Got unexpected value\n");
4156 LocalFree(buf);
4158 /* Test v2 CRL */
4159 info.dwVersion = CRL_V2;
4160 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
4161 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4162 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
4163 "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
4164 if (ret)
4166 ok(size == v2CRL[1] + 2, "Expected size %d, got %ld\n",
4167 v2CRL[1] + 2, size);
4168 ok(!memcmp(buf, v2CRL, size), "Got unexpected value\n");
4169 LocalFree(buf);
4171 /* v1 CRL with a name */
4172 info.dwVersion = CRL_V1;
4173 info.Issuer.cbData = sizeof(encodedCommonName);
4174 info.Issuer.pbData = (BYTE *)encodedCommonName;
4175 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
4176 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4177 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
4178 if (ret)
4180 ok(size == sizeof(v1CRLWithIssuer), "Wrong size %ld\n", size);
4181 ok(!memcmp(buf, v1CRLWithIssuer, size), "Got unexpected value\n");
4182 LocalFree(buf);
4184 if (0)
4186 /* v1 CRL with a name and a NULL entry pointer (crashes on win9x) */
4187 info.cCRLEntry = 1;
4188 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
4189 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4190 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
4191 "Expected STATUS_ACCESS_VIOLATION, got %08lx\n", GetLastError());
4193 /* now set an empty entry */
4194 info.cCRLEntry = 1;
4195 info.rgCRLEntry = &entry;
4196 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
4197 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4198 if (ret)
4200 ok(size == sizeof(v1CRLWithIssuerAndEmptyEntry),
4201 "Wrong size %ld\n", size);
4202 ok(!memcmp(buf, v1CRLWithIssuerAndEmptyEntry, size),
4203 "Got unexpected value\n");
4204 LocalFree(buf);
4206 /* an entry with a serial number */
4207 entry.SerialNumber.cbData = sizeof(serialNum);
4208 entry.SerialNumber.pbData = (BYTE *)serialNum;
4209 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
4210 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4211 if (ret)
4213 ok(size == sizeof(v1CRLWithIssuerAndEntry),
4214 "Wrong size %ld\n", size);
4215 ok(!memcmp(buf, v1CRLWithIssuerAndEntry, size),
4216 "Got unexpected value\n");
4217 LocalFree(buf);
4219 /* an entry with an extension */
4220 entry.cExtension = 1;
4221 entry.rgExtension = &criticalExt;
4222 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
4223 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4224 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
4225 if (ret)
4227 ok(size == sizeof(v1CRLWithEntryExt), "Wrong size %ld\n", size);
4228 ok(!memcmp(buf, v1CRLWithEntryExt, size), "Got unexpected value\n");
4229 LocalFree(buf);
4231 /* a CRL with an extension */
4232 entry.cExtension = 0;
4233 info.cExtension = 1;
4234 info.rgExtension = &criticalExt;
4235 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
4236 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4237 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
4238 if (ret)
4240 ok(size == sizeof(v1CRLWithExt), "Wrong size %ld\n", size);
4241 ok(!memcmp(buf, v1CRLWithExt, size), "Got unexpected value\n");
4242 LocalFree(buf);
4244 /* a v2 CRL with an extension, this time non-critical */
4245 info.dwVersion = CRL_V2;
4246 info.rgExtension = &nonCriticalExt;
4247 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
4248 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4249 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
4250 if (ret)
4252 ok(size == sizeof(v2CRLWithExt), "Wrong size %ld\n", size);
4253 ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n");
4254 LocalFree(buf);
4258 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
4259 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
4260 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
4261 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
4262 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
4263 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
4264 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
4265 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
4266 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
4267 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
4268 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
4269 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
4270 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
4271 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
4272 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
4273 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
4274 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
4275 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
4276 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
4277 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
4278 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
4279 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
4280 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
4281 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
4282 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
4283 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
4284 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
4285 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
4286 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
4287 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
4288 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
4289 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
4290 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
4291 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
4292 0xcd };
4293 static const BYTE verisignCRLWithLotsOfEntries[] = {
4294 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
4295 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
4296 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
4297 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
4298 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
4299 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
4300 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
4301 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
4302 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
4303 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
4304 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
4305 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
4306 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
4307 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
4308 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
4309 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
4310 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
4311 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
4312 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
4313 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
4314 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
4315 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
4316 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
4317 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
4318 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
4319 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
4320 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
4321 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
4322 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
4323 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
4324 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
4325 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
4326 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
4327 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
4328 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
4329 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
4330 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
4331 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
4332 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
4333 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
4334 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
4335 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
4336 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
4337 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
4338 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
4339 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
4340 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
4341 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
4342 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
4343 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
4344 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
4345 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
4346 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
4347 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
4348 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
4349 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
4350 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
4351 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
4352 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
4353 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
4354 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
4355 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
4356 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
4357 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
4358 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
4359 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
4360 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
4361 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
4362 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
4363 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
4364 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
4365 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
4366 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
4367 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
4368 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
4369 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
4370 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
4371 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
4372 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
4373 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
4374 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
4375 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
4376 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
4377 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
4378 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
4379 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
4380 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
4381 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
4382 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
4383 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
4384 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
4385 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
4386 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
4387 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
4388 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
4389 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
4390 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
4391 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
4392 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
4393 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
4394 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
4395 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
4396 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
4397 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
4398 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
4399 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
4400 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
4401 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
4402 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
4403 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
4404 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
4405 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
4406 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
4407 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
4408 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
4409 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
4410 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
4411 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
4412 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
4413 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
4414 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
4415 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
4416 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
4417 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
4418 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
4419 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
4420 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
4421 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
4422 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
4423 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
4424 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
4425 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
4426 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
4427 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
4428 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
4429 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
4430 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
4431 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
4432 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
4433 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
4434 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
4435 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
4436 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
4437 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
4438 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
4439 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
4440 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
4441 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
4442 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
4443 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
4444 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
4445 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
4446 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
4447 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
4448 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
4449 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
4450 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
4451 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
4452 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
4453 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
4454 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
4455 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
4456 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
4457 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
4458 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
4459 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
4460 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
4461 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
4462 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
4463 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
4464 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
4465 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
4466 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
4467 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
4468 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
4469 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
4470 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
4471 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
4472 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
4473 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
4474 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
4475 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
4476 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
4477 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
4478 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
4479 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
4480 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
4481 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
4482 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
4483 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
4484 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
4485 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
4486 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
4487 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
4488 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
4489 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
4490 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
4491 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
4492 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
4493 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
4494 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
4495 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
4496 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
4497 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
4498 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
4499 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
4500 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
4501 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
4502 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
4503 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
4504 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
4505 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
4506 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
4507 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
4508 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
4509 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
4510 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
4511 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
4512 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
4513 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
4514 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
4515 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
4516 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
4517 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
4518 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
4519 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
4520 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
4521 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
4522 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
4523 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
4524 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
4525 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
4526 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
4527 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
4528 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
4529 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
4530 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
4531 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
4532 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
4533 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
4534 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
4535 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
4536 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
4537 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
4538 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
4539 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
4540 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
4541 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
4542 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
4543 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
4544 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
4545 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
4546 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
4547 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
4548 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
4549 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
4550 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
4551 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
4552 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
4553 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
4554 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
4555 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
4556 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
4557 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
4558 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
4559 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
4560 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
4561 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
4562 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
4563 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
4564 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
4565 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
4566 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
4567 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
4568 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
4569 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
4570 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
4571 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
4572 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
4573 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
4574 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
4575 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
4576 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
4577 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
4578 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
4579 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
4580 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
4581 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
4582 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
4583 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
4584 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
4585 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
4586 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
4587 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
4588 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
4589 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
4590 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
4591 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
4592 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
4593 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
4594 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
4595 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
4596 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
4597 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4598 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4599 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4600 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4601 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4602 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4603 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4604 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4605 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4606 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4607 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4608 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4609 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4610 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4611 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4612 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4613 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4614 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4615 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4616 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4617 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4618 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4619 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4620 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4621 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4622 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4623 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4624 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4625 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4626 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4627 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4628 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4629 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4630 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4631 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4632 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4633 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4634 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4635 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4636 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4637 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4638 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4639 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4640 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4641 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4642 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4643 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4644 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4645 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4646 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4647 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4648 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4649 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4650 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4651 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4652 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4653 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4654 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4655 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4656 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4657 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4658 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4659 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4660 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4661 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4662 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4663 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4664 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4665 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4666 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4667 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4668 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4669 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4670 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4671 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4672 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4673 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4674 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4675 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4676 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4677 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4678 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4679 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4680 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4681 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4682 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4683 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4684 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4685 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4686 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4687 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4688 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4689 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4690 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4691 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4692 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4693 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4694 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4695 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4696 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4697 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4698 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4699 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4700 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4701 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4702 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4703 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4704 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4705 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4706 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4707 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4708 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4709 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4710 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4711 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4712 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4713 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4714 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4715 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4716 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4717 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4718 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4719 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4720 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4721 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4722 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4723 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4724 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4725 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4726 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4727 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4728 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4729 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4730 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4731 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4732 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4733 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4734 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4735 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4736 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4737 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4738 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4739 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4740 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4741 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4742 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4743 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4744 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4745 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4746 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4747 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4748 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4749 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4750 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4751 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4752 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4753 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4754 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4755 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4756 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4757 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4758 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4759 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4760 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4761 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4762 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4763 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4764 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4765 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4766 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4767 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4768 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4769 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4770 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4771 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4772 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4773 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4774 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4775 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4776 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4777 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4778 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4779 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4780 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4781 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4782 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4783 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4784 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4785 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4786 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4787 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4788 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4789 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4790 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4791 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4792 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4793 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4794 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4795 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4796 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4797 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4798 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4799 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4800 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4801 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4803 static void test_decodeCRLToBeSigned(DWORD dwEncoding)
4805 static const BYTE *corruptCRLs[] = { v1CRL, v2CRL };
4806 BOOL ret;
4807 BYTE *buf = NULL;
4808 DWORD size = 0, i;
4810 for (i = 0; i < ARRAY_SIZE(corruptCRLs); i++)
4812 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4813 corruptCRLs[i], corruptCRLs[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4814 &buf, &size);
4815 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4816 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4817 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08lx\n",
4818 GetLastError());
4820 /* at a minimum, a CRL must contain an issuer: */
4821 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4822 v1CRLWithIssuer, v1CRLWithIssuer[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4823 &buf, &size);
4824 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
4825 if (ret)
4827 CRL_INFO *info = (CRL_INFO *)buf;
4829 ok(size >= sizeof(CRL_INFO), "Wrong size %ld\n", size);
4830 ok(info->cCRLEntry == 0, "Expected 0 CRL entries, got %ld\n",
4831 info->cCRLEntry);
4832 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4833 "Wrong issuer size %ld\n", info->Issuer.cbData);
4834 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4835 "Unexpected issuer\n");
4836 LocalFree(buf);
4838 /* check decoding with an empty CRL entry */
4839 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4840 v1CRLWithIssuerAndEmptyEntry, v1CRLWithIssuerAndEmptyEntry[1] + 2,
4841 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4842 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4843 GetLastError() == OSS_DATA_ERROR /* Win9x */ ||
4844 GetLastError() == CRYPT_E_BAD_ENCODE /* Win8 */),
4845 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08lx\n",
4846 GetLastError());
4847 /* with a real CRL entry */
4848 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4849 v1CRLWithIssuerAndEntry, v1CRLWithIssuerAndEntry[1] + 2,
4850 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4851 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
4852 if (ret)
4854 CRL_INFO *info = (CRL_INFO *)buf;
4855 CRL_ENTRY *entry;
4857 ok(size >= sizeof(CRL_INFO), "Wrong size %ld\n", size);
4858 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %ld\n",
4859 info->cCRLEntry);
4860 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4861 entry = info->rgCRLEntry;
4862 ok(entry->SerialNumber.cbData == 1,
4863 "Expected serial number size 1, got %ld\n",
4864 entry->SerialNumber.cbData);
4865 ok(*entry->SerialNumber.pbData == *serialNum,
4866 "Expected serial number %d, got %d\n", *serialNum,
4867 *entry->SerialNumber.pbData);
4868 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4869 "Wrong issuer size %ld\n", info->Issuer.cbData);
4870 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4871 "Unexpected issuer\n");
4872 LocalFree(buf);
4874 /* a real CRL from verisign that has extensions */
4875 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4876 verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG,
4877 NULL, &buf, &size);
4878 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
4879 if (ret)
4881 CRL_INFO *info = (CRL_INFO *)buf;
4883 ok(size >= sizeof(CRL_INFO), "Wrong size %ld\n", size);
4884 ok(info->cCRLEntry == 3, "Expected 3 CRL entries, got %ld\n",
4885 info->cCRLEntry);
4886 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4887 ok(info->cExtension == 2, "Expected 2 extensions, got %ld\n",
4888 info->cExtension);
4889 LocalFree(buf);
4891 /* another real CRL from verisign that has lots of entries */
4892 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4893 verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries),
4894 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4895 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
4896 if (ret)
4898 CRL_INFO *info = (CRL_INFO *)buf;
4900 ok(size >= sizeof(CRL_INFO), "Got size %ld\n", size);
4901 ok(info->cCRLEntry == 209, "Expected 209 CRL entries, got %ld\n",
4902 info->cCRLEntry);
4903 ok(info->cExtension == 0, "Expected 0 extensions, got %ld\n",
4904 info->cExtension);
4905 LocalFree(buf);
4907 /* and finally, with an extension */
4908 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4909 v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4910 NULL, &buf, &size);
4911 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
4912 if (ret)
4914 CRL_INFO *info = (CRL_INFO *)buf;
4915 CRL_ENTRY *entry;
4917 ok(size >= sizeof(CRL_INFO), "Wrong size %ld\n", size);
4918 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %ld\n",
4919 info->cCRLEntry);
4920 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4921 entry = info->rgCRLEntry;
4922 ok(entry->SerialNumber.cbData == 1,
4923 "Expected serial number size 1, got %ld\n",
4924 entry->SerialNumber.cbData);
4925 ok(*entry->SerialNumber.pbData == *serialNum,
4926 "Expected serial number %d, got %d\n", *serialNum,
4927 *entry->SerialNumber.pbData);
4928 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4929 "Wrong issuer size %ld\n", info->Issuer.cbData);
4930 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4931 "Unexpected issuer\n");
4932 ok(info->cExtension == 1, "Expected 1 extensions, got %ld\n",
4933 info->cExtension);
4934 LocalFree(buf);
4936 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4937 v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4938 NULL, &buf, &size);
4939 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
4940 if (ret)
4942 CRL_INFO *info = (CRL_INFO *)buf;
4944 ok(info->cExtension == 1, "Expected 1 extensions, got %ld\n",
4945 info->cExtension);
4946 LocalFree(buf);
4950 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
4951 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
4952 static const BYTE encodedUsage[] = {
4953 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4954 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4955 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4957 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding)
4959 BOOL ret;
4960 BYTE *buf = NULL;
4961 DWORD size = 0;
4962 CERT_ENHKEY_USAGE usage;
4964 /* Test with empty usage */
4965 usage.cUsageIdentifier = 0;
4966 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4967 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4968 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
4969 if (ret)
4971 ok(size == sizeof(emptySequence), "Wrong size %ld\n", size);
4972 ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n");
4973 LocalFree(buf);
4975 /* Test with a few usages */
4976 usage.cUsageIdentifier = ARRAY_SIZE(keyUsages);
4977 usage.rgpszUsageIdentifier = (LPSTR *)keyUsages;
4978 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4979 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4980 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
4981 if (ret)
4983 ok(size == sizeof(encodedUsage), "Wrong size %ld\n", size);
4984 ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n");
4985 LocalFree(buf);
4989 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding)
4991 BOOL ret;
4992 LPBYTE buf = NULL;
4993 DWORD size = 0;
4995 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4996 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4997 &buf, &size);
4998 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
4999 if (ret)
5001 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
5003 ok(size >= sizeof(CERT_ENHKEY_USAGE),
5004 "Wrong size %ld\n", size);
5005 ok(usage->cUsageIdentifier == 0, "Expected 0 CRL entries, got %ld\n",
5006 usage->cUsageIdentifier);
5007 LocalFree(buf);
5009 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
5010 encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL,
5011 &buf, &size);
5012 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
5013 if (ret)
5015 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
5016 DWORD i;
5018 ok(size >= sizeof(CERT_ENHKEY_USAGE),
5019 "Wrong size %ld\n", size);
5020 ok(usage->cUsageIdentifier == ARRAY_SIZE(keyUsages),
5021 "Wrong CRL entries count %ld\n", usage->cUsageIdentifier);
5022 for (i = 0; i < usage->cUsageIdentifier; i++)
5023 ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]),
5024 "Expected OID %s, got %s\n", keyUsages[i],
5025 usage->rgpszUsageIdentifier[i]);
5026 LocalFree(buf);
5028 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
5029 encodedUsage, sizeof(encodedUsage), 0, NULL, NULL, &size);
5030 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
5031 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
5032 if (buf)
5034 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
5035 encodedUsage, sizeof(encodedUsage), 0, NULL, buf, &size);
5036 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
5037 HeapFree(GetProcessHeap(), 0, buf);
5041 static BYTE keyId[] = { 1,2,3,4 };
5042 static const BYTE authorityKeyIdWithId[] = {
5043 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
5044 static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
5045 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
5046 0x20,0x4c,0x61,0x6e,0x67,0x00 };
5047 static const BYTE authorityKeyIdWithSerial[] = { 0x30,0x03,0x82,0x01,0x01 };
5049 static void test_encodeAuthorityKeyId(DWORD dwEncoding)
5051 CERT_AUTHORITY_KEY_ID_INFO info = { { 0 } };
5052 BOOL ret;
5053 BYTE *buf = NULL;
5054 DWORD size = 0;
5056 /* Test with empty id */
5057 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
5058 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5059 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
5060 if (ret)
5062 ok(size == sizeof(emptySequence), "Unexpected size %ld\n", size);
5063 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
5064 LocalFree(buf);
5066 /* With just a key id */
5067 info.KeyId.cbData = sizeof(keyId);
5068 info.KeyId.pbData = keyId;
5069 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
5070 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5071 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
5072 if (ret)
5074 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %ld\n", size);
5075 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
5076 LocalFree(buf);
5078 /* With just an issuer */
5079 info.KeyId.cbData = 0;
5080 info.CertIssuer.cbData = sizeof(encodedCommonName);
5081 info.CertIssuer.pbData = (BYTE *)encodedCommonName;
5082 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
5083 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5084 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
5085 if (ret)
5087 ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %ld\n",
5088 size);
5089 ok(!memcmp(buf, authorityKeyIdWithIssuer, size), "Unexpected value\n");
5090 LocalFree(buf);
5092 /* With just a serial number */
5093 info.CertIssuer.cbData = 0;
5094 info.CertSerialNumber.cbData = sizeof(serialNum);
5095 info.CertSerialNumber.pbData = (BYTE *)serialNum;
5096 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
5097 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5098 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
5099 if (ret)
5101 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %ld\n",
5102 size);
5103 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
5104 LocalFree(buf);
5108 static void test_decodeAuthorityKeyId(DWORD dwEncoding)
5110 BOOL ret;
5111 LPBYTE buf = NULL;
5112 DWORD size = 0;
5114 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
5115 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
5116 &buf, &size);
5117 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
5118 if (ret)
5120 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
5122 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %ld\n",
5123 size);
5124 ok(info->KeyId.cbData == 0, "Expected no key id\n");
5125 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
5126 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
5127 LocalFree(buf);
5129 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
5130 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
5131 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5132 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
5133 if (ret)
5135 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
5137 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %ld\n",
5138 size);
5139 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
5140 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
5141 "Unexpected key id\n");
5142 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
5143 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
5144 LocalFree(buf);
5146 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
5147 authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer),
5148 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5149 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
5150 if (ret)
5152 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
5154 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %ld\n",
5155 size);
5156 ok(info->KeyId.cbData == 0, "Expected no key id\n");
5157 ok(info->CertIssuer.cbData == sizeof(encodedCommonName),
5158 "Unexpected issuer len\n");
5159 ok(!memcmp(info->CertIssuer.pbData, encodedCommonName,
5160 sizeof(encodedCommonName)), "Unexpected issuer\n");
5161 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
5162 LocalFree(buf);
5164 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
5165 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
5166 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5167 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
5168 if (ret)
5170 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
5172 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %ld\n",
5173 size);
5174 ok(info->KeyId.cbData == 0, "Expected no key id\n");
5175 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
5176 ok(info->CertSerialNumber.cbData == sizeof(serialNum),
5177 "Unexpected serial number len\n");
5178 ok(!memcmp(info->CertSerialNumber.pbData, serialNum, sizeof(serialNum)),
5179 "Unexpected serial number\n");
5180 LocalFree(buf);
5184 static const BYTE authorityKeyIdWithIssuerUrl[] = { 0x30,0x15,0xa1,0x13,0x86,
5185 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
5186 0x6f,0x72,0x67 };
5188 static void test_encodeAuthorityKeyId2(DWORD dwEncoding)
5190 CERT_AUTHORITY_KEY_ID2_INFO info = { { 0 } };
5191 CERT_ALT_NAME_ENTRY entry = { 0 };
5192 BOOL ret;
5193 BYTE *buf = NULL;
5194 DWORD size = 0;
5196 /* Test with empty id */
5197 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
5198 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5199 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
5200 if (ret)
5202 ok(size == sizeof(emptySequence), "Unexpected size %ld\n", size);
5203 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
5204 LocalFree(buf);
5206 /* With just a key id */
5207 info.KeyId.cbData = sizeof(keyId);
5208 info.KeyId.pbData = keyId;
5209 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
5210 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5211 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
5212 if (ret)
5214 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %ld\n",
5215 size);
5216 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
5217 LocalFree(buf);
5219 /* With a bogus issuer name */
5220 info.KeyId.cbData = 0;
5221 info.AuthorityCertIssuer.cAltEntry = 1;
5222 info.AuthorityCertIssuer.rgAltEntry = &entry;
5223 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
5224 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5225 ok(!ret && GetLastError() == E_INVALIDARG,
5226 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
5227 /* With an issuer name */
5228 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
5229 U(entry).pwszURL = (LPWSTR)url;
5230 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
5231 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5232 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
5233 if (ret)
5235 ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %ld\n",
5236 size);
5237 ok(!memcmp(buf, authorityKeyIdWithIssuerUrl, size),
5238 "Unexpected value\n");
5239 LocalFree(buf);
5241 /* With just a serial number */
5242 info.AuthorityCertIssuer.cAltEntry = 0;
5243 info.AuthorityCertSerialNumber.cbData = sizeof(serialNum);
5244 info.AuthorityCertSerialNumber.pbData = (BYTE *)serialNum;
5245 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
5246 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5247 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
5248 if (ret)
5250 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %ld\n",
5251 size);
5252 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
5253 LocalFree(buf);
5257 static void test_decodeAuthorityKeyId2(DWORD dwEncoding)
5259 BOOL ret;
5260 LPBYTE buf = NULL;
5261 DWORD size = 0;
5263 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
5264 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
5265 &buf, &size);
5266 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
5267 if (ret)
5269 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
5271 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %ld\n",
5272 size);
5273 ok(info->KeyId.cbData == 0, "Expected no key id\n");
5274 ok(info->AuthorityCertIssuer.cAltEntry == 0,
5275 "Expected no issuer name entries\n");
5276 ok(info->AuthorityCertSerialNumber.cbData == 0,
5277 "Expected no serial number\n");
5278 LocalFree(buf);
5280 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
5281 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
5282 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5283 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
5284 if (ret)
5286 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
5288 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %ld\n",
5289 size);
5290 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
5291 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
5292 "Unexpected key id\n");
5293 ok(info->AuthorityCertIssuer.cAltEntry == 0,
5294 "Expected no issuer name entries\n");
5295 ok(info->AuthorityCertSerialNumber.cbData == 0,
5296 "Expected no serial number\n");
5297 LocalFree(buf);
5299 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
5300 authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl),
5301 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5302 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
5303 if (ret)
5305 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
5307 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %ld\n",
5308 size);
5309 ok(info->KeyId.cbData == 0, "Expected no key id\n");
5310 ok(info->AuthorityCertIssuer.cAltEntry == 1,
5311 "Expected 1 issuer entry, got %ld\n",
5312 info->AuthorityCertIssuer.cAltEntry);
5313 ok(info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice ==
5314 CERT_ALT_NAME_URL, "Expected CERT_ALT_NAME_URL, got %ld\n",
5315 info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice);
5316 ok(!lstrcmpW(U(info->AuthorityCertIssuer.rgAltEntry[0]).pwszURL,
5317 url), "Unexpected URL\n");
5318 ok(info->AuthorityCertSerialNumber.cbData == 0,
5319 "Expected no serial number\n");
5320 LocalFree(buf);
5322 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
5323 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
5324 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5325 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
5326 if (ret)
5328 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
5330 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %ld\n",
5331 size);
5332 ok(info->KeyId.cbData == 0, "Expected no key id\n");
5333 ok(info->AuthorityCertIssuer.cAltEntry == 0,
5334 "Expected no issuer name entries\n");
5335 ok(info->AuthorityCertSerialNumber.cbData == sizeof(serialNum),
5336 "Unexpected serial number len\n");
5337 ok(!memcmp(info->AuthorityCertSerialNumber.pbData, serialNum,
5338 sizeof(serialNum)), "Unexpected serial number\n");
5339 LocalFree(buf);
5343 static const BYTE authorityInfoAccessWithUrl[] = {
5344 0x30,0x19,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
5345 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5346 static const BYTE authorityInfoAccessWithUrlAndIPAddr[] = {
5347 0x30,0x29,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
5348 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x0e,0x06,
5349 0x02,0x2d,0x06,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5351 static void test_encodeAuthorityInfoAccess(DWORD dwEncoding)
5353 static char oid1[] = "1.2.3";
5354 static char oid2[] = "1.5.6";
5355 BOOL ret;
5356 BYTE *buf = NULL;
5357 DWORD size = 0;
5358 CERT_ACCESS_DESCRIPTION accessDescription[2];
5359 CERT_AUTHORITY_INFO_ACCESS aia;
5361 memset(accessDescription, 0, sizeof(accessDescription));
5362 aia.cAccDescr = 0;
5363 aia.rgAccDescr = NULL;
5364 /* Having no access descriptions is allowed */
5365 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5366 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5367 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
5368 if (ret)
5370 ok(size == sizeof(emptySequence), "unexpected size %ld\n", size);
5371 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
5372 LocalFree(buf);
5373 buf = NULL;
5375 /* It can't have an empty access method */
5376 aia.cAccDescr = 1;
5377 aia.rgAccDescr = accessDescription;
5378 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5379 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5380 ok(!ret && (GetLastError() == E_INVALIDARG ||
5381 GetLastError() == OSS_LIMITED /* Win9x */),
5382 "expected E_INVALIDARG or OSS_LIMITED, got %08lx\n", GetLastError());
5383 /* It can't have an empty location */
5384 accessDescription[0].pszAccessMethod = oid1;
5385 SetLastError(0xdeadbeef);
5386 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5387 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5388 ok(!ret && GetLastError() == E_INVALIDARG,
5389 "expected E_INVALIDARG, got %08lx\n", GetLastError());
5390 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5391 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
5392 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5393 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5394 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
5395 if (ret)
5397 ok(size == sizeof(authorityInfoAccessWithUrl), "unexpected size %ld\n",
5398 size);
5399 ok(!memcmp(buf, authorityInfoAccessWithUrl, size),
5400 "unexpected value\n");
5401 LocalFree(buf);
5402 buf = NULL;
5404 accessDescription[1].pszAccessMethod = oid2;
5405 accessDescription[1].AccessLocation.dwAltNameChoice =
5406 CERT_ALT_NAME_IP_ADDRESS;
5407 U(accessDescription[1].AccessLocation).IPAddress.cbData =
5408 sizeof(encodedIPAddr);
5409 U(accessDescription[1].AccessLocation).IPAddress.pbData =
5410 (LPBYTE)encodedIPAddr;
5411 aia.cAccDescr = 2;
5412 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5413 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5414 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
5415 if (ret)
5417 ok(size == sizeof(authorityInfoAccessWithUrlAndIPAddr),
5418 "unexpected size %ld\n", size);
5419 ok(!memcmp(buf, authorityInfoAccessWithUrlAndIPAddr, size),
5420 "unexpected value\n");
5421 LocalFree(buf);
5422 buf = NULL;
5426 static void compareAuthorityInfoAccess(LPCSTR header,
5427 const CERT_AUTHORITY_INFO_ACCESS *expected,
5428 const CERT_AUTHORITY_INFO_ACCESS *got)
5430 DWORD i;
5432 ok(expected->cAccDescr == got->cAccDescr,
5433 "%s: expected %ld access descriptions, got %ld\n", header,
5434 expected->cAccDescr, got->cAccDescr);
5435 for (i = 0; i < expected->cAccDescr; i++)
5437 ok(!strcmp(expected->rgAccDescr[i].pszAccessMethod,
5438 got->rgAccDescr[i].pszAccessMethod), "%s[%ld]: expected %s, got %s\n",
5439 header, i, expected->rgAccDescr[i].pszAccessMethod,
5440 got->rgAccDescr[i].pszAccessMethod);
5441 compareAltNameEntry(&expected->rgAccDescr[i].AccessLocation,
5442 &got->rgAccDescr[i].AccessLocation);
5446 static void test_decodeAuthorityInfoAccess(DWORD dwEncoding)
5448 static char oid1[] = "1.2.3";
5449 static char oid2[] = "1.5.6";
5450 BOOL ret;
5451 LPBYTE buf = NULL;
5452 DWORD size = 0;
5454 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5455 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
5456 &buf, &size);
5457 ok(ret, "CryptDecodeObjectEx failed: %lx\n", GetLastError());
5458 if (ret)
5460 CERT_AUTHORITY_INFO_ACCESS aia = { 0, NULL };
5462 compareAuthorityInfoAccess("empty AIA", &aia,
5463 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5464 LocalFree(buf);
5465 buf = NULL;
5467 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5468 authorityInfoAccessWithUrl, sizeof(authorityInfoAccessWithUrl),
5469 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5470 ok(ret, "CryptDecodeObjectEx failed: %lx\n", GetLastError());
5471 if (ret)
5473 CERT_ACCESS_DESCRIPTION accessDescription;
5474 CERT_AUTHORITY_INFO_ACCESS aia;
5476 accessDescription.pszAccessMethod = oid1;
5477 accessDescription.AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5478 U(accessDescription.AccessLocation).pwszURL = (LPWSTR)url;
5479 aia.cAccDescr = 1;
5480 aia.rgAccDescr = &accessDescription;
5481 compareAuthorityInfoAccess("AIA with URL", &aia,
5482 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5483 LocalFree(buf);
5484 buf = NULL;
5486 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5487 authorityInfoAccessWithUrlAndIPAddr,
5488 sizeof(authorityInfoAccessWithUrlAndIPAddr), CRYPT_DECODE_ALLOC_FLAG,
5489 NULL, &buf, &size);
5490 ok(ret, "CryptDecodeObjectEx failed: %lx\n", GetLastError());
5491 if (ret)
5493 CERT_ACCESS_DESCRIPTION accessDescription[2];
5494 CERT_AUTHORITY_INFO_ACCESS aia;
5496 accessDescription[0].pszAccessMethod = oid1;
5497 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5498 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
5499 accessDescription[1].pszAccessMethod = oid2;
5500 accessDescription[1].AccessLocation.dwAltNameChoice =
5501 CERT_ALT_NAME_IP_ADDRESS;
5502 U(accessDescription[1].AccessLocation).IPAddress.cbData =
5503 sizeof(encodedIPAddr);
5504 U(accessDescription[1].AccessLocation).IPAddress.pbData =
5505 (LPBYTE)encodedIPAddr;
5506 aia.cAccDescr = 2;
5507 aia.rgAccDescr = accessDescription;
5508 compareAuthorityInfoAccess("AIA with URL and IP addr", &aia,
5509 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5510 LocalFree(buf);
5511 buf = NULL;
5513 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5514 authorityInfoAccessWithUrlAndIPAddr,
5515 sizeof(authorityInfoAccessWithUrlAndIPAddr), 0, NULL, NULL, &size);
5516 ok(ret, "CryptDecodeObjectEx failed: %lx\n", GetLastError());
5517 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
5518 if (buf)
5520 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5521 authorityInfoAccessWithUrlAndIPAddr,
5522 sizeof(authorityInfoAccessWithUrlAndIPAddr), 0, NULL, buf, &size);
5523 ok(ret, "CryptDecodeObjectEx failed: %lx\n", GetLastError());
5524 HeapFree(GetProcessHeap(), 0, buf);
5528 static const BYTE emptyCTL[] = {
5529 0x30,0x17,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5530 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5531 static const BYTE emptyCTLWithVersion1[] = {
5532 0x30,0x1a,0x02,0x01,0x01,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5533 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5534 static const BYTE ctlWithUsageIdentifier[] = {
5535 0x30,0x1b,0x30,0x04,0x06,0x02,0x2a,0x03,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
5536 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5537 static const BYTE ctlWithListIdentifier[] = {
5538 0x30,0x1a,0x30,0x00,0x04,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5539 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5540 static const BYTE ctlWithSequenceNumber[] = {
5541 0x30,0x1a,0x30,0x00,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5542 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5543 static const BYTE ctlWithThisUpdate[] = {
5544 0x30,0x15,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5545 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5546 static const BYTE ctlWithThisAndNextUpdate[] = {
5547 0x30,0x24,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5548 0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5549 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5550 static const BYTE ctlWithAlgId[] = {
5551 0x30,0x1b,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5552 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5553 static const BYTE ctlWithBogusEntry[] = {
5554 0x30,0x29,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5555 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x10,0x30,0x0e,0x04,
5556 0x01,0x01,0x31,0x09,0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,0x01 };
5557 static const BYTE ctlWithOneEntry[] = {
5558 0x30,0x2a,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5559 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x11,0x30,0x0f,0x04,
5560 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00 };
5561 static const BYTE ctlWithTwoEntries[] = {
5562 0x30,0x41,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5563 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x28,0x30,0x0f,0x04,
5564 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00,0x30,
5565 0x15,0x04,0x01,0x01,0x31,0x10,0x30,0x0e,0x06,0x02,0x2d,0x06,0x31,0x08,0x30,
5566 0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5568 static void test_encodeCTL(DWORD dwEncoding)
5570 static char oid1[] = "1.2.3";
5571 static char oid2[] = "1.5.6";
5572 char *pOid1 = oid1;
5573 BOOL ret;
5574 BYTE *buf = NULL;
5575 DWORD size = 0;
5576 CTL_INFO info;
5577 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5578 CTL_ENTRY ctlEntry[2];
5579 CRYPT_ATTRIBUTE attr1, attr2;
5580 CRYPT_ATTR_BLOB value1, value2;
5582 memset(&info, 0, sizeof(info));
5583 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5584 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5585 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
5586 if (ret)
5588 ok(size == sizeof(emptyCTL), "unexpected size %ld\n", size);
5589 ok(!memcmp(buf, emptyCTL, size), "unexpected value\n");
5590 LocalFree(buf);
5591 buf = NULL;
5593 info.dwVersion = 1;
5594 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5595 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5596 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
5597 if (ret)
5599 ok(size == sizeof(emptyCTLWithVersion1), "unexpected size %ld\n", size);
5600 ok(!memcmp(buf, emptyCTLWithVersion1, size), "unexpected value\n");
5601 LocalFree(buf);
5602 buf = NULL;
5604 info.dwVersion = 0;
5605 info.SubjectUsage.cUsageIdentifier = 1;
5606 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5607 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5608 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5609 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
5610 if (ret)
5612 ok(size == sizeof(ctlWithUsageIdentifier), "unexpected size %ld\n",
5613 size);
5614 ok(!memcmp(buf, ctlWithUsageIdentifier, size), "unexpected value\n");
5615 LocalFree(buf);
5616 buf = NULL;
5618 info.SubjectUsage.cUsageIdentifier = 0;
5619 info.ListIdentifier.cbData = sizeof(serialNum);
5620 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5621 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5622 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5623 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
5624 if (ret)
5626 ok(size == sizeof(ctlWithListIdentifier), "unexpected size %ld\n", size);
5627 ok(!memcmp(buf, ctlWithListIdentifier, size), "unexpected value\n");
5628 LocalFree(buf);
5629 buf = NULL;
5631 info.ListIdentifier.cbData = 0;
5632 info.SequenceNumber.cbData = sizeof(serialNum);
5633 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5634 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5635 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5636 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
5637 if (ret)
5639 ok(size == sizeof(ctlWithSequenceNumber), "unexpected size %ld\n",
5640 size);
5641 ok(!memcmp(buf, ctlWithSequenceNumber, size), "unexpected value\n");
5642 LocalFree(buf);
5643 buf = NULL;
5645 info.SequenceNumber.cbData = 0;
5646 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5647 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5648 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5649 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
5650 if (ret)
5652 ok(size == sizeof(ctlWithThisUpdate), "unexpected size %ld\n", size);
5653 ok(!memcmp(buf, ctlWithThisUpdate, size), "unexpected value\n");
5654 LocalFree(buf);
5655 buf = NULL;
5657 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5658 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5659 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5660 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
5661 if (ret)
5663 ok(size == sizeof(ctlWithThisAndNextUpdate), "unexpected size %ld\n",
5664 size);
5665 ok(!memcmp(buf, ctlWithThisAndNextUpdate, size), "unexpected value\n");
5666 LocalFree(buf);
5667 buf = NULL;
5669 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5670 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5671 info.SubjectAlgorithm.pszObjId = oid2;
5672 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5673 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5674 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
5675 if (ret)
5677 ok(size == sizeof(ctlWithAlgId), "unexpected size %ld\n", size);
5678 ok(!memcmp(buf, ctlWithAlgId, size), "unexpected value\n");
5679 LocalFree(buf);
5680 buf = NULL;
5682 /* The value is supposed to be asn.1 encoded, so this'll fail to decode
5683 * (see tests below) but it'll encode fine.
5685 info.SubjectAlgorithm.pszObjId = NULL;
5686 value1.cbData = sizeof(serialNum);
5687 value1.pbData = (LPBYTE)serialNum;
5688 attr1.pszObjId = oid1;
5689 attr1.cValue = 1;
5690 attr1.rgValue = &value1;
5691 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5692 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5693 ctlEntry[0].cAttribute = 1;
5694 ctlEntry[0].rgAttribute = &attr1;
5695 info.cCTLEntry = 1;
5696 info.rgCTLEntry = ctlEntry;
5697 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5698 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5699 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
5700 if (ret)
5702 ok(size == sizeof(ctlWithBogusEntry), "unexpected size %ld\n", size);
5703 ok(!memcmp(buf, ctlWithBogusEntry, size), "unexpected value\n");
5704 LocalFree(buf);
5705 buf = NULL;
5707 value1.cbData = sizeof(emptySequence);
5708 value1.pbData = (LPBYTE)emptySequence;
5709 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5710 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5711 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
5712 if (ret)
5714 ok(size == sizeof(ctlWithOneEntry), "unexpected size %ld\n", size);
5715 ok(!memcmp(buf, ctlWithOneEntry, size), "unexpected value\n");
5716 LocalFree(buf);
5717 buf = NULL;
5719 value2.cbData = sizeof(encodedIPAddr);
5720 value2.pbData = (LPBYTE)encodedIPAddr;
5721 attr2.pszObjId = oid2;
5722 attr2.cValue = 1;
5723 attr2.rgValue = &value2;
5724 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5725 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5726 ctlEntry[1].cAttribute = 1;
5727 ctlEntry[1].rgAttribute = &attr2;
5728 info.cCTLEntry = 2;
5729 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5730 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5731 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
5732 if (ret)
5734 ok(size == sizeof(ctlWithTwoEntries), "unexpected size %ld\n", size);
5735 ok(!memcmp(buf, ctlWithTwoEntries, size), "unexpected value\n");
5736 LocalFree(buf);
5737 buf = NULL;
5741 static void compareCTLInfo(LPCSTR header, const CTL_INFO *expected,
5742 const CTL_INFO *got)
5744 DWORD i, j, k;
5746 ok(expected->dwVersion == got->dwVersion,
5747 "%s: expected version %ld, got %ld\n", header, expected->dwVersion,
5748 got->dwVersion);
5749 ok(expected->SubjectUsage.cUsageIdentifier ==
5750 got->SubjectUsage.cUsageIdentifier,
5751 "%s: expected %ld usage identifiers, got %ld\n", header,
5752 expected->SubjectUsage.cUsageIdentifier,
5753 got->SubjectUsage.cUsageIdentifier);
5754 for (i = 0; i < expected->SubjectUsage.cUsageIdentifier; i++)
5755 ok(!strcmp(expected->SubjectUsage.rgpszUsageIdentifier[i],
5756 got->SubjectUsage.rgpszUsageIdentifier[i]),
5757 "%s[%ld]: expected %s, got %s\n", header, i,
5758 expected->SubjectUsage.rgpszUsageIdentifier[i],
5759 got->SubjectUsage.rgpszUsageIdentifier[i]);
5760 ok(expected->ListIdentifier.cbData == got->ListIdentifier.cbData,
5761 "%s: expected list identifier of %ld bytes, got %ld\n", header,
5762 expected->ListIdentifier.cbData, got->ListIdentifier.cbData);
5763 if (expected->ListIdentifier.cbData)
5764 ok(!memcmp(expected->ListIdentifier.pbData, got->ListIdentifier.pbData,
5765 expected->ListIdentifier.cbData),
5766 "%s: unexpected list identifier value\n", header);
5767 ok(expected->SequenceNumber.cbData == got->SequenceNumber.cbData,
5768 "%s: expected sequence number of %ld bytes, got %ld\n", header,
5769 expected->SequenceNumber.cbData, got->SequenceNumber.cbData);
5770 if (expected->SequenceNumber.cbData)
5771 ok(!memcmp(expected->SequenceNumber.pbData, got->SequenceNumber.pbData,
5772 expected->SequenceNumber.cbData),
5773 "%s: unexpected sequence number value\n", header);
5774 ok(!memcmp(&expected->ThisUpdate, &got->ThisUpdate, sizeof(FILETIME)),
5775 "%s: expected this update = (%ld, %ld), got (%ld, %ld)\n", header,
5776 expected->ThisUpdate.dwLowDateTime, expected->ThisUpdate.dwHighDateTime,
5777 got->ThisUpdate.dwLowDateTime, got->ThisUpdate.dwHighDateTime);
5778 ok(!memcmp(&expected->NextUpdate, &got->NextUpdate, sizeof(FILETIME)),
5779 "%s: expected next update = (%ld, %ld), got (%ld, %ld)\n", header,
5780 expected->NextUpdate.dwLowDateTime, expected->NextUpdate.dwHighDateTime,
5781 got->NextUpdate.dwLowDateTime, got->NextUpdate.dwHighDateTime);
5782 if (expected->SubjectAlgorithm.pszObjId &&
5783 *expected->SubjectAlgorithm.pszObjId && !got->SubjectAlgorithm.pszObjId)
5784 ok(0, "%s: expected subject algorithm %s, got NULL\n", header,
5785 expected->SubjectAlgorithm.pszObjId);
5786 if (expected->SubjectAlgorithm.pszObjId && got->SubjectAlgorithm.pszObjId)
5787 ok(!strcmp(expected->SubjectAlgorithm.pszObjId,
5788 got->SubjectAlgorithm.pszObjId),
5789 "%s: expected subject algorithm %s, got %s\n", header,
5790 expected->SubjectAlgorithm.pszObjId, got->SubjectAlgorithm.pszObjId);
5791 ok(expected->SubjectAlgorithm.Parameters.cbData ==
5792 got->SubjectAlgorithm.Parameters.cbData,
5793 "%s: expected subject algorithm parameters of %ld bytes, got %ld\n", header,
5794 expected->SubjectAlgorithm.Parameters.cbData,
5795 got->SubjectAlgorithm.Parameters.cbData);
5796 if (expected->SubjectAlgorithm.Parameters.cbData)
5797 ok(!memcmp(expected->SubjectAlgorithm.Parameters.pbData,
5798 got->SubjectAlgorithm.Parameters.pbData,
5799 expected->SubjectAlgorithm.Parameters.cbData),
5800 "%s: unexpected subject algorithm parameter value\n", header);
5801 ok(expected->cCTLEntry == got->cCTLEntry,
5802 "%s: expected %ld CTL entries, got %ld\n", header, expected->cCTLEntry,
5803 got->cCTLEntry);
5804 for (i = 0; i < expected->cCTLEntry; i++)
5806 ok(expected->rgCTLEntry[i].SubjectIdentifier.cbData ==
5807 got->rgCTLEntry[i].SubjectIdentifier.cbData,
5808 "%s[%ld]: expected subject identifier of %ld bytes, got %ld\n",
5809 header, i, expected->rgCTLEntry[i].SubjectIdentifier.cbData,
5810 got->rgCTLEntry[i].SubjectIdentifier.cbData);
5811 if (expected->rgCTLEntry[i].SubjectIdentifier.cbData)
5812 ok(!memcmp(expected->rgCTLEntry[i].SubjectIdentifier.pbData,
5813 got->rgCTLEntry[i].SubjectIdentifier.pbData,
5814 expected->rgCTLEntry[i].SubjectIdentifier.cbData),
5815 "%s[%ld]: unexpected subject identifier value\n",
5816 header, i);
5817 for (j = 0; j < expected->rgCTLEntry[i].cAttribute; j++)
5819 ok(!strcmp(expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5820 got->rgCTLEntry[i].rgAttribute[j].pszObjId),
5821 "%s[%ld][%ld]: expected attribute OID %s, got %s\n", header, i, j,
5822 expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5823 got->rgCTLEntry[i].rgAttribute[j].pszObjId);
5824 for (k = 0; k < expected->rgCTLEntry[i].rgAttribute[j].cValue; k++)
5826 ok(expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData ==
5827 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5828 "%s[%ld][%ld][%ld]: expected value of %ld bytes, got %ld\n",
5829 header, i, j, k,
5830 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5831 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData);
5832 if (expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData)
5833 ok(!memcmp(
5834 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5835 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5836 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData),
5837 "%s[%ld][%ld][%ld]: unexpected value\n",
5838 header, i, j, k);
5842 ok(expected->cExtension == got->cExtension,
5843 "%s: expected %ld extensions, got %ld\n", header, expected->cExtension,
5844 got->cExtension);
5845 for (i = 0; i < expected->cExtension; i++)
5847 ok(!strcmp(expected->rgExtension[i].pszObjId,
5848 got->rgExtension[i].pszObjId), "%s[%ld]: expected %s, got %s\n",
5849 header, i, expected->rgExtension[i].pszObjId,
5850 got->rgExtension[i].pszObjId);
5851 ok(expected->rgExtension[i].fCritical == got->rgExtension[i].fCritical,
5852 "%s[%ld]: expected fCritical = %d, got %d\n", header, i,
5853 expected->rgExtension[i].fCritical, got->rgExtension[i].fCritical);
5854 ok(expected->rgExtension[i].Value.cbData ==
5855 got->rgExtension[i].Value.cbData,
5856 "%s[%ld]: expected extension value to have %ld bytes, got %ld\n",
5857 header, i, expected->rgExtension[i].Value.cbData,
5858 got->rgExtension[i].Value.cbData);
5859 if (expected->rgExtension[i].Value.cbData)
5860 ok(!memcmp(expected->rgExtension[i].Value.pbData,
5861 got->rgExtension[i].Value.pbData,
5862 expected->rgExtension[i].Value.cbData),
5863 "%s[%ld]: unexpected extension value\n", header, i);
5867 static const BYTE signedCTL[] = {
5868 0x30,0x81,0xc7,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
5869 0x81,0xb9,0x30,0x81,0xb6,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
5870 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x28,0x06,0x09,0x2a,0x86,
5871 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x1b,0x04,0x19,0x30,0x17,0x30,0x00,
5872 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5873 0x30,0x5a,0x30,0x02,0x06,0x00,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
5874 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
5875 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
5876 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5877 0x00,0x04,0x40,0xca,0xd8,0x32,0xd1,0xbd,0x97,0x61,0x54,0xd6,0x80,0xcf,0x0d,
5878 0xbd,0xa2,0x42,0xc7,0xca,0x37,0x91,0x7d,0x9d,0xac,0x8c,0xdf,0x05,0x8a,0x39,
5879 0xc6,0x07,0xc1,0x37,0xe6,0xb9,0xd1,0x0d,0x26,0xec,0xa5,0xb0,0x8a,0x51,0x26,
5880 0x2b,0x4f,0x73,0x44,0x86,0x83,0x5e,0x2b,0x6e,0xcc,0xf8,0x1b,0x85,0x53,0xe9,
5881 0x7a,0x80,0x8f,0x6b,0x42,0x19,0x93 };
5882 static const BYTE signedCTLWithCTLInnerContent[] = {
5883 0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
5884 0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
5885 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
5886 0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
5887 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5888 0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
5889 0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
5890 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
5891 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
5892 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
5893 0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
5894 0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
5895 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
5896 0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5897 0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
5898 0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
5899 0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
5900 0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
5901 0x57,0x6c,0x0b,0x47,0xb8 };
5903 static void test_decodeCTL(DWORD dwEncoding)
5905 static char oid1[] = "1.2.3";
5906 static char oid2[] = "1.5.6";
5907 static BYTE nullData[] = { 5,0 };
5908 char *pOid1 = oid1;
5909 BOOL ret;
5910 BYTE *buf = NULL;
5911 DWORD size = 0;
5912 CTL_INFO info;
5913 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5914 CTL_ENTRY ctlEntry[2];
5915 CRYPT_ATTRIBUTE attr1, attr2;
5916 CRYPT_ATTR_BLOB value1, value2;
5918 memset(&info, 0, sizeof(info));
5919 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTL, sizeof(emptyCTL),
5920 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5921 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
5922 if (ret)
5924 compareCTLInfo("empty CTL", &info, (CTL_INFO *)buf);
5925 LocalFree(buf);
5926 buf = NULL;
5928 info.dwVersion = 1;
5929 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTLWithVersion1,
5930 sizeof(emptyCTLWithVersion1), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
5931 &size);
5932 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
5933 if (ret)
5935 compareCTLInfo("v1 CTL", &info, (CTL_INFO *)buf);
5936 LocalFree(buf);
5937 buf = NULL;
5939 info.dwVersion = 0;
5940 info.SubjectUsage.cUsageIdentifier = 1;
5941 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5942 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithUsageIdentifier,
5943 sizeof(ctlWithUsageIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5944 &buf, &size);
5945 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
5946 if (ret)
5948 compareCTLInfo("CTL with usage identifier", &info, (CTL_INFO *)buf);
5949 LocalFree(buf);
5950 buf = NULL;
5952 info.SubjectUsage.cUsageIdentifier = 0;
5953 info.ListIdentifier.cbData = sizeof(serialNum);
5954 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5955 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithListIdentifier,
5956 sizeof(ctlWithListIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5957 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
5958 if (ret)
5960 compareCTLInfo("CTL with list identifier", &info, (CTL_INFO *)buf);
5961 LocalFree(buf);
5962 buf = NULL;
5964 info.ListIdentifier.cbData = 0;
5965 info.SequenceNumber.cbData = sizeof(serialNum);
5966 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5967 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithSequenceNumber,
5968 sizeof(ctlWithSequenceNumber), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5969 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
5970 if (ret)
5972 compareCTLInfo("CTL with sequence number", &info, (CTL_INFO *)buf);
5973 LocalFree(buf);
5974 buf = NULL;
5976 info.SequenceNumber.cbData = 0;
5977 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5978 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisUpdate,
5979 sizeof(ctlWithThisUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5980 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
5981 if (ret)
5983 compareCTLInfo("CTL with this update", &info, (CTL_INFO *)buf);
5984 LocalFree(buf);
5985 buf = NULL;
5987 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5988 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisAndNextUpdate,
5989 sizeof(ctlWithThisAndNextUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5990 &buf, &size);
5991 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
5992 if (ret)
5994 compareCTLInfo("CTL with this and next update", &info, (CTL_INFO *)buf);
5995 LocalFree(buf);
5996 buf = NULL;
5998 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5999 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
6000 info.SubjectAlgorithm.pszObjId = oid2;
6001 info.SubjectAlgorithm.Parameters.cbData = sizeof(nullData);
6002 info.SubjectAlgorithm.Parameters.pbData = nullData;
6003 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithAlgId,
6004 sizeof(ctlWithAlgId), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6005 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
6006 if (ret)
6008 compareCTLInfo("CTL with algorithm identifier", &info, (CTL_INFO *)buf);
6009 LocalFree(buf);
6010 buf = NULL;
6012 SetLastError(0xdeadbeef);
6013 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithBogusEntry,
6014 sizeof(ctlWithBogusEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6015 ok(!ret &&
6016 (GetLastError() == CRYPT_E_ASN1_EOD ||
6017 GetLastError() == CRYPT_E_ASN1_CORRUPT ||
6018 GetLastError() == OSS_MORE_INPUT), /* Win9x */
6019 "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08lx\n",
6020 GetLastError());
6021 info.SubjectAlgorithm.Parameters.cbData = 0;
6022 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
6023 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
6024 info.SubjectAlgorithm.pszObjId = NULL;
6025 value1.cbData = sizeof(emptySequence);
6026 value1.pbData = (LPBYTE)emptySequence;
6027 attr1.pszObjId = oid1;
6028 attr1.cValue = 1;
6029 attr1.rgValue = &value1;
6030 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
6031 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
6032 ctlEntry[0].cAttribute = 1;
6033 ctlEntry[0].rgAttribute = &attr1;
6034 info.cCTLEntry = 1;
6035 info.rgCTLEntry = ctlEntry;
6036 SetLastError(0xdeadbeef);
6037 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithOneEntry,
6038 sizeof(ctlWithOneEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6039 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
6040 if (ret)
6042 compareCTLInfo("CTL with one entry", &info, (CTL_INFO *)buf);
6043 LocalFree(buf);
6044 buf = NULL;
6046 value2.cbData = sizeof(encodedIPAddr);
6047 value2.pbData = (LPBYTE)encodedIPAddr;
6048 attr2.pszObjId = oid2;
6049 attr2.cValue = 1;
6050 attr2.rgValue = &value2;
6051 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
6052 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
6053 ctlEntry[1].cAttribute = 1;
6054 ctlEntry[1].rgAttribute = &attr2;
6055 info.cCTLEntry = 2;
6056 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithTwoEntries,
6057 sizeof(ctlWithTwoEntries), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6058 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
6059 if (ret)
6061 compareCTLInfo("CTL with two entries", &info, (CTL_INFO *)buf);
6062 LocalFree(buf);
6063 buf = NULL;
6065 /* A signed CTL isn't decodable, even if the inner content is a CTL */
6066 SetLastError(0xdeadbeef);
6067 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, signedCTL,
6068 sizeof(signedCTL), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6069 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
6070 GetLastError() == OSS_DATA_ERROR /* Win9x */),
6071 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08lx\n",
6072 GetLastError());
6073 SetLastError(0xdeadbeef);
6074 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL,
6075 signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent),
6076 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6077 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
6078 GetLastError() == OSS_DATA_ERROR /* Win9x */),
6079 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08lx\n",
6080 GetLastError());
6083 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
6084 static const BYTE emptyPKCSContentInfoExtraBytes[] = { 0x30,0x04,0x06,0x02,0x2a,
6085 0x03,0,0,0,0,0,0 };
6086 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
6087 0xa0,0x01,0x01 };
6088 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
6089 0x03,0x02,0x01,0x01 };
6090 static BYTE bogusDER[] = { 1 };
6092 static void test_encodePKCSContentInfo(DWORD dwEncoding)
6094 BOOL ret;
6095 BYTE *buf = NULL;
6096 DWORD size = 0;
6097 CRYPT_CONTENT_INFO info = { 0 };
6098 char oid1[] = "1.2.3";
6100 if (0)
6102 /* Crashes on win9x */
6103 SetLastError(0xdeadbeef);
6104 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL,
6105 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6106 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
6107 "Expected STATUS_ACCESS_VIOLATION, got %lx\n", GetLastError());
6109 SetLastError(0xdeadbeef);
6110 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
6111 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6112 ok(!ret && (GetLastError() == E_INVALIDARG ||
6113 GetLastError() == OSS_LIMITED /* Win9x */),
6114 "Expected E_INVALIDARG or OSS_LIMITED, got %lx\n", GetLastError());
6115 info.pszObjId = oid1;
6116 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
6117 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6118 ok(ret, "CryptEncodeObjectEx failed: %lx\n", GetLastError());
6119 if (ret)
6121 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %ld\n", size);
6122 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n");
6123 LocalFree(buf);
6125 info.Content.pbData = bogusDER;
6126 info.Content.cbData = sizeof(bogusDER);
6127 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
6128 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6129 ok(ret, "CryptEncodeObjectEx failed; %lx\n", GetLastError());
6130 if (ret)
6132 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %ld\n", size);
6133 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n");
6134 LocalFree(buf);
6136 info.Content.pbData = (BYTE *)ints[0].encoded;
6137 info.Content.cbData = ints[0].encoded[1] + 2;
6138 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
6139 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6140 if (ret)
6142 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %ld\n", size);
6143 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n");
6144 LocalFree(buf);
6148 static const BYTE indefiniteSignedPKCSContent[] = {
6149 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
6150 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
6151 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
6152 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
6153 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
6154 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
6155 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
6156 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
6157 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
6158 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
6159 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
6160 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
6161 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
6162 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
6163 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
6164 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
6165 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
6166 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
6167 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
6168 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
6169 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
6170 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
6171 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
6172 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
6173 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
6174 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
6175 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
6176 0x00,0x00,0x00,0x00,0x00,0x00 };
6178 static const BYTE content_abcd[] = {
6179 ASN_SEQUENCE, 0x80,
6180 ASN_OBJECTIDENTIFIER, 2, 42,3,
6181 ASN_CONTEXT|ASN_CONSTRUCTOR, 0x80,
6182 ASN_OCTETSTRING, 4, 'a','b','c','d',
6183 0,0,
6184 0,0,
6187 static const BYTE encoded_abcd[] = {
6188 ASN_OCTETSTRING, 4, 'a','b','c','d',
6191 static const BYTE content_constructed_abcd[] = {
6192 ASN_SEQUENCE, 0x80,
6193 ASN_OBJECTIDENTIFIER, 2, 42,3,
6194 ASN_CONTEXT|ASN_CONSTRUCTOR, 0x80,
6195 ASN_CONSTRUCTOR|ASN_OCTETSTRING,0x80,
6196 ASN_OCTETSTRING, 4, 'a','b','0','0',
6197 0,0,
6198 0,0,
6199 0,0,
6200 1,2,3,4,5,6,7 /* extra garbage */
6203 static void test_decodePKCSContentInfo(DWORD dwEncoding)
6205 BOOL ret;
6206 LPBYTE buf = NULL;
6207 DWORD size = 0, i;
6208 CRYPT_CONTENT_INFO *info;
6210 const struct {
6211 const BYTE *encoded;
6212 UINT encoded_size;
6213 const char *obj_id;
6214 const BYTE *content;
6215 UINT content_size;
6216 } tests[] = {
6217 { emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo),
6218 "1.2.3", NULL, 0 },
6219 { emptyPKCSContentInfoExtraBytes, sizeof(emptyPKCSContentInfoExtraBytes),
6220 "1.2.3", NULL, 0 },
6221 { intPKCSContentInfo, sizeof(intPKCSContentInfo),
6222 "1.2.3", ints[0].encoded, ints[0].encoded[1] + 2 },
6223 { indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent),
6224 "1.2.840.113549.1.7.2", NULL, 392 },
6225 { content_abcd, sizeof(content_abcd),
6226 "1.2.3", encoded_abcd, 6 },
6227 { content_constructed_abcd, sizeof(content_constructed_abcd),
6228 "1.2.3", content_constructed_abcd + 8, 10 }
6231 for (i = 0; i < ARRAY_SIZE(tests); i++)
6233 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, tests[i].encoded,
6234 tests[i].encoded_size, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6235 ok(ret, "[%lu] CryptDecodeObjectEx failed: %lx\n", i, GetLastError());
6236 if (!ret) continue;
6238 info = (CRYPT_CONTENT_INFO *)buf;
6240 ok(!strcmp(info->pszObjId, tests[i].obj_id), "[%lu] Expected %s, got %s\n",
6241 i, tests[i].obj_id, info->pszObjId);
6242 ok(info->Content.cbData == tests[i].content_size,
6243 "[%lu] Unexpected size %ld expected %d\n", i, info->Content.cbData,
6244 tests[i].content_size);
6245 if (tests[i].content)
6246 ok(!memcmp(info->Content.pbData, tests[i].content, tests[i].content_size),
6247 "[%lu] Unexpected value\n", i);
6248 LocalFree(buf);
6251 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
6252 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo),
6253 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6254 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
6255 * I doubt an app depends on that.
6257 ok((!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
6258 GetLastError() == CRYPT_E_ASN1_CORRUPT)) || broken(ret),
6259 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %lx\n",
6260 GetLastError());
6263 static const BYTE emptyPKCSAttr[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
6264 0x00 };
6265 static const BYTE bogusPKCSAttr[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
6266 0x01 };
6267 static const BYTE intPKCSAttr[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
6268 0x02,0x01,0x01 };
6270 static void test_encodePKCSAttribute(DWORD dwEncoding)
6272 CRYPT_ATTRIBUTE attr = { 0 };
6273 BOOL ret;
6274 LPBYTE buf = NULL;
6275 DWORD size = 0;
6276 CRYPT_ATTR_BLOB blob;
6277 char oid[] = "1.2.3";
6279 if (0)
6281 /* Crashes on win9x */
6282 SetLastError(0xdeadbeef);
6283 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, NULL,
6284 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6285 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
6286 "Expected STATUS_ACCESS_VIOLATION, got %lx\n", GetLastError());
6288 SetLastError(0xdeadbeef);
6289 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
6290 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6291 ok(!ret && (GetLastError() == E_INVALIDARG ||
6292 GetLastError() == OSS_LIMITED /* Win9x */),
6293 "Expected E_INVALIDARG or OSS_LIMITED, got %lx\n", GetLastError());
6294 attr.pszObjId = oid;
6295 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
6296 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6297 ok(ret, "CryptEncodeObjectEx failed: %lx\n", GetLastError());
6298 if (ret)
6300 ok(size == sizeof(emptyPKCSAttr), "Unexpected size %ld\n", size);
6301 ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n");
6302 LocalFree(buf);
6304 blob.cbData = sizeof(bogusDER);
6305 blob.pbData = bogusDER;
6306 attr.cValue = 1;
6307 attr.rgValue = &blob;
6308 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
6309 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6310 ok(ret, "CryptEncodeObjectEx failed: %lx\n", GetLastError());
6311 if (ret)
6313 ok(size == sizeof(bogusPKCSAttr), "Unexpected size %ld\n", size);
6314 ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n");
6315 LocalFree(buf);
6317 blob.pbData = (BYTE *)ints[0].encoded;
6318 blob.cbData = ints[0].encoded[1] + 2;
6319 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
6320 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6321 if (ret)
6323 ok(size == sizeof(intPKCSAttr), "Unexpected size %ld\n", size);
6324 ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n");
6325 LocalFree(buf);
6329 static void test_decodePKCSAttribute(DWORD dwEncoding)
6331 BOOL ret;
6332 LPBYTE buf = NULL;
6333 DWORD size = 0;
6334 CRYPT_ATTRIBUTE *attr;
6336 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
6337 emptyPKCSAttr, sizeof(emptyPKCSAttr),
6338 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6339 ok(ret, "CryptDecodeObjectEx failed: %lx\n", GetLastError());
6340 if (ret)
6342 attr = (CRYPT_ATTRIBUTE *)buf;
6344 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
6345 attr->pszObjId);
6346 ok(attr->cValue == 0, "Expected no value, got %ld\n", attr->cValue);
6347 LocalFree(buf);
6349 SetLastError(0xdeadbeef);
6350 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
6351 bogusPKCSAttr, sizeof(bogusPKCSAttr),
6352 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6353 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
6354 * I doubt an app depends on that.
6356 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
6357 GetLastError() == CRYPT_E_ASN1_CORRUPT ||
6358 GetLastError() == OSS_MORE_INPUT /* Win9x */),
6359 "Expected CRYPT_E_ASN1_EOD, CRYPT_E_ASN1_CORRUPT, or OSS_MORE_INPUT, got %lx\n",
6360 GetLastError());
6361 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
6362 intPKCSAttr, sizeof(intPKCSAttr),
6363 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6364 ok(ret, "CryptDecodeObjectEx failed: %lx\n", GetLastError());
6365 if (ret)
6367 attr = (CRYPT_ATTRIBUTE *)buf;
6369 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
6370 attr->pszObjId);
6371 ok(attr->cValue == 1, "Expected 1 value, got %ld\n", attr->cValue);
6372 ok(attr->rgValue[0].cbData == ints[0].encoded[1] + 2,
6373 "Unexpected size %ld\n", attr->rgValue[0].cbData);
6374 ok(!memcmp(attr->rgValue[0].pbData, ints[0].encoded,
6375 attr->rgValue[0].cbData), "Unexpected value\n");
6376 LocalFree(buf);
6380 static const BYTE emptyPKCSAttributes[] = { 0x31,0x00 };
6381 static const BYTE singlePKCSAttributes[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
6382 0x2a,0x03,0x31,0x00 };
6383 static const BYTE doublePKCSAttributes[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
6384 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
6386 static void test_encodePKCSAttributes(DWORD dwEncoding)
6388 CRYPT_ATTRIBUTES attributes = { 0 };
6389 CRYPT_ATTRIBUTE attr[2] = { { 0 } };
6390 CRYPT_ATTR_BLOB blob;
6391 BOOL ret;
6392 LPBYTE buf = NULL;
6393 DWORD size = 0;
6394 char oid1[] = "1.2.3", oid2[] = "1.5.6";
6396 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6397 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6398 ok(ret, "CryptEncodeObjectEx failed: %lx\n", GetLastError());
6399 if (ret)
6401 ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %ld\n", size);
6402 ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n");
6403 LocalFree(buf);
6405 attributes.cAttr = 1;
6406 attributes.rgAttr = attr;
6407 SetLastError(0xdeadbeef);
6408 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6409 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6410 ok(!ret && (GetLastError() == E_INVALIDARG ||
6411 GetLastError() == OSS_LIMITED /* Win9x */),
6412 "Expected E_INVALIDARG or OSS_LIMITED, got %08lx\n", GetLastError());
6413 attr[0].pszObjId = oid1;
6414 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6415 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6416 if (ret)
6418 ok(size == sizeof(singlePKCSAttributes), "Unexpected size %ld\n", size);
6419 ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n");
6420 LocalFree(buf);
6422 attr[1].pszObjId = oid2;
6423 attr[1].cValue = 1;
6424 attr[1].rgValue = &blob;
6425 blob.pbData = (BYTE *)ints[0].encoded;
6426 blob.cbData = ints[0].encoded[1] + 2;
6427 attributes.cAttr = 2;
6428 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6429 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6430 ok(ret, "CryptEncodeObjectEx failed: %lx\n", GetLastError());
6431 if (ret)
6433 ok(size == sizeof(doublePKCSAttributes), "Unexpected size %ld\n", size);
6434 ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n");
6435 LocalFree(buf);
6439 static void test_decodePKCSAttributes(DWORD dwEncoding)
6441 BOOL ret;
6442 LPBYTE buf = NULL;
6443 DWORD size = 0;
6444 CRYPT_ATTRIBUTES *attributes;
6446 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6447 emptyPKCSAttributes, sizeof(emptyPKCSAttributes),
6448 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6449 ok(ret, "CryptDecodeObjectEx failed: %lx\n", GetLastError());
6450 if (ret)
6452 attributes = (CRYPT_ATTRIBUTES *)buf;
6453 ok(attributes->cAttr == 0, "Expected no attributes, got %ld\n",
6454 attributes->cAttr);
6455 LocalFree(buf);
6457 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6458 singlePKCSAttributes, sizeof(singlePKCSAttributes),
6459 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6460 ok(ret, "CryptDecodeObjectEx failed: %lx\n", GetLastError());
6461 if (ret)
6463 attributes = (CRYPT_ATTRIBUTES *)buf;
6464 ok(attributes->cAttr == 1, "Expected 1 attribute, got %ld\n",
6465 attributes->cAttr);
6466 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
6467 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
6468 ok(attributes->rgAttr[0].cValue == 0,
6469 "Expected no attributes, got %ld\n", attributes->rgAttr[0].cValue);
6470 LocalFree(buf);
6472 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6473 doublePKCSAttributes, sizeof(doublePKCSAttributes),
6474 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6475 ok(ret, "CryptDecodeObjectEx failed: %lx\n", GetLastError());
6476 if (ret)
6478 attributes = (CRYPT_ATTRIBUTES *)buf;
6479 ok(attributes->cAttr == 2, "Expected 2 attributes, got %ld\n",
6480 attributes->cAttr);
6481 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
6482 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
6483 ok(attributes->rgAttr[0].cValue == 0,
6484 "Expected no attributes, got %ld\n", attributes->rgAttr[0].cValue);
6485 ok(!strcmp(attributes->rgAttr[1].pszObjId, "1.5.6"),
6486 "Expected 1.5.6, got %s\n", attributes->rgAttr[1].pszObjId);
6487 ok(attributes->rgAttr[1].cValue == 1,
6488 "Expected 1 attribute, got %ld\n", attributes->rgAttr[1].cValue);
6489 ok(attributes->rgAttr[1].rgValue[0].cbData == ints[0].encoded[1] + 2,
6490 "Unexpected size %ld\n", attributes->rgAttr[1].rgValue[0].cbData);
6491 ok(!memcmp(attributes->rgAttr[1].rgValue[0].pbData, ints[0].encoded,
6492 attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n");
6493 LocalFree(buf);
6495 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6496 doublePKCSAttributes, sizeof(doublePKCSAttributes), 0, NULL, NULL, &size);
6497 ok(ret, "CryptDecodeObjectEx failed: %lx\n", GetLastError());
6498 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
6499 if (buf)
6501 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6502 doublePKCSAttributes, sizeof(doublePKCSAttributes), 0, NULL, buf, &size);
6503 ok(ret, "CryptDecodeObjectEx failed: %lx\n", GetLastError());
6504 HeapFree(GetProcessHeap(), 0, buf);
6508 static const BYTE singleCapability[] = {
6509 0x30,0x06,0x30,0x04,0x06,0x02,0x2d,0x06 };
6510 static const BYTE twoCapabilities[] = {
6511 0x30,0x0c,0x30,0x04,0x06,0x02,0x2d,0x06,0x30,0x04,0x06,0x02,0x2a,0x03 };
6512 static const BYTE singleCapabilitywithNULL[] = {
6513 0x30,0x08,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
6515 static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding)
6517 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6518 BOOL ret;
6519 LPBYTE buf = NULL;
6520 DWORD size = 0;
6521 CRYPT_SMIME_CAPABILITY capability[2];
6522 CRYPT_SMIME_CAPABILITIES capabilities;
6524 /* An empty capabilities is allowed */
6525 capabilities.cCapability = 0;
6526 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6527 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6528 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
6529 if (ret)
6531 ok(size == sizeof(emptySequence), "unexpected size %ld\n", size);
6532 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
6533 LocalFree(buf);
6535 /* A non-empty capabilities with an empty capability (lacking an OID) is
6536 * not allowed
6538 capability[0].pszObjId = NULL;
6539 capability[0].Parameters.cbData = 0;
6540 capabilities.cCapability = 1;
6541 capabilities.rgCapability = capability;
6542 SetLastError(0xdeadbeef);
6543 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6544 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6545 ok(!ret && (GetLastError() == E_INVALIDARG ||
6546 GetLastError() == OSS_LIMITED /* Win9x */),
6547 "Expected E_INVALIDARG or OSS_LIMITED, got %08lx\n", GetLastError());
6548 capability[0].pszObjId = oid1;
6549 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6550 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6551 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
6552 if (ret)
6554 ok(size == sizeof(singleCapability), "unexpected size %ld\n", size);
6555 ok(!memcmp(buf, singleCapability, size), "unexpected value\n");
6556 LocalFree(buf);
6558 capability[1].pszObjId = oid2;
6559 capability[1].Parameters.cbData = 0;
6560 capabilities.cCapability = 2;
6561 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6562 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6563 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
6564 if (ret)
6566 ok(size == sizeof(twoCapabilities), "unexpected size %ld\n", size);
6567 ok(!memcmp(buf, twoCapabilities, size), "unexpected value\n");
6568 LocalFree(buf);
6572 static void compareSMimeCapabilities(LPCSTR header,
6573 const CRYPT_SMIME_CAPABILITIES *expected, const CRYPT_SMIME_CAPABILITIES *got)
6575 DWORD i;
6577 ok(got->cCapability == expected->cCapability,
6578 "%s: expected %ld capabilities, got %ld\n", header, expected->cCapability,
6579 got->cCapability);
6580 for (i = 0; i < expected->cCapability; i++)
6582 ok(!strcmp(expected->rgCapability[i].pszObjId,
6583 got->rgCapability[i].pszObjId), "%s[%ld]: expected %s, got %s\n",
6584 header, i, expected->rgCapability[i].pszObjId,
6585 got->rgCapability[i].pszObjId);
6586 ok(expected->rgCapability[i].Parameters.cbData ==
6587 got->rgCapability[i].Parameters.cbData,
6588 "%s[%ld]: expected %ld bytes, got %ld\n", header, i,
6589 expected->rgCapability[i].Parameters.cbData,
6590 got->rgCapability[i].Parameters.cbData);
6591 if (expected->rgCapability[i].Parameters.cbData)
6592 ok(!memcmp(expected->rgCapability[i].Parameters.pbData,
6593 got->rgCapability[i].Parameters.pbData,
6594 expected->rgCapability[i].Parameters.cbData),
6595 "%s[%ld]: unexpected value\n", header, i);
6599 static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding)
6601 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6602 BOOL ret;
6603 DWORD size = 0;
6604 CRYPT_SMIME_CAPABILITY capability[2];
6605 CRYPT_SMIME_CAPABILITIES capabilities, *ptr;
6607 SetLastError(0xdeadbeef);
6608 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6609 emptySequence, sizeof(emptySequence),
6610 CRYPT_DECODE_ALLOC_FLAG, NULL, &ptr, &size);
6611 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
6612 if (ret)
6614 capabilities.cCapability = 0;
6615 compareSMimeCapabilities("empty capabilities", &capabilities, ptr);
6616 LocalFree(ptr);
6618 SetLastError(0xdeadbeef);
6619 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6620 singleCapability, sizeof(singleCapability), CRYPT_DECODE_ALLOC_FLAG, NULL,
6621 &ptr, &size);
6622 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
6623 if (ret)
6625 capability[0].pszObjId = oid1;
6626 capability[0].Parameters.cbData = 0;
6627 capabilities.cCapability = 1;
6628 capabilities.rgCapability = capability;
6629 compareSMimeCapabilities("single capability", &capabilities, ptr);
6630 LocalFree(ptr);
6632 SetLastError(0xdeadbeef);
6633 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6634 singleCapabilitywithNULL, sizeof(singleCapabilitywithNULL),
6635 CRYPT_DECODE_ALLOC_FLAG, NULL, &ptr, &size);
6636 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
6637 if (ret)
6639 BYTE NULLparam[] = {0x05, 0x00};
6640 capability[0].pszObjId = oid1;
6641 capability[0].Parameters.cbData = 2;
6642 capability[0].Parameters.pbData = NULLparam;
6643 capabilities.cCapability = 1;
6644 capabilities.rgCapability = capability;
6645 compareSMimeCapabilities("single capability with NULL", &capabilities,
6646 ptr);
6647 LocalFree(ptr);
6649 SetLastError(0xdeadbeef);
6650 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6651 twoCapabilities, sizeof(twoCapabilities), CRYPT_DECODE_ALLOC_FLAG, NULL,
6652 &ptr, &size);
6653 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
6654 if (ret)
6656 capability[0].Parameters.cbData = 0;
6657 capability[1].pszObjId = oid2;
6658 capability[1].Parameters.cbData = 0;
6659 capabilities.cCapability = 2;
6660 compareSMimeCapabilities("two capabilities", &capabilities, ptr);
6661 LocalFree(ptr);
6663 SetLastError(0xdeadbeef);
6664 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6665 twoCapabilities, sizeof(twoCapabilities), 0, NULL, NULL, &size);
6666 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
6667 ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
6668 if (ptr)
6670 SetLastError(0xdeadbeef);
6671 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6672 twoCapabilities, sizeof(twoCapabilities), 0, NULL, ptr, &size);
6673 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
6674 HeapFree(GetProcessHeap(), 0, ptr);
6678 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
6679 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
6680 0x67 };
6681 static const BYTE minimalPKCSSigner[] = {
6682 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6683 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6684 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6685 static const BYTE PKCSSignerWithSerial[] = {
6686 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6687 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6688 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
6689 0x00 };
6690 static const BYTE PKCSSignerWithHashAlgo[] = {
6691 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6692 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6693 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
6694 0x00,0x04,0x00 };
6695 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = {
6696 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6697 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6698 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6699 0x06,0x05,0x00,0x04,0x00 };
6700 static const BYTE PKCSSignerWithHash[] = {
6701 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6702 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6703 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6704 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
6705 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6706 static const BYTE PKCSSignerWithAuthAttr[] = {
6707 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6708 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6709 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
6710 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
6711 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
6712 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
6713 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6715 static void test_encodePKCSSignerInfo(DWORD dwEncoding)
6717 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6718 BOOL ret;
6719 LPBYTE buf = NULL;
6720 DWORD size = 0;
6721 CMSG_SIGNER_INFO info = { 0 };
6722 char oid_common_name[] = szOID_COMMON_NAME;
6723 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
6724 (LPBYTE)encodedCommonName };
6725 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
6727 SetLastError(0xdeadbeef);
6728 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6729 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6730 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6732 skip("no PKCS7_SIGNER_INFO encode support\n");
6733 return;
6735 ok(!ret && (GetLastError() == E_INVALIDARG ||
6736 GetLastError() == OSS_LIMITED /* Win9x */),
6737 "Expected E_INVALIDARG or OSS_LIMITED, got %08lx\n", GetLastError());
6738 /* To be encoded, a signer must have an issuer at least, and the encoding
6739 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
6740 * see decoding tests.)
6742 info.Issuer.cbData = sizeof(encodedCommonNameNoNull);
6743 info.Issuer.pbData = encodedCommonNameNoNull;
6744 SetLastError(0xdeadbeef);
6745 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6746 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6747 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6748 ok(!ret && GetLastError() == E_INVALIDARG,
6749 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
6750 else
6752 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6753 "CryptEncodeObjectEx failed: %lx\n", GetLastError());
6754 if (ret)
6756 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %ld\n", size);
6757 if (size == sizeof(minimalPKCSSigner))
6758 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6759 else
6760 ok(0, "Unexpected value\n");
6761 LocalFree(buf);
6764 info.SerialNumber.cbData = sizeof(serialNum);
6765 info.SerialNumber.pbData = (BYTE *)serialNum;
6766 SetLastError(0xdeadbeef);
6767 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6768 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6769 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6770 ok(!ret && GetLastError() == E_INVALIDARG,
6771 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
6772 else
6774 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6775 "CryptEncodeObjectEx failed: %lx\n", GetLastError());
6776 if (ret)
6778 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %ld\n",
6779 size);
6780 if (size == sizeof(PKCSSignerWithSerial))
6781 ok(!memcmp(buf, PKCSSignerWithSerial, size),
6782 "Unexpected value\n");
6783 else
6784 ok(0, "Unexpected value\n");
6785 LocalFree(buf);
6788 info.HashAlgorithm.pszObjId = oid1;
6789 SetLastError(0xdeadbeef);
6790 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6791 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6792 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6793 ok(!ret && GetLastError() == E_INVALIDARG,
6794 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
6795 else
6797 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6798 "CryptEncodeObjectEx failed: %lx\n", GetLastError());
6799 if (ret)
6801 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %ld\n",
6802 size);
6803 if (size == sizeof(PKCSSignerWithHashAlgo))
6804 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6805 "Unexpected value\n");
6806 else
6807 ok(0, "Unexpected value\n");
6808 LocalFree(buf);
6811 info.HashEncryptionAlgorithm.pszObjId = oid2;
6812 SetLastError(0xdeadbeef);
6813 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6814 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6815 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6816 ok(!ret && GetLastError() == E_INVALIDARG,
6817 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
6818 else
6820 ok(ret, "CryptEncodeObjectEx failed: %lx\n", GetLastError());
6821 if (ret)
6823 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6824 "Unexpected size %ld\n", size);
6825 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo))
6826 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6827 "Unexpected value\n");
6828 else
6829 ok(0, "Unexpected value\n");
6830 LocalFree(buf);
6833 info.EncryptedHash.cbData = sizeof(hash);
6834 info.EncryptedHash.pbData = (BYTE *)hash;
6835 SetLastError(0xdeadbeef);
6836 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6837 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6838 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6839 ok(!ret && GetLastError() == E_INVALIDARG,
6840 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
6841 else
6843 ok(ret, "CryptEncodeObjectEx failed: %lx\n", GetLastError());
6844 if (ret)
6846 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %ld\n",
6847 size);
6848 if (size == sizeof(PKCSSignerWithHash))
6849 ok(!memcmp(buf, PKCSSignerWithHash, size),
6850 "Unexpected value\n");
6851 else
6852 ok(0, "Unexpected value\n");
6853 LocalFree(buf);
6856 info.AuthAttrs.cAttr = 1;
6857 info.AuthAttrs.rgAttr = &attr;
6858 SetLastError(0xdeadbeef);
6859 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6860 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6861 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6862 ok(!ret && GetLastError() == E_INVALIDARG,
6863 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
6864 else
6866 ok(ret, "CryptEncodeObjectEx failed: %lx\n", GetLastError());
6867 if (ret)
6869 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %ld\n",
6870 size);
6871 if (size == sizeof(PKCSSignerWithAuthAttr))
6872 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
6873 "Unexpected value\n");
6874 else
6875 ok(0, "Unexpected value\n");
6876 LocalFree(buf);
6881 static void test_decodePKCSSignerInfo(DWORD dwEncoding)
6883 BOOL ret;
6884 LPBYTE buf = NULL;
6885 DWORD size = 0;
6886 CMSG_SIGNER_INFO *info;
6888 /* A PKCS signer can't be decoded without a serial number. */
6889 SetLastError(0xdeadbeef);
6890 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6891 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6892 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6893 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
6894 GetLastError() == OSS_DATA_ERROR /* Win9x */),
6895 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %lx\n",
6896 GetLastError());
6897 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6898 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6899 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6900 ok(ret || broken(GetLastError() == OSS_DATA_ERROR),
6901 "CryptDecodeObjectEx failed: %lx\n", GetLastError());
6902 if (ret)
6904 info = (CMSG_SIGNER_INFO *)buf;
6905 ok(info->dwVersion == 0, "Expected version 0, got %ld\n",
6906 info->dwVersion);
6907 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6908 "Unexpected size %ld\n", info->Issuer.cbData);
6909 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6910 info->Issuer.cbData), "Unexpected value\n");
6911 ok(info->SerialNumber.cbData == sizeof(serialNum),
6912 "Unexpected size %ld\n", info->SerialNumber.cbData);
6913 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6914 "Unexpected value\n");
6915 LocalFree(buf);
6917 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6918 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6919 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6920 if (ret)
6922 info = (CMSG_SIGNER_INFO *)buf;
6923 ok(info->dwVersion == 0, "Expected version 0, got %ld\n",
6924 info->dwVersion);
6925 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6926 "Unexpected size %ld\n", info->Issuer.cbData);
6927 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6928 info->Issuer.cbData), "Unexpected value\n");
6929 ok(info->SerialNumber.cbData == sizeof(serialNum),
6930 "Unexpected size %ld\n", info->SerialNumber.cbData);
6931 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6932 "Unexpected value\n");
6933 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6934 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6935 LocalFree(buf);
6937 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6938 PKCSSignerWithHashAndEncryptionAlgo,
6939 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6940 NULL, &buf, &size);
6941 if (ret)
6943 info = (CMSG_SIGNER_INFO *)buf;
6944 ok(info->dwVersion == 0, "Expected version 0, got %ld\n",
6945 info->dwVersion);
6946 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6947 "Unexpected size %ld\n", info->Issuer.cbData);
6948 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6949 info->Issuer.cbData), "Unexpected value\n");
6950 ok(info->SerialNumber.cbData == sizeof(serialNum),
6951 "Unexpected size %ld\n", info->SerialNumber.cbData);
6952 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6953 "Unexpected value\n");
6954 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6955 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6956 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6957 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6958 LocalFree(buf);
6960 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6961 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6962 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6963 if (ret)
6965 info = (CMSG_SIGNER_INFO *)buf;
6966 ok(info->dwVersion == 0, "Expected version 0, got %ld\n",
6967 info->dwVersion);
6968 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6969 "Unexpected size %ld\n", info->Issuer.cbData);
6970 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6971 info->Issuer.cbData), "Unexpected value\n");
6972 ok(info->SerialNumber.cbData == sizeof(serialNum),
6973 "Unexpected size %ld\n", info->SerialNumber.cbData);
6974 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6975 "Unexpected value\n");
6976 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6977 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6978 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6979 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6980 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %ld\n",
6981 info->EncryptedHash.cbData);
6982 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6983 "Unexpected value\n");
6984 LocalFree(buf);
6986 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6987 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
6988 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6989 if (ret)
6991 info = (CMSG_SIGNER_INFO *)buf;
6992 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %ld\n",
6993 info->AuthAttrs.cAttr);
6994 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
6995 "Expected %s, got %s\n", szOID_COMMON_NAME,
6996 info->AuthAttrs.rgAttr[0].pszObjId);
6997 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %ld\n",
6998 info->AuthAttrs.rgAttr[0].cValue);
6999 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
7000 sizeof(encodedCommonName), "Unexpected size %ld\n",
7001 info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
7002 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
7003 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
7004 LocalFree(buf);
7008 static const BYTE CMSSignerWithKeyId[] = {
7009 0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,
7010 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
7012 static void test_encodeCMSSignerInfo(DWORD dwEncoding)
7014 BOOL ret;
7015 LPBYTE buf = NULL;
7016 DWORD size = 0;
7017 CMSG_CMS_SIGNER_INFO info = { 0 };
7018 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
7020 SetLastError(0xdeadbeef);
7021 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
7022 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7023 ok(!ret, "Expected failure, got %d\n", ret);
7024 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7026 skip("no CMS_SIGNER_INFO encode support\n");
7027 return;
7029 ok(GetLastError() == E_INVALIDARG,
7030 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
7031 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
7032 SetLastError(0xdeadbeef);
7033 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
7034 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7035 ok(!ret, "Expected failure, got %d\n", ret);
7036 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7038 skip("no CMS_SIGNER_INFO encode support\n");
7039 return;
7041 ok(GetLastError() == E_INVALIDARG,
7042 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
7043 /* To be encoded, a signer must have a valid cert ID, where a valid ID may
7044 * be a key id or an issuer serial number with at least the issuer set, and
7045 * the encoding must include PKCS_7_ASN_ENCODING.
7046 * (That isn't enough to be decoded, see decoding tests.)
7048 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
7049 sizeof(encodedCommonNameNoNull);
7050 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
7051 SetLastError(0xdeadbeef);
7052 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
7053 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7054 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
7055 ok(!ret && GetLastError() == E_INVALIDARG,
7056 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
7057 else
7059 ok(ret, "CryptEncodeObjectEx failed: %lx\n", GetLastError());
7060 if (ret)
7062 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %ld\n", size);
7063 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
7064 LocalFree(buf);
7067 U(info.SignerId).IssuerSerialNumber.SerialNumber.cbData = sizeof(serialNum);
7068 U(info.SignerId).IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
7069 SetLastError(0xdeadbeef);
7070 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
7071 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7072 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
7073 ok(!ret && GetLastError() == E_INVALIDARG,
7074 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
7075 else
7077 ok(ret, "CryptEncodeObjectEx failed: %lx\n", GetLastError());
7078 if (ret)
7080 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %ld\n",
7081 size);
7082 ok(!memcmp(buf, PKCSSignerWithSerial, size), "Unexpected value\n");
7083 LocalFree(buf);
7086 info.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
7087 U(info.SignerId).KeyId.cbData = sizeof(serialNum);
7088 U(info.SignerId).KeyId.pbData = (BYTE *)serialNum;
7089 SetLastError(0xdeadbeef);
7090 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
7091 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7092 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
7093 ok(!ret && GetLastError() == E_INVALIDARG,
7094 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
7095 else
7097 ok(ret, "CryptEncodeObjectEx failed: %lx\n", GetLastError());
7098 if (ret)
7100 ok(size == sizeof(CMSSignerWithKeyId), "Unexpected size %ld\n",
7101 size);
7102 ok(!memcmp(buf, CMSSignerWithKeyId, size), "Unexpected value\n");
7103 LocalFree(buf);
7106 /* While a CERT_ID can have a hash type, that's not allowed in CMS, where
7107 * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed
7108 * (see RFC 3852, section 5.3.)
7110 info.SignerId.dwIdChoice = CERT_ID_SHA1_HASH;
7111 U(info.SignerId).HashId.cbData = sizeof(hash);
7112 U(info.SignerId).HashId.pbData = (BYTE *)hash;
7113 SetLastError(0xdeadbeef);
7114 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
7115 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7116 ok(!ret && GetLastError() == E_INVALIDARG,
7117 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
7118 /* Now with a hash algo */
7119 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
7120 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
7121 sizeof(encodedCommonNameNoNull);
7122 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
7123 info.HashAlgorithm.pszObjId = oid1;
7124 SetLastError(0xdeadbeef);
7125 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
7126 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7127 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
7128 ok(!ret && GetLastError() == E_INVALIDARG,
7129 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
7130 else
7132 ok(ret, "CryptEncodeObjectEx failed: %lx\n", GetLastError());
7133 if (ret)
7135 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %ld\n",
7136 size);
7137 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
7138 "Unexpected value\n");
7139 LocalFree(buf);
7142 info.HashEncryptionAlgorithm.pszObjId = oid2;
7143 SetLastError(0xdeadbeef);
7144 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
7145 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7146 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
7147 ok(!ret && GetLastError() == E_INVALIDARG,
7148 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
7149 else
7151 ok(ret, "CryptEncodeObjectEx failed: %lx\n", GetLastError());
7152 if (ret)
7154 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
7155 "Unexpected size %ld\n", size);
7156 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
7157 "Unexpected value\n");
7158 LocalFree(buf);
7161 info.EncryptedHash.cbData = sizeof(hash);
7162 info.EncryptedHash.pbData = (BYTE *)hash;
7163 SetLastError(0xdeadbeef);
7164 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
7165 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7166 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
7167 ok(!ret && GetLastError() == E_INVALIDARG,
7168 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
7169 else
7171 ok(ret, "CryptEncodeObjectEx failed: %lx\n", GetLastError());
7172 if (ret)
7174 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %ld\n",
7175 size);
7176 ok(!memcmp(buf, PKCSSignerWithHash, size), "Unexpected value\n");
7177 LocalFree(buf);
7182 static void test_decodeCMSSignerInfo(DWORD dwEncoding)
7184 BOOL ret;
7185 LPBYTE buf = NULL;
7186 DWORD size = 0;
7187 CMSG_CMS_SIGNER_INFO *info;
7188 static const char oid1[] = "1.2.3", oid2[] = "1.5.6";
7190 /* A CMS signer can't be decoded without a serial number. */
7191 SetLastError(0xdeadbeef);
7192 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
7193 minimalPKCSSigner, sizeof(minimalPKCSSigner),
7194 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
7195 ok(!ret, "expected failure\n");
7196 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7198 skip("no CMS_SIGNER_INFO decode support\n");
7199 return;
7201 ok(GetLastError() == CRYPT_E_ASN1_CORRUPT,
7202 "Expected CRYPT_E_ASN1_CORRUPT, got %lx\n", GetLastError());
7203 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
7204 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
7205 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
7206 ok(ret, "CryptDecodeObjectEx failed: %lx\n", GetLastError());
7207 if (ret)
7209 info = (CMSG_CMS_SIGNER_INFO *)buf;
7210 ok(info->dwVersion == 0, "Expected version 0, got %ld\n",
7211 info->dwVersion);
7212 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
7213 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %ld\n",
7214 info->SignerId.dwIdChoice);
7215 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
7216 sizeof(encodedCommonNameNoNull), "Unexpected size %ld\n",
7217 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
7218 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
7219 encodedCommonNameNoNull,
7220 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
7221 "Unexpected value\n");
7222 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
7223 sizeof(serialNum), "Unexpected size %ld\n",
7224 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
7225 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
7226 serialNum, sizeof(serialNum)), "Unexpected value\n");
7227 LocalFree(buf);
7229 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
7230 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
7231 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
7232 ok(ret, "CryptDecodeObjectEx failed: %lx\n", GetLastError());
7233 if (ret)
7235 info = (CMSG_CMS_SIGNER_INFO *)buf;
7236 ok(info->dwVersion == 0, "Expected version 0, got %ld\n",
7237 info->dwVersion);
7238 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
7239 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %ld\n",
7240 info->SignerId.dwIdChoice);
7241 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
7242 sizeof(encodedCommonNameNoNull), "Unexpected size %ld\n",
7243 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
7244 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
7245 encodedCommonNameNoNull,
7246 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
7247 "Unexpected value\n");
7248 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
7249 sizeof(serialNum), "Unexpected size %ld\n",
7250 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
7251 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
7252 serialNum, sizeof(serialNum)), "Unexpected value\n");
7253 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
7254 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
7255 LocalFree(buf);
7257 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
7258 PKCSSignerWithHashAndEncryptionAlgo,
7259 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
7260 NULL, &buf, &size);
7261 ok(ret, "CryptDecodeObjectEx failed: %lx\n", GetLastError());
7262 if (ret)
7264 info = (CMSG_CMS_SIGNER_INFO *)buf;
7265 ok(info->dwVersion == 0, "Expected version 0, got %ld\n",
7266 info->dwVersion);
7267 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
7268 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %ld\n",
7269 info->SignerId.dwIdChoice);
7270 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
7271 sizeof(encodedCommonNameNoNull), "Unexpected size %ld\n",
7272 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
7273 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
7274 encodedCommonNameNoNull,
7275 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
7276 "Unexpected value\n");
7277 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
7278 sizeof(serialNum), "Unexpected size %ld\n",
7279 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
7280 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
7281 serialNum, sizeof(serialNum)), "Unexpected value\n");
7282 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
7283 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
7284 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
7285 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
7286 LocalFree(buf);
7288 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
7289 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
7290 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
7291 ok(ret, "CryptDecodeObjectEx failed: %lx\n", GetLastError());
7292 if (ret)
7294 info = (CMSG_CMS_SIGNER_INFO *)buf;
7295 ok(info->dwVersion == 0, "Expected version 0, got %ld\n",
7296 info->dwVersion);
7297 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
7298 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %ld\n",
7299 info->SignerId.dwIdChoice);
7300 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
7301 sizeof(encodedCommonNameNoNull), "Unexpected size %ld\n",
7302 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
7303 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
7304 encodedCommonNameNoNull,
7305 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
7306 "Unexpected value\n");
7307 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
7308 sizeof(serialNum), "Unexpected size %ld\n",
7309 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
7310 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
7311 serialNum, sizeof(serialNum)), "Unexpected value\n");
7312 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
7313 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
7314 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
7315 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
7316 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %ld\n",
7317 info->EncryptedHash.cbData);
7318 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
7319 "Unexpected value\n");
7320 LocalFree(buf);
7322 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
7323 CMSSignerWithKeyId, sizeof(CMSSignerWithKeyId),
7324 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
7325 ok(ret, "CryptDecodeObjectEx failed: %lx\n", GetLastError());
7326 if (ret)
7328 info = (CMSG_CMS_SIGNER_INFO *)buf;
7329 ok(info->dwVersion == 0, "Expected version 0, got %ld\n",
7330 info->dwVersion);
7331 ok(info->SignerId.dwIdChoice == CERT_ID_KEY_IDENTIFIER,
7332 "Expected CERT_ID_KEY_IDENTIFIER, got %ld\n",
7333 info->SignerId.dwIdChoice);
7334 ok(U(info->SignerId).KeyId.cbData == sizeof(serialNum),
7335 "Unexpected size %ld\n", U(info->SignerId).KeyId.cbData);
7336 ok(!memcmp(U(info->SignerId).KeyId.pbData, serialNum, sizeof(serialNum)),
7337 "Unexpected value\n");
7338 LocalFree(buf);
7342 static BYTE emptyDNSPermittedConstraints[] = {
7343 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
7344 static BYTE emptyDNSExcludedConstraints[] = {
7345 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
7346 static BYTE DNSExcludedConstraints[] = {
7347 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
7348 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7349 static BYTE permittedAndExcludedConstraints[] = {
7350 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7351 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
7352 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7353 static BYTE permittedAndExcludedWithMinConstraints[] = {
7354 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7355 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
7356 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7357 static BYTE permittedAndExcludedWithMinMaxConstraints[] = {
7358 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7359 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
7360 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7362 static void test_encodeNameConstraints(DWORD dwEncoding)
7364 BOOL ret;
7365 CERT_NAME_CONSTRAINTS_INFO constraints = { 0 };
7366 CERT_GENERAL_SUBTREE permitted = { { 0 } };
7367 CERT_GENERAL_SUBTREE excluded = { { 0 } };
7368 LPBYTE buf;
7369 DWORD size;
7371 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7372 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7373 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7375 skip("no X509_NAME_CONSTRAINTS encode support\n");
7376 return;
7378 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
7379 if (ret)
7381 ok(size == sizeof(emptySequence), "Unexpected size\n");
7382 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
7383 LocalFree(buf);
7385 constraints.cPermittedSubtree = 1;
7386 constraints.rgPermittedSubtree = &permitted;
7387 SetLastError(0xdeadbeef);
7388 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7389 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7390 ok(!ret && GetLastError() == E_INVALIDARG,
7391 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
7392 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
7393 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7394 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7395 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
7396 if (ret)
7398 ok(size == sizeof(emptyDNSPermittedConstraints), "Unexpected size\n");
7399 ok(!memcmp(buf, emptyDNSPermittedConstraints, size),
7400 "Unexpected value\n");
7401 LocalFree(buf);
7403 constraints.cPermittedSubtree = 0;
7404 constraints.cExcludedSubtree = 1;
7405 constraints.rgExcludedSubtree = &excluded;
7406 excluded.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
7407 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7408 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7409 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
7410 if (ret)
7412 ok(size == sizeof(emptyDNSExcludedConstraints), "Unexpected size\n");
7413 ok(!memcmp(buf, emptyDNSExcludedConstraints, size),
7414 "Unexpected value\n");
7415 LocalFree(buf);
7417 U(excluded.Base).pwszURL = (LPWSTR)url;
7418 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7419 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7420 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
7421 if (ret)
7423 ok(size == sizeof(DNSExcludedConstraints), "Unexpected size\n");
7424 ok(!memcmp(buf, DNSExcludedConstraints, size),
7425 "Unexpected value\n");
7426 LocalFree(buf);
7428 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
7429 U(permitted.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7430 U(permitted.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7431 constraints.cPermittedSubtree = 1;
7432 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7433 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7434 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
7435 if (ret)
7437 ok(size == sizeof(permittedAndExcludedConstraints),
7438 "Unexpected size\n");
7439 ok(!memcmp(buf, permittedAndExcludedConstraints, size),
7440 "Unexpected value\n");
7441 LocalFree(buf);
7443 permitted.dwMinimum = 5;
7444 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7445 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7446 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
7447 if (ret)
7449 ok(size == sizeof(permittedAndExcludedWithMinConstraints),
7450 "Unexpected size\n");
7451 ok(!memcmp(buf, permittedAndExcludedWithMinConstraints, size),
7452 "Unexpected value\n");
7453 LocalFree(buf);
7455 permitted.fMaximum = TRUE;
7456 permitted.dwMaximum = 3;
7457 SetLastError(0xdeadbeef);
7458 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7459 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7460 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
7461 if (ret)
7463 ok(size == sizeof(permittedAndExcludedWithMinMaxConstraints),
7464 "Unexpected size\n");
7465 ok(!memcmp(buf, permittedAndExcludedWithMinMaxConstraints, size),
7466 "Unexpected value\n");
7467 LocalFree(buf);
7471 struct EncodedNameConstraints
7473 CRYPT_DATA_BLOB encoded;
7474 CERT_NAME_CONSTRAINTS_INFO constraints;
7477 static CERT_GENERAL_SUBTREE emptyDNSSubtree = {
7478 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
7479 static CERT_GENERAL_SUBTREE DNSSubtree = {
7480 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
7481 static CERT_GENERAL_SUBTREE IPAddressSubtree = {
7482 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 0 };
7483 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree = {
7484 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, 0 };
7485 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree = {
7486 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, TRUE, 3 };
7488 static const struct EncodedNameConstraints encodedNameConstraints[] = {
7489 { { sizeof(emptySequence), (LPBYTE)emptySequence }, { 0 } },
7490 { { sizeof(emptyDNSPermittedConstraints), emptyDNSPermittedConstraints },
7491 { 1, &emptyDNSSubtree, 0, NULL } },
7492 { { sizeof(emptyDNSExcludedConstraints), emptyDNSExcludedConstraints },
7493 { 0, NULL, 1, &emptyDNSSubtree } },
7494 { { sizeof(DNSExcludedConstraints), DNSExcludedConstraints },
7495 { 0, NULL, 1, &DNSSubtree } },
7496 { { sizeof(permittedAndExcludedConstraints), permittedAndExcludedConstraints },
7497 { 1, &IPAddressSubtree, 1, &DNSSubtree } },
7498 { { sizeof(permittedAndExcludedWithMinConstraints),
7499 permittedAndExcludedWithMinConstraints },
7500 { 1, &IPAddressWithMinSubtree, 1, &DNSSubtree } },
7501 { { sizeof(permittedAndExcludedWithMinMaxConstraints),
7502 permittedAndExcludedWithMinMaxConstraints },
7503 { 1, &IPAddressWithMinMaxSubtree, 1, &DNSSubtree } },
7506 static void test_decodeNameConstraints(DWORD dwEncoding)
7508 BOOL ret;
7509 DWORD i;
7510 CERT_NAME_CONSTRAINTS_INFO *constraints;
7512 U(DNSSubtree.Base).pwszURL = (LPWSTR)url;
7513 U(IPAddressSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7514 U(IPAddressSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7515 U(IPAddressWithMinSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7516 U(IPAddressWithMinSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7517 U(IPAddressWithMinMaxSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7518 U(IPAddressWithMinMaxSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7519 for (i = 0; i < ARRAY_SIZE(encodedNameConstraints); i++)
7521 DWORD size;
7523 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS,
7524 encodedNameConstraints[i].encoded.pbData,
7525 encodedNameConstraints[i].encoded.cbData,
7526 CRYPT_DECODE_ALLOC_FLAG, NULL, &constraints, &size);
7527 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7529 skip("no X509_NAME_CONSTRAINTS decode support\n");
7530 return;
7532 ok(ret, "%ld: CryptDecodeObjectEx failed: %08lx\n", i, GetLastError());
7533 if (ret)
7535 DWORD j;
7537 if (constraints->cPermittedSubtree !=
7538 encodedNameConstraints[i].constraints.cPermittedSubtree)
7539 fprintf(stderr, "%ld: expected %lu permitted, got %lu\n", i,
7540 encodedNameConstraints[i].constraints.cPermittedSubtree,
7541 constraints->cPermittedSubtree);
7542 if (constraints->cPermittedSubtree ==
7543 encodedNameConstraints[i].constraints.cPermittedSubtree)
7545 for (j = 0; j < constraints->cPermittedSubtree; j++)
7547 compareAltNameEntry(&constraints->rgPermittedSubtree[j].Base,
7548 &encodedNameConstraints[i].constraints.rgPermittedSubtree[j].Base);
7551 if (constraints->cExcludedSubtree !=
7552 encodedNameConstraints[i].constraints.cExcludedSubtree)
7553 fprintf(stderr, "%ld: expected %lu excluded, got %lu\n", i,
7554 encodedNameConstraints[i].constraints.cExcludedSubtree,
7555 constraints->cExcludedSubtree);
7556 if (constraints->cExcludedSubtree ==
7557 encodedNameConstraints[i].constraints.cExcludedSubtree)
7559 for (j = 0; j < constraints->cExcludedSubtree; j++)
7561 compareAltNameEntry(&constraints->rgExcludedSubtree[j].Base,
7562 &encodedNameConstraints[i].constraints.rgExcludedSubtree[j].Base);
7565 LocalFree(constraints);
7570 static WCHAR noticeText[] = { 'T','h','i','s',' ','i','s',' ','a',' ',
7571 'n','o','t','i','c','e',0 };
7572 static const BYTE noticeWithDisplayText[] = {
7573 0x30,0x22,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,0x00,
7574 0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,0x74,
7575 0x00,0x69,0x00,0x63,0x00,0x65
7577 static char org[] = "Wine";
7578 static int noticeNumbers[] = { 2,3 };
7579 static BYTE noticeWithReference[] = {
7580 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7581 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7582 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7583 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7586 static void test_encodePolicyQualifierUserNotice(DWORD dwEncoding)
7588 BOOL ret;
7589 LPBYTE buf;
7590 DWORD size;
7591 CERT_POLICY_QUALIFIER_USER_NOTICE notice;
7592 CERT_POLICY_QUALIFIER_NOTICE_REFERENCE reference;
7594 memset(&notice, 0, sizeof(notice));
7595 ret = pCryptEncodeObjectEx(dwEncoding,
7596 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, &notice, CRYPT_ENCODE_ALLOC_FLAG,
7597 NULL, &buf, &size);
7598 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7600 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE encode support\n");
7601 return;
7603 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
7604 if (ret)
7606 ok(sizeof(emptySequence) == size, "unexpected size %ld\n", size);
7607 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
7608 LocalFree(buf);
7610 notice.pszDisplayText = noticeText;
7611 ret = pCryptEncodeObjectEx(dwEncoding,
7612 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, &notice, CRYPT_ENCODE_ALLOC_FLAG,
7613 NULL, &buf, &size);
7614 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
7615 if (ret)
7617 ok(sizeof(noticeWithDisplayText) == size, "unexpected size %ld\n", size);
7618 ok(!memcmp(buf, noticeWithDisplayText, size), "unexpected value\n");
7619 LocalFree(buf);
7621 reference.pszOrganization = org;
7622 reference.cNoticeNumbers = 2;
7623 reference.rgNoticeNumbers = noticeNumbers;
7624 notice.pNoticeReference = &reference;
7625 ret = pCryptEncodeObjectEx(dwEncoding,
7626 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, &notice, CRYPT_ENCODE_ALLOC_FLAG,
7627 NULL, &buf, &size);
7628 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
7629 if (ret)
7631 ok(sizeof(noticeWithReference) == size, "unexpected size %ld\n", size);
7632 ok(!memcmp(buf, noticeWithReference, size), "unexpected value\n");
7633 LocalFree(buf);
7637 static void test_decodePolicyQualifierUserNotice(DWORD dwEncoding)
7639 BOOL ret;
7640 CERT_POLICY_QUALIFIER_USER_NOTICE *notice;
7641 DWORD size;
7643 ret = pCryptDecodeObjectEx(dwEncoding,
7644 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7645 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7646 &notice, &size);
7647 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7649 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE decode support\n");
7650 return;
7652 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
7653 if (ret)
7655 ok(notice->pszDisplayText == NULL, "unexpected display text\n");
7656 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7657 LocalFree(notice);
7659 ret = pCryptDecodeObjectEx(dwEncoding,
7660 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7661 noticeWithDisplayText, sizeof(noticeWithDisplayText),
7662 CRYPT_DECODE_ALLOC_FLAG, NULL, &notice, &size);
7663 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
7664 if (ret)
7666 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7667 "unexpected display text\n");
7668 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7669 LocalFree(notice);
7671 ret = pCryptDecodeObjectEx(dwEncoding,
7672 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7673 noticeWithReference, sizeof(noticeWithReference),
7674 CRYPT_DECODE_ALLOC_FLAG, NULL, &notice, &size);
7675 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
7676 if (ret)
7678 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7679 "unexpected display text\n");
7680 ok(notice->pNoticeReference != NULL, "expected a notice reference\n");
7681 if (notice->pNoticeReference)
7683 ok(!strcmp(notice->pNoticeReference->pszOrganization, org),
7684 "unexpected organization %s\n",
7685 notice->pNoticeReference->pszOrganization);
7686 ok(notice->pNoticeReference->cNoticeNumbers == 2,
7687 "expected 2 notice numbers, got %ld\n",
7688 notice->pNoticeReference->cNoticeNumbers);
7689 ok(notice->pNoticeReference->rgNoticeNumbers[0] == noticeNumbers[0],
7690 "unexpected notice number %d\n",
7691 notice->pNoticeReference->rgNoticeNumbers[0]);
7692 ok(notice->pNoticeReference->rgNoticeNumbers[1] == noticeNumbers[1],
7693 "unexpected notice number %d\n",
7694 notice->pNoticeReference->rgNoticeNumbers[1]);
7696 LocalFree(notice);
7700 static char oid_any_policy[] = "2.5.29.32.0";
7701 static const BYTE policiesWithAnyPolicy[] = {
7702 0x30,0x08,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00
7704 static char oid1[] = "1.2.3";
7705 static char oid_user_notice[] = "1.3.6.1.5.5.7.2.2";
7706 static const BYTE twoPolicies[] = {
7707 0x30,0x50,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00,0x30,0x46,0x06,0x02,0x2a,
7708 0x03,0x30,0x40,0x30,0x3e,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x02,
7709 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7710 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7711 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7712 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7715 static void test_encodeCertPolicies(DWORD dwEncoding)
7717 BOOL ret;
7718 CERT_POLICIES_INFO info;
7719 CERT_POLICY_INFO policy[2];
7720 CERT_POLICY_QUALIFIER_INFO qualifier;
7721 LPBYTE buf;
7722 DWORD size;
7724 memset(&info, 0, sizeof(info));
7725 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7726 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7727 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
7728 if (ret)
7730 ok(sizeof(emptySequence) == size, "unexpected size %ld\n", size);
7731 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
7732 LocalFree(buf);
7734 memset(policy, 0, sizeof(policy));
7735 info.cPolicyInfo = 1;
7736 info.rgPolicyInfo = policy;
7737 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7738 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7739 ok(!ret && (GetLastError() == E_INVALIDARG ||
7740 GetLastError() == OSS_LIMITED /* Win9x/NT4 */),
7741 "expected E_INVALIDARG or OSS_LIMITED, got %08lx\n", GetLastError());
7742 policy[0].pszPolicyIdentifier = oid_any_policy;
7743 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7744 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7745 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
7746 if (ret)
7748 ok(sizeof(policiesWithAnyPolicy) == size, "unexpected size %ld\n", size);
7749 ok(!memcmp(buf, policiesWithAnyPolicy, size), "unexpected value\n");
7750 LocalFree(buf);
7752 policy[1].pszPolicyIdentifier = oid1;
7753 memset(&qualifier, 0, sizeof(qualifier));
7754 qualifier.pszPolicyQualifierId = oid_user_notice;
7755 qualifier.Qualifier.cbData = sizeof(noticeWithReference);
7756 qualifier.Qualifier.pbData = noticeWithReference;
7757 policy[1].cPolicyQualifier = 1;
7758 policy[1].rgPolicyQualifier = &qualifier;
7759 info.cPolicyInfo = 2;
7760 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7761 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7762 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
7763 if (ret)
7765 ok(sizeof(twoPolicies) == size, "unexpected size %ld\n", size);
7766 ok(!memcmp(buf, twoPolicies, size), "unexpected value\n");
7767 LocalFree(buf);
7771 static void test_decodeCertPolicies(DWORD dwEncoding)
7773 BOOL ret;
7774 CERT_POLICIES_INFO *info;
7775 DWORD size;
7777 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7778 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7779 &info, &size);
7780 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
7781 if (ret)
7783 ok(info->cPolicyInfo == 0, "unexpected policy info %ld\n",
7784 info->cPolicyInfo);
7785 LocalFree(info);
7787 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7788 policiesWithAnyPolicy, sizeof(policiesWithAnyPolicy),
7789 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7790 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
7791 if (ret)
7793 ok(info->cPolicyInfo == 1, "unexpected policy info %ld\n",
7794 info->cPolicyInfo);
7795 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy),
7796 "unexpected policy id %s\n",
7797 info->rgPolicyInfo[0].pszPolicyIdentifier);
7798 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0,
7799 "unexpected policy qualifier count %ld\n",
7800 info->rgPolicyInfo[0].cPolicyQualifier);
7801 LocalFree(info);
7803 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7804 twoPolicies, sizeof(twoPolicies),
7805 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7806 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
7807 if (ret)
7809 ok(info->cPolicyInfo == 2, "unexpected policy info %ld\n",
7810 info->cPolicyInfo);
7811 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy),
7812 "unexpected policy id %s\n",
7813 info->rgPolicyInfo[0].pszPolicyIdentifier);
7814 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0,
7815 "unexpected policy qualifier count %ld\n",
7816 info->rgPolicyInfo[0].cPolicyQualifier);
7817 ok(!strcmp(info->rgPolicyInfo[1].pszPolicyIdentifier, oid1),
7818 "unexpected policy id %s\n",
7819 info->rgPolicyInfo[1].pszPolicyIdentifier);
7820 ok(info->rgPolicyInfo[1].cPolicyQualifier == 1,
7821 "unexpected policy qualifier count %ld\n",
7822 info->rgPolicyInfo[1].cPolicyQualifier);
7823 ok(!strcmp(
7824 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId,
7825 oid_user_notice), "unexpected policy qualifier id %s\n",
7826 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId);
7827 ok(info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData ==
7828 sizeof(noticeWithReference), "unexpected qualifier size %ld\n",
7829 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData);
7830 ok(!memcmp(
7831 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.pbData,
7832 noticeWithReference, sizeof(noticeWithReference)),
7833 "unexpected qualifier value\n");
7834 LocalFree(info);
7836 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7837 twoPolicies, sizeof(twoPolicies), 0, NULL, NULL, &size);
7838 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
7839 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
7840 if (info)
7842 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7843 twoPolicies, sizeof(twoPolicies), 0, NULL, info, &size);
7844 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
7845 HeapFree(GetProcessHeap(), 0, info);
7849 static const BYTE policyMappingWithOneMapping[] = {
7850 0x30,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04 };
7851 static const BYTE policyMappingWithTwoMappings[] = {
7852 0x30,0x14,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04,0x30,0x08,0x06,
7853 0x02,0x2b,0x04,0x06,0x02,0x55,0x06 };
7854 static const LPCSTR mappingOids[] = { X509_POLICY_MAPPINGS,
7855 szOID_POLICY_MAPPINGS, szOID_LEGACY_POLICY_MAPPINGS };
7857 static void test_encodeCertPolicyMappings(DWORD dwEncoding)
7859 static char oid2[] = "2.3.4";
7860 static char oid3[] = "1.3.4";
7861 static char oid4[] = "2.5.6";
7862 BOOL ret;
7863 CERT_POLICY_MAPPINGS_INFO info = { 0 };
7864 CERT_POLICY_MAPPING mapping[2];
7865 LPBYTE buf;
7866 DWORD size, i;
7868 /* Each of the mapping OIDs is equivalent, so check with all of them */
7869 for (i = 0; i < ARRAY_SIZE(mappingOids); i++)
7871 memset(&info, 0, sizeof(info));
7872 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7873 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7874 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
7875 "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
7876 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7878 win_skip("no policy mappings support\n");
7879 return;
7881 if (ret)
7883 ok(size == sizeof(emptySequence), "unexpected size %ld\n", size);
7884 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
7885 "unexpected value\n");
7886 LocalFree(buf);
7888 mapping[0].pszIssuerDomainPolicy = NULL;
7889 mapping[0].pszSubjectDomainPolicy = NULL;
7890 info.cPolicyMapping = 1;
7891 info.rgPolicyMapping = mapping;
7892 SetLastError(0xdeadbeef);
7893 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7894 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7895 ok(!ret && GetLastError() == E_INVALIDARG,
7896 "expected E_INVALIDARG, got %08lx\n", GetLastError());
7897 mapping[0].pszIssuerDomainPolicy = oid1;
7898 mapping[0].pszSubjectDomainPolicy = oid2;
7899 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7900 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7901 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
7902 if (ret)
7904 ok(size == sizeof(policyMappingWithOneMapping),
7905 "unexpected size %ld\n", size);
7906 ok(!memcmp(buf, policyMappingWithOneMapping, size),
7907 "unexpected value\n");
7908 LocalFree(buf);
7910 mapping[1].pszIssuerDomainPolicy = oid3;
7911 mapping[1].pszSubjectDomainPolicy = oid4;
7912 info.cPolicyMapping = 2;
7913 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7914 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7915 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
7916 if (ret)
7918 ok(size == sizeof(policyMappingWithTwoMappings),
7919 "unexpected size %ld\n", size);
7920 ok(!memcmp(buf, policyMappingWithTwoMappings, size),
7921 "unexpected value\n");
7922 LocalFree(buf);
7927 static void test_decodeCertPolicyMappings(DWORD dwEncoding)
7929 DWORD size, i;
7930 CERT_POLICY_MAPPINGS_INFO *info;
7931 BOOL ret;
7933 /* Each of the mapping OIDs is equivalent, so check with all of them */
7934 for (i = 0; i < ARRAY_SIZE(mappingOids); i++)
7936 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7937 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7938 &info, &size);
7939 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
7940 "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
7941 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7943 win_skip("no policy mappings support\n");
7944 return;
7946 if (ret)
7948 ok(info->cPolicyMapping == 0,
7949 "expected 0 policy mappings, got %ld\n", info->cPolicyMapping);
7950 LocalFree(info);
7952 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7953 policyMappingWithOneMapping, sizeof(policyMappingWithOneMapping),
7954 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7955 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
7956 if (ret)
7958 ok(info->cPolicyMapping == 1,
7959 "expected 1 policy mappings, got %ld\n", info->cPolicyMapping);
7960 ok(!strcmp(info->rgPolicyMapping[0].pszIssuerDomainPolicy, "1.2.3"),
7961 "unexpected issuer policy %s\n",
7962 info->rgPolicyMapping[0].pszIssuerDomainPolicy);
7963 ok(!strcmp(info->rgPolicyMapping[0].pszSubjectDomainPolicy,
7964 "2.3.4"), "unexpected subject policy %s\n",
7965 info->rgPolicyMapping[0].pszSubjectDomainPolicy);
7966 LocalFree(info);
7968 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7969 policyMappingWithTwoMappings, sizeof(policyMappingWithTwoMappings),
7970 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7971 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
7972 if (ret)
7974 ok(info->cPolicyMapping == 2,
7975 "expected 2 policy mappings, got %ld\n", info->cPolicyMapping);
7976 ok(!strcmp(info->rgPolicyMapping[0].pszIssuerDomainPolicy, "1.2.3"),
7977 "unexpected issuer policy %s\n",
7978 info->rgPolicyMapping[0].pszIssuerDomainPolicy);
7979 ok(!strcmp(info->rgPolicyMapping[0].pszSubjectDomainPolicy,
7980 "2.3.4"), "unexpected subject policy %s\n",
7981 info->rgPolicyMapping[0].pszSubjectDomainPolicy);
7982 ok(!strcmp(info->rgPolicyMapping[1].pszIssuerDomainPolicy, "1.3.4"),
7983 "unexpected issuer policy %s\n",
7984 info->rgPolicyMapping[1].pszIssuerDomainPolicy);
7985 ok(!strcmp(info->rgPolicyMapping[1].pszSubjectDomainPolicy,
7986 "2.5.6"), "unexpected subject policy %s\n",
7987 info->rgPolicyMapping[1].pszSubjectDomainPolicy);
7988 LocalFree(info);
7990 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7991 policyMappingWithTwoMappings, sizeof(policyMappingWithTwoMappings), 0,
7992 NULL, NULL, &size);
7993 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
7994 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
7995 if (info)
7997 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7998 policyMappingWithTwoMappings, sizeof(policyMappingWithTwoMappings), 0,
7999 NULL, info, &size);
8000 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
8001 HeapFree(GetProcessHeap(), 0, info);
8006 static const BYTE policyConstraintsWithRequireExplicit[] = {
8007 0x30,0x03,0x80,0x01,0x00 };
8008 static const BYTE policyConstraintsWithInhibitMapping[] = {
8009 0x30,0x03,0x81,0x01,0x01 };
8010 static const BYTE policyConstraintsWithBoth[] = {
8011 0x30,0x06,0x80,0x01,0x01,0x81,0x01,0x01 };
8013 static void test_encodeCertPolicyConstraints(DWORD dwEncoding)
8015 CERT_POLICY_CONSTRAINTS_INFO info = { 0 };
8016 LPBYTE buf;
8017 DWORD size;
8018 BOOL ret;
8020 /* Even though RFC 5280 explicitly states CAs must not issue empty
8021 * policy constraints (section 4.2.1.11), the API doesn't prevent it.
8023 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
8024 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
8025 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
8026 "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
8027 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
8029 win_skip("no policy constraints support\n");
8030 return;
8032 if (ret)
8034 ok(size == sizeof(emptySequence), "unexpected size %ld\n", size);
8035 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
8036 "unexpected value\n");
8037 LocalFree(buf);
8039 /* If fRequireExplicitPolicy is set but dwRequireExplicitPolicySkipCerts
8040 * is not, then a skip of 0 is encoded.
8042 info.fRequireExplicitPolicy = TRUE;
8043 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
8044 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
8045 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
8046 if (ret)
8048 ok(size == sizeof(policyConstraintsWithRequireExplicit),
8049 "unexpected size %ld\n", size);
8050 ok(!memcmp(buf, policyConstraintsWithRequireExplicit,
8051 sizeof(policyConstraintsWithRequireExplicit)), "unexpected value\n");
8052 LocalFree(buf);
8054 /* With inhibit policy mapping */
8055 info.fRequireExplicitPolicy = FALSE;
8056 info.dwRequireExplicitPolicySkipCerts = 0;
8057 info.fInhibitPolicyMapping = TRUE;
8058 info.dwInhibitPolicyMappingSkipCerts = 1;
8059 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
8060 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
8061 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
8062 if (ret)
8064 ok(size == sizeof(policyConstraintsWithInhibitMapping),
8065 "unexpected size %ld\n", size);
8066 ok(!memcmp(buf, policyConstraintsWithInhibitMapping,
8067 sizeof(policyConstraintsWithInhibitMapping)), "unexpected value\n");
8068 LocalFree(buf);
8070 /* And with both */
8071 info.fRequireExplicitPolicy = TRUE;
8072 info.dwRequireExplicitPolicySkipCerts = 1;
8073 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
8074 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
8075 ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
8076 if (ret)
8078 ok(size == sizeof(policyConstraintsWithBoth), "unexpected size %ld\n",
8079 size);
8080 ok(!memcmp(buf, policyConstraintsWithBoth,
8081 sizeof(policyConstraintsWithBoth)), "unexpected value\n");
8082 LocalFree(buf);
8086 static void test_decodeCertPolicyConstraints(DWORD dwEncoding)
8088 CERT_POLICY_CONSTRAINTS_INFO *info;
8089 DWORD size;
8090 BOOL ret;
8092 /* Again, even though CAs must not issue such constraints, they can be
8093 * decoded.
8095 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
8096 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
8097 &info, &size);
8098 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
8099 "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
8100 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
8102 win_skip("no policy mappings support\n");
8103 return;
8105 if (ret)
8107 ok(!info->fRequireExplicitPolicy,
8108 "expected require explicit = FALSE\n");
8109 ok(!info->fInhibitPolicyMapping,
8110 "expected implicit mapping = FALSE\n");
8111 LocalFree(info);
8113 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
8114 policyConstraintsWithRequireExplicit,
8115 sizeof(policyConstraintsWithRequireExplicit), CRYPT_DECODE_ALLOC_FLAG,
8116 NULL, &info, &size);
8117 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
8118 if (ret)
8120 ok(info->fRequireExplicitPolicy,
8121 "expected require explicit = TRUE\n");
8122 ok(info->dwRequireExplicitPolicySkipCerts == 0, "expected 0, got %ld\n",
8123 info->dwRequireExplicitPolicySkipCerts);
8124 ok(!info->fInhibitPolicyMapping,
8125 "expected implicit mapping = FALSE\n");
8126 LocalFree(info);
8128 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
8129 policyConstraintsWithInhibitMapping,
8130 sizeof(policyConstraintsWithInhibitMapping), CRYPT_DECODE_ALLOC_FLAG,
8131 NULL, &info, &size);
8132 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
8133 if (ret)
8135 ok(!info->fRequireExplicitPolicy,
8136 "expected require explicit = FALSE\n");
8137 ok(info->fInhibitPolicyMapping,
8138 "expected implicit mapping = TRUE\n");
8139 ok(info->dwInhibitPolicyMappingSkipCerts == 1, "expected 1, got %ld\n",
8140 info->dwInhibitPolicyMappingSkipCerts);
8141 LocalFree(info);
8143 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
8144 policyConstraintsWithBoth, sizeof(policyConstraintsWithBoth),
8145 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
8146 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
8147 if (ret)
8149 ok(info->fRequireExplicitPolicy,
8150 "expected require explicit = TRUE\n");
8151 ok(info->dwRequireExplicitPolicySkipCerts == 1, "expected 1, got %ld\n",
8152 info->dwRequireExplicitPolicySkipCerts);
8153 ok(info->fInhibitPolicyMapping,
8154 "expected implicit mapping = TRUE\n");
8155 ok(info->dwInhibitPolicyMappingSkipCerts == 1, "expected 1, got %ld\n",
8156 info->dwInhibitPolicyMappingSkipCerts);
8157 LocalFree(info);
8161 static const BYTE rsaPrivKeyDer[] = {
8162 0x30,0x82,0x04,0xa5,0x02,0x01,0x00,0x02,0x82,0x01,0x01,0x00,
8163 0xae,0xba,0x3c,0x41,0xeb,0x25,0x41,0xb0,0x1c,0x41,0xd4,0x26,
8164 0xf9,0xf8,0x31,0x64,0x7e,0x97,0x65,0x54,0x9c,0x90,0xdf,0x34,
8165 0x07,0xfb,0xb0,0x69,0x99,0x3b,0x45,0x39,0x06,0xe4,0x3a,0x7a,
8166 0x01,0xe0,0xeb,0x3f,0xe1,0xd5,0x91,0xe0,0x16,0xe0,0xf2,0x35,
8167 0x59,0xdf,0x32,0x2d,0x69,0x3a,0x4a,0xbc,0xd1,0xba,0x1b,0x3b,
8168 0x7a,0x55,0x76,0xba,0x11,0xdd,0x2f,0xc7,0x58,0x66,0xf2,0x6c,
8169 0xd1,0x68,0x27,0x6c,0x85,0x74,0x0b,0xc9,0x7b,0x1a,0xde,0x3c,
8170 0x62,0x73,0xe2,0x9e,0x36,0x3a,0x29,0x3b,0x91,0x85,0x3d,0xd2,
8171 0xe1,0xe5,0x61,0x84,0x1e,0x28,0xfd,0xb7,0x97,0x68,0xc1,0xbb,
8172 0x0f,0x93,0x14,0xc2,0x03,0x60,0x41,0x11,0x7a,0xda,0x76,0x01,
8173 0x65,0x08,0xe6,0x0c,0xf6,0xfc,0x1d,0x64,0x12,0x7b,0x42,0xb0,
8174 0xb8,0xfe,0x61,0xe5,0xe2,0xe5,0x61,0x44,0xcc,0x94,0xe8,0xc0,
8175 0x4f,0x58,0x9a,0xea,0x99,0xaf,0x9c,0xa4,0xf2,0xd7,0x2b,0x31,
8176 0x90,0x3b,0x41,0x2e,0x4a,0x74,0x7c,0x1a,0xfc,0x42,0xa9,0x17,
8177 0xff,0x53,0x20,0x76,0xa7,0xf0,0x2c,0xb9,0xd5,0x1f,0xa9,0x8a,
8178 0x77,0xa8,0x09,0x5c,0x0e,0xd1,0x54,0xc5,0xf2,0x86,0xf1,0x2f,
8179 0x23,0xd6,0x63,0xba,0xe9,0x2b,0x73,0xf9,0xf0,0xdc,0xcb,0xf9,
8180 0xcb,0xe8,0x40,0x62,0x47,0x09,0x85,0xe1,0x9c,0xfd,0xcf,0x75,
8181 0x5a,0x65,0xfd,0x86,0x1c,0x50,0xfa,0x24,0x36,0x0f,0x54,0x5e,
8182 0x81,0xe7,0xf6,0x63,0x2d,0x87,0x0c,0x50,0x03,0x25,0x49,0xe7,
8183 0xc5,0x20,0xaa,0xbc,0x6c,0xf9,0xbe,0x49,0x8f,0x4f,0xb8,0x9a,
8184 0x73,0x9f,0x55,0x43,0x02,0x03,0x01,0x00,0x01,0x02,0x82,0x01,
8185 0x01,0x00,0x99,0x03,0xcd,0x5b,0x69,0x03,0x32,0x98,0x78,0xd6,
8186 0x89,0x65,0x2c,0xc9,0xd6,0xef,0x8c,0x11,0x27,0x93,0x46,0x9d,
8187 0x74,0x6a,0xcb,0x86,0xf6,0x02,0x34,0x47,0xfc,0xa2,0x29,0x4f,
8188 0xdb,0x8a,0x17,0x75,0x12,0x6f,0xda,0x65,0x3f,0x1f,0xc0,0xc9,
8189 0x74,0x33,0x96,0xa5,0xe8,0xfa,0x6d,0xc9,0xb7,0xc3,0xcd,0xe3,
8190 0x2e,0x90,0x12,0xdd,0x1f,0x61,0x69,0xdd,0x8b,0x47,0x07,0x3a,
8191 0xf8,0x98,0xa5,0x76,0x91,0xf7,0xee,0x93,0x26,0xf3,0x66,0x54,
8192 0xac,0x44,0xb3,0x6f,0x8b,0x09,0x44,0xb2,0x00,0x84,0x03,0x37,
8193 0x6d,0x61,0xed,0xa4,0x04,0x97,0x40,0x16,0x63,0xc2,0xd0,0xdc,
8194 0xd3,0xb3,0xee,0xba,0xbe,0x95,0xfd,0x80,0xe0,0xda,0xde,0xfc,
8195 0xcc,0x15,0x02,0x97,0x1d,0x68,0x43,0x2f,0x9c,0xc8,0x20,0x23,
8196 0xeb,0x00,0x4c,0x74,0x3d,0x27,0x20,0x14,0x23,0x95,0xfc,0x8c,
8197 0xb7,0x7e,0x7f,0xb0,0xdb,0xaf,0x8a,0x48,0x1b,0xfe,0x59,0xab,
8198 0x75,0xe2,0xbf,0x69,0xf2,0x73,0xe3,0xb9,0x92,0xa9,0x90,0x03,
8199 0xe5,0xd4,0x2d,0x86,0xff,0x12,0x54,0xb3,0xbb,0xe2,0xce,0x81,
8200 0x58,0x71,0xa4,0xde,0x45,0x05,0xf8,0x2d,0x45,0xf5,0xd8,0x5e,
8201 0x4c,0x5d,0x06,0x69,0x0c,0x86,0x9f,0x66,0x9f,0xb1,0x60,0xfd,
8202 0xf2,0x33,0x85,0x15,0xd5,0x18,0xf7,0xba,0x99,0x65,0x15,0x1d,
8203 0xfa,0xaa,0x76,0xdd,0x25,0xed,0xdf,0x90,0x6e,0xba,0x61,0x96,
8204 0x79,0xde,0xd2,0xda,0x66,0x03,0x74,0x3b,0x13,0x39,0x68,0xbc,
8205 0x94,0x01,0x00,0x2d,0xf8,0xf0,0x8c,0xbd,0x4c,0x9c,0x7e,0x87,
8206 0x9c,0x62,0x9f,0xb6,0x90,0x11,0x02,0x81,0x81,0x00,0xe3,0x5e,
8207 0xfe,0xdd,0xed,0x76,0xb6,0x4e,0xfc,0x5b,0xe0,0x20,0x99,0x7b,
8208 0x48,0x3b,0x1e,0x5f,0x7f,0x9f,0xa4,0x68,0xbe,0xc3,0x7f,0xb8,
8209 0x62,0x98,0xb0,0x95,0x8a,0xfa,0x0d,0xa3,0x79,0x63,0x39,0xf7,
8210 0xdb,0x76,0x3d,0x53,0x4a,0x0a,0x33,0xdf,0xe0,0x47,0x22,0xd5,
8211 0x96,0x80,0xc7,0xcd,0x24,0xef,0xac,0x49,0x46,0x37,0x6c,0x25,
8212 0xcf,0x6c,0x4d,0xe5,0x31,0xf8,0x2f,0xd2,0x59,0x74,0x00,0x38,
8213 0xdb,0xce,0xd1,0x72,0xc3,0xa8,0x30,0x70,0xd8,0x02,0x20,0xe7,
8214 0x56,0xe7,0xca,0xf0,0x3b,0x52,0x5d,0x11,0xbe,0x53,0x4e,0xd0,
8215 0xd9,0x2e,0xa6,0xb8,0xe2,0xd9,0xbf,0xb9,0x77,0xe7,0x3b,0xed,
8216 0x5e,0xd7,0x16,0x4a,0x3a,0xc5,0x86,0xd7,0x74,0x20,0xa7,0x8e,
8217 0xbf,0xb7,0x33,0xdb,0x51,0xe9,0x02,0x81,0x81,0x00,0xc4,0xba,
8218 0x57,0xf0,0x6e,0xcf,0xe8,0xce,0xce,0x9d,0x4a,0xe9,0x0f,0xe1,
8219 0xab,0x91,0x62,0xaa,0x66,0x5d,0x82,0x66,0x1c,0x72,0x18,0x6f,
8220 0x68,0x9c,0x7d,0x5e,0xfc,0xaf,0x4a,0xd6,0x8e,0xc6,0xae,0x40,
8221 0xf2,0x40,0x84,0x93,0xee,0x7c,0x87,0xa9,0xa6,0xcd,0x2b,0xc3,
8222 0xe6,0x29,0x3a,0xe2,0x4a,0xed,0xb0,0x4d,0x9f,0xc0,0xe9,0xd6,
8223 0xa3,0xca,0x97,0xee,0xac,0xab,0xa4,0x32,0x05,0x40,0x4d,0xf2,
8224 0x95,0x99,0xaf,0xa0,0xe1,0xe1,0xe7,0x3a,0x64,0xa4,0x70,0x6b,
8225 0x3d,0x1d,0x7b,0xf1,0x53,0xfa,0xb0,0xe0,0xe2,0x68,0x1a,0x61,
8226 0x2c,0x37,0xa5,0x39,0x7b,0xb2,0xcf,0xe6,0x5f,0x9b,0xc6,0x64,
8227 0xaf,0x48,0x86,0xfb,0xc1,0xf3,0x39,0x97,0x10,0x36,0xf5,0xa9,
8228 0x3d,0x08,0xa5,0x2f,0xe6,0x4b,0x02,0x81,0x81,0x00,0x86,0xe7,
8229 0x02,0x08,0xe2,0xaf,0xa0,0x93,0x54,0x9f,0x9e,0x67,0x39,0x29,
8230 0x30,0x3e,0x03,0x53,0x5e,0x01,0x76,0x26,0xbf,0xa8,0x76,0xcb,
8231 0x0b,0x94,0xd4,0x90,0xa5,0x98,0x9f,0x26,0xf3,0x0a,0xb0,0x86,
8232 0x22,0xac,0x10,0xce,0xae,0x0b,0x47,0xa3,0xf9,0x09,0xbb,0xdd,
8233 0x46,0x22,0xba,0x69,0x39,0x15,0x0a,0xff,0x9e,0xad,0x9b,0x79,
8234 0x03,0x8c,0x9a,0xda,0xf5,0xbe,0xef,0x80,0xba,0x9a,0x5c,0xd7,
8235 0x5f,0x73,0x62,0x49,0xd9,0x54,0x9d,0x09,0x16,0xe0,0x8c,0x6d,
8236 0x35,0xde,0xe9,0x45,0x87,0xac,0xe2,0x93,0x78,0x7d,0x2d,0x32,
8237 0x34,0xe9,0xbc,0xf9,0xcd,0x7e,0xac,0x86,0x7a,0x61,0xb3,0xe8,
8238 0xae,0x70,0xa7,0x44,0xfb,0x81,0xde,0xf3,0x4e,0x6f,0x61,0x7b,
8239 0x0c,0xbc,0xc2,0x03,0xca,0xa1,0x02,0x81,0x80,0x69,0x5b,0x4a,
8240 0xa1,0x4f,0x17,0x35,0x9d,0x1b,0xf6,0x0d,0x1a,0x48,0x11,0x19,
8241 0xab,0x20,0xe6,0x15,0x30,0x5b,0x17,0x88,0x80,0x6a,0x29,0xb0,
8242 0x22,0xae,0xd9,0xe2,0x05,0x96,0xd4,0xd5,0x5d,0xfe,0x10,0x76,
8243 0x2c,0xab,0x53,0xf6,0x52,0xe6,0xec,0xaa,0x92,0x12,0xb0,0x35,
8244 0x61,0x3b,0x51,0xd9,0xc2,0xf5,0xba,0x7c,0xa5,0xfa,0x15,0xa3,
8245 0x5e,0x6a,0x83,0xbe,0x21,0xa6,0x2b,0xcb,0xb8,0x26,0x86,0x96,
8246 0x2b,0xda,0x6d,0x14,0xcb,0xc0,0xe3,0xfa,0xe6,0x3d,0xf6,0x90,
8247 0xa2,0x6b,0xb0,0x50,0xc3,0x5f,0x5a,0xf0,0xa5,0xc4,0x0a,0xea,
8248 0x7d,0x5a,0x95,0x30,0x74,0x10,0xf7,0x55,0x98,0xbd,0x65,0x4a,
8249 0xa2,0x52,0xf8,0x1d,0x64,0xbf,0x20,0xf1,0xe4,0x1d,0x28,0x67,
8250 0xb1,0x6b,0x95,0xfd,0x85,0x02,0x81,0x81,0x00,0xda,0xb4,0x31,
8251 0x34,0xe1,0xec,0x9a,0x1e,0x07,0xd7,0xda,0x20,0x46,0xbf,0x6b,
8252 0xf0,0x45,0xbd,0x50,0xa2,0x0f,0x8a,0x14,0x51,0x52,0x83,0x7c,
8253 0x47,0xc8,0x9c,0x4e,0x68,0x6b,0xae,0x00,0x25,0x63,0xdd,0x13,
8254 0x2a,0x66,0x65,0xb6,0x74,0x91,0x5b,0xb6,0x47,0x3e,0x8e,0x46,
8255 0x62,0xcd,0x9d,0xc1,0xf7,0x14,0x14,0xbc,0x60,0xd6,0x3c,0x7c,
8256 0x3a,0xce,0xff,0x96,0x04,0x84,0xf6,0x44,0x1a,0xf8,0xdb,0x40,
8257 0x1c,0xf2,0xf1,0x4d,0xb2,0x68,0x3e,0xa3,0x0b,0xc6,0xb1,0xd0,
8258 0xa6,0x88,0x18,0x68,0xa1,0x05,0x2a,0xfc,0x2b,0x3a,0xa1,0xe6,
8259 0x31,0x4a,0x46,0x88,0x39,0x1e,0x44,0x11,0x6c,0xc5,0x8b,0xb6,
8260 0x8b,0xce,0x3d,0xd5,0xcb,0xbd,0xf0,0xd4,0xd9,0xfb,0x02,0x35,
8261 0x96,0x39,0x26,0x85,0xf9 };
8262 static const BYTE rsaPrivKeyModulus[] = {
8263 0x43,0x55,0x9f,0x73,0x9a,0xb8,0x4f,0x8f,0x49,0xbe,0xf9,0x6c,
8264 0xbc,0xaa,0x20,0xc5,0xe7,0x49,0x25,0x03,0x50,0x0c,0x87,0x2d,
8265 0x63,0xf6,0xe7,0x81,0x5e,0x54,0x0f,0x36,0x24,0xfa,0x50,0x1c,
8266 0x86,0xfd,0x65,0x5a,0x75,0xcf,0xfd,0x9c,0xe1,0x85,0x09,0x47,
8267 0x62,0x40,0xe8,0xcb,0xf9,0xcb,0xdc,0xf0,0xf9,0x73,0x2b,0xe9,
8268 0xba,0x63,0xd6,0x23,0x2f,0xf1,0x86,0xf2,0xc5,0x54,0xd1,0x0e,
8269 0x5c,0x09,0xa8,0x77,0x8a,0xa9,0x1f,0xd5,0xb9,0x2c,0xf0,0xa7,
8270 0x76,0x20,0x53,0xff,0x17,0xa9,0x42,0xfc,0x1a,0x7c,0x74,0x4a,
8271 0x2e,0x41,0x3b,0x90,0x31,0x2b,0xd7,0xf2,0xa4,0x9c,0xaf,0x99,
8272 0xea,0x9a,0x58,0x4f,0xc0,0xe8,0x94,0xcc,0x44,0x61,0xe5,0xe2,
8273 0xe5,0x61,0xfe,0xb8,0xb0,0x42,0x7b,0x12,0x64,0x1d,0xfc,0xf6,
8274 0x0c,0xe6,0x08,0x65,0x01,0x76,0xda,0x7a,0x11,0x41,0x60,0x03,
8275 0xc2,0x14,0x93,0x0f,0xbb,0xc1,0x68,0x97,0xb7,0xfd,0x28,0x1e,
8276 0x84,0x61,0xe5,0xe1,0xd2,0x3d,0x85,0x91,0x3b,0x29,0x3a,0x36,
8277 0x9e,0xe2,0x73,0x62,0x3c,0xde,0x1a,0x7b,0xc9,0x0b,0x74,0x85,
8278 0x6c,0x27,0x68,0xd1,0x6c,0xf2,0x66,0x58,0xc7,0x2f,0xdd,0x11,
8279 0xba,0x76,0x55,0x7a,0x3b,0x1b,0xba,0xd1,0xbc,0x4a,0x3a,0x69,
8280 0x2d,0x32,0xdf,0x59,0x35,0xf2,0xe0,0x16,0xe0,0x91,0xd5,0xe1,
8281 0x3f,0xeb,0xe0,0x01,0x7a,0x3a,0xe4,0x06,0x39,0x45,0x3b,0x99,
8282 0x69,0xb0,0xfb,0x07,0x34,0xdf,0x90,0x9c,0x54,0x65,0x97,0x7e,
8283 0x64,0x31,0xf8,0xf9,0x26,0xd4,0x41,0x1c,0xb0,0x41,0x25,0xeb,
8284 0x41,0x3c,0xba,0xae };
8285 static const BYTE rsaPrivKeyPrime1[] = {
8286 0xe9,0x51,0xdb,0x33,0xb7,0xbf,0x8e,0xa7,0x20,0x74,0xd7,0x86,
8287 0xc5,0x3a,0x4a,0x16,0xd7,0x5e,0xed,0x3b,0xe7,0x77,0xb9,0xbf,
8288 0xd9,0xe2,0xb8,0xa6,0x2e,0xd9,0xd0,0x4e,0x53,0xbe,0x11,0x5d,
8289 0x52,0x3b,0xf0,0xca,0xe7,0x56,0xe7,0x20,0x02,0xd8,0x70,0x30,
8290 0xa8,0xc3,0x72,0xd1,0xce,0xdb,0x38,0x00,0x74,0x59,0xd2,0x2f,
8291 0xf8,0x31,0xe5,0x4d,0x6c,0xcf,0x25,0x6c,0x37,0x46,0x49,0xac,
8292 0xef,0x24,0xcd,0xc7,0x80,0x96,0xd5,0x22,0x47,0xe0,0xdf,0x33,
8293 0x0a,0x4a,0x53,0x3d,0x76,0xdb,0xf7,0x39,0x63,0x79,0xa3,0x0d,
8294 0xfa,0x8a,0x95,0xb0,0x98,0x62,0xb8,0x7f,0xc3,0xbe,0x68,0xa4,
8295 0x9f,0x7f,0x5f,0x1e,0x3b,0x48,0x7b,0x99,0x20,0xe0,0x5b,0xfc,
8296 0x4e,0xb6,0x76,0xed,0xdd,0xfe,0x5e,0xe3 };
8297 static const BYTE rsaPrivKeyPrime2[] = {
8298 0x4b,0xe6,0x2f,0xa5,0x08,0x3d,0xa9,0xf5,0x36,0x10,0x97,0x39,
8299 0xf3,0xc1,0xfb,0x86,0x48,0xaf,0x64,0xc6,0x9b,0x5f,0xe6,0xcf,
8300 0xb2,0x7b,0x39,0xa5,0x37,0x2c,0x61,0x1a,0x68,0xe2,0xe0,0xb0,
8301 0xfa,0x53,0xf1,0x7b,0x1d,0x3d,0x6b,0x70,0xa4,0x64,0x3a,0xe7,
8302 0xe1,0xe1,0xa0,0xaf,0x99,0x95,0xf2,0x4d,0x40,0x05,0x32,0xa4,
8303 0xab,0xac,0xee,0x97,0xca,0xa3,0xd6,0xe9,0xc0,0x9f,0x4d,0xb0,
8304 0xed,0x4a,0xe2,0x3a,0x29,0xe6,0xc3,0x2b,0xcd,0xa6,0xa9,0x87,
8305 0x7c,0xee,0x93,0x84,0x40,0xf2,0x40,0xae,0xc6,0x8e,0xd6,0x4a,
8306 0xaf,0xfc,0x5e,0x7d,0x9c,0x68,0x6f,0x18,0x72,0x1c,0x66,0x82,
8307 0x5d,0x66,0xaa,0x62,0x91,0xab,0xe1,0x0f,0xe9,0x4a,0x9d,0xce,
8308 0xce,0xe8,0xcf,0x6e,0xf0,0x57,0xba,0xc4 };
8309 static const BYTE rsaPrivKeyExponent1[] = {
8310 0xa1,0xca,0x03,0xc2,0xbc,0x0c,0x7b,0x61,0x6f,0x4e,0xf3,0xde,
8311 0x81,0xfb,0x44,0xa7,0x70,0xae,0xe8,0xb3,0x61,0x7a,0x86,0xac,
8312 0x7e,0xcd,0xf9,0xbc,0xe9,0x34,0x32,0x2d,0x7d,0x78,0x93,0xe2,
8313 0xac,0x87,0x45,0xe9,0xde,0x35,0x6d,0x8c,0xe0,0x16,0x09,0x9d,
8314 0x54,0xd9,0x49,0x62,0x73,0x5f,0xd7,0x5c,0x9a,0xba,0x80,0xef,
8315 0xbe,0xf5,0xda,0x9a,0x8c,0x03,0x79,0x9b,0xad,0x9e,0xff,0x0a,
8316 0x15,0x39,0x69,0xba,0x22,0x46,0xdd,0xbb,0x09,0xf9,0xa3,0x47,
8317 0x0b,0xae,0xce,0x10,0xac,0x22,0x86,0xb0,0x0a,0xf3,0x26,0x9f,
8318 0x98,0xa5,0x90,0xd4,0x94,0x0b,0xcb,0x76,0xa8,0xbf,0x26,0x76,
8319 0x01,0x5e,0x53,0x03,0x3e,0x30,0x29,0x39,0x67,0x9e,0x9f,0x54,
8320 0x93,0xa0,0xaf,0xe2,0x08,0x02,0xe7,0x86 };
8321 static const BYTE rsaPrivKeyExponent2[] = {
8322 0x85,0xfd,0x95,0x6b,0xb1,0x67,0x28,0x1d,0xe4,0xf1,0x20,0xbf,
8323 0x64,0x1d,0xf8,0x52,0xa2,0x4a,0x65,0xbd,0x98,0x55,0xf7,0x10,
8324 0x74,0x30,0x95,0x5a,0x7d,0xea,0x0a,0xc4,0xa5,0xf0,0x5a,0x5f,
8325 0xc3,0x50,0xb0,0x6b,0xa2,0x90,0xf6,0x3d,0xe6,0xfa,0xe3,0xc0,
8326 0xcb,0x14,0x6d,0xda,0x2b,0x96,0x86,0x26,0xb8,0xcb,0x2b,0xa6,
8327 0x21,0xbe,0x83,0x6a,0x5e,0xa3,0x15,0xfa,0xa5,0x7c,0xba,0xf5,
8328 0xc2,0xd9,0x51,0x3b,0x61,0x35,0xb0,0x12,0x92,0xaa,0xec,0xe6,
8329 0x52,0xf6,0x53,0xab,0x2c,0x76,0x10,0xfe,0x5d,0xd5,0xd4,0x96,
8330 0x05,0xe2,0xd9,0xae,0x22,0xb0,0x29,0x6a,0x80,0x88,0x17,0x5b,
8331 0x30,0x15,0xe6,0x20,0xab,0x19,0x11,0x48,0x1a,0x0d,0xf6,0x1b,
8332 0x9d,0x35,0x17,0x4f,0xa1,0x4a,0x5b,0x69 };
8333 static const BYTE rsaPrivKeyCoefficient[] = {
8334 0xf9,0x85,0x26,0x39,0x96,0x35,0x02,0xfb,0xd9,0xd4,0xf0,0xbd,
8335 0xcb,0xd5,0x3d,0xce,0x8b,0xb6,0x8b,0xc5,0x6c,0x11,0x44,0x1e,
8336 0x39,0x88,0x46,0x4a,0x31,0xe6,0xa1,0x3a,0x2b,0xfc,0x2a,0x05,
8337 0xa1,0x68,0x18,0x88,0xa6,0xd0,0xb1,0xc6,0x0b,0xa3,0x3e,0x68,
8338 0xb2,0x4d,0xf1,0xf2,0x1c,0x40,0xdb,0xf8,0x1a,0x44,0xf6,0x84,
8339 0x04,0x96,0xff,0xce,0x3a,0x7c,0x3c,0xd6,0x60,0xbc,0x14,0x14,
8340 0xf7,0xc1,0x9d,0xcd,0x62,0x46,0x8e,0x3e,0x47,0xb6,0x5b,0x91,
8341 0x74,0xb6,0x65,0x66,0x2a,0x13,0xdd,0x63,0x25,0x00,0xae,0x6b,
8342 0x68,0x4e,0x9c,0xc8,0x47,0x7c,0x83,0x52,0x51,0x14,0x8a,0x0f,
8343 0xa2,0x50,0xbd,0x45,0xf0,0x6b,0xbf,0x46,0x20,0xda,0xd7,0x07,
8344 0x1e,0x9a,0xec,0xe1,0x34,0x31,0xb4,0xda };
8345 static const BYTE rsaPrivKeyPrivateExponent[] = {
8346 0x11,0x90,0xb6,0x9f,0x62,0x9c,0x87,0x7e,0x9c,0x4c,0xbd,0x8c,
8347 0xf0,0xf8,0x2d,0x00,0x01,0x94,0xbc,0x68,0x39,0x13,0x3b,0x74,
8348 0x03,0x66,0xda,0xd2,0xde,0x79,0x96,0x61,0xba,0x6e,0x90,0xdf,
8349 0xed,0x25,0xdd,0x76,0xaa,0xfa,0x1d,0x15,0x65,0x99,0xba,0xf7,
8350 0x18,0xd5,0x15,0x85,0x33,0xf2,0xfd,0x60,0xb1,0x9f,0x66,0x9f,
8351 0x86,0x0c,0x69,0x06,0x5d,0x4c,0x5e,0xd8,0xf5,0x45,0x2d,0xf8,
8352 0x05,0x45,0xde,0xa4,0x71,0x58,0x81,0xce,0xe2,0xbb,0xb3,0x54,
8353 0x12,0xff,0x86,0x2d,0xd4,0xe5,0x03,0x90,0xa9,0x92,0xb9,0xe3,
8354 0x73,0xf2,0x69,0xbf,0xe2,0x75,0xab,0x59,0xfe,0x1b,0x48,0x8a,
8355 0xaf,0xdb,0xb0,0x7f,0x7e,0xb7,0x8c,0xfc,0x95,0x23,0x14,0x20,
8356 0x27,0x3d,0x74,0x4c,0x00,0xeb,0x23,0x20,0xc8,0x9c,0x2f,0x43,
8357 0x68,0x1d,0x97,0x02,0x15,0xcc,0xfc,0xde,0xda,0xe0,0x80,0xfd,
8358 0x95,0xbe,0xba,0xee,0xb3,0xd3,0xdc,0xd0,0xc2,0x63,0x16,0x40,
8359 0x97,0x04,0xa4,0xed,0x61,0x6d,0x37,0x03,0x84,0x00,0xb2,0x44,
8360 0x09,0x8b,0x6f,0xb3,0x44,0xac,0x54,0x66,0xf3,0x26,0x93,0xee,
8361 0xf7,0x91,0x76,0xa5,0x98,0xf8,0x3a,0x07,0x47,0x8b,0xdd,0x69,
8362 0x61,0x1f,0xdd,0x12,0x90,0x2e,0xe3,0xcd,0xc3,0xb7,0xc9,0x6d,
8363 0xfa,0xe8,0xa5,0x96,0x33,0x74,0xc9,0xc0,0x1f,0x3f,0x65,0xda,
8364 0x6f,0x12,0x75,0x17,0x8a,0xdb,0x4f,0x29,0xa2,0xfc,0x47,0x34,
8365 0x02,0xf6,0x86,0xcb,0x6a,0x74,0x9d,0x46,0x93,0x27,0x11,0x8c,
8366 0xef,0xd6,0xc9,0x2c,0x65,0x89,0xd6,0x78,0x98,0x32,0x03,0x69,
8367 0x5b,0xcd,0x03,0x99 };
8369 static void test_decodeRsaPrivateKey(DWORD dwEncoding)
8371 LPBYTE buf = NULL;
8372 DWORD bufSize = 0;
8373 BOOL ret;
8375 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_RSA_PRIVATE_KEY,
8376 rsaPrivKeyDer, sizeof(rsaPrivKeyDer)-10,
8377 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
8378 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD),
8379 "Expected CRYPT_E_ASN1_EOD, got %08lx\n",
8380 GetLastError());
8382 buf = NULL;
8383 bufSize = 0;
8384 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_RSA_PRIVATE_KEY,
8385 rsaPrivKeyDer, sizeof(rsaPrivKeyDer),
8386 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
8387 ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
8389 if (ret)
8391 BLOBHEADER *hdr = (BLOBHEADER *)buf;
8392 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER));
8393 static const int bitlen = 2048;
8394 BYTE *modulus = (BYTE*)(rsaPubKey + 1);
8395 BYTE *prime1 = modulus + bitlen/8;
8396 BYTE *prime2 = prime1 + bitlen/16;
8397 BYTE *exponent1 = prime2 + bitlen/16;
8398 BYTE *exponent2 = exponent1 + bitlen/16;
8399 BYTE *coefficient = exponent2 + bitlen/16;
8400 BYTE *privateExponent = coefficient + bitlen/16;
8402 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
8403 (bitlen * 9 / 16),
8404 "Wrong size %ld\n", bufSize);
8406 ok(hdr->bType == PRIVATEKEYBLOB,
8407 "Expected type PRIVATEKEYBLOB (%d), got %d\n", PRIVATEKEYBLOB,
8408 hdr->bType);
8409 ok(hdr->bVersion == CUR_BLOB_VERSION,
8410 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
8411 CUR_BLOB_VERSION, hdr->bVersion);
8412 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n",
8413 hdr->reserved);
8414 ok(hdr->aiKeyAlg == CALG_RSA_KEYX,
8415 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg);
8417 ok(rsaPubKey->magic == 0x32415352,
8418 "Expected magic 0x32415352, got 0x%lx\n", rsaPubKey->magic);
8419 ok(rsaPubKey->bitlen == bitlen,
8420 "Expected bitlen %d, got %ld\n", bitlen, rsaPubKey->bitlen);
8421 ok(rsaPubKey->pubexp == 65537,
8422 "Expected pubexp 65537, got %ld\n", rsaPubKey->pubexp);
8424 ok(!memcmp(modulus, rsaPrivKeyModulus, bitlen/8),
8425 "unexpected modulus\n");
8426 ok(!memcmp(prime1, rsaPrivKeyPrime1, bitlen/16),
8427 "unexpected prime1\n");
8428 ok(!memcmp(prime2, rsaPrivKeyPrime2, bitlen/16),
8429 "unexpected prime2\n");
8430 ok(!memcmp(exponent1, rsaPrivKeyExponent1, bitlen/16),
8431 "unexpected exponent1\n");
8432 ok(!memcmp(exponent2, rsaPrivKeyExponent2, bitlen/16),
8433 "unexpected exponent2\n");
8434 ok(!memcmp(coefficient, rsaPrivKeyCoefficient, bitlen/16),
8435 "unexpected coefficient\n");
8436 ok(!memcmp(privateExponent, rsaPrivKeyPrivateExponent, bitlen/8),
8437 "unexpected privateExponent\n");
8439 LocalFree(buf);
8443 /* Free *pInfo with HeapFree */
8444 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
8446 BOOL ret;
8447 DWORD size = 0;
8448 HCRYPTKEY key;
8450 /* This crashes
8451 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
8453 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size);
8454 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
8455 "Expected ERROR_INVALID_PARAMETER, got %08lx\n", GetLastError());
8456 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL,
8457 &size);
8458 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
8459 "Expected ERROR_INVALID_PARAMETER, got %08lx\n", GetLastError());
8460 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL,
8461 NULL, &size);
8462 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
8463 "Expected ERROR_INVALID_PARAMETER, got %08lx\n", GetLastError());
8464 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
8465 0, NULL, NULL, &size);
8466 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
8467 "Expected ERROR_INVALID_PARAMETER, got %08lx\n", GetLastError());
8468 /* Test with no key */
8469 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
8470 0, NULL, NULL, &size);
8471 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08lx\n",
8472 GetLastError());
8473 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
8474 ok(ret, "CryptGenKey failed: %08lx\n", GetLastError());
8475 if (ret)
8477 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
8478 NULL, 0, NULL, NULL, &size);
8479 ok(ret, "CryptExportPublicKeyInfoEx failed: %08lx\n", GetLastError());
8480 *pInfo = HeapAlloc(GetProcessHeap(), 0, size);
8481 if (*pInfo)
8483 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
8484 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size);
8485 ok(ret, "CryptExportPublicKeyInfoEx failed: %08lx\n",
8486 GetLastError());
8487 if (ret)
8489 /* By default (we passed NULL as the OID) the OID is
8490 * szOID_RSA_RSA.
8492 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA),
8493 "Expected %s, got %s\n", szOID_RSA_RSA,
8494 (*pInfo)->Algorithm.pszObjId);
8498 CryptDestroyKey(key);
8501 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
8502 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
8503 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
8504 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
8505 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
8506 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
8507 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
8508 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
8509 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
8510 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
8511 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
8512 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
8513 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
8514 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
8515 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
8516 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
8517 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
8518 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
8519 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
8520 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
8521 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
8522 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
8523 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
8524 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
8525 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
8527 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info)
8529 BOOL ret;
8530 HCRYPTKEY key;
8531 BCRYPT_KEY_HANDLE key2;
8532 PCCERT_CONTEXT context;
8533 DWORD dwSize;
8534 ALG_ID ai;
8536 /* These crash
8537 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
8538 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
8539 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
8540 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
8541 NULL);
8543 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key);
8544 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
8545 "Expected ERROR_FILE_NOT_FOUND, got %08lx\n", GetLastError());
8546 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key);
8547 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
8548 "Expected ERROR_FILE_NOT_FOUND, got %08lx\n", GetLastError());
8549 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL,
8550 &key);
8551 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
8552 "Expected ERROR_INVALID_PARAMETER, got %08lx\n", GetLastError());
8554 /* Export key with standard algorithm (CALG_RSA_KEYX) */
8555 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
8556 &key);
8557 ok(ret, "CryptImportPublicKeyInfoEx failed: %08lx\n", GetLastError());
8559 dwSize = sizeof(ai);
8560 ret = CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
8561 ok(ret, "CryptGetKeyParam failed: %08lx\n", GetLastError());
8562 if(ret)
8564 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %ld\n",dwSize);
8565 ok(ai == CALG_RSA_KEYX, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai);
8568 CryptDestroyKey(key);
8570 /* Repeat with forced algorithm */
8571 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, CALG_RSA_SIGN, 0, NULL,
8572 &key);
8573 ok(ret, "CryptImportPublicKeyInfoEx failed: %08lx\n", GetLastError());
8575 dwSize = sizeof(ai);
8576 ret = CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
8577 ok(ret, "CryptGetKeyParam failed: %08lx\n", GetLastError());
8578 if(ret)
8580 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %ld\n",dwSize);
8581 ok(ai == CALG_RSA_SIGN, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai);
8584 CryptDestroyKey(key);
8586 /* Test importing a public key from a certificate context */
8587 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert,
8588 sizeof(expiredCert));
8589 ok(context != NULL, "CertCreateCertificateContext failed: %08lx\n",
8590 GetLastError());
8591 if (context)
8593 ok(!strcmp(szOID_RSA_RSA,
8594 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId),
8595 "Expected %s, got %s\n", szOID_RSA_RSA,
8596 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
8597 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING,
8598 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
8599 ok(ret, "CryptImportPublicKeyInfoEx failed: %08lx\n", GetLastError());
8600 CryptDestroyKey(key);
8602 ret = CryptImportPublicKeyInfoEx2(X509_ASN_ENCODING,
8603 &context->pCertInfo->SubjectPublicKeyInfo, 0, NULL, &key2);
8604 ok(ret, "CryptImportPublicKeyInfoEx2 failed: %08lx\n", GetLastError());
8605 BCryptDestroyKey(key2);
8607 CertFreeCertificateContext(context);
8611 static const char cspName[] = "WineCryptTemp";
8613 static void testPortPublicKeyInfo(void)
8615 HCRYPTPROV csp;
8616 BOOL ret;
8617 PCERT_PUBLIC_KEY_INFO info = NULL;
8619 /* Just in case a previous run failed, delete this thing */
8620 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV_A, PROV_RSA_FULL,
8621 CRYPT_DELETEKEYSET);
8622 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV_A, PROV_RSA_FULL,
8623 CRYPT_NEWKEYSET);
8624 ok(ret,"CryptAcquireContextA failed\n");
8626 testExportPublicKey(csp, &info);
8627 testImportPublicKey(csp, info);
8629 HeapFree(GetProcessHeap(), 0, info);
8630 CryptReleaseContext(csp, 0);
8631 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV_A, PROV_RSA_FULL,
8632 CRYPT_DELETEKEYSET);
8633 ok(ret,"CryptAcquireContextA failed\n");
8636 static void test_encodeOCSPRequestInfo(DWORD dwEncoding)
8638 static const BYTE expected[] =
8639 {0x30, 0x68, 0xa1, 0x17, 0x82, 0x15, 0x2a, 0x2e, 0x63, 0x6d, 0x2e, 0x73, 0x74, 0x65, 0x61, 0x6d,
8640 0x70, 0x6f, 0x77, 0x65, 0x72, 0x65, 0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x4d, 0x30, 0x4b, 0x30,
8641 0x49, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0xe4, 0xe3,
8642 0x95, 0xa2, 0x29, 0xd3, 0xd4, 0xc1, 0xc3, 0x1f, 0xf0, 0x98 ,0x0c, 0x0b, 0x4e, 0xc0, 0x09, 0x8a,
8643 0xab, 0xd8, 0x04, 0x14, 0xb7, 0x6b, 0xa2, 0xea, 0xa8, 0xaa, 0x84, 0x8c, 0x79, 0xea, 0xb4, 0xda,
8644 0x0f, 0x98, 0xb2, 0xc5, 0x95, 0x76, 0xb9, 0xf4, 0x02, 0x10, 0xb1, 0xc1, 0x87, 0x54, 0x54, 0xac,
8645 0x1e, 0x55, 0x40, 0xfb, 0xef, 0xd9, 0x6d, 0x8f, 0x49, 0x08};
8646 static const BYTE expected2[] =
8647 {0x30, 0x81, 0xb6, 0xa1, 0x17, 0x82, 0x15, 0x2a, 0x2e, 0x63, 0x6d, 0x2e, 0x73, 0x74, 0x65, 0x61,
8648 0x6d, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x65, 0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x81, 0x9a, 0x30,
8649 0x4b, 0x30, 0x49, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14,
8650 0xe4, 0xe3, 0x95, 0xa2, 0x29, 0xd3, 0xd4, 0xc1, 0xc3, 0x1f, 0xf0, 0x98, 0x0c, 0x0b, 0x4e, 0xc0,
8651 0x09, 0x8a, 0xab, 0xd8, 0x04, 0x14, 0xb7, 0x6b, 0xa2, 0xea, 0xa8, 0xaa, 0x84, 0x8c, 0x79, 0xea,
8652 0xb4, 0xda, 0x0f, 0x98, 0xb2, 0xc5, 0x95, 0x76, 0xb9, 0xf4, 0x02, 0x10, 0xb1, 0xc1, 0x87, 0x54,
8653 0x54, 0xac, 0x1e, 0x55, 0x40, 0xfb, 0xef, 0xd9, 0x6d, 0x8f, 0x49, 0x08, 0x30, 0x4b, 0x30, 0x49,
8654 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0xe4, 0xe3, 0x95,
8655 0xa2, 0x29, 0xd3, 0xd4, 0xc1, 0xc3, 0x1f, 0xf0, 0x98, 0x0c, 0x0b, 0x4e, 0xc0, 0x09, 0x8a, 0xab,
8656 0xd8, 0x04, 0x14, 0xb7, 0x6b, 0xa2, 0xea, 0xa8, 0xaa, 0x84, 0x8c, 0x79, 0xea, 0xb4, 0xda, 0x0f,
8657 0x98, 0xb2, 0xc5, 0x95, 0x76, 0xb9, 0xf4, 0x02, 0x10, 0xb1, 0xc1, 0x87, 0x54, 0x54, 0xac, 0x1e,
8658 0x55, 0x40, 0xfb, 0xef, 0xd9, 0x6d, 0x8f, 0x49, 0x08};
8659 static const BYTE expected3[] =
8660 {0x30, 0x81, 0x9d, 0x30, 0x81, 0x9a, 0x30, 0x4b, 0x30, 0x49, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
8661 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0xe4, 0xe3, 0x95, 0xa2, 0x29, 0xd3, 0xd4, 0xc1, 0xc3,
8662 0x1f, 0xf0, 0x98, 0x0c, 0x0b, 0x4e, 0xc0, 0x09, 0x8a, 0xab, 0xd8, 0x04, 0x14, 0xb7, 0x6b, 0xa2,
8663 0xea, 0xa8, 0xaa, 0x84, 0x8c, 0x79, 0xea, 0xb4, 0xda, 0x0f, 0x98, 0xb2, 0xc5, 0x95, 0x76, 0xb9,
8664 0xf4, 0x02, 0x10, 0xb1, 0xc1, 0x87, 0x54, 0x54, 0xac, 0x1e, 0x55, 0x40, 0xfb, 0xef, 0xd9, 0x6d,
8665 0x8f, 0x49, 0x08, 0x30, 0x4b, 0x30, 0x49, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a,
8666 0x05, 0x00, 0x04, 0x14, 0xe4, 0xe3, 0x95, 0xa2, 0x29, 0xd3, 0xd4, 0xc1, 0xc3, 0x1f, 0xf0, 0x98,
8667 0x0c, 0x0b, 0x4e, 0xc0, 0x09, 0x8a, 0xab, 0xd8, 0x04, 0x14, 0xb7, 0x6b, 0xa2, 0xea, 0xa8, 0xaa,
8668 0x84, 0x8c, 0x79, 0xea, 0xb4, 0xda, 0x0f, 0x98, 0xb2, 0xc5, 0x95, 0x76, 0xb9, 0xf4, 0x02, 0x10,
8669 0xb1, 0xc1, 0x87, 0x54, 0x54, 0xac, 0x1e, 0x55, 0x40, 0xfb, 0xef, 0xd9, 0x6d, 0x8f, 0x49, 0x08};
8670 static const BYTE expected4[] =
8671 {0x30, 0x6a, 0x30, 0x68, 0xa1, 0x17, 0x82, 0x15, 0x2a, 0x2e, 0x63, 0x6d, 0x2e, 0x73, 0x74, 0x65,
8672 0x61, 0x6d, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x65, 0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x4d, 0x30,
8673 0x4b, 0x30, 0x49, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14,
8674 0xe4, 0xe3, 0x95, 0xa2, 0x29, 0xd3, 0xd4, 0xc1, 0xc3, 0x1f, 0xf0, 0x98, 0x0c, 0x0b, 0x4e, 0xc0,
8675 0x09, 0x8a, 0xab, 0xd8, 0x04, 0x14, 0xb7, 0x6b, 0xa2, 0xea, 0xa8, 0xaa, 0x84, 0x8c, 0x79, 0xea,
8676 0xb4, 0xda, 0x0f, 0x98, 0xb2, 0xc5, 0x95, 0x76, 0xb9, 0xf4, 0x02, 0x10, 0xb1, 0xc1, 0x87, 0x54,
8677 0x54, 0xac, 0x1e, 0x55, 0x40, 0xfb, 0xef, 0xd9, 0x6d, 0x8f, 0x49, 0x08};
8678 static const BYTE issuer_name[] =
8679 {0xe4, 0xe3 ,0x95, 0xa2, 0x29, 0xd3, 0xd4, 0xc1, 0xc3, 0x1f, 0xf0, 0x98, 0x0c, 0x0b, 0x4e, 0xc0,
8680 0x09, 0x8a, 0xab, 0xd8};
8681 static const BYTE issuer_key[] =
8682 {0xb7, 0x6b, 0xa2, 0xea, 0xa8, 0xaa, 0x84, 0x8c, 0x79, 0xea, 0xb4, 0xda, 0x0f, 0x98, 0xb2, 0xc5,
8683 0x95, 0x76, 0xb9, 0xf4};
8684 static const BYTE serial[] =
8685 {0x08, 0x49, 0x8f, 0x6d, 0xd9, 0xef, 0xfb, 0x40, 0x55, 0x1e, 0xac, 0x54, 0x54, 0x87, 0xc1, 0xb1};
8686 OCSP_REQUEST_ENTRY entry[2];
8687 CERT_ALT_NAME_ENTRY name;
8688 OCSP_REQUEST_INFO info;
8689 OCSP_SIGNED_REQUEST_INFO info_signed;
8690 DWORD size;
8691 BYTE *buf, *buf2;
8692 BOOL ret;
8694 memset(&entry, 0, sizeof(entry));
8695 entry[0].CertId.HashAlgorithm.pszObjId = (char *)szOID_OIWSEC_sha1;
8696 entry[0].CertId.IssuerNameHash.cbData = sizeof(issuer_name);
8697 entry[0].CertId.IssuerNameHash.pbData = (BYTE *)issuer_name;
8698 entry[0].CertId.IssuerKeyHash.cbData = sizeof(issuer_key);
8699 entry[0].CertId.IssuerKeyHash.pbData = (BYTE *)issuer_key;
8700 entry[0].CertId.SerialNumber.cbData = sizeof(serial);
8701 entry[0].CertId.SerialNumber.pbData = (BYTE *)serial;
8703 name.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
8704 name.pwszDNSName = (WCHAR *)L"*.cm.steampowered.com";
8706 info.dwVersion = OCSP_REQUEST_V1;
8707 info.pRequestorName = &name;
8708 info.cRequestEntry = 1;
8709 info.rgRequestEntry = entry;
8710 info.cExtension = 0;
8711 info.rgExtension = NULL;
8713 size = 0;
8714 SetLastError(0xdeadbeef);
8715 ret = pCryptEncodeObjectEx(dwEncoding, OCSP_REQUEST, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
8716 ok(ret, "got %08lx\n", GetLastError());
8717 ok(size == sizeof(expected), "got %lu\n", size);
8718 ok(!memcmp(buf, expected, sizeof(expected)), "unexpected value\n");
8720 /* wrapped in OCSP_SIGNED_REQUEST_INFO */
8721 info_signed.ToBeSigned.cbData = size;
8722 info_signed.ToBeSigned.pbData = buf;
8723 info_signed.pOptionalSignatureInfo = NULL;
8724 size = 0;
8725 SetLastError(0xdeadbeef);
8726 ret = pCryptEncodeObjectEx(dwEncoding, OCSP_SIGNED_REQUEST, &info_signed, CRYPT_ENCODE_ALLOC_FLAG, NULL,
8727 &buf2, &size);
8728 ok(ret, "got %08lx\n", GetLastError());
8729 ok(size == sizeof(expected4), "got %lu\n", size);
8730 ok(!memcmp(buf2, expected4, sizeof(expected4)), "unexpected value\n");
8731 LocalFree(buf);
8732 LocalFree(buf2);
8734 /* two entries */
8735 entry[1].CertId.HashAlgorithm.pszObjId = (char *)szOID_OIWSEC_sha1;
8736 entry[1].CertId.IssuerNameHash.cbData = sizeof(issuer_name);
8737 entry[1].CertId.IssuerNameHash.pbData = (BYTE *)issuer_name;
8738 entry[1].CertId.IssuerKeyHash.cbData = sizeof(issuer_key);
8739 entry[1].CertId.IssuerKeyHash.pbData = (BYTE *)issuer_key;
8740 entry[1].CertId.SerialNumber.cbData = sizeof(serial);
8741 entry[1].CertId.SerialNumber.pbData = (BYTE *)serial;
8742 info.cRequestEntry = 2;
8744 size = 0;
8745 SetLastError(0xdeadbeef);
8746 ret = pCryptEncodeObjectEx(dwEncoding, OCSP_REQUEST, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
8747 ok(ret, "got %08lx\n", GetLastError());
8748 ok(size == sizeof(expected2), "got %lu\n", size);
8749 ok(!memcmp(buf, expected2, sizeof(expected2)), "unexpected value\n");
8750 LocalFree(buf);
8752 /* requestor name not set */
8753 info.pRequestorName = NULL;
8754 size = 0;
8755 SetLastError(0xdeadbeef);
8756 ret = pCryptEncodeObjectEx(dwEncoding, OCSP_REQUEST, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
8757 ok(ret, "got %08lx\n", GetLastError());
8758 ok(size == sizeof(expected3), "got %lu\n", size);
8759 ok(!memcmp(buf, expected3, sizeof(expected3)), "unexpected value\n");
8760 LocalFree(buf);
8763 static const BYTE ocsp_response[] = {
8764 0x30, 0x03, 0x0a, 0x01, 0x06
8767 static const BYTE ocsp_response2[] = {
8768 0x30, 0x82, 0x01, 0xd3, 0x0a, 0x01, 0x00, 0xa0, 0x82, 0x01, 0xcc, 0x30,
8769 0x82, 0x01, 0xc8, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30,
8770 0x01, 0x01, 0x04, 0x82, 0x01, 0xb9, 0x30, 0x82, 0x01, 0xb5, 0x30, 0x81,
8771 0x9e, 0xa2, 0x16, 0x04, 0x14, 0xb7, 0x6b, 0xa2, 0xea, 0xa8, 0xaa, 0x84,
8772 0x8c, 0x79, 0xea, 0xb4, 0xda, 0x0f, 0x98, 0xb2, 0xc5, 0x95, 0x76, 0xb9,
8773 0xf4, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x32, 0x30, 0x33, 0x30, 0x37, 0x31,
8774 0x38, 0x33, 0x36, 0x34, 0x33, 0x5a, 0x30, 0x73, 0x30, 0x71, 0x30, 0x49,
8775 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04,
8776 0x14, 0xe4, 0xe3, 0x95, 0xa2, 0x29, 0xd3, 0xd4, 0xc1, 0xc3, 0x1f, 0xf0,
8777 0x98, 0x0c, 0x0b, 0x4e, 0xc0, 0x09, 0x8a, 0xab, 0xd8, 0x04, 0x14, 0xb7,
8778 0x6b, 0xa2, 0xea, 0xa8, 0xaa, 0x84, 0x8c, 0x79, 0xea, 0xb4, 0xda, 0x0f,
8779 0x98, 0xb2, 0xc5, 0x95, 0x76, 0xb9, 0xf4, 0x02, 0x10, 0x08, 0x49, 0x8f,
8780 0x6d, 0xd9, 0xef, 0xfb, 0x40, 0x55, 0x1e, 0xac, 0x54, 0x54, 0x87, 0xc1,
8781 0xb1, 0x80, 0x00, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x32, 0x30, 0x33, 0x30,
8782 0x37, 0x31, 0x38, 0x32, 0x31, 0x30, 0x31, 0x5a, 0xa0, 0x11, 0x18, 0x0f,
8783 0x32, 0x30, 0x32, 0x32, 0x30, 0x33, 0x31, 0x34, 0x31, 0x37, 0x33, 0x36,
8784 0x30, 0x31, 0x5a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
8785 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x2a,
8786 0xf3, 0x5f, 0xf7, 0x72, 0x6b, 0x27, 0x38, 0x6b, 0xae, 0x66, 0x42, 0xe0,
8787 0x3b, 0xc6, 0x44, 0x5f, 0x95, 0xe2, 0x1f, 0xbc, 0x3f, 0xb3, 0x1d, 0x6c,
8788 0x6c, 0x7c, 0x91, 0xb3, 0x02, 0x23, 0x0f, 0xf0, 0x13, 0x5f, 0x62, 0x92,
8789 0x0d, 0x91, 0xa9, 0x8f, 0x66, 0xe9, 0x18, 0xe3, 0xb1, 0xe0, 0x4c, 0x63,
8790 0x40, 0x9e, 0x14, 0x26, 0x28, 0x7a, 0x5e, 0x51, 0x99, 0x43, 0x1c, 0xd5,
8791 0xbd, 0x84, 0x88, 0x68, 0xd9, 0x0e, 0xd9, 0xf4, 0x78, 0x48, 0x9f, 0x01,
8792 0x4c, 0x34, 0x14, 0x1e, 0x7c, 0x72, 0x9c, 0xdd, 0x94, 0xcb, 0x6e, 0x28,
8793 0xf5, 0x76, 0x75, 0xa2, 0xbe, 0x4b, 0x52, 0xac, 0x38, 0x9d, 0xce, 0x52,
8794 0x68, 0x33, 0xbc, 0x52, 0xc7, 0xdc, 0x2f, 0x19, 0xff, 0x15, 0x9c, 0x4b,
8795 0xdb, 0x83, 0x4e, 0xd7, 0xf6, 0x9b, 0x7f, 0x76, 0x58, 0xa5, 0x46, 0x49,
8796 0xe3, 0x2d, 0x41, 0x26, 0xf8, 0xce, 0xb7, 0x56, 0x61, 0xb2, 0x88, 0x65,
8797 0x2b, 0xb8, 0x4d, 0xf2, 0xf2, 0x32, 0x50, 0x53, 0x8b, 0x0d, 0xc6, 0x58,
8798 0xac, 0xd8, 0xe4, 0x8d, 0x38, 0x9e, 0x61, 0xeb, 0x6b, 0xd2, 0xd6, 0x50,
8799 0x8d, 0xfa, 0x93, 0x47, 0x4e, 0x6e, 0x2b, 0xd3, 0xb9, 0xdc, 0xb9, 0xb5,
8800 0x86, 0x46, 0xcb, 0xda, 0xd9, 0xd8, 0xd5, 0x99, 0x7a, 0x7c, 0x73, 0xee,
8801 0xc1, 0x52, 0x8e, 0xc5, 0xca, 0x28, 0x1d, 0x15, 0x94, 0x06, 0xa0, 0xa5,
8802 0x01, 0xf3, 0xbd, 0x67, 0x3f, 0x3d, 0x46, 0x63, 0xc5, 0xba, 0xd5, 0x12,
8803 0xde, 0xb4, 0xc5, 0x86, 0xfe, 0x97, 0x6b, 0x70, 0xfe, 0xa4, 0x6a, 0x25,
8804 0x63, 0x8e, 0xcf, 0xa4, 0x13, 0x1c, 0x2b, 0xf7, 0xf4, 0xc9, 0x79, 0x8e,
8805 0x07, 0xa3, 0x25, 0x9f, 0xcf, 0x33, 0x65, 0x49, 0x84, 0xad, 0x7f, 0x90,
8806 0x44, 0x85, 0xd8, 0xa7, 0x73, 0x53, 0x56, 0x73, 0xca, 0x15, 0x39, 0x99,
8807 0x5f, 0x39, 0xfd
8810 static void test_decodeOCSPResponseInfo(DWORD dwEncoding)
8812 OCSP_RESPONSE_INFO *info;
8813 DWORD size;
8814 BOOL ret;
8816 ret = pCryptDecodeObjectEx(dwEncoding, OCSP_RESPONSE, ocsp_response, sizeof(ocsp_response),
8817 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
8818 ok(ret, "got %08lx\n", GetLastError());
8819 ok(info->dwStatus == OCSP_UNAUTHORIZED_RESPONSE, "got %lu\n", info->dwStatus);
8820 ok(info->pszObjId == NULL, "got %s\n", wine_dbgstr_a(info->pszObjId));
8821 ok(!info->Value.cbData, "got %lu\n", info->Value.cbData);
8822 ok(info->Value.pbData == NULL, "got %p\n", info->Value.pbData);
8823 LocalFree(info);
8825 ret = pCryptDecodeObjectEx(dwEncoding, OCSP_RESPONSE, ocsp_response2, sizeof(ocsp_response2),
8826 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
8827 ok(ret, "got %08lx\n", GetLastError());
8828 ok(info->dwStatus == OCSP_SUCCESSFUL_RESPONSE, "got %lu\n", info->dwStatus);
8829 ok(!strcmp(info->pszObjId, szOID_PKIX_OCSP_BASIC_SIGNED_RESPONSE), "got %s\n", wine_dbgstr_a(info->pszObjId));
8830 ok(info->Value.cbData == 441, "got %lu\n", info->Value.cbData);
8831 ok(info->Value.pbData != NULL, "got %p\n", info->Value.pbData);
8832 LocalFree(info);
8835 static const BYTE ocsp_basic_signed_response[] = {
8836 0x30, 0x82, 0x01, 0xb5, 0x30, 0x81, 0x9e, 0xa2, 0x16, 0x04, 0x14, 0xb7,
8837 0x6b, 0xa2, 0xea, 0xa8, 0xaa, 0x84, 0x8c, 0x79, 0xea, 0xb4, 0xda, 0x0f,
8838 0x98, 0xb2, 0xc5, 0x95, 0x76, 0xb9, 0xf4, 0x18, 0x0f, 0x32, 0x30, 0x32,
8839 0x32, 0x30, 0x33, 0x31, 0x30, 0x31, 0x38, 0x33, 0x36, 0x34, 0x38, 0x5a,
8840 0x30, 0x73, 0x30, 0x71, 0x30, 0x49, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
8841 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0xe4, 0xe3, 0x95, 0xa2, 0x29,
8842 0xd3, 0xd4, 0xc1, 0xc3, 0x1f, 0xf0, 0x98, 0x0c, 0x0b, 0x4e, 0xc0, 0x09,
8843 0x8a, 0xab, 0xd8, 0x04, 0x14, 0xb7, 0x6b, 0xa2, 0xea, 0xa8, 0xaa, 0x84,
8844 0x8c, 0x79, 0xea, 0xb4, 0xda, 0x0f, 0x98, 0xb2, 0xc5, 0x95, 0x76, 0xb9,
8845 0xf4, 0x02, 0x10, 0x08, 0x49, 0x8f, 0x6d, 0xd9, 0xef, 0xfb, 0x40, 0x55,
8846 0x1e, 0xac, 0x54, 0x54, 0x87, 0xc1, 0xb1, 0x80, 0x00, 0x18, 0x0f, 0x32,
8847 0x30, 0x32, 0x32, 0x30, 0x33, 0x31, 0x30, 0x31, 0x38, 0x32, 0x31, 0x30,
8848 0x31, 0x5a, 0xa0, 0x11, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x32, 0x30, 0x33,
8849 0x31, 0x37, 0x31, 0x37, 0x33, 0x36, 0x30, 0x31, 0x5a, 0x30, 0x0d, 0x06,
8850 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
8851 0x03, 0x82, 0x01, 0x01, 0x00, 0x6a, 0x4c, 0xfa, 0xe6, 0xe3, 0x48, 0xbb,
8852 0xd6, 0x18, 0x33, 0x04, 0x9d, 0x6a, 0x92, 0x4d, 0x01, 0x74, 0x4f, 0x1a,
8853 0x70, 0xfa, 0xf2, 0x8b, 0xba, 0x0d, 0x2c, 0x06, 0x30, 0xc9, 0x55, 0xce,
8854 0x95, 0x13, 0x4d, 0x4c, 0x65, 0x99, 0xe7, 0xd6, 0x78, 0x9c, 0x3c, 0x9a,
8855 0x60, 0xeb, 0x43, 0x3c, 0x08, 0x1c, 0x02, 0x6d, 0x45, 0x2d, 0x5b, 0xdf,
8856 0xab, 0xf2, 0x92, 0xf1, 0x71, 0x61, 0xb4, 0x34, 0xcf, 0x84, 0x1f, 0xc9,
8857 0x3f, 0x45, 0x9e, 0x64, 0x89, 0x58, 0xdb, 0x2c, 0x73, 0xa8, 0x04, 0xae,
8858 0xad, 0xf2, 0xc5, 0x80, 0x80, 0xcf, 0x96, 0x4b, 0xf1, 0xb4, 0xf1, 0x2a,
8859 0x86, 0x1c, 0x7f, 0x1d, 0xcc, 0xbf, 0xd6, 0xa2, 0x3f, 0x44, 0xb8, 0x62,
8860 0x5b, 0x9b, 0x55, 0xc1, 0x4e, 0x18, 0x67, 0x5a, 0xbe, 0x31, 0xf5, 0x16,
8861 0x6d, 0x74, 0xc4, 0xf2, 0x60, 0x4f, 0xa1, 0x63, 0x49, 0xe9, 0xff, 0x37,
8862 0x3d, 0x66, 0xcd, 0xc3, 0x79, 0x4e, 0x38, 0x68, 0x1b, 0xbf, 0x0b, 0x3b,
8863 0xdb, 0xa0, 0x13, 0x70, 0xb8, 0xd1, 0x59, 0xe2, 0x8e, 0x88, 0xfe, 0x77,
8864 0x39, 0xa8, 0x3f, 0x93, 0xe1, 0xc6, 0x5e, 0x13, 0x9e, 0xea, 0xec, 0x49,
8865 0x65, 0x0b, 0x6d, 0xbf, 0x76, 0xd5, 0x11, 0x59, 0x7b, 0xfe, 0xe6, 0xb2,
8866 0x58, 0xa8, 0xbd, 0xd0, 0xe6, 0x13, 0x26, 0x72, 0x83, 0x78, 0x90, 0x85,
8867 0x82, 0x86, 0x9f, 0x2e, 0x20, 0x64, 0x90, 0xc3, 0xd1, 0x37, 0x50, 0xac,
8868 0xde, 0x52, 0x8e, 0x83, 0x9f, 0x02, 0x7b, 0xff, 0xf1, 0xd4, 0xe5, 0x8b,
8869 0x77, 0x8d, 0xef, 0x61, 0xcb, 0x85, 0x4d, 0xa0, 0x2e, 0x05, 0x28, 0xc0,
8870 0x86, 0x78, 0x59, 0xa9, 0x94, 0xb3, 0x90, 0x6b, 0xf7, 0xff, 0xd3, 0x08,
8871 0x96, 0x7c, 0xbe, 0x22, 0xd8, 0xb6, 0x35, 0xce, 0x1e, 0xae, 0x70, 0x34,
8872 0x05, 0x51, 0x49, 0xac, 0x2f, 0xe8, 0x67, 0xcf, 0xa7
8875 static const BYTE ocsp_to_be_signed[] = {
8876 0x30, 0x81, 0x9e, 0xa2, 0x16, 0x04, 0x14, 0xb7, 0x6b, 0xa2, 0xea, 0xa8,
8877 0xaa, 0x84, 0x8c, 0x79, 0xea, 0xb4, 0xda, 0x0f, 0x98, 0xb2, 0xc5, 0x95,
8878 0x76, 0xb9, 0xf4, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x32, 0x30, 0x33, 0x31,
8879 0x30, 0x31, 0x38, 0x33, 0x36, 0x34, 0x38, 0x5a, 0x30, 0x73, 0x30, 0x71,
8880 0x30, 0x49, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
8881 0x00, 0x04, 0x14, 0xe4, 0xe3, 0x95, 0xa2, 0x29, 0xd3, 0xd4, 0xc1, 0xc3,
8882 0x1f, 0xf0, 0x98, 0x0c, 0x0b, 0x4e, 0xc0, 0x09, 0x8a, 0xab, 0xd8, 0x04,
8883 0x14, 0xb7, 0x6b, 0xa2, 0xea, 0xa8, 0xaa, 0x84, 0x8c, 0x79, 0xea, 0xb4,
8884 0xda, 0x0f, 0x98, 0xb2, 0xc5, 0x95, 0x76, 0xb9, 0xf4, 0x02, 0x10, 0x08,
8885 0x49, 0x8f, 0x6d, 0xd9, 0xef, 0xfb, 0x40, 0x55, 0x1e, 0xac, 0x54, 0x54,
8886 0x87, 0xc1, 0xb1, 0x80, 0x00, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x32, 0x30,
8887 0x33, 0x31, 0x30, 0x31, 0x38, 0x32, 0x31, 0x30, 0x31, 0x5a, 0xa0, 0x11,
8888 0x18, 0x0f, 0x32, 0x30, 0x32, 0x32, 0x30, 0x33, 0x31, 0x37, 0x31, 0x37,
8889 0x33, 0x36, 0x30, 0x31, 0x5a
8892 static const BYTE ocsp_signature[] = {
8893 0x6a, 0x4c, 0xfa, 0xe6, 0xe3, 0x48, 0xbb, 0xd6, 0x18, 0x33, 0x04, 0x9d,
8894 0x6a, 0x92, 0x4d, 0x01, 0x74, 0x4f, 0x1a, 0x70, 0xfa, 0xf2, 0x8b, 0xba,
8895 0x0d, 0x2c, 0x06, 0x30, 0xc9, 0x55, 0xce, 0x95, 0x13, 0x4d, 0x4c, 0x65,
8896 0x99, 0xe7, 0xd6, 0x78, 0x9c, 0x3c, 0x9a, 0x60, 0xeb, 0x43, 0x3c, 0x08,
8897 0x1c, 0x02, 0x6d, 0x45, 0x2d, 0x5b, 0xdf, 0xab, 0xf2, 0x92, 0xf1, 0x71,
8898 0x61, 0xb4, 0x34, 0xcf, 0x84, 0x1f, 0xc9, 0x3f, 0x45, 0x9e, 0x64, 0x89,
8899 0x58, 0xdb, 0x2c, 0x73, 0xa8, 0x04, 0xae, 0xad, 0xf2, 0xc5, 0x80, 0x80,
8900 0xcf, 0x96, 0x4b, 0xf1, 0xb4, 0xf1, 0x2a, 0x86, 0x1c, 0x7f, 0x1d, 0xcc,
8901 0xbf, 0xd6, 0xa2, 0x3f, 0x44, 0xb8, 0x62, 0x5b, 0x9b, 0x55, 0xc1, 0x4e,
8902 0x18, 0x67, 0x5a, 0xbe, 0x31, 0xf5, 0x16, 0x6d, 0x74, 0xc4, 0xf2, 0x60,
8903 0x4f, 0xa1, 0x63, 0x49, 0xe9, 0xff, 0x37, 0x3d, 0x66, 0xcd, 0xc3, 0x79,
8904 0x4e, 0x38, 0x68, 0x1b, 0xbf, 0x0b, 0x3b, 0xdb, 0xa0, 0x13, 0x70, 0xb8,
8905 0xd1, 0x59, 0xe2, 0x8e, 0x88, 0xfe, 0x77, 0x39, 0xa8, 0x3f, 0x93, 0xe1,
8906 0xc6, 0x5e, 0x13, 0x9e, 0xea, 0xec, 0x49, 0x65, 0x0b, 0x6d, 0xbf, 0x76,
8907 0xd5, 0x11, 0x59, 0x7b, 0xfe, 0xe6, 0xb2, 0x58, 0xa8, 0xbd, 0xd0, 0xe6,
8908 0x13, 0x26, 0x72, 0x83, 0x78, 0x90, 0x85, 0x82, 0x86, 0x9f, 0x2e, 0x20,
8909 0x64, 0x90, 0xc3, 0xd1, 0x37, 0x50, 0xac, 0xde, 0x52, 0x8e, 0x83, 0x9f,
8910 0x02, 0x7b, 0xff, 0xf1, 0xd4, 0xe5, 0x8b, 0x77, 0x8d, 0xef, 0x61, 0xcb,
8911 0x85, 0x4d, 0xa0, 0x2e, 0x05, 0x28, 0xc0, 0x86, 0x78, 0x59, 0xa9, 0x94,
8912 0xb3, 0x90, 0x6b, 0xf7, 0xff, 0xd3, 0x08, 0x96, 0x7c, 0xbe, 0x22, 0xd8,
8913 0xb6, 0x35, 0xce, 0x1e, 0xae, 0x70, 0x34, 0x05, 0x51, 0x49, 0xac, 0x2f,
8914 0xe8, 0x67, 0xcf, 0xa7
8917 static void test_decodeOCSPBasicSignedResponseInfo(DWORD dwEncoding)
8919 OCSP_BASIC_SIGNED_RESPONSE_INFO *info;
8920 DWORD size;
8921 BOOL ret;
8923 size = 0;
8924 ret = pCryptDecodeObjectEx(dwEncoding, OCSP_BASIC_SIGNED_RESPONSE, ocsp_basic_signed_response,
8925 sizeof(ocsp_basic_signed_response), CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
8926 ok(ret, "got %08lx\n", GetLastError());
8927 if (sizeof(void *) == 4) todo_wine ok(size == 496, "got %lu\n", size);
8928 else ok(size == 536, "got %lu\n", size);
8929 ok(info->ToBeSigned.cbData == sizeof(ocsp_to_be_signed), "got %lu\n", info->ToBeSigned.cbData);
8930 ok(!memcmp(info->ToBeSigned.pbData, ocsp_to_be_signed, sizeof(ocsp_to_be_signed)), "wrong data\n");
8932 ok(!strcmp(info->SignatureInfo.SignatureAlgorithm.pszObjId, szOID_RSA_SHA256RSA),
8933 "got %s\n", info->SignatureInfo.SignatureAlgorithm.pszObjId);
8934 ok(info->SignatureInfo.SignatureAlgorithm.Parameters.cbData == 2,
8935 "got %lu\n", info->SignatureInfo.SignatureAlgorithm.Parameters.cbData);
8936 ok(info->SignatureInfo.SignatureAlgorithm.Parameters.pbData[0] == 5, "got 0x%02x\n",
8937 info->SignatureInfo.SignatureAlgorithm.Parameters.pbData[0]);
8938 ok(!info->SignatureInfo.SignatureAlgorithm.Parameters.pbData[1], "got 0x%02x\n",
8939 info->SignatureInfo.SignatureAlgorithm.Parameters.pbData[1]);
8941 ok(info->SignatureInfo.Signature.cbData == sizeof(ocsp_signature), "got %lu\n",
8942 info->SignatureInfo.Signature.cbData);
8943 ok(!memcmp(info->SignatureInfo.Signature.pbData, ocsp_signature, sizeof(ocsp_signature)),
8944 "wrong signature data\n");
8946 ok(!info->SignatureInfo.cCertEncoded, "got %lu\n", info->SignatureInfo.cCertEncoded);
8947 ok(!info->SignatureInfo.rgCertEncoded, "got %p\n", info->SignatureInfo.rgCertEncoded);
8948 LocalFree(info);
8951 static void test_decodeOCSPBasicResponseInfo(DWORD dwEncoding)
8953 static const BYTE resp_id[] = {
8954 0xb7, 0x6b, 0xa2, 0xea, 0xa8, 0xaa, 0x84, 0x8c, 0x79, 0xea, 0xb4, 0xda, 0x0f, 0x98, 0xb2, 0xc5,
8955 0x95, 0x76, 0xb9, 0xf4};
8956 static const BYTE name_hash[] = {
8957 0xe4, 0xe3, 0x95, 0xa2, 0x29, 0xd3, 0xd4, 0xc1, 0xc3, 0x1f, 0xf0, 0x98, 0x0c, 0x0b, 0x4e, 0xc0,
8958 0x09, 0x8a, 0xab, 0xd8};
8959 static const BYTE key_hash[] = {
8960 0xb7, 0x6b, 0xa2, 0xea, 0xa8, 0xaa, 0x84, 0x8c, 0x79, 0xea, 0xb4, 0xda, 0x0f, 0x98, 0xb2, 0xc5,
8961 0x95, 0x76, 0xb9, 0xf4};
8962 static const BYTE serial[] = {
8963 0xb1, 0xc1, 0x87, 0x54, 0x54, 0xac, 0x1e, 0x55, 0x40, 0xfb, 0xef, 0xd9, 0x6d, 0x8f, 0x49, 0x08};
8964 OCSP_BASIC_RESPONSE_INFO *info;
8965 OCSP_BASIC_RESPONSE_ENTRY *entry;
8966 DWORD size;
8967 BOOL ret;
8969 size = 0;
8970 ret = pCryptDecodeObjectEx(dwEncoding, OCSP_BASIC_RESPONSE, ocsp_to_be_signed,
8971 sizeof(ocsp_to_be_signed), CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
8972 ok(ret, "got %08lx\n", GetLastError());
8974 ok(!info->dwVersion, "got %lu\n", info->dwVersion);
8975 ok(info->dwResponderIdChoice == 2, "got %lu\n", info->dwResponderIdChoice);
8976 ok(info->ByKeyResponderId.cbData == sizeof(resp_id), "got %lu\n", info->ByKeyResponderId.cbData);
8977 ok(!memcmp(info->ByKeyResponderId.pbData, resp_id, sizeof(resp_id)), "wrong data\n");
8978 ok(info->ProducedAt.dwLowDateTime == 3438583808, "got %lu\n", info->ProducedAt.dwLowDateTime);
8979 ok(info->ProducedAt.dwHighDateTime == 30946477, "got %lu\n", info->ProducedAt.dwHighDateTime);
8980 ok(info->cResponseEntry == 1, "got %lu\n", info->cResponseEntry);
8981 ok(info->rgResponseEntry != NULL, "got %p\n", info->rgResponseEntry);
8983 entry = info->rgResponseEntry;
8984 ok(!strcmp(entry->CertId.HashAlgorithm.pszObjId, szOID_OIWSEC_sha1), "got '%s'\n", entry->CertId.HashAlgorithm.pszObjId);
8985 ok(entry->CertId.HashAlgorithm.Parameters.cbData == 2, "got %lu\n", entry->CertId.HashAlgorithm.Parameters.cbData);
8986 ok(entry->CertId.HashAlgorithm.Parameters.pbData[0] == 5, "got 0x%02x\n", entry->CertId.HashAlgorithm.Parameters.pbData[0]);
8987 ok(!entry->CertId.HashAlgorithm.Parameters.pbData[1], "got 0x%02x\n", entry->CertId.HashAlgorithm.Parameters.pbData[1]);
8988 ok(entry->CertId.IssuerNameHash.cbData == 20, "got %lu\n", entry->CertId.IssuerNameHash.cbData);
8989 ok(!memcmp(entry->CertId.IssuerNameHash.pbData, name_hash, sizeof(name_hash)), "wrong data\n");
8990 ok(entry->CertId.IssuerKeyHash.cbData == 20, "got %lu\n", entry->CertId.IssuerKeyHash.cbData);
8991 ok(!memcmp(entry->CertId.IssuerKeyHash.pbData, key_hash, sizeof(key_hash)), "wrong data\n");
8992 ok(entry->CertId.SerialNumber.cbData == 16, "got %lu\n", entry->CertId.SerialNumber.cbData);
8993 ok(!memcmp(entry->CertId.SerialNumber.pbData, serial, sizeof(serial)), "wrong data\n");
8994 ok(entry->dwCertStatus == 0, "got %lu\n", entry->dwCertStatus);
8995 ok(entry->pRevokedInfo == NULL, "got %p\n", entry->pRevokedInfo);
8996 ok(entry->ThisUpdate.dwLowDateTime == 2558518400, "got %lu\n", entry->ThisUpdate.dwLowDateTime);
8997 ok(entry->ThisUpdate.dwHighDateTime == 30946475, "got %lu\n", entry->ThisUpdate.dwHighDateTime);
8998 ok(entry->NextUpdate.dwLowDateTime == 2014369408, "got %lu\n", entry->NextUpdate.dwLowDateTime);
8999 ok(entry->NextUpdate.dwHighDateTime == 30947877, "got %lu\n", entry->NextUpdate.dwHighDateTime);
9000 ok(!entry->cExtension, "got %lu\n", entry->cExtension);
9001 ok(entry->rgExtension == NULL, "got %p\n", entry->rgExtension);
9003 ok(!info->cExtension, "got %lu\n", info->cExtension);
9004 ok(info->rgExtension == NULL, "got %p\n", info->rgExtension);
9005 LocalFree(info);
9008 START_TEST(encode)
9010 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
9011 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING };
9012 HMODULE hCrypt32;
9013 DWORD i;
9015 hCrypt32 = GetModuleHandleA("crypt32.dll");
9016 pCryptDecodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptDecodeObjectEx");
9017 pCryptEncodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptEncodeObjectEx");
9018 if (!pCryptDecodeObjectEx || !pCryptEncodeObjectEx)
9020 win_skip("CryptDecodeObjectEx() is not available\n");
9021 return;
9024 for (i = 0; i < ARRAY_SIZE(encodings); i++)
9026 test_encodeInt(encodings[i]);
9027 test_decodeInt(encodings[i]);
9028 test_encodeEnumerated(encodings[i]);
9029 test_decodeEnumerated(encodings[i]);
9030 test_encodeFiletime(encodings[i]);
9031 test_decodeFiletime(encodings[i]);
9032 test_encodeName(encodings[i]);
9033 test_decodeName(encodings[i]);
9034 test_encodeUnicodeName(encodings[i]);
9035 test_decodeUnicodeName(encodings[i]);
9036 test_encodeNameValue(encodings[i]);
9037 test_decodeNameValue(encodings[i]);
9038 test_encodeUnicodeNameValue(encodings[i]);
9039 test_decodeUnicodeNameValue(encodings[i]);
9040 test_encodeAltName(encodings[i]);
9041 test_decodeAltName(encodings[i]);
9042 test_encodeOctets(encodings[i]);
9043 test_decodeOctets(encodings[i]);
9044 test_encodeBits(encodings[i]);
9045 test_decodeBits(encodings[i]);
9046 test_encodeBasicConstraints(encodings[i]);
9047 test_decodeBasicConstraints(encodings[i]);
9048 test_encodeRsaPublicKey(encodings[i]);
9049 test_decodeRsaPublicKey(encodings[i]);
9050 test_encodeRsaPublicKey_Bcrypt(encodings[i]);
9051 test_decodeRsaPublicKey_Bcrypt(encodings[i]);
9052 test_encodeSequenceOfAny(encodings[i]);
9053 test_decodeSequenceOfAny(encodings[i]);
9054 test_encodeExtensions(encodings[i]);
9055 test_decodeExtensions(encodings[i]);
9056 test_encodePublicKeyInfo(encodings[i]);
9057 test_decodePublicKeyInfo(encodings[i]);
9058 test_encodeCertToBeSigned(encodings[i]);
9059 test_decodeCertToBeSigned(encodings[i]);
9060 test_encodeCert(encodings[i]);
9061 test_decodeCert(encodings[i]);
9062 test_encodeCRLDistPoints(encodings[i]);
9063 test_decodeCRLDistPoints(encodings[i]);
9064 test_encodeCRLIssuingDistPoint(encodings[i]);
9065 test_decodeCRLIssuingDistPoint(encodings[i]);
9066 test_encodeCRLToBeSigned(encodings[i]);
9067 test_decodeCRLToBeSigned(encodings[i]);
9068 test_encodeEnhancedKeyUsage(encodings[i]);
9069 test_decodeEnhancedKeyUsage(encodings[i]);
9070 test_encodeAuthorityKeyId(encodings[i]);
9071 test_decodeAuthorityKeyId(encodings[i]);
9072 test_encodeAuthorityKeyId2(encodings[i]);
9073 test_decodeAuthorityKeyId2(encodings[i]);
9074 test_encodeAuthorityInfoAccess(encodings[i]);
9075 test_decodeAuthorityInfoAccess(encodings[i]);
9076 test_encodeCTL(encodings[i]);
9077 test_decodeCTL(encodings[i]);
9078 test_encodePKCSContentInfo(encodings[i]);
9079 test_decodePKCSContentInfo(encodings[i]);
9080 test_encodePKCSAttribute(encodings[i]);
9081 test_decodePKCSAttribute(encodings[i]);
9082 test_encodePKCSAttributes(encodings[i]);
9083 test_decodePKCSAttributes(encodings[i]);
9084 test_encodePKCSSMimeCapabilities(encodings[i]);
9085 test_decodePKCSSMimeCapabilities(encodings[i]);
9086 test_encodePKCSSignerInfo(encodings[i]);
9087 test_decodePKCSSignerInfo(encodings[i]);
9088 test_encodeCMSSignerInfo(encodings[i]);
9089 test_decodeCMSSignerInfo(encodings[i]);
9090 test_encodeNameConstraints(encodings[i]);
9091 test_decodeNameConstraints(encodings[i]);
9092 test_encodePolicyQualifierUserNotice(encodings[i]);
9093 test_decodePolicyQualifierUserNotice(encodings[i]);
9094 test_encodeCertPolicies(encodings[i]);
9095 test_decodeCertPolicies(encodings[i]);
9096 test_encodeCertPolicyMappings(encodings[i]);
9097 test_decodeCertPolicyMappings(encodings[i]);
9098 test_encodeCertPolicyConstraints(encodings[i]);
9099 test_decodeCertPolicyConstraints(encodings[i]);
9100 test_decodeRsaPrivateKey(encodings[i]);
9101 test_encodeOCSPRequestInfo(encodings[i]);
9102 test_decodeOCSPResponseInfo(encodings[i]);
9103 test_decodeOCSPBasicSignedResponseInfo(encodings[i]);
9104 test_decodeOCSPBasicResponseInfo(encodings[i]);
9106 testPortPublicKeyInfo();