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
27 #include "wine/test.h"
30 static BOOL (WINAPI *pCryptDecodeObjectEx)(DWORD,LPCSTR,const BYTE*,DWORD,DWORD,PCRYPT_DECODE_PARA,void*,DWORD*);
31 static BOOL (WINAPI *pCryptEncodeObjectEx)(DWORD,LPCSTR,const void*,DWORD,PCRYPT_ENCODE_PARA,void*,DWORD*);
39 static const BYTE bin1[] = {0x02,0x01,0x01};
40 static const BYTE bin2[] = {0x02,0x01,0x7f};
41 static const BYTE bin3[] = {0x02,0x02,0x00,0x80};
42 static const BYTE bin4[] = {0x02,0x02,0x01,0x00};
43 static const BYTE bin5[] = {0x02,0x01,0x80};
44 static const BYTE bin6[] = {0x02,0x02,0xff,0x7f};
45 static const BYTE bin7[] = {0x02,0x04,0xba,0xdd,0xf0,0x0d};
47 static const struct encodedInt ints[] = {
64 static const BYTE bin8[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
65 static const BYTE bin9[] = {0x02,0x0a,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0};
66 static const BYTE bin10[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
68 static const BYTE bin11[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0xff,0};
69 static const BYTE bin12[] = {0x02,0x09,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
70 static const BYTE bin13[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0};
72 static const struct encodedBigInt bigInts[] = {
73 { bin8, bin9, bin10 },
74 { bin11, bin12, bin13 },
77 static const BYTE bin14[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
78 static const BYTE bin15[] = {0x02,0x0a,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0};
79 static const BYTE bin16[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0xff,0};
80 static const BYTE bin17[] = {0x02,0x0c,0x00,0xff,0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
82 /* Decoded is the same as original, so don't bother storing a separate copy */
83 static const struct encodedBigInt bigUInts[] = {
84 { bin14, bin15, NULL },
85 { bin16, bin17, NULL },
88 static void test_encodeInt(DWORD dwEncoding)
93 CRYPT_INTEGER_BLOB blob;
96 /* CryptEncodeObjectEx with NULL bufSize crashes..
97 ret = pCryptEncodeObjectEx(3, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
100 /* check bogus encoding */
101 ret = pCryptEncodeObjectEx(0, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
103 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
104 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
107 /* check with NULL integer buffer. Windows XP incorrectly returns an
108 * NTSTATUS (crashes on win9x).
110 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, NULL, 0, NULL, NULL,
112 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
113 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
115 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
117 /* encode as normal integer */
118 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, &ints[i].val, 0,
119 NULL, NULL, &bufSize);
120 ok(ret, "Expected success, got %d\n", GetLastError());
121 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, &ints[i].val,
122 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
123 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
126 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
128 ok(buf[1] == ints[i].encoded[1], "Got length %d, expected %d\n",
129 buf[1], ints[i].encoded[1]);
130 ok(!memcmp(buf + 1, ints[i].encoded + 1, ints[i].encoded[1] + 1),
131 "Encoded value of 0x%08x didn't match expected\n", ints[i].val);
134 /* encode as multibyte integer */
135 blob.cbData = sizeof(ints[i].val);
136 blob.pbData = (BYTE *)&ints[i].val;
137 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
138 0, NULL, NULL, &bufSize);
139 ok(ret, "Expected success, got %d\n", GetLastError());
140 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
141 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
142 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
145 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
147 ok(buf[1] == ints[i].encoded[1], "Got length %d, expected %d\n",
148 buf[1], ints[i].encoded[1]);
149 ok(!memcmp(buf + 1, ints[i].encoded + 1, ints[i].encoded[1] + 1),
150 "Encoded value of 0x%08x didn't match expected\n", ints[i].val);
154 /* encode a couple bigger ints, just to show it's little-endian and leading
155 * sign bytes are dropped
157 for (i = 0; i < sizeof(bigInts) / sizeof(bigInts[0]); i++)
159 blob.cbData = strlen((const char*)bigInts[i].val);
160 blob.pbData = (BYTE *)bigInts[i].val;
161 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
162 0, NULL, NULL, &bufSize);
163 ok(ret, "Expected success, got %d\n", GetLastError());
164 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
165 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
166 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
169 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
171 ok(buf[1] == bigInts[i].encoded[1], "Got length %d, expected %d\n",
172 buf[1], bigInts[i].encoded[1]);
173 ok(!memcmp(buf + 1, bigInts[i].encoded + 1,
174 bigInts[i].encoded[1] + 1),
175 "Encoded value didn't match expected\n");
179 /* and, encode some uints */
180 for (i = 0; i < sizeof(bigUInts) / sizeof(bigUInts[0]); i++)
182 blob.cbData = strlen((const char*)bigUInts[i].val);
183 blob.pbData = (BYTE*)bigUInts[i].val;
184 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, &blob,
185 0, NULL, NULL, &bufSize);
186 ok(ret, "Expected success, got %d\n", GetLastError());
187 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, &blob,
188 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
189 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
192 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
194 ok(buf[1] == bigUInts[i].encoded[1], "Got length %d, expected %d\n",
195 buf[1], bigUInts[i].encoded[1]);
196 ok(!memcmp(buf + 1, bigUInts[i].encoded + 1,
197 bigUInts[i].encoded[1] + 1),
198 "Encoded value didn't match expected\n");
204 static void test_decodeInt(DWORD dwEncoding)
206 static const BYTE bigInt[] = { 2, 5, 0xff, 0xfe, 0xff, 0xfe, 0xff };
207 static const BYTE testStr[] = { 0x16, 4, 't', 'e', 's', 't' };
208 static const BYTE longForm[] = { 2, 0x81, 0x01, 0x01 };
209 static const BYTE bigBogus[] = { 0x02, 0x84, 0x01, 0xff, 0xff, 0xf9 };
210 static const BYTE extraBytes[] = { 2, 1, 1, 0, 0, 0, 0 };
216 /* CryptDecodeObjectEx with NULL bufSize crashes..
217 ret = pCryptDecodeObjectEx(3, X509_INTEGER, &ints[0].encoded,
218 ints[0].encoded[1] + 2, 0, NULL, NULL, NULL);
220 /* check bogus encoding */
221 ret = pCryptDecodeObjectEx(3, X509_INTEGER, (BYTE *)&ints[0].encoded,
222 ints[0].encoded[1] + 2, 0, NULL, NULL, &bufSize);
223 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
224 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
225 /* check with NULL integer buffer */
226 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, NULL, 0, 0, NULL, NULL,
228 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
229 GetLastError() == OSS_BAD_ARG /* Win9x */),
230 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
231 /* check with a valid, but too large, integer */
232 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, bigInt, bigInt[1] + 2,
233 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
234 ok((!ret && GetLastError() == CRYPT_E_ASN1_LARGE) ||
235 broken(ret) /* Win9x */,
236 "Expected CRYPT_E_ASN1_LARGE, got %d\n", GetLastError());
237 /* check with a DER-encoded string */
238 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, testStr, testStr[1] + 2,
239 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
240 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
241 GetLastError() == OSS_PDU_MISMATCH /* Win9x */ ),
242 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %08x\n",
244 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
246 /* When the output buffer is NULL, this always succeeds */
247 SetLastError(0xdeadbeef);
248 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER,
249 ints[i].encoded, ints[i].encoded[1] + 2, 0, NULL, NULL,
251 ok(ret && GetLastError() == NOERROR,
252 "Expected success and NOERROR, got %d\n", GetLastError());
253 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER,
254 ints[i].encoded, ints[i].encoded[1] + 2,
255 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
256 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
257 ok(bufSize == sizeof(int), "Wrong size %d\n", bufSize);
258 ok(buf != NULL, "Expected allocated buffer\n");
261 ok(!memcmp(buf, &ints[i].val, bufSize), "Expected %d, got %d\n",
262 ints[i].val, *(int *)buf);
266 for (i = 0; i < sizeof(bigInts) / sizeof(bigInts[0]); i++)
268 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER,
269 bigInts[i].encoded, bigInts[i].encoded[1] + 2, 0, NULL, NULL,
271 ok(ret && GetLastError() == NOERROR,
272 "Expected success and NOERROR, got %d\n", GetLastError());
273 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER,
274 bigInts[i].encoded, bigInts[i].encoded[1] + 2,
275 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
276 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
277 ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %d\n", bufSize);
278 ok(buf != NULL, "Expected allocated buffer\n");
281 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
283 ok(blob->cbData == strlen((const char*)bigInts[i].decoded),
284 "Expected len %d, got %d\n", lstrlenA((const char*)bigInts[i].decoded),
286 ok(!memcmp(blob->pbData, bigInts[i].decoded, blob->cbData),
287 "Unexpected value\n");
291 for (i = 0; i < sizeof(bigUInts) / sizeof(bigUInts[0]); i++)
293 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT,
294 bigUInts[i].encoded, bigUInts[i].encoded[1] + 2, 0, NULL, NULL,
296 ok(ret && GetLastError() == NOERROR,
297 "Expected success and NOERROR, got %d\n", GetLastError());
298 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT,
299 bigUInts[i].encoded, bigUInts[i].encoded[1] + 2,
300 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
301 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
302 ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %d\n", bufSize);
303 ok(buf != NULL, "Expected allocated buffer\n");
306 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
308 ok(blob->cbData == strlen((const char*)bigUInts[i].val),
309 "Expected len %d, got %d\n", lstrlenA((const char*)bigUInts[i].val),
311 ok(!memcmp(blob->pbData, bigUInts[i].val, blob->cbData),
312 "Unexpected value\n");
316 /* Decode the value 1 with long-form length */
317 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, longForm,
318 sizeof(longForm), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
319 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
322 ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf);
325 /* check with extra bytes at the end */
326 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, extraBytes,
327 sizeof(extraBytes), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
328 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
331 ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf);
334 /* Try to decode some bogus large items */
335 /* The buffer size is smaller than the encoded length, so this should fail
336 * with CRYPT_E_ASN1_EOD if it's being decoded.
337 * Under XP it fails with CRYPT_E_ASN1_LARGE, which means there's a limit
338 * on the size decoded, but in ME it fails with CRYPT_E_ASN1_EOD or crashes.
339 * So this test unfortunately isn't useful.
340 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, tooBig,
341 0x7fffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
342 ok(!ret && GetLastError() == CRYPT_E_ASN1_LARGE,
343 "Expected CRYPT_E_ASN1_LARGE, got %08x\n", GetLastError());
345 /* This will try to decode the buffer and overflow it, check that it's
350 /* a large buffer isn't guaranteed to crash, it depends on memory allocation order */
351 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, bigBogus,
352 0x01ffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
353 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
354 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
358 static const BYTE bin18[] = {0x0a,0x01,0x01};
359 static const BYTE bin19[] = {0x0a,0x05,0x00,0xff,0xff,0xff,0x80};
361 /* These are always encoded unsigned, and aren't constrained to be any
364 static const struct encodedInt enums[] = {
369 /* X509_CRL_REASON_CODE is also an enumerated type, but it's #defined to
372 static const LPCSTR enumeratedTypes[] = { X509_ENUMERATED,
373 szOID_CRL_REASON_CODE };
375 static void test_encodeEnumerated(DWORD dwEncoding)
379 for (i = 0; i < sizeof(enumeratedTypes) / sizeof(enumeratedTypes[0]); i++)
381 for (j = 0; j < sizeof(enums) / sizeof(enums[0]); j++)
387 ret = pCryptEncodeObjectEx(dwEncoding, enumeratedTypes[i],
388 &enums[j].val, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
390 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
394 "Got unexpected type %d for enumerated (expected 0xa)\n",
396 ok(buf[1] == enums[j].encoded[1],
397 "Got length %d, expected %d\n", buf[1], enums[j].encoded[1]);
398 ok(!memcmp(buf + 1, enums[j].encoded + 1,
399 enums[j].encoded[1] + 1),
400 "Encoded value of 0x%08x didn't match expected\n",
408 static void test_decodeEnumerated(DWORD dwEncoding)
412 for (i = 0; i < sizeof(enumeratedTypes) / sizeof(enumeratedTypes[0]); i++)
414 for (j = 0; j < sizeof(enums) / sizeof(enums[0]); j++)
417 DWORD bufSize = sizeof(int);
420 ret = pCryptDecodeObjectEx(dwEncoding, enumeratedTypes[i],
421 enums[j].encoded, enums[j].encoded[1] + 2, 0, NULL,
422 (BYTE *)&val, &bufSize);
423 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
424 ok(bufSize == sizeof(int),
425 "Got unexpected size %d for enumerated\n", bufSize);
426 ok(val == enums[j].val, "Unexpected value %d, expected %d\n",
432 struct encodedFiletime
435 const BYTE *encodedTime;
438 static void testTimeEncoding(DWORD dwEncoding, LPCSTR structType,
439 const struct encodedFiletime *time)
446 ret = SystemTimeToFileTime(&time->sysTime, &ft);
447 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
448 ret = pCryptEncodeObjectEx(dwEncoding, structType, &ft,
449 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
450 /* years other than 1950-2050 are not allowed for encodings other than
451 * X509_CHOICE_OF_TIME.
453 if (structType == X509_CHOICE_OF_TIME ||
454 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050))
456 ok(ret, "CryptEncodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
458 ok(buf != NULL, "Expected an allocated buffer\n");
461 ok(buf[0] == time->encodedTime[0],
462 "Expected type 0x%02x, got 0x%02x\n", time->encodedTime[0],
464 ok(buf[1] == time->encodedTime[1], "Expected %d bytes, got %d\n",
465 time->encodedTime[1], bufSize);
466 ok(!memcmp(time->encodedTime + 2, buf + 2, time->encodedTime[1]),
467 "Got unexpected value for time encoding\n");
472 ok((!ret && GetLastError() == CRYPT_E_BAD_ENCODE) ||
473 broken(GetLastError() == ERROR_SUCCESS),
474 "Expected CRYPT_E_BAD_ENCODE, got 0x%08x\n", GetLastError());
477 static const char *printSystemTime(const SYSTEMTIME *st)
481 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st->wMonth, st->wDay,
482 st->wYear, st->wHour, st->wMinute, st->wSecond, st->wMilliseconds);
486 static const char *printFileTime(const FILETIME *ft)
491 FileTimeToSystemTime(ft, &st);
492 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st.wMonth, st.wDay,
493 st.wYear, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
497 static void compareTime(const SYSTEMTIME *expected, const FILETIME *got)
501 FileTimeToSystemTime(got, &st);
502 ok((expected->wYear == st.wYear &&
503 expected->wMonth == st.wMonth &&
504 expected->wDay == st.wDay &&
505 expected->wHour == st.wHour &&
506 expected->wMinute == st.wMinute &&
507 expected->wSecond == st.wSecond &&
508 abs(expected->wMilliseconds - st.wMilliseconds) <= 1) ||
509 /* Some Windows systems only seem to be accurate in their time decoding to
510 * within about an hour.
512 broken(expected->wYear == st.wYear &&
513 expected->wMonth == st.wMonth &&
514 expected->wDay == st.wDay &&
515 abs(expected->wHour - st.wHour) <= 1),
516 "Got unexpected value for time decoding:\nexpected %s, got %s\n",
517 printSystemTime(expected), printFileTime(got));
520 static void testTimeDecoding(DWORD dwEncoding, LPCSTR structType,
521 const struct encodedFiletime *time)
524 DWORD size = sizeof(ft);
527 ret = pCryptDecodeObjectEx(dwEncoding, structType, time->encodedTime,
528 time->encodedTime[1] + 2, 0, NULL, &ft, &size);
529 /* years other than 1950-2050 are not allowed for encodings other than
530 * X509_CHOICE_OF_TIME.
532 if (structType == X509_CHOICE_OF_TIME ||
533 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050))
535 ok(ret || broken(GetLastError() == OSS_DATA_ERROR),
536 "CryptDecodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
539 compareTime(&time->sysTime, &ft);
542 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
543 GetLastError() == OSS_PDU_MISMATCH /* Win9x */ ),
544 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %08x\n",
548 static const BYTE bin20[] = {
549 0x17,0x0d,'0','5','0','6','0','6','1','6','1','0','0','0','Z'};
550 static const BYTE bin21[] = {
551 0x18,0x0f,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
552 static const BYTE bin22[] = {
553 0x18,0x0f,'2','1','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
555 static const struct encodedFiletime times[] = {
556 { { 2005, 6, 1, 6, 16, 10, 0, 0 }, bin20 },
557 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin21 },
558 { { 2145, 6, 1, 6, 16, 10, 0, 0 }, bin22 },
561 static void test_encodeFiletime(DWORD dwEncoding)
565 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
567 testTimeEncoding(dwEncoding, X509_CHOICE_OF_TIME, ×[i]);
568 testTimeEncoding(dwEncoding, PKCS_UTC_TIME, ×[i]);
569 testTimeEncoding(dwEncoding, szOID_RSA_signingTime, ×[i]);
573 static const BYTE bin23[] = {
574 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','0','0','0','Z'};
575 static const BYTE bin24[] = {
576 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','9','9','9','Z'};
577 static const BYTE bin25[] = {
578 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','+','0','1','0','0'};
579 static const BYTE bin26[] = {
580 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','0','0'};
581 static const BYTE bin27[] = {
582 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','1','5'};
583 static const BYTE bin28[] = {
584 0x18,0x0a,'2','1','4','5','0','6','0','6','1','6'};
585 static const BYTE bin29[] = {
586 0x17,0x0a,'4','5','0','6','0','6','1','6','1','0'};
587 static const BYTE bin30[] = {
588 0x17,0x0b,'4','5','0','6','0','6','1','6','1','0','Z'};
589 static const BYTE bin31[] = {
590 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','+','0','1'};
591 static const BYTE bin32[] = {
592 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','-','0','1'};
593 static const BYTE bin33[] = {
594 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','+','0','1','0','0'};
595 static const BYTE bin34[] = {
596 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','-','0','1','0','0'};
597 static const BYTE bin35[] = {
598 0x17,0x08, '4','5','0','6','0','6','1','6'};
599 static const BYTE bin36[] = {
600 0x18,0x0f, 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','Z'};
601 static const BYTE bin37[] = {
602 0x18,0x04, '2','1','4','5'};
603 static const BYTE bin38[] = {
604 0x18,0x08, '2','1','4','5','0','6','0','6'};
606 static void test_decodeFiletime(DWORD dwEncoding)
608 static const struct encodedFiletime otherTimes[] = {
609 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin23 },
610 { { 1945, 6, 1, 6, 16, 10, 0, 999 }, bin24 },
611 { { 1945, 6, 1, 6, 17, 10, 0, 0 }, bin25 },
612 { { 1945, 6, 1, 6, 15, 10, 0, 0 }, bin26 },
613 { { 1945, 6, 1, 6, 14, 55, 0, 0 }, bin27 },
614 { { 2145, 6, 1, 6, 16, 0, 0, 0 }, bin28 },
615 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin29 },
616 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin30 },
617 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin31 },
618 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin32 },
619 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin33 },
620 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin34 },
622 /* An oddball case that succeeds in Windows, but doesn't seem correct
623 { { 2145, 6, 1, 2, 11, 31, 0, 0 }, "\x18" "\x13" "21450606161000-9999" },
625 static const unsigned char *bogusTimes[] = {
626 /* oddly, this succeeds on Windows, with year 2765
627 "\x18" "\x0f" "21r50606161000Z",
635 FILETIME ft1 = { 0 }, ft2 = { 0 };
638 /* Check bogus length with non-NULL buffer */
639 ret = SystemTimeToFileTime(×[0].sysTime, &ft1);
640 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
642 ret = pCryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
643 times[0].encodedTime, times[0].encodedTime[1] + 2, 0, NULL, &ft2, &size);
644 ok(!ret && GetLastError() == ERROR_MORE_DATA,
645 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
647 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
649 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, ×[i]);
650 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, ×[i]);
651 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, ×[i]);
653 for (i = 0; i < sizeof(otherTimes) / sizeof(otherTimes[0]); i++)
655 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &otherTimes[i]);
656 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &otherTimes[i]);
657 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &otherTimes[i]);
659 for (i = 0; i < sizeof(bogusTimes) / sizeof(bogusTimes[0]); i++)
662 ret = pCryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
663 bogusTimes[i], bogusTimes[i][1] + 2, 0, NULL, &ft1, &size);
664 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
665 GetLastError() == OSS_DATA_ERROR /* Win9x */),
666 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
671 static const char commonName[] = "Juan Lang";
672 static const char surName[] = "Lang";
674 static const BYTE emptySequence[] = { 0x30, 0 };
675 static const BYTE emptyRDNs[] = { 0x30, 0x02, 0x31, 0 };
676 static const BYTE twoRDNs[] = {
677 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
678 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
679 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0};
680 static const BYTE encodedTwoRDNs[] = {
681 0x30,0x2e,0x31,0x2c,0x30,0x2a,0x06,0x03,0x55,0x04,0x03,0x30,0x23,0x31,0x21,
682 0x30,0x0c,0x06,0x03,0x55,0x04,0x04,0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,
683 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
687 static const BYTE us[] = { 0x55, 0x53 };
688 static const BYTE minnesota[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x73, 0x6f,
690 static const BYTE minneapolis[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x61, 0x70,
691 0x6f, 0x6c, 0x69, 0x73 };
692 static const BYTE codeweavers[] = { 0x43, 0x6f, 0x64, 0x65, 0x57, 0x65, 0x61,
693 0x76, 0x65, 0x72, 0x73 };
694 static const BYTE wine[] = { 0x57, 0x69, 0x6e, 0x65, 0x20, 0x44, 0x65, 0x76,
695 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74 };
696 static const BYTE localhostAttr[] = { 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
698 static const BYTE aric[] = { 0x61, 0x72, 0x69, 0x63, 0x40, 0x63, 0x6f, 0x64,
699 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d };
701 #define RDNA(arr) oid_ ## arr, CERT_RDN_PRINTABLE_STRING, { sizeof(arr), (LPBYTE)arr }
702 #define RDNIA5(arr) oid_ ## arr, CERT_RDN_IA5_STRING, { sizeof(arr), (LPBYTE)arr }
704 static CHAR oid_us[] = "2.5.4.6",
705 oid_minnesota[] = "2.5.4.8",
706 oid_minneapolis[] = "2.5.4.7",
707 oid_codeweavers[] = "2.5.4.10",
708 oid_wine[] = "2.5.4.11",
709 oid_localhostAttr[] = "2.5.4.3",
710 oid_aric[] = "1.2.840.113549.1.9.1";
711 static CERT_RDN_ATTR rdnAttrs[] = { { RDNA(us) },
713 { RDNA(minneapolis) },
714 { RDNA(codeweavers) },
716 { RDNA(localhostAttr) },
718 static CERT_RDN_ATTR decodedRdnAttrs[] = { { RDNA(us) },
719 { RDNA(localhostAttr) },
721 { RDNA(minneapolis) },
722 { RDNA(codeweavers) },
729 static const BYTE encodedRDNAttrs[] = {
730 0x30,0x81,0x96,0x31,0x81,0x93,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
731 0x53,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x68,
732 0x6f,0x73,0x74,0x30,0x10,0x06,0x03,0x55,0x04,0x08,0x13,0x09,0x4d,0x69,0x6e,0x6e,
733 0x65,0x73,0x6f,0x74,0x61,0x30,0x12,0x06,0x03,0x55,0x04,0x07,0x13,0x0b,0x4d,0x69,
734 0x6e,0x6e,0x65,0x61,0x70,0x6f,0x6c,0x69,0x73,0x30,0x12,0x06,0x03,0x55,0x04,0x0a,
735 0x13,0x0b,0x43,0x6f,0x64,0x65,0x57,0x65,0x61,0x76,0x65,0x72,0x73,0x30,0x17,0x06,
736 0x03,0x55,0x04,0x0b,0x13,0x10,0x57,0x69,0x6e,0x65,0x20,0x44,0x65,0x76,0x65,0x6c,
737 0x6f,0x70,0x6d,0x65,0x6e,0x74,0x30,0x21,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
738 0x01,0x09,0x01,0x16,0x14,0x61,0x72,0x69,0x63,0x40,0x63,0x6f,0x64,0x65,0x77,0x65,
739 0x61,0x76,0x65,0x72,0x73,0x2e,0x63,0x6f,0x6d
742 static void test_encodeName(DWORD dwEncoding)
744 CERT_RDN_ATTR attrs[2];
747 static CHAR oid_common_name[] = szOID_COMMON_NAME,
748 oid_sur_name[] = szOID_SUR_NAME;
755 /* Test with NULL pvStructInfo (crashes on win9x) */
756 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, NULL,
757 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
758 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
759 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
761 /* Test with empty CERT_NAME_INFO */
764 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
765 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
766 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
769 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
770 "Got unexpected encoding for empty name\n");
775 /* Test with bogus CERT_RDN (crashes on win9x) */
777 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
778 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
779 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
780 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
782 /* Test with empty CERT_RDN */
784 rdn.rgRDNAttr = NULL;
787 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
788 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
789 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
792 ok(!memcmp(buf, emptyRDNs, sizeof(emptyRDNs)),
793 "Got unexpected encoding for empty RDN array\n");
798 /* Test with bogus attr array (crashes on win9x) */
800 rdn.rgRDNAttr = NULL;
801 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
802 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
803 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
804 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
806 /* oddly, a bogus OID is accepted by Windows XP; not testing.
807 attrs[0].pszObjId = "bogus";
808 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
809 attrs[0].Value.cbData = sizeof(commonName);
810 attrs[0].Value.pbData = (BYTE *)commonName;
812 rdn.rgRDNAttr = attrs;
813 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
814 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
815 ok(!ret, "Expected failure, got success\n");
817 /* Check with two CERT_RDN_ATTRs. Note DER encoding forces the order of
818 * the encoded attributes to be swapped.
820 attrs[0].pszObjId = oid_common_name;
821 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
822 attrs[0].Value.cbData = sizeof(commonName);
823 attrs[0].Value.pbData = (BYTE *)commonName;
824 attrs[1].pszObjId = oid_sur_name;
825 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
826 attrs[1].Value.cbData = sizeof(surName);
827 attrs[1].Value.pbData = (BYTE *)surName;
829 rdn.rgRDNAttr = attrs;
830 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
831 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
832 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
835 ok(!memcmp(buf, twoRDNs, sizeof(twoRDNs)),
836 "Got unexpected encoding for two RDN array\n");
839 /* A name can be "encoded" with previously encoded RDN attrs. */
840 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
841 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
842 attrs[0].Value.cbData = sizeof(twoRDNs);
844 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
845 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
846 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
849 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
850 ok(!memcmp(buf, encodedTwoRDNs, size),
851 "Unexpected value for re-endoded two RDN array\n");
854 /* CERT_RDN_ANY_TYPE is too vague for X509_NAMEs, check the return */
856 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
857 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
858 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
859 ok(!ret && GetLastError() == E_INVALIDARG,
860 "Expected E_INVALIDARG, got %08x\n", GetLastError());
861 /* Test a more complex name */
862 rdn.cRDNAttr = sizeof(rdnAttrs) / sizeof(rdnAttrs[0]);
863 rdn.rgRDNAttr = (PCERT_RDN_ATTR)rdnAttrs;
868 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, X509_NAME, &info,
869 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
870 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
873 ok(size == sizeof(encodedRDNAttrs), "Wrong size %d\n", size);
874 ok(!memcmp(buf, encodedRDNAttrs, size), "Unexpected value\n");
879 static WCHAR commonNameW[] = { 'J','u','a','n',' ','L','a','n','g',0 };
880 static WCHAR surNameW[] = { 'L','a','n','g',0 };
882 static const BYTE twoRDNsNoNull[] = {
883 0x30,0x21,0x31,0x1f,0x30,0x0b,0x06,0x03,0x55,0x04,0x04,0x13,0x04,0x4c,0x61,
884 0x6e,0x67,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,
885 0x20,0x4c,0x61,0x6e,0x67 };
886 static const BYTE anyType[] = {
887 0x30,0x2f,0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x1e,0x24,0x23,0x30,
888 0x21,0x31,0x0c,0x30,0x03,0x06,0x04,0x55,0x13,0x04,0x4c,0x05,0x6e,0x61,0x00,
889 0x67,0x11,0x30,0x03,0x06,0x04,0x55,0x13,0x03,0x4a,0x0a,0x61,0x75,0x20,0x6e,
890 0x61,0x4c,0x67,0x6e };
892 static void test_encodeUnicodeName(DWORD dwEncoding)
894 CERT_RDN_ATTR attrs[2];
897 static CHAR oid_common_name[] = szOID_COMMON_NAME,
898 oid_sur_name[] = szOID_SUR_NAME;
905 /* Test with NULL pvStructInfo (crashes on win9x) */
906 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, NULL,
907 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
908 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
909 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
911 /* Test with empty CERT_NAME_INFO */
914 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
915 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
916 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
919 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
920 "Got unexpected encoding for empty name\n");
923 /* Check with one CERT_RDN_ATTR, that has an invalid character for the
924 * encoding (the NULL).
926 attrs[0].pszObjId = oid_common_name;
927 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
928 attrs[0].Value.cbData = sizeof(commonNameW);
929 attrs[0].Value.pbData = (BYTE *)commonNameW;
931 rdn.rgRDNAttr = attrs;
934 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
935 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
936 ok(!ret && GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING,
937 "Expected CRYPT_E_INVALID_PRINTABLE_STRING, got %08x\n", GetLastError());
938 ok(size == 9, "Unexpected error index %08x\n", size);
939 /* Check with two NULL-terminated CERT_RDN_ATTRs. Note DER encoding
940 * forces the order of the encoded attributes to be swapped.
942 attrs[0].pszObjId = oid_common_name;
943 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
944 attrs[0].Value.cbData = 0;
945 attrs[0].Value.pbData = (BYTE *)commonNameW;
946 attrs[1].pszObjId = oid_sur_name;
947 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
948 attrs[1].Value.cbData = 0;
949 attrs[1].Value.pbData = (BYTE *)surNameW;
951 rdn.rgRDNAttr = attrs;
954 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
955 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
956 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
959 ok(!memcmp(buf, twoRDNsNoNull, sizeof(twoRDNsNoNull)),
960 "Got unexpected encoding for two RDN array\n");
963 /* A name can be "encoded" with previously encoded RDN attrs. */
964 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
965 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
966 attrs[0].Value.cbData = sizeof(twoRDNs);
968 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
969 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
970 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
973 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
974 ok(!memcmp(buf, encodedTwoRDNs, size),
975 "Unexpected value for re-endoded two RDN array\n");
978 /* Unicode names infer the type for CERT_RDN_ANY_TYPE */
980 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
981 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
982 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
983 todo_wine ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
986 ok(size == sizeof(anyType), "Unexpected size %d\n", size);
987 ok(!memcmp(buf, anyType, size), "Unexpected value\n");
992 static void compareNameValues(const CERT_NAME_VALUE *expected,
993 const CERT_NAME_VALUE *got)
995 ok(got->dwValueType == expected->dwValueType,
996 "Expected string type %d, got %d\n", expected->dwValueType,
998 ok(got->Value.cbData == expected->Value.cbData,
999 "String type %d: unexpected data size, got %d, expected %d\n",
1000 expected->dwValueType, got->Value.cbData, expected->Value.cbData);
1001 if (got->Value.cbData && got->Value.pbData)
1002 ok(!memcmp(got->Value.pbData, expected->Value.pbData,
1003 min(got->Value.cbData, expected->Value.cbData)),
1004 "String type %d: unexpected value\n", expected->dwValueType);
1007 static void compareRDNAttrs(const CERT_RDN_ATTR *expected,
1008 const CERT_RDN_ATTR *got)
1010 if (expected->pszObjId && strlen(expected->pszObjId))
1012 ok(got->pszObjId != NULL, "Expected OID %s, got NULL\n",
1013 expected->pszObjId);
1016 ok(!strcmp(got->pszObjId, expected->pszObjId),
1017 "Got unexpected OID %s, expected %s\n", got->pszObjId,
1018 expected->pszObjId);
1021 compareNameValues((const CERT_NAME_VALUE *)&expected->dwValueType,
1022 (const CERT_NAME_VALUE *)&got->dwValueType);
1025 static void compareRDNs(const CERT_RDN *expected, const CERT_RDN *got)
1027 ok(got->cRDNAttr == expected->cRDNAttr,
1028 "Expected %d RDN attrs, got %d\n", expected->cRDNAttr, got->cRDNAttr);
1033 for (i = 0; i < got->cRDNAttr; i++)
1034 compareRDNAttrs(&expected->rgRDNAttr[i], &got->rgRDNAttr[i]);
1038 static void compareNames(const CERT_NAME_INFO *expected,
1039 const CERT_NAME_INFO *got)
1041 ok(got->cRDN == expected->cRDN, "Expected %d RDNs, got %d\n",
1042 expected->cRDN, got->cRDN);
1047 for (i = 0; i < got->cRDN; i++)
1048 compareRDNs(&expected->rgRDN[i], &got->rgRDN[i]);
1052 static const BYTE emptyIndefiniteSequence[] = { 0x30,0x80,0x00,0x00 };
1053 static const BYTE twoRDNsExtraBytes[] = {
1054 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
1055 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1056 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0,0,0,0,0,0};
1058 static void test_decodeName(DWORD dwEncoding)
1064 CERT_NAME_INFO info = { 1, &rdn };
1066 /* test empty name */
1068 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptySequence,
1069 emptySequence[1] + 2,
1070 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1071 (BYTE *)&buf, &bufSize);
1072 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1073 /* Interestingly, in Windows, if cRDN is 0, rgRGN may not be NULL. My
1074 * decoder works the same way, so only test the count.
1078 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1079 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1080 "Expected 0 RDNs in empty info, got %d\n",
1081 ((CERT_NAME_INFO *)buf)->cRDN);
1084 /* test empty name with indefinite-length encoding */
1085 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyIndefiniteSequence,
1086 sizeof(emptyIndefiniteSequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
1087 (BYTE *)&buf, &bufSize);
1088 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1091 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1092 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1093 "Expected 0 RDNs in empty info, got %d\n",
1094 ((CERT_NAME_INFO *)buf)->cRDN);
1097 /* test empty RDN */
1099 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyRDNs,
1101 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1102 (BYTE *)&buf, &bufSize);
1103 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1106 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1108 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1109 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1110 "Got unexpected value for empty RDN\n");
1113 /* test two RDN attrs */
1115 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNs,
1117 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1118 (BYTE *)&buf, &bufSize);
1119 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1122 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1123 oid_common_name[] = szOID_COMMON_NAME;
1125 CERT_RDN_ATTR attrs[] = {
1126 { oid_sur_name, CERT_RDN_PRINTABLE_STRING, { sizeof(surName),
1127 (BYTE *)surName } },
1128 { oid_common_name, CERT_RDN_PRINTABLE_STRING, { sizeof(commonName),
1129 (BYTE *)commonName } },
1132 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1133 rdn.rgRDNAttr = attrs;
1134 compareNames(&info, (CERT_NAME_INFO *)buf);
1137 /* test that two RDN attrs with extra bytes succeeds */
1139 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNsExtraBytes,
1140 sizeof(twoRDNsExtraBytes), 0, NULL, NULL, &bufSize);
1141 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1142 /* And, a slightly more complicated name */
1145 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME, encodedRDNAttrs,
1146 sizeof(encodedRDNAttrs), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1147 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1150 rdn.cRDNAttr = sizeof(decodedRdnAttrs) / sizeof(decodedRdnAttrs[0]);
1151 rdn.rgRDNAttr = (PCERT_RDN_ATTR)decodedRdnAttrs;
1152 compareNames(&info, (CERT_NAME_INFO *)buf);
1157 static void test_decodeUnicodeName(DWORD dwEncoding)
1163 CERT_NAME_INFO info = { 1, &rdn };
1165 /* test empty name */
1167 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptySequence,
1168 emptySequence[1] + 2,
1169 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1170 (BYTE *)&buf, &bufSize);
1171 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1174 ok(bufSize == sizeof(CERT_NAME_INFO),
1175 "Got wrong bufSize %d\n", bufSize);
1176 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1177 "Expected 0 RDNs in empty info, got %d\n",
1178 ((CERT_NAME_INFO *)buf)->cRDN);
1181 /* test empty RDN */
1183 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptyRDNs,
1185 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1186 (BYTE *)&buf, &bufSize);
1187 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1190 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1192 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1193 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1194 "Got unexpected value for empty RDN\n");
1197 /* test two RDN attrs */
1199 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, twoRDNsNoNull,
1200 sizeof(twoRDNsNoNull),
1201 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1202 (BYTE *)&buf, &bufSize);
1203 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1206 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1207 oid_common_name[] = szOID_COMMON_NAME;
1209 CERT_RDN_ATTR attrs[] = {
1210 { oid_sur_name, CERT_RDN_PRINTABLE_STRING,
1211 { lstrlenW(surNameW) * sizeof(WCHAR), (BYTE *)surNameW } },
1212 { oid_common_name, CERT_RDN_PRINTABLE_STRING,
1213 { lstrlenW(commonNameW) * sizeof(WCHAR), (BYTE *)commonNameW } },
1216 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1217 rdn.rgRDNAttr = attrs;
1218 compareNames(&info, (CERT_NAME_INFO *)buf);
1223 struct EncodedNameValue
1225 CERT_NAME_VALUE value;
1226 const BYTE *encoded;
1230 static const char bogusIA5[] = "\x80";
1231 static const char bogusPrintable[] = "~";
1232 static const char bogusNumeric[] = "A";
1233 static const BYTE bin42[] = { 0x16,0x02,0x80,0x00 };
1234 static const BYTE bin43[] = { 0x13,0x02,0x7e,0x00 };
1235 static const BYTE bin44[] = { 0x12,0x02,0x41,0x00 };
1236 static BYTE octetCommonNameValue[] = {
1237 0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1238 static BYTE numericCommonNameValue[] = {
1239 0x12,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1240 static BYTE printableCommonNameValue[] = {
1241 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1242 static BYTE t61CommonNameValue[] = {
1243 0x14,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1244 static BYTE videotexCommonNameValue[] = {
1245 0x15,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1246 static BYTE ia5CommonNameValue[] = {
1247 0x16,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1248 static BYTE graphicCommonNameValue[] = {
1249 0x19,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1250 static BYTE visibleCommonNameValue[] = {
1251 0x1a,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1252 static BYTE generalCommonNameValue[] = {
1253 0x1b,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1254 static BYTE bmpCommonNameValue[] = {
1255 0x1e,0x14,0x00,0x4a,0x00,0x75,0x00,0x61,0x00,0x6e,0x00,0x20,0x00,0x4c,0x00,
1256 0x61,0x00,0x6e,0x00,0x67,0x00,0x00 };
1257 static BYTE utf8CommonNameValue[] = {
1258 0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1260 static struct EncodedNameValue nameValues[] = {
1261 { { CERT_RDN_OCTET_STRING, { sizeof(commonName), (BYTE *)commonName } },
1262 octetCommonNameValue, sizeof(octetCommonNameValue) },
1263 { { CERT_RDN_NUMERIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1264 numericCommonNameValue, sizeof(numericCommonNameValue) },
1265 { { CERT_RDN_PRINTABLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1266 printableCommonNameValue, sizeof(printableCommonNameValue) },
1267 { { CERT_RDN_T61_STRING, { sizeof(commonName), (BYTE *)commonName } },
1268 t61CommonNameValue, sizeof(t61CommonNameValue) },
1269 { { CERT_RDN_VIDEOTEX_STRING, { sizeof(commonName), (BYTE *)commonName } },
1270 videotexCommonNameValue, sizeof(videotexCommonNameValue) },
1271 { { CERT_RDN_IA5_STRING, { sizeof(commonName), (BYTE *)commonName } },
1272 ia5CommonNameValue, sizeof(ia5CommonNameValue) },
1273 { { CERT_RDN_GRAPHIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1274 graphicCommonNameValue, sizeof(graphicCommonNameValue) },
1275 { { CERT_RDN_VISIBLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1276 visibleCommonNameValue, sizeof(visibleCommonNameValue) },
1277 { { CERT_RDN_GENERAL_STRING, { sizeof(commonName), (BYTE *)commonName } },
1278 generalCommonNameValue, sizeof(generalCommonNameValue) },
1279 { { CERT_RDN_BMP_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1280 bmpCommonNameValue, sizeof(bmpCommonNameValue) },
1281 { { CERT_RDN_UTF8_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1282 utf8CommonNameValue, sizeof(utf8CommonNameValue) },
1283 /* The following tests succeed under Windows, but really should fail,
1284 * they contain characters that are illegal for the encoding. I'm
1285 * including them to justify my lazy encoding.
1287 { { CERT_RDN_IA5_STRING, { sizeof(bogusIA5), (BYTE *)bogusIA5 } }, bin42,
1289 { { CERT_RDN_PRINTABLE_STRING, { sizeof(bogusPrintable),
1290 (BYTE *)bogusPrintable } }, bin43, sizeof(bin43) },
1291 { { CERT_RDN_NUMERIC_STRING, { sizeof(bogusNumeric), (BYTE *)bogusNumeric } },
1292 bin44, sizeof(bin44) },
1295 static void test_encodeNameValue(DWORD dwEncoding)
1300 CERT_NAME_VALUE value = { 0, { 0, NULL } };
1302 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1303 value.Value.pbData = printableCommonNameValue;
1304 value.Value.cbData = sizeof(printableCommonNameValue);
1305 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, &value,
1306 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1307 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1310 ok(size == sizeof(printableCommonNameValue), "Unexpected size %d\n",
1312 ok(!memcmp(buf, printableCommonNameValue, size),
1313 "Unexpected encoding\n");
1316 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1318 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE,
1319 &nameValues[i].value, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1321 ok(ret, "Type %d: CryptEncodeObjectEx failed: %08x\n",
1322 nameValues[i].value.dwValueType, GetLastError());
1325 ok(size == nameValues[i].encodedSize,
1326 "Expected size %d, got %d\n", nameValues[i].encodedSize, size);
1327 ok(!memcmp(buf, nameValues[i].encoded, size),
1328 "Got unexpected encoding\n");
1334 static void test_decodeNameValue(DWORD dwEncoding)
1341 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1343 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE,
1344 nameValues[i].encoded, nameValues[i].encoded[1] + 2,
1345 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1346 (BYTE *)&buf, &bufSize);
1347 ok(ret, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
1348 nameValues[i].value.dwValueType, GetLastError());
1351 compareNameValues(&nameValues[i].value,
1352 (const CERT_NAME_VALUE *)buf);
1358 static const BYTE emptyURL[] = { 0x30, 0x02, 0x86, 0x00 };
1359 static const BYTE emptyURLExtraBytes[] = { 0x30, 0x02, 0x86, 0x00, 0, 0, 0 };
1360 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e',
1361 'h','q','.','o','r','g',0 };
1362 static const BYTE encodedURL[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74,
1363 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e,
1365 static const WCHAR nihongoURL[] = { 'h','t','t','p',':','/','/',0x226f,
1367 static const WCHAR dnsName[] = { 'w','i','n','e','h','q','.','o','r','g',0 };
1368 static const BYTE encodedDnsName[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69,
1369 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
1370 static const BYTE localhost[] = { 127, 0, 0, 1 };
1371 static const BYTE encodedIPAddr[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00,
1373 static const unsigned char encodedCommonName[] = {
1374 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0};
1375 static const BYTE encodedOidName[] = { 0x30,0x04,0x88,0x02,0x2a,0x03 };
1376 static const BYTE encodedDirectoryName[] = {
1377 0x30,0x19,0xa4,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1378 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1380 static void test_encodeAltName(DWORD dwEncoding)
1382 CERT_ALT_NAME_INFO info = { 0 };
1383 CERT_ALT_NAME_ENTRY entry = { 0 };
1387 char oid[] = "1.2.3";
1389 /* Test with empty info */
1390 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1391 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1394 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
1395 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
1398 /* Test with an empty entry */
1400 info.rgAltEntry = &entry;
1401 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1402 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1403 ok(!ret && GetLastError() == E_INVALIDARG,
1404 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1405 /* Test with an empty pointer */
1406 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
1407 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1408 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1411 ok(size == sizeof(emptyURL), "Wrong size %d\n", size);
1412 ok(!memcmp(buf, emptyURL, size), "Unexpected value\n");
1415 /* Test with a real URL */
1416 U(entry).pwszURL = (LPWSTR)url;
1417 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1418 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1421 ok(size == sizeof(encodedURL), "Wrong size %d\n", size);
1422 ok(!memcmp(buf, encodedURL, size), "Unexpected value\n");
1425 /* Now with the URL containing an invalid IA5 char */
1426 U(entry).pwszURL = (LPWSTR)nihongoURL;
1427 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1428 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1429 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
1430 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
1431 /* The first invalid character is at index 7 */
1432 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
1433 "Expected invalid char at index 7, got %d\n",
1434 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
1435 /* Now with the URL missing a scheme */
1436 U(entry).pwszURL = (LPWSTR)dnsName;
1437 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1438 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1439 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1442 /* This succeeds, but it shouldn't, so don't worry about conforming */
1445 /* Now with a DNS name */
1446 entry.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
1447 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1448 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1449 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1452 ok(size == sizeof(encodedDnsName), "Wrong size %d\n", size);
1453 ok(!memcmp(buf, encodedDnsName, size), "Unexpected value\n");
1456 /* Test with an IP address */
1457 entry.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
1458 U(entry).IPAddress.cbData = sizeof(localhost);
1459 U(entry).IPAddress.pbData = (LPBYTE)localhost;
1460 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1461 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1464 ok(size == sizeof(encodedIPAddr), "Wrong size %d\n", size);
1465 ok(!memcmp(buf, encodedIPAddr, size), "Unexpected value\n");
1469 entry.dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID;
1470 U(entry).pszRegisteredID = oid;
1471 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1472 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1475 ok(size == sizeof(encodedOidName), "Wrong size %d\n", size);
1476 ok(!memcmp(buf, encodedOidName, size), "Unexpected value\n");
1479 /* Test with directory name */
1480 entry.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
1481 U(entry).DirectoryName.cbData = sizeof(encodedCommonName);
1482 U(entry).DirectoryName.pbData = (LPBYTE)encodedCommonName;
1483 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1484 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1487 ok(size == sizeof(encodedDirectoryName), "Wrong size %d\n", size);
1488 ok(!memcmp(buf, encodedDirectoryName, size), "Unexpected value\n");
1493 static void test_decodeAltName(DWORD dwEncoding)
1495 static const BYTE unimplementedType[] = { 0x30, 0x06, 0x85, 0x04, 0x7f,
1497 static const BYTE bogusType[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00,
1502 CERT_ALT_NAME_INFO *info;
1504 /* Test some bogus ones first */
1505 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1506 unimplementedType, sizeof(unimplementedType), CRYPT_DECODE_ALLOC_FLAG,
1507 NULL, (BYTE *)&buf, &bufSize);
1508 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
1509 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1510 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
1512 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1513 bogusType, sizeof(bogusType), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1515 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
1516 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1517 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
1519 /* Now expected cases */
1520 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptySequence,
1521 emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1523 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1526 info = (CERT_ALT_NAME_INFO *)buf;
1528 ok(info->cAltEntry == 0, "Expected 0 entries, got %d\n",
1532 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptyURL,
1533 emptyURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1535 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1538 info = (CERT_ALT_NAME_INFO *)buf;
1540 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1542 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1543 "Expected CERT_ALT_NAME_URL, got %d\n",
1544 info->rgAltEntry[0].dwAltNameChoice);
1545 ok(U(info->rgAltEntry[0]).pwszURL == NULL || !*U(info->rgAltEntry[0]).pwszURL,
1546 "Expected empty URL\n");
1549 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1550 emptyURLExtraBytes, sizeof(emptyURLExtraBytes), 0, NULL, NULL, &bufSize);
1551 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1552 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedURL,
1553 encodedURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1555 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1558 info = (CERT_ALT_NAME_INFO *)buf;
1560 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1562 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1563 "Expected CERT_ALT_NAME_URL, got %d\n",
1564 info->rgAltEntry[0].dwAltNameChoice);
1565 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszURL, url), "Unexpected URL\n");
1568 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedDnsName,
1569 encodedDnsName[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1571 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1574 info = (CERT_ALT_NAME_INFO *)buf;
1576 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1578 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1579 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1580 info->rgAltEntry[0].dwAltNameChoice);
1581 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszDNSName, dnsName),
1582 "Unexpected DNS name\n");
1585 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedIPAddr,
1586 encodedIPAddr[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1588 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1591 info = (CERT_ALT_NAME_INFO *)buf;
1593 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1595 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS,
1596 "Expected CERT_ALT_NAME_IP_ADDRESS, got %d\n",
1597 info->rgAltEntry[0].dwAltNameChoice);
1598 ok(U(info->rgAltEntry[0]).IPAddress.cbData == sizeof(localhost),
1599 "Unexpected IP address length %d\n",
1600 U(info->rgAltEntry[0]).IPAddress.cbData);
1601 ok(!memcmp(U(info->rgAltEntry[0]).IPAddress.pbData, localhost,
1602 sizeof(localhost)), "Unexpected IP address value\n");
1605 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedOidName,
1606 sizeof(encodedOidName), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1608 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1611 info = (CERT_ALT_NAME_INFO *)buf;
1613 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1615 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_REGISTERED_ID,
1616 "Expected CERT_ALT_NAME_REGISTERED_ID, got %d\n",
1617 info->rgAltEntry[0].dwAltNameChoice);
1618 ok(!strcmp(U(info->rgAltEntry[0]).pszRegisteredID, "1.2.3"),
1619 "Expected OID 1.2.3, got %s\n", U(info->rgAltEntry[0]).pszRegisteredID);
1622 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1623 encodedDirectoryName, sizeof(encodedDirectoryName),
1624 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1625 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1628 info = (CERT_ALT_NAME_INFO *)buf;
1630 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1632 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME,
1633 "Expected CERT_ALT_NAME_DIRECTORY_NAME, got %d\n",
1634 info->rgAltEntry[0].dwAltNameChoice);
1635 ok(U(info->rgAltEntry[0]).DirectoryName.cbData ==
1636 sizeof(encodedCommonName), "Unexpected directory name length %d\n",
1637 U(info->rgAltEntry[0]).DirectoryName.cbData);
1638 ok(!memcmp(U(info->rgAltEntry[0]).DirectoryName.pbData,
1639 encodedCommonName, sizeof(encodedCommonName)),
1640 "Unexpected directory name value\n");
1645 struct UnicodeExpectedError
1653 static const WCHAR oneW[] = { '1',0 };
1654 static const WCHAR aW[] = { 'a',0 };
1655 static const WCHAR quoteW[] = { '"', 0 };
1657 static struct UnicodeExpectedError unicodeErrors[] = {
1658 { CERT_RDN_ANY_TYPE, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1659 { CERT_RDN_ENCODED_BLOB, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1660 { CERT_RDN_OCTET_STRING, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1661 { CERT_RDN_NUMERIC_STRING, aW, 0, CRYPT_E_INVALID_NUMERIC_STRING },
1662 { CERT_RDN_PRINTABLE_STRING, quoteW, 0, CRYPT_E_INVALID_PRINTABLE_STRING },
1663 { CERT_RDN_IA5_STRING, nihongoURL, 7, CRYPT_E_INVALID_IA5_STRING },
1666 struct UnicodeExpectedResult
1670 CRYPT_DATA_BLOB encoded;
1673 static BYTE oneNumeric[] = { 0x12, 0x01, 0x31 };
1674 static BYTE onePrintable[] = { 0x13, 0x01, 0x31 };
1675 static BYTE oneTeletex[] = { 0x14, 0x01, 0x31 };
1676 static BYTE oneVideotex[] = { 0x15, 0x01, 0x31 };
1677 static BYTE oneIA5[] = { 0x16, 0x01, 0x31 };
1678 static BYTE oneGraphic[] = { 0x19, 0x01, 0x31 };
1679 static BYTE oneVisible[] = { 0x1a, 0x01, 0x31 };
1680 static BYTE oneUniversal[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 };
1681 static BYTE oneGeneral[] = { 0x1b, 0x01, 0x31 };
1682 static BYTE oneBMP[] = { 0x1e, 0x02, 0x00, 0x31 };
1683 static BYTE oneUTF8[] = { 0x0c, 0x01, 0x31 };
1684 static BYTE nihongoT61[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,
1686 static BYTE nihongoGeneral[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1688 static BYTE nihongoBMP[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,
1689 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
1690 static BYTE nihongoUTF8[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1691 0xe2,0x89,0xaf,0xe5,0x9d,0x9b };
1693 static struct UnicodeExpectedResult unicodeResults[] = {
1694 { CERT_RDN_NUMERIC_STRING, oneW, { sizeof(oneNumeric), oneNumeric } },
1695 { CERT_RDN_PRINTABLE_STRING, oneW, { sizeof(onePrintable), onePrintable } },
1696 { CERT_RDN_TELETEX_STRING, oneW, { sizeof(oneTeletex), oneTeletex } },
1697 { CERT_RDN_VIDEOTEX_STRING, oneW, { sizeof(oneVideotex), oneVideotex } },
1698 { CERT_RDN_IA5_STRING, oneW, { sizeof(oneIA5), oneIA5 } },
1699 { CERT_RDN_GRAPHIC_STRING, oneW, { sizeof(oneGraphic), oneGraphic } },
1700 { CERT_RDN_VISIBLE_STRING, oneW, { sizeof(oneVisible), oneVisible } },
1701 { CERT_RDN_UNIVERSAL_STRING, oneW, { sizeof(oneUniversal), oneUniversal } },
1702 { CERT_RDN_GENERAL_STRING, oneW, { sizeof(oneGeneral), oneGeneral } },
1703 { CERT_RDN_BMP_STRING, oneW, { sizeof(oneBMP), oneBMP } },
1704 { CERT_RDN_UTF8_STRING, oneW, { sizeof(oneUTF8), oneUTF8 } },
1705 { CERT_RDN_BMP_STRING, nihongoURL, { sizeof(nihongoBMP), nihongoBMP } },
1706 { CERT_RDN_UTF8_STRING, nihongoURL, { sizeof(nihongoUTF8), nihongoUTF8 } },
1709 static struct UnicodeExpectedResult unicodeWeirdness[] = {
1710 { CERT_RDN_TELETEX_STRING, nihongoURL, { sizeof(nihongoT61), nihongoT61 } },
1711 { CERT_RDN_GENERAL_STRING, nihongoURL, { sizeof(nihongoGeneral), nihongoGeneral } },
1714 static void test_encodeUnicodeNameValue(DWORD dwEncoding)
1719 CERT_NAME_VALUE value;
1723 /* Crashes on win9x */
1724 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, NULL,
1725 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1726 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1727 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1729 /* Have to have a string of some sort */
1730 value.dwValueType = 0; /* aka CERT_RDN_ANY_TYPE */
1731 value.Value.pbData = NULL;
1732 value.Value.cbData = 0;
1733 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1734 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1735 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1736 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1737 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1738 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1739 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1740 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1741 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1742 value.dwValueType = CERT_RDN_ANY_TYPE;
1743 value.Value.pbData = (LPBYTE)oneW;
1744 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1745 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1746 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1747 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1748 value.Value.cbData = sizeof(oneW);
1749 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1750 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1751 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1752 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1753 /* An encoded string with specified length isn't good enough either */
1754 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1755 value.Value.pbData = oneUniversal;
1756 value.Value.cbData = sizeof(oneUniversal);
1757 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1758 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1759 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1760 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1761 /* More failure checking */
1762 value.Value.cbData = 0;
1763 for (i = 0; i < sizeof(unicodeErrors) / sizeof(unicodeErrors[0]); i++)
1765 value.Value.pbData = (LPBYTE)unicodeErrors[i].str;
1766 value.dwValueType = unicodeErrors[i].valueType;
1767 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1768 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1769 ok(!ret && GetLastError() == unicodeErrors[i].error,
1770 "Value type %d: expected %08x, got %08x\n", value.dwValueType,
1771 unicodeErrors[i].error, GetLastError());
1772 ok(size == unicodeErrors[i].errorIndex,
1773 "Expected error index %d, got %d\n", unicodeErrors[i].errorIndex,
1776 /* cbData can be zero if the string is NULL-terminated */
1777 value.Value.cbData = 0;
1778 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1780 value.Value.pbData = (LPBYTE)unicodeResults[i].str;
1781 value.dwValueType = unicodeResults[i].valueType;
1782 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1783 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1784 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
1785 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1788 ok(size == unicodeResults[i].encoded.cbData,
1789 "Value type %d: expected size %d, got %d\n",
1790 value.dwValueType, unicodeResults[i].encoded.cbData, size);
1791 ok(!memcmp(unicodeResults[i].encoded.pbData, buf, size),
1792 "Value type %d: unexpected value\n", value.dwValueType);
1796 /* These "encode," but they do so by truncating each unicode character
1797 * rather than properly encoding it. Kept separate from the proper results,
1798 * because the encoded forms won't decode to their original strings.
1800 for (i = 0; i < sizeof(unicodeWeirdness) / sizeof(unicodeWeirdness[0]); i++)
1802 value.Value.pbData = (LPBYTE)unicodeWeirdness[i].str;
1803 value.dwValueType = unicodeWeirdness[i].valueType;
1804 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1805 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1806 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1809 ok(size == unicodeWeirdness[i].encoded.cbData,
1810 "Value type %d: expected size %d, got %d\n",
1811 value.dwValueType, unicodeWeirdness[i].encoded.cbData, size);
1812 ok(!memcmp(unicodeWeirdness[i].encoded.pbData, buf, size),
1813 "Value type %d: unexpected value\n", value.dwValueType);
1819 static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
1821 if (n <= 0) return 0;
1822 while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
1823 return *str1 - *str2;
1826 static void test_decodeUnicodeNameValue(DWORD dwEncoding)
1830 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1836 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE,
1837 unicodeResults[i].encoded.pbData, unicodeResults[i].encoded.cbData,
1838 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1839 ok(ret || broken(GetLastError() == CRYPT_E_NOT_CHAR_STRING /* Win9x */),
1840 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1843 PCERT_NAME_VALUE value = (PCERT_NAME_VALUE)buf;
1845 ok(value->dwValueType == unicodeResults[i].valueType,
1846 "Expected value type %d, got %d\n", unicodeResults[i].valueType,
1847 value->dwValueType);
1848 ok(!strncmpW((LPWSTR)value->Value.pbData, unicodeResults[i].str,
1849 value->Value.cbData / sizeof(WCHAR)),
1850 "Unexpected decoded value for index %d (value type %d)\n", i,
1851 unicodeResults[i].valueType);
1857 struct encodedOctets
1860 const BYTE *encoded;
1863 static const unsigned char bin46[] = { 'h','i',0 };
1864 static const unsigned char bin47[] = { 0x04,0x02,'h','i',0 };
1865 static const unsigned char bin48[] = {
1866 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1867 static const unsigned char bin49[] = {
1868 0x04,0x0f,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1869 static const unsigned char bin50[] = { 0 };
1870 static const unsigned char bin51[] = { 0x04,0x00,0 };
1872 static const struct encodedOctets octets[] = {
1878 static void test_encodeOctets(DWORD dwEncoding)
1880 CRYPT_DATA_BLOB blob;
1883 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1889 blob.cbData = strlen((const char*)octets[i].val);
1890 blob.pbData = (BYTE*)octets[i].val;
1891 ret = pCryptEncodeObjectEx(dwEncoding, X509_OCTET_STRING, &blob,
1892 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1893 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
1897 "Got unexpected type %d for octet string (expected 4)\n", buf[0]);
1898 ok(buf[1] == octets[i].encoded[1], "Got length %d, expected %d\n",
1899 buf[1], octets[i].encoded[1]);
1900 ok(!memcmp(buf + 1, octets[i].encoded + 1,
1901 octets[i].encoded[1] + 1), "Got unexpected value\n");
1907 static void test_decodeOctets(DWORD dwEncoding)
1911 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1917 ret = pCryptDecodeObjectEx(dwEncoding, X509_OCTET_STRING,
1918 (BYTE *)octets[i].encoded, octets[i].encoded[1] + 2,
1919 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1920 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1921 ok(bufSize >= sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1],
1922 "Expected size >= %d, got %d\n",
1923 (int)sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1], bufSize);
1924 ok(buf != NULL, "Expected allocated buffer\n");
1927 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)buf;
1930 ok(!memcmp(blob->pbData, octets[i].val, blob->cbData),
1931 "Unexpected value\n");
1937 static const BYTE bytesToEncode[] = { 0xff, 0xff };
1942 const BYTE *encoded;
1944 const BYTE *decoded;
1947 static const unsigned char bin52[] = { 0x03,0x03,0x00,0xff,0xff };
1948 static const unsigned char bin53[] = { 0xff,0xff };
1949 static const unsigned char bin54[] = { 0x03,0x03,0x01,0xff,0xfe };
1950 static const unsigned char bin55[] = { 0xff,0xfe };
1951 static const unsigned char bin56[] = { 0x03,0x02,0x01,0xfe };
1952 static const unsigned char bin57[] = { 0xfe };
1953 static const unsigned char bin58[] = { 0x03,0x01,0x00 };
1955 static const struct encodedBits bits[] = {
1956 /* normal test cases */
1957 { 0, bin52, 2, bin53 },
1958 { 1, bin54, 2, bin55 },
1959 /* strange test case, showing cUnusedBits >= 8 is allowed */
1960 { 9, bin56, 1, bin57 },
1961 /* even stranger test case, showing cUnusedBits > cbData * 8 is allowed */
1962 { 17, bin58, 0, NULL },
1965 static void test_encodeBits(DWORD dwEncoding)
1969 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
1971 CRYPT_BIT_BLOB blob;
1976 blob.cbData = sizeof(bytesToEncode);
1977 blob.pbData = (BYTE *)bytesToEncode;
1978 blob.cUnusedBits = bits[i].cUnusedBits;
1979 ret = pCryptEncodeObjectEx(dwEncoding, X509_BITS, &blob,
1980 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1981 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1984 ok(bufSize == bits[i].encoded[1] + 2,
1985 "Got unexpected size %d, expected %d\n", bufSize,
1986 bits[i].encoded[1] + 2);
1987 ok(!memcmp(buf, bits[i].encoded, bits[i].encoded[1] + 2),
1988 "Unexpected value\n");
1994 static void test_decodeBits(DWORD dwEncoding)
1996 static const BYTE ber[] = "\x03\x02\x01\xff";
1997 static const BYTE berDecoded = 0xfe;
2004 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
2006 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, bits[i].encoded,
2007 bits[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2009 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2012 CRYPT_BIT_BLOB *blob;
2014 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + bits[i].cbDecoded,
2015 "Got unexpected size %d\n", bufSize);
2016 blob = (CRYPT_BIT_BLOB *)buf;
2017 ok(blob->cbData == bits[i].cbDecoded,
2018 "Got unexpected length %d, expected %d\n", blob->cbData,
2020 if (blob->cbData && bits[i].cbDecoded)
2021 ok(!memcmp(blob->pbData, bits[i].decoded, bits[i].cbDecoded),
2022 "Unexpected value\n");
2026 /* special case: check that something that's valid in BER but not in DER
2027 * decodes successfully
2029 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, ber, ber[1] + 2,
2030 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2031 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2034 CRYPT_BIT_BLOB *blob;
2036 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + sizeof(berDecoded),
2037 "Got unexpected size %d\n", bufSize);
2038 blob = (CRYPT_BIT_BLOB *)buf;
2039 ok(blob->cbData == sizeof(berDecoded),
2040 "Got unexpected length %d\n", blob->cbData);
2042 ok(*blob->pbData == berDecoded, "Unexpected value\n");
2049 CERT_BASIC_CONSTRAINTS2_INFO info;
2050 const BYTE *encoded;
2053 static const unsigned char bin59[] = { 0x30,0x00 };
2054 static const unsigned char bin60[] = { 0x30,0x03,0x01,0x01,0xff };
2055 static const unsigned char bin61[] = { 0x30,0x03,0x02,0x01,0x00 };
2056 static const unsigned char bin62[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2057 static const struct Constraints2 constraints2[] = {
2058 /* empty constraints */
2059 { { FALSE, FALSE, 0}, bin59 },
2061 { { TRUE, FALSE, 0}, bin60 },
2062 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well,
2063 * but that's not the case
2065 { { FALSE, TRUE, 0}, bin61 },
2066 /* can be a CA and has path length constraints set */
2067 { { TRUE, TRUE, 1}, bin62 },
2070 static const BYTE emptyConstraint[] = { 0x30, 0x03, 0x03, 0x01, 0x00 };
2071 static const BYTE encodedDomainName[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11,
2072 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
2073 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
2074 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2075 static const BYTE constraintWithDomainName[] = { 0x30, 0x32, 0x03, 0x01, 0x00,
2076 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
2077 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30,
2078 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
2079 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2081 static void test_encodeBasicConstraints(DWORD dwEncoding)
2083 DWORD i, bufSize = 0;
2084 CERT_BASIC_CONSTRAINTS_INFO info = { { 0 } };
2085 CERT_NAME_BLOB nameBlob = { sizeof(encodedDomainName),
2086 (LPBYTE)encodedDomainName };
2090 /* First test with the simpler info2 */
2091 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2093 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2094 &constraints2[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2096 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2099 ok(bufSize == constraints2[i].encoded[1] + 2,
2100 "Expected %d bytes, got %d\n", constraints2[i].encoded[1] + 2,
2102 ok(!memcmp(buf, constraints2[i].encoded,
2103 constraints2[i].encoded[1] + 2), "Unexpected value\n");
2107 /* Now test with more complex basic constraints */
2108 info.SubjectType.cbData = 0;
2109 info.fPathLenConstraint = FALSE;
2110 info.cSubtreesConstraint = 0;
2111 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2112 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2113 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2114 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2117 ok(bufSize == sizeof(emptyConstraint), "Wrong size %d\n", bufSize);
2118 ok(!memcmp(buf, emptyConstraint, sizeof(emptyConstraint)),
2119 "Unexpected value\n");
2122 /* None of the certs I examined had any subtree constraint, but I test one
2123 * anyway just in case.
2125 info.cSubtreesConstraint = 1;
2126 info.rgSubtreesConstraint = &nameBlob;
2127 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2128 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2129 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2130 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2133 ok(bufSize == sizeof(constraintWithDomainName), "Wrong size %d\n", bufSize);
2134 ok(!memcmp(buf, constraintWithDomainName,
2135 sizeof(constraintWithDomainName)), "Unexpected value\n");
2138 /* FIXME: test encoding with subject type. */
2141 static const unsigned char bin63[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 };
2143 static void test_decodeBasicConstraints(DWORD dwEncoding)
2145 static const BYTE inverted[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01,
2147 static const struct Constraints2 badBool = { { TRUE, TRUE, 1 }, bin63 };
2153 /* First test with simpler info2 */
2154 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2156 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2157 constraints2[i].encoded, constraints2[i].encoded[1] + 2,
2158 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2159 ok(ret, "CryptDecodeObjectEx failed for item %d: %08x\n", i,
2163 CERT_BASIC_CONSTRAINTS2_INFO *info =
2164 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2166 ok(!memcmp(info, &constraints2[i].info, sizeof(*info)),
2167 "Unexpected value for item %d\n", i);
2171 /* Check with the order of encoded elements inverted */
2173 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2174 inverted, inverted[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2176 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2177 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2178 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2180 ok(!buf, "Expected buf to be set to NULL\n");
2181 /* Check with a non-DER bool */
2182 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2183 badBool.encoded, badBool.encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2184 (BYTE *)&buf, &bufSize);
2185 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2188 CERT_BASIC_CONSTRAINTS2_INFO *info =
2189 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2191 ok(!memcmp(info, &badBool.info, sizeof(*info)), "Unexpected value\n");
2194 /* Check with a non-basic constraints value */
2195 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2196 (LPBYTE)encodedCommonName, encodedCommonName[1] + 2,
2197 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2198 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2199 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2200 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2202 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */
2203 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2204 emptyConstraint, sizeof(emptyConstraint), CRYPT_DECODE_ALLOC_FLAG, NULL,
2205 (BYTE *)&buf, &bufSize);
2206 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2209 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2211 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2212 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2213 ok(info->cSubtreesConstraint == 0, "Expected no subtree constraints\n");
2216 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2217 constraintWithDomainName, sizeof(constraintWithDomainName),
2218 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2219 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2222 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2224 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2225 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2226 ok(info->cSubtreesConstraint == 1, "Expected a subtree constraint\n");
2227 if (info->cSubtreesConstraint && info->rgSubtreesConstraint)
2229 ok(info->rgSubtreesConstraint[0].cbData ==
2230 sizeof(encodedDomainName), "Wrong size %d\n",
2231 info->rgSubtreesConstraint[0].cbData);
2232 ok(!memcmp(info->rgSubtreesConstraint[0].pbData, encodedDomainName,
2233 sizeof(encodedDomainName)), "Unexpected value\n");
2239 /* These are terrible public keys of course, I'm just testing encoding */
2240 static const BYTE modulus1[] = { 0,0,0,1,1,1,1,1 };
2241 static const BYTE modulus2[] = { 1,1,1,1,1,0,0,0 };
2242 static const BYTE modulus3[] = { 0x80,1,1,1,1,0,0,0 };
2243 static const BYTE modulus4[] = { 1,1,1,1,1,0,0,0x80 };
2244 static const BYTE mod1_encoded[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 };
2245 static const BYTE mod2_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2246 static const BYTE mod3_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 };
2247 static const BYTE mod4_encoded[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2249 struct EncodedRSAPubKey
2251 const BYTE *modulus;
2253 const BYTE *encoded;
2254 size_t decodedModulusLen;
2257 struct EncodedRSAPubKey rsaPubKeys[] = {
2258 { modulus1, sizeof(modulus1), mod1_encoded, sizeof(modulus1) },
2259 { modulus2, sizeof(modulus2), mod2_encoded, 5 },
2260 { modulus3, sizeof(modulus3), mod3_encoded, 5 },
2261 { modulus4, sizeof(modulus4), mod4_encoded, 8 },
2264 static void test_encodeRsaPublicKey(DWORD dwEncoding)
2266 BYTE toEncode[sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + sizeof(modulus1)];
2267 BLOBHEADER *hdr = (BLOBHEADER *)toEncode;
2268 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(toEncode + sizeof(BLOBHEADER));
2271 DWORD bufSize = 0, i;
2273 /* Try with a bogus blob type */
2275 hdr->bVersion = CUR_BLOB_VERSION;
2277 hdr->aiKeyAlg = CALG_RSA_KEYX;
2278 rsaPubKey->magic = 0x31415352;
2279 rsaPubKey->bitlen = sizeof(modulus1) * 8;
2280 rsaPubKey->pubexp = 65537;
2281 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), modulus1,
2284 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2285 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2287 ok(!ret && GetLastError() == E_INVALIDARG,
2288 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2289 /* Now with a bogus reserved field */
2290 hdr->bType = PUBLICKEYBLOB;
2292 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2293 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2297 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2298 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2299 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2302 /* Now with a bogus blob version */
2305 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2306 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2310 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2311 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2312 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2315 /* And with a bogus alg ID */
2316 hdr->bVersion = CUR_BLOB_VERSION;
2317 hdr->aiKeyAlg = CALG_DES;
2318 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2319 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2323 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2324 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2325 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2328 /* Check a couple of RSA-related OIDs */
2329 hdr->aiKeyAlg = CALG_RSA_KEYX;
2330 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_RSA,
2331 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2332 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2333 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2334 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2335 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2336 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2337 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2338 /* Finally, all valid */
2339 hdr->aiKeyAlg = CALG_RSA_KEYX;
2340 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2342 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2343 rsaPubKeys[i].modulus, rsaPubKeys[i].modulusLen);
2344 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2345 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2346 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2349 ok(bufSize == rsaPubKeys[i].encoded[1] + 2,
2350 "Expected size %d, got %d\n", rsaPubKeys[i].encoded[1] + 2,
2352 ok(!memcmp(buf, rsaPubKeys[i].encoded, bufSize),
2353 "Unexpected value\n");
2359 static void test_decodeRsaPublicKey(DWORD dwEncoding)
2366 /* Try with a bad length */
2367 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2368 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1],
2369 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2370 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2371 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2372 /* Try with a couple of RSA-related OIDs */
2373 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_RSA,
2374 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2375 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2376 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2377 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2378 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2379 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2380 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2381 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2382 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2383 /* Now try success cases */
2384 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2387 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2388 rsaPubKeys[i].encoded, rsaPubKeys[i].encoded[1] + 2,
2389 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2390 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2393 BLOBHEADER *hdr = (BLOBHEADER *)buf;
2394 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER));
2396 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2397 rsaPubKeys[i].decodedModulusLen,
2398 "Wrong size %d\n", bufSize);
2399 ok(hdr->bType == PUBLICKEYBLOB,
2400 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB,
2402 ok(hdr->bVersion == CUR_BLOB_VERSION,
2403 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
2404 CUR_BLOB_VERSION, hdr->bVersion);
2405 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n",
2407 ok(hdr->aiKeyAlg == CALG_RSA_KEYX,
2408 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg);
2409 ok(rsaPubKey->magic == 0x31415352,
2410 "Expected magic RSA1, got %08x\n", rsaPubKey->magic);
2411 ok(rsaPubKey->bitlen == rsaPubKeys[i].decodedModulusLen * 8,
2412 "Wrong bit len %d\n", rsaPubKey->bitlen);
2413 ok(rsaPubKey->pubexp == 65537, "Expected pubexp 65537, got %d\n",
2415 ok(!memcmp(buf + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2416 rsaPubKeys[i].modulus, rsaPubKeys[i].decodedModulusLen),
2417 "Unexpected modulus\n");
2423 static const BYTE intSequence[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01,
2424 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02,
2425 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2427 static const BYTE mixedSequence[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
2428 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f,
2429 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02,
2430 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2432 static void test_encodeSequenceOfAny(DWORD dwEncoding)
2434 CRYPT_DER_BLOB blobs[sizeof(ints) / sizeof(ints[0])];
2435 CRYPT_SEQUENCE_OF_ANY seq;
2441 /* Encode a homogeneous sequence */
2442 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
2444 blobs[i].cbData = ints[i].encoded[1] + 2;
2445 blobs[i].pbData = (BYTE *)ints[i].encoded;
2447 seq.cValue = sizeof(ints) / sizeof(ints[0]);
2448 seq.rgValue = blobs;
2450 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2451 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2452 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2455 ok(bufSize == sizeof(intSequence), "Wrong size %d\n", bufSize);
2456 ok(!memcmp(buf, intSequence, intSequence[1] + 2), "Unexpected value\n");
2459 /* Change the type of the first element in the sequence, and give it
2462 blobs[0].cbData = times[0].encodedTime[1] + 2;
2463 blobs[0].pbData = (BYTE *)times[0].encodedTime;
2464 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2465 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2466 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2469 ok(bufSize == sizeof(mixedSequence), "Wrong size %d\n", bufSize);
2470 ok(!memcmp(buf, mixedSequence, mixedSequence[1] + 2),
2471 "Unexpected value\n");
2476 static void test_decodeSequenceOfAny(DWORD dwEncoding)
2482 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, intSequence,
2483 intSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2484 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2487 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2490 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2491 "Wrong elements %d\n", seq->cValue);
2492 for (i = 0; i < min(seq->cValue, sizeof(ints) / sizeof(ints[0])); i++)
2494 ok(seq->rgValue[i].cbData == ints[i].encoded[1] + 2,
2495 "Expected %d bytes, got %d\n", ints[i].encoded[1] + 2,
2496 seq->rgValue[i].cbData);
2497 ok(!memcmp(seq->rgValue[i].pbData, ints[i].encoded,
2498 ints[i].encoded[1] + 2), "Unexpected value\n");
2502 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, mixedSequence,
2503 mixedSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2505 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2508 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2510 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2511 "Wrong elements %d\n", seq->cValue);
2512 /* Just check the first element since it's all that changed */
2513 ok(seq->rgValue[0].cbData == times[0].encodedTime[1] + 2,
2514 "Expected %d bytes, got %d\n", times[0].encodedTime[1] + 2,
2515 seq->rgValue[0].cbData);
2516 ok(!memcmp(seq->rgValue[0].pbData, times[0].encodedTime,
2517 times[0].encodedTime[1] + 2), "Unexpected value\n");
2522 struct encodedExtensions
2524 CERT_EXTENSIONS exts;
2525 const BYTE *encoded;
2528 static BYTE crit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2529 static BYTE noncrit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2530 static CHAR oid_basic_constraints2[] = szOID_BASIC_CONSTRAINTS2;
2531 static CERT_EXTENSION criticalExt =
2532 { oid_basic_constraints2, TRUE, { 8, crit_ext_data } };
2533 static CERT_EXTENSION nonCriticalExt =
2534 { oid_basic_constraints2, FALSE, { 8, noncrit_ext_data } };
2536 static const BYTE ext0[] = { 0x30,0x00 };
2537 static const BYTE ext1[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2538 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2539 static const BYTE ext2[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2540 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2542 static const struct encodedExtensions exts[] = {
2543 { { 0, NULL }, ext0 },
2544 { { 1, &criticalExt }, ext1 },
2545 { { 1, &nonCriticalExt }, ext2 },
2548 static void test_encodeExtensions(DWORD dwEncoding)
2552 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2558 ret = pCryptEncodeObjectEx(dwEncoding, X509_EXTENSIONS, &exts[i].exts,
2559 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2560 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2563 ok(bufSize == exts[i].encoded[1] + 2,
2564 "Expected %d bytes, got %d\n", exts[i].encoded[1] + 2, bufSize);
2565 ok(!memcmp(buf, exts[i].encoded, exts[i].encoded[1] + 2),
2566 "Unexpected value\n");
2572 static void test_decodeExtensions(DWORD dwEncoding)
2576 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2582 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS,
2583 exts[i].encoded, exts[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2584 NULL, (BYTE *)&buf, &bufSize);
2585 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2588 CERT_EXTENSIONS *ext = (CERT_EXTENSIONS *)buf;
2591 ok(ext->cExtension == exts[i].exts.cExtension,
2592 "Expected %d extensions, see %d\n", exts[i].exts.cExtension,
2594 for (j = 0; j < min(ext->cExtension, exts[i].exts.cExtension); j++)
2596 ok(!strcmp(ext->rgExtension[j].pszObjId,
2597 exts[i].exts.rgExtension[j].pszObjId),
2598 "Expected OID %s, got %s\n",
2599 exts[i].exts.rgExtension[j].pszObjId,
2600 ext->rgExtension[j].pszObjId);
2601 ok(!memcmp(ext->rgExtension[j].Value.pbData,
2602 exts[i].exts.rgExtension[j].Value.pbData,
2603 exts[i].exts.rgExtension[j].Value.cbData),
2604 "Unexpected value\n");
2611 /* MS encodes public key info with a NULL if the algorithm identifier's
2612 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2613 * it encodes them by omitting the algorithm parameters. This latter approach
2614 * seems more correct, so accept either form.
2616 struct encodedPublicKey
2618 CERT_PUBLIC_KEY_INFO info;
2619 const BYTE *encoded;
2620 const BYTE *encodedNoNull;
2621 CERT_PUBLIC_KEY_INFO decoded;
2624 static const BYTE aKey[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2626 static const BYTE params[] = { 0x02, 0x01, 0x01 };
2628 static const unsigned char bin64[] = {
2629 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2630 static const unsigned char bin65[] = {
2631 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2632 static const unsigned char bin66[] = {
2633 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2634 static const unsigned char bin67[] = {
2635 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2636 static const unsigned char bin68[] = {
2637 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01,
2638 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2639 static const unsigned char bin69[] = {
2640 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2641 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2642 static const unsigned char bin70[] = {
2643 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2644 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2646 static const unsigned char bin71[] = {
2647 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2648 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2650 static unsigned char bin72[] = { 0x05,0x00};
2652 static CHAR oid_bogus[] = "1.2.3",
2653 oid_rsa[] = szOID_RSA;
2655 static const struct encodedPublicKey pubKeys[] = {
2656 /* with a bogus OID */
2657 { { { oid_bogus, { 0, NULL } }, { 0, NULL, 0 } },
2659 { { oid_bogus, { 2, bin72 } }, { 0, NULL, 0 } } },
2660 /* some normal keys */
2661 { { { oid_rsa, { 0, NULL } }, { 0, NULL, 0} },
2663 { { oid_rsa, { 2, bin72 } }, { 0, NULL, 0 } } },
2664 { { { oid_rsa, { 0, NULL } }, { sizeof(aKey), (BYTE *)aKey, 0} },
2666 { { oid_rsa, { 2, bin72 } }, { sizeof(aKey), (BYTE *)aKey, 0} } },
2667 /* with add'l parameters--note they must be DER-encoded */
2668 { { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2669 (BYTE *)aKey, 0 } },
2671 { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2672 (BYTE *)aKey, 0 } } },
2675 static void test_encodePublicKeyInfo(DWORD dwEncoding)
2679 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2685 ret = pCryptEncodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2686 &pubKeys[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2688 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2689 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2692 ok(bufSize == pubKeys[i].encoded[1] + 2 ||
2693 bufSize == pubKeys[i].encodedNoNull[1] + 2,
2694 "Expected %d or %d bytes, got %d\n", pubKeys[i].encoded[1] + 2,
2695 pubKeys[i].encodedNoNull[1] + 2, bufSize);
2696 if (bufSize == pubKeys[i].encoded[1] + 2)
2697 ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2),
2698 "Unexpected value\n");
2699 else if (bufSize == pubKeys[i].encodedNoNull[1] + 2)
2700 ok(!memcmp(buf, pubKeys[i].encodedNoNull,
2701 pubKeys[i].encodedNoNull[1] + 2), "Unexpected value\n");
2707 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO *expected,
2708 const CERT_PUBLIC_KEY_INFO *got)
2710 ok(!strcmp(expected->Algorithm.pszObjId, got->Algorithm.pszObjId),
2711 "Expected OID %s, got %s\n", expected->Algorithm.pszObjId,
2712 got->Algorithm.pszObjId);
2713 ok(expected->Algorithm.Parameters.cbData ==
2714 got->Algorithm.Parameters.cbData,
2715 "Expected parameters of %d bytes, got %d\n",
2716 expected->Algorithm.Parameters.cbData, got->Algorithm.Parameters.cbData);
2717 if (expected->Algorithm.Parameters.cbData)
2718 ok(!memcmp(expected->Algorithm.Parameters.pbData,
2719 got->Algorithm.Parameters.pbData, got->Algorithm.Parameters.cbData),
2720 "Unexpected algorithm parameters\n");
2721 ok(expected->PublicKey.cbData == got->PublicKey.cbData,
2722 "Expected public key of %d bytes, got %d\n",
2723 expected->PublicKey.cbData, got->PublicKey.cbData);
2724 if (expected->PublicKey.cbData)
2725 ok(!memcmp(expected->PublicKey.pbData, got->PublicKey.pbData,
2726 got->PublicKey.cbData), "Unexpected public key value\n");
2729 static void test_decodePublicKeyInfo(DWORD dwEncoding)
2731 static const BYTE bogusPubKeyInfo[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
2732 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
2733 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
2734 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2740 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2742 /* The NULL form decodes to the decoded member */
2743 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2744 pubKeys[i].encoded, pubKeys[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2745 NULL, (BYTE *)&buf, &bufSize);
2746 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2749 comparePublicKeyInfo(&pubKeys[i].decoded,
2750 (CERT_PUBLIC_KEY_INFO *)buf);
2753 /* The non-NULL form decodes to the original */
2754 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2755 pubKeys[i].encodedNoNull, pubKeys[i].encodedNoNull[1] + 2,
2756 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2757 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2760 comparePublicKeyInfo(&pubKeys[i].info, (CERT_PUBLIC_KEY_INFO *)buf);
2764 /* Test with bogus (not valid DER) parameters */
2765 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2766 bogusPubKeyInfo, bogusPubKeyInfo[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2767 NULL, (BYTE *)&buf, &bufSize);
2768 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2769 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2770 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2774 static const BYTE v1Cert[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
2775 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2776 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
2777 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
2778 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2779 static const BYTE v2Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02,
2780 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2781 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2782 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2783 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2784 static const BYTE v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2785 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2786 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2787 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2788 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2789 static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
2790 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2791 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2792 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2793 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2794 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2795 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2796 static const BYTE v1CertWithSerial[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
2797 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2798 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2799 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2800 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2801 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2802 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2803 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2804 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
2805 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
2806 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
2807 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
2808 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
2809 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
2810 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
2811 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
2812 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2813 static const BYTE v1CertWithPubKey[] = {
2814 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2815 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2816 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2817 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2818 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2819 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2820 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2821 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2822 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
2823 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
2825 static const BYTE v1CertWithPubKeyNoNull[] = {
2826 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2827 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2828 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2829 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2830 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2831 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2832 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2833 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2834 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
2835 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2836 static const BYTE v1CertWithSubjectKeyId[] = {
2837 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2838 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2839 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2840 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2841 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2842 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2843 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
2844 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2845 0x4c,0x61,0x6e,0x67,0x00 };
2847 static const BYTE serialNum[] = { 0x01 };
2849 static void test_encodeCertToBeSigned(DWORD dwEncoding)
2854 CERT_INFO info = { 0 };
2855 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2856 static char oid_subject_key_identifier[] = szOID_SUBJECT_KEY_IDENTIFIER;
2861 /* Test with NULL pvStructInfo (crashes on win9x) */
2862 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL,
2863 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2864 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2865 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2867 /* Test with a V1 cert */
2868 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2869 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2870 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2871 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2874 ok(size == v1Cert[1] + 2, "Expected size %d, got %d\n",
2875 v1Cert[1] + 2, size);
2876 ok(!memcmp(buf, v1Cert, size), "Got unexpected value\n");
2880 info.dwVersion = CERT_V2;
2881 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2882 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2883 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2884 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2887 ok(size == sizeof(v2Cert), "Wrong size %d\n", size);
2888 ok(!memcmp(buf, v2Cert, size), "Got unexpected value\n");
2892 info.dwVersion = CERT_V3;
2893 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2894 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2895 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2896 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2899 ok(size == sizeof(v3Cert), "Wrong size %d\n", size);
2900 ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n");
2903 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
2904 * API doesn't prevent it)
2906 info.dwVersion = CERT_V1;
2907 info.cExtension = 1;
2908 info.rgExtension = &criticalExt;
2909 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2910 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2911 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2912 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2915 ok(size == sizeof(v1CertWithConstraints), "Wrong size %d\n", size);
2916 ok(!memcmp(buf, v1CertWithConstraints, size), "Got unexpected value\n");
2919 /* test v1 cert with a serial number */
2920 info.SerialNumber.cbData = sizeof(serialNum);
2921 info.SerialNumber.pbData = (BYTE *)serialNum;
2922 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2923 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2926 ok(size == sizeof(v1CertWithSerial), "Wrong size %d\n", size);
2927 ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n");
2930 /* Test v1 cert with an issuer name, a subject name, and a serial number */
2931 info.Issuer.cbData = sizeof(encodedCommonName);
2932 info.Issuer.pbData = (BYTE *)encodedCommonName;
2933 info.Subject.cbData = sizeof(encodedCommonName);
2934 info.Subject.pbData = (BYTE *)encodedCommonName;
2935 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2936 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2939 ok(size == sizeof(bigCert), "Wrong size %d\n", size);
2940 ok(!memcmp(buf, bigCert, size), "Got unexpected value\n");
2943 /* Add a public key */
2944 info.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2945 info.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2946 info.SubjectPublicKeyInfo.PublicKey.pbData = (LPBYTE)aKey;
2947 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2948 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2951 ok(size == sizeof(v1CertWithPubKey) ||
2952 size == sizeof(v1CertWithPubKeyNoNull), "Wrong size %d\n", size);
2953 if (size == sizeof(v1CertWithPubKey))
2954 ok(!memcmp(buf, v1CertWithPubKey, size), "Got unexpected value\n");
2955 else if (size == sizeof(v1CertWithPubKeyNoNull))
2956 ok(!memcmp(buf, v1CertWithPubKeyNoNull, size),
2957 "Got unexpected value\n");
2960 /* Remove the public key, and add a subject key identifier extension */
2961 info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2962 info.SubjectPublicKeyInfo.PublicKey.cbData = 0;
2963 info.SubjectPublicKeyInfo.PublicKey.pbData = NULL;
2964 ext.pszObjId = oid_subject_key_identifier;
2965 ext.fCritical = FALSE;
2966 ext.Value.cbData = sizeof(octetCommonNameValue);
2967 ext.Value.pbData = (BYTE *)octetCommonNameValue;
2968 info.cExtension = 1;
2969 info.rgExtension = &ext;
2970 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2971 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2974 ok(size == sizeof(v1CertWithSubjectKeyId), "Wrong size %d\n", size);
2975 ok(!memcmp(buf, v1CertWithSubjectKeyId, size), "Unexpected value\n");
2980 static void test_decodeCertToBeSigned(DWORD dwEncoding)
2982 static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert,
2983 v1CertWithConstraints, v1CertWithSerial };
2988 /* Test with NULL pbEncoded */
2989 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 0,
2990 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2991 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
2992 GetLastError() == OSS_BAD_ARG /* Win9x */),
2993 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
2996 /* Crashes on win9x */
2997 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 1,
2998 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2999 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3000 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3002 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT, because at a
3003 * minimum a cert must have a non-zero serial number, an issuer, and a
3006 for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++)
3008 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3009 corruptCerts[i], corruptCerts[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3010 (BYTE *)&buf, &size);
3011 ok(!ret, "Expected failure\n");
3013 /* Now check with serial number, subject and issuer specified */
3014 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert,
3015 sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3016 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3019 CERT_INFO *info = (CERT_INFO *)buf;
3021 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3022 ok(info->SerialNumber.cbData == 1,
3023 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3024 ok(*info->SerialNumber.pbData == *serialNum,
3025 "Expected serial number %d, got %d\n", *serialNum,
3026 *info->SerialNumber.pbData);
3027 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3028 "Wrong size %d\n", info->Issuer.cbData);
3029 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3030 "Unexpected issuer\n");
3031 ok(info->Subject.cbData == sizeof(encodedCommonName),
3032 "Wrong size %d\n", info->Subject.cbData);
3033 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3034 info->Subject.cbData), "Unexpected subject\n");
3037 /* Check again with pub key specified */
3038 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3039 v1CertWithPubKey, sizeof(v1CertWithPubKey), CRYPT_DECODE_ALLOC_FLAG, NULL,
3040 (BYTE *)&buf, &size);
3041 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3044 CERT_INFO *info = (CERT_INFO *)buf;
3046 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3047 ok(info->SerialNumber.cbData == 1,
3048 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3049 ok(*info->SerialNumber.pbData == *serialNum,
3050 "Expected serial number %d, got %d\n", *serialNum,
3051 *info->SerialNumber.pbData);
3052 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3053 "Wrong size %d\n", info->Issuer.cbData);
3054 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3055 "Unexpected issuer\n");
3056 ok(info->Subject.cbData == sizeof(encodedCommonName),
3057 "Wrong size %d\n", info->Subject.cbData);
3058 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3059 info->Subject.cbData), "Unexpected subject\n");
3060 ok(!strcmp(info->SubjectPublicKeyInfo.Algorithm.pszObjId,
3061 szOID_RSA_RSA), "Expected szOID_RSA_RSA, got %s\n",
3062 info->SubjectPublicKeyInfo.Algorithm.pszObjId);
3063 ok(info->SubjectPublicKeyInfo.PublicKey.cbData == sizeof(aKey),
3064 "Wrong size %d\n", info->SubjectPublicKeyInfo.PublicKey.cbData);
3065 ok(!memcmp(info->SubjectPublicKeyInfo.PublicKey.pbData, aKey,
3066 sizeof(aKey)), "Unexpected public key\n");
3071 static const BYTE hash[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
3074 static const BYTE signedBigCert[] = {
3075 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
3076 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
3077 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
3078 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3079 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
3080 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
3081 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
3082 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
3083 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
3084 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3085 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
3086 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
3088 static void test_encodeCert(DWORD dwEncoding)
3090 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
3091 * also that bigCert is a NULL-terminated string, so don't count its
3092 * last byte (otherwise the signed cert won't decode.)
3094 CERT_SIGNED_CONTENT_INFO info = { { sizeof(bigCert), (BYTE *)bigCert },
3095 { NULL, { 0, NULL } }, { sizeof(hash), (BYTE *)hash, 0 } };
3100 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT, &info,
3101 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
3102 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3105 ok(bufSize == sizeof(signedBigCert), "Wrong size %d\n", bufSize);
3106 ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n");
3111 static void test_decodeCert(DWORD dwEncoding)
3117 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert,
3118 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3119 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3122 CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf;
3124 ok(info->ToBeSigned.cbData == sizeof(bigCert),
3125 "Wrong cert size %d\n", info->ToBeSigned.cbData);
3126 ok(!memcmp(info->ToBeSigned.pbData, bigCert, info->ToBeSigned.cbData),
3127 "Unexpected cert\n");
3128 ok(info->Signature.cbData == sizeof(hash),
3129 "Wrong signature size %d\n", info->Signature.cbData);
3130 ok(!memcmp(info->Signature.pbData, hash, info->Signature.cbData),
3131 "Unexpected signature\n");
3134 /* A signed cert decodes as a CERT_INFO too */
3135 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCert,
3136 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3137 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3140 CERT_INFO *info = (CERT_INFO *)buf;
3142 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3143 ok(info->SerialNumber.cbData == 1,
3144 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3145 ok(*info->SerialNumber.pbData == *serialNum,
3146 "Expected serial number %d, got %d\n", *serialNum,
3147 *info->SerialNumber.pbData);
3148 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3149 "Wrong size %d\n", info->Issuer.cbData);
3150 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3151 "Unexpected issuer\n");
3152 ok(info->Subject.cbData == sizeof(encodedCommonName),
3153 "Wrong size %d\n", info->Subject.cbData);
3154 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3155 info->Subject.cbData), "Unexpected subject\n");
3160 static const BYTE emptyDistPoint[] = { 0x30, 0x02, 0x30, 0x00 };
3161 static const BYTE distPointWithUrl[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3162 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3163 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3164 static const BYTE distPointWithReason[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3166 static const BYTE distPointWithIssuer[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3167 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3168 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3169 static const BYTE distPointWithUrlAndIssuer[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3170 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3171 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3172 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3173 0x2e, 0x6f, 0x72, 0x67 };
3174 static const BYTE crlReason = CRL_REASON_KEY_COMPROMISE |
3175 CRL_REASON_AFFILIATION_CHANGED;
3177 static void test_encodeCRLDistPoints(DWORD dwEncoding)
3179 CRL_DIST_POINTS_INFO info = { 0 };
3180 CRL_DIST_POINT point = { { 0 } };
3181 CERT_ALT_NAME_ENTRY entry = { 0 };
3186 /* Test with an empty info */
3187 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3188 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3189 ok(!ret && GetLastError() == E_INVALIDARG,
3190 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3191 /* Test with one empty dist point */
3192 info.cDistPoint = 1;
3193 info.rgDistPoint = &point;
3194 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3195 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3198 ok(size == sizeof(emptyDistPoint), "Wrong size %d\n", size);
3199 ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n");
3202 /* A dist point with an invalid name */
3203 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3204 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3205 U(entry).pwszURL = (LPWSTR)nihongoURL;
3206 U(point.DistPointName).FullName.cAltEntry = 1;
3207 U(point.DistPointName).FullName.rgAltEntry = &entry;
3208 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3209 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3210 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
3211 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
3212 /* The first invalid character is at index 7 */
3213 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
3214 "Expected invalid char at index 7, got %d\n",
3215 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
3216 /* A dist point with (just) a valid name */
3217 U(entry).pwszURL = (LPWSTR)url;
3218 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3219 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3222 ok(size == sizeof(distPointWithUrl), "Wrong size %d\n", size);
3223 ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n");
3226 /* A dist point with (just) reason flags */
3227 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3228 point.ReasonFlags.cbData = sizeof(crlReason);
3229 point.ReasonFlags.pbData = (LPBYTE)&crlReason;
3230 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3231 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3234 ok(size == sizeof(distPointWithReason), "Wrong size %d\n", size);
3235 ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n");
3238 /* A dist point with just an issuer */
3239 point.ReasonFlags.cbData = 0;
3240 point.CRLIssuer.cAltEntry = 1;
3241 point.CRLIssuer.rgAltEntry = &entry;
3242 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3243 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3246 ok(size == sizeof(distPointWithIssuer), "Wrong size %d\n", size);
3247 ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n");
3250 /* A dist point with both a name and an issuer */
3251 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3252 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3253 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3256 ok(size == sizeof(distPointWithUrlAndIssuer),
3257 "Wrong size %d\n", size);
3258 ok(!memcmp(buf, distPointWithUrlAndIssuer, size), "Unexpected value\n");
3263 static void test_decodeCRLDistPoints(DWORD dwEncoding)
3268 PCRL_DIST_POINTS_INFO info;
3269 PCRL_DIST_POINT point;
3270 PCERT_ALT_NAME_ENTRY entry;
3272 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3273 emptyDistPoint, emptyDistPoint[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3274 (BYTE *)&buf, &size);
3277 info = (PCRL_DIST_POINTS_INFO)buf;
3278 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3279 "Wrong size %d\n", size);
3280 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3282 point = info->rgDistPoint;
3283 ok(point->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_NO_NAME,
3284 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3285 point->DistPointName.dwDistPointNameChoice);
3286 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3287 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3290 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3291 distPointWithUrl, distPointWithUrl[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3292 (BYTE *)&buf, &size);
3295 info = (PCRL_DIST_POINTS_INFO)buf;
3296 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3297 "Wrong size %d\n", size);
3298 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3300 point = info->rgDistPoint;
3301 ok(point->DistPointName.dwDistPointNameChoice ==
3302 CRL_DIST_POINT_FULL_NAME,
3303 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3304 point->DistPointName.dwDistPointNameChoice);
3305 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3306 "Expected 1 name entry, got %d\n",
3307 U(point->DistPointName).FullName.cAltEntry);
3308 entry = U(point->DistPointName).FullName.rgAltEntry;
3309 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3310 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3311 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3312 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3313 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3316 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3317 distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
3318 NULL, (BYTE *)&buf, &size);
3321 info = (PCRL_DIST_POINTS_INFO)buf;
3322 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3323 "Wrong size %d\n", size);
3324 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3326 point = info->rgDistPoint;
3327 ok(point->DistPointName.dwDistPointNameChoice ==
3328 CRL_DIST_POINT_NO_NAME,
3329 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3330 point->DistPointName.dwDistPointNameChoice);
3331 ok(point->ReasonFlags.cbData == sizeof(crlReason),
3332 "Expected reason length\n");
3333 ok(!memcmp(point->ReasonFlags.pbData, &crlReason, sizeof(crlReason)),
3334 "Unexpected reason\n");
3335 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3338 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3339 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2,
3340 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3343 info = (PCRL_DIST_POINTS_INFO)buf;
3344 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3345 "Wrong size %d\n", size);
3346 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3348 point = info->rgDistPoint;
3349 ok(point->DistPointName.dwDistPointNameChoice ==
3350 CRL_DIST_POINT_FULL_NAME,
3351 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3352 point->DistPointName.dwDistPointNameChoice);
3353 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3354 "Expected 1 name entry, got %d\n",
3355 U(point->DistPointName).FullName.cAltEntry);
3356 entry = U(point->DistPointName).FullName.rgAltEntry;
3357 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3358 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3359 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3360 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3361 ok(point->CRLIssuer.cAltEntry == 1,
3362 "Expected 1 issuer entry, got %d\n", point->CRLIssuer.cAltEntry);
3363 entry = point->CRLIssuer.rgAltEntry;
3364 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3365 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3366 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3371 static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3372 static const BYTE emptyNameIDP[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3373 static const BYTE urlIDP[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3374 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3377 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding)
3382 CRL_ISSUING_DIST_POINT point = { { 0 } };
3383 CERT_ALT_NAME_ENTRY entry;
3385 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, NULL,
3386 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3387 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3389 skip("no X509_ISSUING_DIST_POINT encode support\n");
3392 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3393 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3394 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3395 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3396 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3399 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
3400 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
3403 /* nonsensical flags */
3404 point.fOnlyContainsUserCerts = TRUE;
3405 point.fOnlyContainsCACerts = TRUE;
3406 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3407 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3408 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3411 ok(size == sizeof(badFlagsIDP), "Unexpected size %d\n", size);
3412 ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n");
3415 /* unimplemented name type */
3416 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3417 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_ISSUER_RDN_NAME;
3418 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3419 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3420 ok(!ret && GetLastError() == E_INVALIDARG,
3421 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3423 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3424 U(point.DistPointName).FullName.cAltEntry = 0;
3425 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3426 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3427 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3430 ok(size == sizeof(emptyNameIDP), "Unexpected size %d\n", size);
3431 ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n");
3434 /* name with URL entry */
3435 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3436 U(entry).pwszURL = (LPWSTR)url;
3437 U(point.DistPointName).FullName.cAltEntry = 1;
3438 U(point.DistPointName).FullName.rgAltEntry = &entry;
3439 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3440 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3441 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3444 ok(size == sizeof(urlIDP), "Unexpected size %d\n", size);
3445 ok(!memcmp(buf, urlIDP, size), "Unexpected value\n");
3450 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY *expected,
3451 const CERT_ALT_NAME_ENTRY *got)
3453 ok(expected->dwAltNameChoice == got->dwAltNameChoice,
3454 "Expected name choice %d, got %d\n", expected->dwAltNameChoice,
3455 got->dwAltNameChoice);
3456 if (expected->dwAltNameChoice == got->dwAltNameChoice)
3458 switch (got->dwAltNameChoice)
3460 case CERT_ALT_NAME_RFC822_NAME:
3461 case CERT_ALT_NAME_DNS_NAME:
3462 case CERT_ALT_NAME_EDI_PARTY_NAME:
3463 case CERT_ALT_NAME_URL:
3464 case CERT_ALT_NAME_REGISTERED_ID:
3465 ok((!U(*expected).pwszURL && !U(*got).pwszURL) ||
3466 (!U(*expected).pwszURL && !lstrlenW(U(*got).pwszURL)) ||
3467 (!U(*got).pwszURL && !lstrlenW(U(*expected).pwszURL)) ||
3468 !lstrcmpW(U(*expected).pwszURL, U(*got).pwszURL),
3469 "Unexpected name\n");
3471 case CERT_ALT_NAME_X400_ADDRESS:
3472 case CERT_ALT_NAME_DIRECTORY_NAME:
3473 case CERT_ALT_NAME_IP_ADDRESS:
3474 ok(U(*got).IPAddress.cbData == U(*expected).IPAddress.cbData,
3475 "Unexpected IP address length %d\n", U(*got).IPAddress.cbData);
3476 ok(!memcmp(U(*got).IPAddress.pbData, U(*got).IPAddress.pbData,
3477 U(*got).IPAddress.cbData), "Unexpected value\n");
3483 static void compareAltNameInfo(const CERT_ALT_NAME_INFO *expected,
3484 const CERT_ALT_NAME_INFO *got)
3488 ok(expected->cAltEntry == got->cAltEntry, "Expected %d entries, got %d\n",
3489 expected->cAltEntry, got->cAltEntry);
3490 for (i = 0; i < min(expected->cAltEntry, got->cAltEntry); i++)
3491 compareAltNameEntry(&expected->rgAltEntry[i], &got->rgAltEntry[i]);
3494 static void compareDistPointName(const CRL_DIST_POINT_NAME *expected,
3495 const CRL_DIST_POINT_NAME *got)
3497 ok(got->dwDistPointNameChoice == expected->dwDistPointNameChoice,
3498 "Unexpected name choice %d\n", got->dwDistPointNameChoice);
3499 if (got->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME)
3500 compareAltNameInfo(&(U(*expected).FullName), &(U(*got).FullName));
3503 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT *expected,
3504 const CRL_ISSUING_DIST_POINT *got)
3506 compareDistPointName(&expected->DistPointName, &got->DistPointName);
3507 ok(got->fOnlyContainsUserCerts == expected->fOnlyContainsUserCerts,
3508 "Unexpected fOnlyContainsUserCerts\n");
3509 ok(got->fOnlyContainsCACerts == expected->fOnlyContainsCACerts,
3510 "Unexpected fOnlyContainsCACerts\n");
3511 ok(got->OnlySomeReasonFlags.cbData == expected->OnlySomeReasonFlags.cbData,
3512 "Unexpected reason flags\n");
3513 ok(got->fIndirectCRL == expected->fIndirectCRL,
3514 "Unexpected fIndirectCRL\n");
3517 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding)
3522 CRL_ISSUING_DIST_POINT point = { { 0 } };
3524 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3525 emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3526 (BYTE *)&buf, &size);
3527 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3529 skip("no X509_ISSUING_DIST_POINT decode support\n");
3532 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3535 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3538 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3539 badFlagsIDP, badFlagsIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3540 (BYTE *)&buf, &size);
3541 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3544 point.fOnlyContainsUserCerts = point.fOnlyContainsCACerts = TRUE;
3545 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3548 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3549 emptyNameIDP, emptyNameIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3550 (BYTE *)&buf, &size);
3551 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3554 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3555 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3556 U(point.DistPointName).FullName.cAltEntry = 0;
3557 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3560 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3561 urlIDP, urlIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3562 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3565 CERT_ALT_NAME_ENTRY entry;
3567 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3568 U(entry).pwszURL = (LPWSTR)url;
3569 U(point.DistPointName).FullName.cAltEntry = 1;
3570 U(point.DistPointName).FullName.rgAltEntry = &entry;
3571 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3576 static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3577 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3579 static const BYTE v2CRL[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3580 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3581 0x30, 0x30, 0x30, 0x30, 0x5a };
3582 static const BYTE v1CRLWithIssuer[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3583 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3584 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3585 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3587 static const BYTE v1CRLWithIssuerAndEmptyEntry[] = { 0x30, 0x43, 0x30, 0x02,
3588 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3589 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3590 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3591 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3592 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3593 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3594 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3595 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3596 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3597 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3598 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3599 static const BYTE v1CRLWithEntryExt[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3600 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3601 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3602 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3603 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3604 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3605 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3606 static const BYTE v1CRLWithExt[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3607 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3608 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3609 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
3610 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3611 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
3612 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3613 static const BYTE v2CRLWithExt[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
3614 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
3615 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
3616 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
3617 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
3618 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
3619 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3620 static const BYTE v2CRLWithIssuingDistPoint[] = { 0x30,0x5c,0x02,0x01,0x01,
3621 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
3622 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
3623 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
3624 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3625 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
3626 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3628 static void test_encodeCRLToBeSigned(DWORD dwEncoding)
3632 static CHAR oid_issuing_dist_point[] = szOID_ISSUING_DIST_POINT;
3634 CRL_INFO info = { 0 };
3635 CRL_ENTRY entry = { { 0 }, { 0 }, 0, 0 };
3638 /* Test with a V1 CRL */
3639 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3640 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3641 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3642 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3645 ok(size == sizeof(v1CRL), "Wrong size %d\n", size);
3646 ok(!memcmp(buf, v1CRL, size), "Got unexpected value\n");
3650 info.dwVersion = CRL_V2;
3651 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3652 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3653 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3654 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3657 ok(size == v2CRL[1] + 2, "Expected size %d, got %d\n",
3658 v2CRL[1] + 2, size);
3659 ok(!memcmp(buf, v2CRL, size), "Got unexpected value\n");
3662 /* v1 CRL with a name */
3663 info.dwVersion = CRL_V1;
3664 info.Issuer.cbData = sizeof(encodedCommonName);
3665 info.Issuer.pbData = (BYTE *)encodedCommonName;
3666 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3667 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3668 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3671 ok(size == sizeof(v1CRLWithIssuer), "Wrong size %d\n", size);
3672 ok(!memcmp(buf, v1CRLWithIssuer, size), "Got unexpected value\n");
3677 /* v1 CRL with a name and a NULL entry pointer (crashes on win9x) */
3679 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3680 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3681 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3682 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3684 /* now set an empty entry */
3686 info.rgCRLEntry = &entry;
3687 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3688 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3691 ok(size == sizeof(v1CRLWithIssuerAndEmptyEntry),
3692 "Wrong size %d\n", size);
3693 ok(!memcmp(buf, v1CRLWithIssuerAndEmptyEntry, size),
3694 "Got unexpected value\n");
3697 /* an entry with a serial number */
3698 entry.SerialNumber.cbData = sizeof(serialNum);
3699 entry.SerialNumber.pbData = (BYTE *)serialNum;
3700 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3701 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3704 ok(size == sizeof(v1CRLWithIssuerAndEntry),
3705 "Wrong size %d\n", size);
3706 ok(!memcmp(buf, v1CRLWithIssuerAndEntry, size),
3707 "Got unexpected value\n");
3710 /* an entry with an extension */
3711 entry.cExtension = 1;
3712 entry.rgExtension = &criticalExt;
3713 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3714 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3715 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3718 ok(size == sizeof(v1CRLWithEntryExt), "Wrong size %d\n", size);
3719 ok(!memcmp(buf, v1CRLWithEntryExt, size), "Got unexpected value\n");
3722 /* a CRL with an extension */
3723 entry.cExtension = 0;
3724 info.cExtension = 1;
3725 info.rgExtension = &criticalExt;
3726 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3727 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3728 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3731 ok(size == sizeof(v1CRLWithExt), "Wrong size %d\n", size);
3732 ok(!memcmp(buf, v1CRLWithExt, size), "Got unexpected value\n");
3735 /* a v2 CRL with an extension, this time non-critical */
3736 info.dwVersion = CRL_V2;
3737 info.rgExtension = &nonCriticalExt;
3738 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3739 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3740 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3743 ok(size == sizeof(v2CRLWithExt), "Wrong size %d\n", size);
3744 ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n");
3747 /* a v2 CRL with an issuing dist point extension */
3748 ext.pszObjId = oid_issuing_dist_point;
3749 ext.fCritical = TRUE;
3750 ext.Value.cbData = sizeof(urlIDP);
3751 ext.Value.pbData = (LPBYTE)urlIDP;
3752 entry.rgExtension = &ext;
3753 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3754 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3755 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3758 ok(size == sizeof(v2CRLWithIssuingDistPoint), "Wrong size %d\n", size);
3759 ok(!memcmp(buf, v2CRLWithIssuingDistPoint, size), "Unexpected value\n");
3764 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
3765 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
3766 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
3767 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
3768 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
3769 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
3770 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
3771 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
3772 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
3773 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
3774 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
3775 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
3776 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
3777 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
3778 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
3779 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
3780 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
3781 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
3782 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
3783 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
3784 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
3785 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
3786 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
3787 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
3788 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
3789 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
3790 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
3791 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
3792 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
3793 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
3794 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
3795 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
3796 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
3797 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
3799 static const BYTE verisignCRLWithLotsOfEntries[] = {
3800 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
3801 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
3802 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
3803 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
3804 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
3805 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
3806 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
3807 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
3808 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
3809 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
3810 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
3811 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
3812 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
3813 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
3814 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
3815 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
3816 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3817 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
3818 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
3819 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3820 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
3821 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
3822 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
3823 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
3824 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
3825 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
3826 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
3827 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
3828 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
3829 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
3830 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3831 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
3832 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
3833 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3834 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
3835 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
3836 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
3837 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
3838 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
3839 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
3840 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
3841 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
3842 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
3843 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
3844 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
3845 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
3846 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
3847 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
3848 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
3849 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
3850 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
3851 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
3852 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
3853 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
3854 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3855 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
3856 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
3857 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
3858 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
3859 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
3860 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
3861 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
3862 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
3863 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
3864 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
3865 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
3866 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
3867 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
3868 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
3869 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
3870 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
3871 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
3872 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
3873 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
3874 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
3875 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
3876 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
3877 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
3878 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
3879 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
3880 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
3881 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
3882 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3883 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
3884 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
3885 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
3886 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
3887 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
3888 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
3889 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
3890 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
3891 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
3892 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
3893 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
3894 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
3895 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
3896 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
3897 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
3898 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
3899 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
3900 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
3901 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
3902 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
3903 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
3904 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
3905 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
3906 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
3907 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
3908 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
3909 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
3910 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3911 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
3912 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
3913 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
3914 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
3915 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
3916 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
3917 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
3918 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
3919 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
3920 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
3921 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
3922 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
3923 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
3924 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3925 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
3926 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
3927 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
3928 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
3929 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
3930 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
3931 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
3932 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
3933 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
3934 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
3935 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
3936 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
3937 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
3938 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
3939 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
3940 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
3941 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
3942 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
3943 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
3944 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
3945 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
3946 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
3947 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
3948 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
3949 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
3950 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
3951 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
3952 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
3953 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
3954 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
3955 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
3956 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
3957 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
3958 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
3959 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
3960 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
3961 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
3962 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
3963 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
3964 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
3965 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
3966 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
3967 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
3968 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
3969 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
3970 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
3971 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
3972 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
3973 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
3974 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
3975 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
3976 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
3977 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
3978 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
3979 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
3980 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
3981 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
3982 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
3983 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
3984 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
3985 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
3986 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
3987 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
3988 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
3989 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
3990 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
3991 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
3992 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
3993 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
3994 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
3995 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
3996 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
3997 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
3998 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
3999 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
4000 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
4001 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
4002 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
4003 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
4004 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
4005 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
4006 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
4007 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
4008 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
4009 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
4010 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
4011 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
4012 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
4013 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
4014 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
4015 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
4016 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
4017 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
4018 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
4019 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
4020 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
4021 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
4022 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
4023 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
4024 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
4025 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
4026 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
4027 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
4028 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
4029 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
4030 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
4031 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
4032 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
4033 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
4034 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
4035 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
4036 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
4037 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
4038 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
4039 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
4040 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
4041 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
4042 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
4043 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
4044 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
4045 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
4046 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
4047 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
4048 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
4049 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
4050 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
4051 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
4052 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
4053 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
4054 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
4055 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
4056 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
4057 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
4058 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
4059 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
4060 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
4061 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
4062 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
4063 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
4064 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
4065 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
4066 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
4067 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
4068 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
4069 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
4070 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
4071 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
4072 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
4073 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
4074 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
4075 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
4076 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
4077 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
4078 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
4079 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
4080 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
4081 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
4082 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
4083 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
4084 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
4085 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
4086 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
4087 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
4088 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
4089 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
4090 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
4091 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
4092 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
4093 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
4094 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
4095 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
4096 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
4097 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
4098 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
4099 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
4100 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
4101 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
4102 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
4103 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4104 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4105 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4106 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4107 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4108 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4109 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4110 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4111 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4112 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4113 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4114 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4115 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4116 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4117 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4118 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4119 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4120 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4121 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4122 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4123 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4124 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4125 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4126 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4127 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4128 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4129 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4130 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4131 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4132 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4133 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4134 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4135 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4136 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4137 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4138 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4139 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4140 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4141 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4142 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4143 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4144 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4145 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4146 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4147 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4148 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4149 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4150 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4151 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4152 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4153 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4154 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4155 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4156 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4157 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4158 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4159 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4160 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4161 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4162 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4163 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4164 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4165 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4166 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4167 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4168 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4169 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4170 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4171 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4172 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4173 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4174 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4175 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4176 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4177 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4178 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4179 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4180 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4181 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4182 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4183 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4184 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4185 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4186 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4187 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4188 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4189 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4190 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4191 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4192 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4193 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4194 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4195 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4196 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4197 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4198 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4199 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4200 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4201 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4202 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4203 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4204 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4205 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4206 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4207 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4208 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4209 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4210 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4211 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4212 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4213 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4214 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4215 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4216 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4217 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4218 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4219 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4220 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4221 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4222 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4223 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4224 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4225 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4226 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4227 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4228 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4229 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4230 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4231 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4232 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4233 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4234 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4235 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4236 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4237 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4238 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4239 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4240 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4241 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4242 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4243 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4244 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4245 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4246 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4247 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4248 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4249 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4250 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4251 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4252 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4253 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4254 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4255 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4256 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4257 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4258 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4259 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4260 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4261 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4262 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4263 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4264 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4265 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4266 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4267 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4268 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4269 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4270 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4271 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4272 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4273 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4274 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4275 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4276 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4277 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4278 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4279 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4280 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4281 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4282 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4283 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4284 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4285 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4286 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4287 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4288 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4289 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4290 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4291 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4292 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4293 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4294 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4295 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4296 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4297 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4298 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4299 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4300 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4301 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4302 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4303 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4304 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4305 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4306 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4307 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4309 static void test_decodeCRLToBeSigned(DWORD dwEncoding)
4311 static const BYTE *corruptCRLs[] = { v1CRL, v2CRL };
4316 for (i = 0; i < sizeof(corruptCRLs) / sizeof(corruptCRLs[0]); i++)
4318 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4319 corruptCRLs[i], corruptCRLs[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4320 (BYTE *)&buf, &size);
4321 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4322 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4323 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4326 /* at a minimum, a CRL must contain an issuer: */
4327 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4328 v1CRLWithIssuer, v1CRLWithIssuer[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4329 (BYTE *)&buf, &size);
4330 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4333 CRL_INFO *info = (CRL_INFO *)buf;
4335 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4336 ok(info->cCRLEntry == 0, "Expected 0 CRL entries, got %d\n",
4338 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4339 "Wrong issuer size %d\n", info->Issuer.cbData);
4340 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4341 "Unexpected issuer\n");
4344 /* check decoding with an empty CRL entry */
4345 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4346 v1CRLWithIssuerAndEmptyEntry, v1CRLWithIssuerAndEmptyEntry[1] + 2,
4347 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4348 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4349 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4350 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4352 /* with a real CRL entry */
4353 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4354 v1CRLWithIssuerAndEntry, v1CRLWithIssuerAndEntry[1] + 2,
4355 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4356 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4359 CRL_INFO *info = (CRL_INFO *)buf;
4362 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4363 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4365 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4366 entry = info->rgCRLEntry;
4367 ok(entry->SerialNumber.cbData == 1,
4368 "Expected serial number size 1, got %d\n",
4369 entry->SerialNumber.cbData);
4370 ok(*entry->SerialNumber.pbData == *serialNum,
4371 "Expected serial number %d, got %d\n", *serialNum,
4372 *entry->SerialNumber.pbData);
4373 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4374 "Wrong issuer size %d\n", info->Issuer.cbData);
4375 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4376 "Unexpected issuer\n");
4379 /* a real CRL from verisign that has extensions */
4380 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4381 verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG,
4382 NULL, (BYTE *)&buf, &size);
4383 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4386 CRL_INFO *info = (CRL_INFO *)buf;
4389 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4390 ok(info->cCRLEntry == 3, "Expected 3 CRL entries, got %d\n",
4392 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4393 entry = info->rgCRLEntry;
4394 ok(info->cExtension == 2, "Expected 2 extensions, got %d\n",
4398 /* another real CRL from verisign that has lots of entries */
4399 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4400 verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries),
4401 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4402 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4405 CRL_INFO *info = (CRL_INFO *)buf;
4407 ok(size >= sizeof(CRL_INFO), "Got size %d\n", size);
4408 ok(info->cCRLEntry == 209, "Expected 209 CRL entries, got %d\n",
4410 ok(info->cExtension == 0, "Expected 0 extensions, got %d\n",
4414 /* and finally, with an extension */
4415 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4416 v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4417 NULL, (BYTE *)&buf, &size);
4418 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4421 CRL_INFO *info = (CRL_INFO *)buf;
4424 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4425 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4427 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4428 entry = info->rgCRLEntry;
4429 ok(entry->SerialNumber.cbData == 1,
4430 "Expected serial number size 1, got %d\n",
4431 entry->SerialNumber.cbData);
4432 ok(*entry->SerialNumber.pbData == *serialNum,
4433 "Expected serial number %d, got %d\n", *serialNum,
4434 *entry->SerialNumber.pbData);
4435 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4436 "Wrong issuer size %d\n", info->Issuer.cbData);
4437 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4438 "Unexpected issuer\n");
4439 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4443 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4444 v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4445 NULL, (BYTE *)&buf, &size);
4446 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4449 CRL_INFO *info = (CRL_INFO *)buf;
4451 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4455 /* And again, with an issuing dist point */
4456 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4457 v2CRLWithIssuingDistPoint, sizeof(v2CRLWithIssuingDistPoint),
4458 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4459 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4462 CRL_INFO *info = (CRL_INFO *)buf;
4464 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4470 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
4471 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
4472 static const BYTE encodedUsage[] = {
4473 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4474 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4475 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4477 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding)
4482 CERT_ENHKEY_USAGE usage;
4484 /* Test with empty usage */
4485 usage.cUsageIdentifier = 0;
4486 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4487 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4488 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4491 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
4492 ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n");
4495 /* Test with a few usages */
4496 usage.cUsageIdentifier = sizeof(keyUsages) / sizeof(keyUsages[0]);
4497 usage.rgpszUsageIdentifier = (LPSTR *)keyUsages;
4498 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4499 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4500 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4503 ok(size == sizeof(encodedUsage), "Wrong size %d\n", size);
4504 ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n");
4509 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding)
4515 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4516 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4517 (BYTE *)&buf, &size);
4518 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4521 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4523 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4524 "Wrong size %d\n", size);
4525 ok(usage->cUsageIdentifier == 0, "Expected 0 CRL entries, got %d\n",
4526 usage->cUsageIdentifier);
4529 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4530 encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL,
4531 (BYTE *)&buf, &size);
4532 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4535 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4538 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4539 "Wrong size %d\n", size);
4540 ok(usage->cUsageIdentifier == sizeof(keyUsages) / sizeof(keyUsages[0]),
4541 "Wrong CRL entries count %d\n", usage->cUsageIdentifier);
4542 for (i = 0; i < usage->cUsageIdentifier; i++)
4543 ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]),
4544 "Expected OID %s, got %s\n", keyUsages[i],
4545 usage->rgpszUsageIdentifier[i]);
4550 static BYTE keyId[] = { 1,2,3,4 };
4551 static const BYTE authorityKeyIdWithId[] = {
4552 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4553 static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4554 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4555 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4556 static const BYTE authorityKeyIdWithSerial[] = { 0x30,0x03,0x82,0x01,0x01 };
4558 static void test_encodeAuthorityKeyId(DWORD dwEncoding)
4560 CERT_AUTHORITY_KEY_ID_INFO info = { { 0 } };
4565 /* Test with empty id */
4566 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4567 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4568 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4571 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4572 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4575 /* With just a key id */
4576 info.KeyId.cbData = sizeof(keyId);
4577 info.KeyId.pbData = keyId;
4578 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4579 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4580 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4583 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", size);
4584 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4587 /* With just an issuer */
4588 info.KeyId.cbData = 0;
4589 info.CertIssuer.cbData = sizeof(encodedCommonName);
4590 info.CertIssuer.pbData = (BYTE *)encodedCommonName;
4591 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4592 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4593 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4596 ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %d\n",
4598 ok(!memcmp(buf, authorityKeyIdWithIssuer, size), "Unexpected value\n");
4601 /* With just a serial number */
4602 info.CertIssuer.cbData = 0;
4603 info.CertSerialNumber.cbData = sizeof(serialNum);
4604 info.CertSerialNumber.pbData = (BYTE *)serialNum;
4605 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4606 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4607 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4610 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4612 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4617 static void test_decodeAuthorityKeyId(DWORD dwEncoding)
4623 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4624 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4625 (BYTE *)&buf, &size);
4626 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4629 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4631 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4633 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4634 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4635 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4638 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4639 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4640 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4641 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4644 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4646 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4648 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4649 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4650 "Unexpected key id\n");
4651 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4652 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4655 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4656 authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer),
4657 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4658 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4661 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4663 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4665 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4666 ok(info->CertIssuer.cbData == sizeof(encodedCommonName),
4667 "Unexpected issuer len\n");
4668 ok(!memcmp(info->CertIssuer.pbData, encodedCommonName,
4669 sizeof(encodedCommonName)), "Unexpected issuer\n");
4670 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4673 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4674 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4675 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4676 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4679 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4681 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4683 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4684 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4685 ok(info->CertSerialNumber.cbData == sizeof(serialNum),
4686 "Unexpected serial number len\n");
4687 ok(!memcmp(info->CertSerialNumber.pbData, serialNum, sizeof(serialNum)),
4688 "Unexpected serial number\n");
4693 static const BYTE authorityKeyIdWithIssuerUrl[] = { 0x30,0x15,0xa1,0x13,0x86,
4694 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
4697 static void test_encodeAuthorityKeyId2(DWORD dwEncoding)
4699 CERT_AUTHORITY_KEY_ID2_INFO info = { { 0 } };
4700 CERT_ALT_NAME_ENTRY entry = { 0 };
4705 /* Test with empty id */
4706 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4707 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4708 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4711 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4712 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4715 /* With just a key id */
4716 info.KeyId.cbData = sizeof(keyId);
4717 info.KeyId.pbData = keyId;
4718 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4719 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4720 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4723 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n",
4725 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4728 /* With a bogus issuer name */
4729 info.KeyId.cbData = 0;
4730 info.AuthorityCertIssuer.cAltEntry = 1;
4731 info.AuthorityCertIssuer.rgAltEntry = &entry;
4732 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4733 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4734 ok(!ret && GetLastError() == E_INVALIDARG,
4735 "Expected E_INVALIDARG, got %08x\n", GetLastError());
4736 /* With an issuer name */
4737 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
4738 U(entry).pwszURL = (LPWSTR)url;
4739 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4740 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4741 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4744 ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %d\n",
4746 ok(!memcmp(buf, authorityKeyIdWithIssuerUrl, size),
4747 "Unexpected value\n");
4750 /* With just a serial number */
4751 info.AuthorityCertIssuer.cAltEntry = 0;
4752 info.AuthorityCertSerialNumber.cbData = sizeof(serialNum);
4753 info.AuthorityCertSerialNumber.pbData = (BYTE *)serialNum;
4754 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4755 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4756 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4759 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4761 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4766 static void test_decodeAuthorityKeyId2(DWORD dwEncoding)
4772 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4773 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4774 (BYTE *)&buf, &size);
4775 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4778 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4780 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4782 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4783 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4784 "Expected no issuer name entries\n");
4785 ok(info->AuthorityCertSerialNumber.cbData == 0,
4786 "Expected no serial number\n");
4789 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4790 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4791 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4792 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4795 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4797 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4799 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4800 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4801 "Unexpected key id\n");
4802 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4803 "Expected no issuer name entries\n");
4804 ok(info->AuthorityCertSerialNumber.cbData == 0,
4805 "Expected no serial number\n");
4808 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4809 authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl),
4810 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4811 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4814 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4816 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4818 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4819 ok(info->AuthorityCertIssuer.cAltEntry == 1,
4820 "Expected 1 issuer entry, got %d\n",
4821 info->AuthorityCertIssuer.cAltEntry);
4822 ok(info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice ==
4823 CERT_ALT_NAME_URL, "Expected CERT_ALT_NAME_URL, got %d\n",
4824 info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice);
4825 ok(!lstrcmpW(U(info->AuthorityCertIssuer.rgAltEntry[0]).pwszURL,
4826 url), "Unexpected URL\n");
4827 ok(info->AuthorityCertSerialNumber.cbData == 0,
4828 "Expected no serial number\n");
4831 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4832 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4833 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4834 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4837 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4839 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4841 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4842 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4843 "Expected no issuer name entries\n");
4844 ok(info->AuthorityCertSerialNumber.cbData == sizeof(serialNum),
4845 "Unexpected serial number len\n");
4846 ok(!memcmp(info->AuthorityCertSerialNumber.pbData, serialNum,
4847 sizeof(serialNum)), "Unexpected serial number\n");
4852 static const BYTE authorityInfoAccessWithUrl[] = {
4853 0x30,0x19,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
4854 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
4855 static const BYTE authorityInfoAccessWithUrlAndIPAddr[] = {
4856 0x30,0x29,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
4857 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x0e,0x06,
4858 0x02,0x2d,0x06,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
4860 static void test_encodeAuthorityInfoAccess(DWORD dwEncoding)
4862 static char oid1[] = "1.2.3";
4863 static char oid2[] = "1.5.6";
4867 CERT_ACCESS_DESCRIPTION accessDescription[2];
4868 CERT_AUTHORITY_INFO_ACCESS aia;
4870 memset(accessDescription, 0, sizeof(accessDescription));
4872 aia.rgAccDescr = NULL;
4873 /* Having no access descriptions is allowed */
4874 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4875 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4876 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4879 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
4880 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
4884 /* It can't have an empty access method */
4886 aia.rgAccDescr = accessDescription;
4887 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4888 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4889 ok(!ret && (GetLastError() == E_INVALIDARG ||
4890 GetLastError() == OSS_LIMITED /* Win9x */),
4891 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
4892 /* It can't have an empty location */
4893 accessDescription[0].pszAccessMethod = oid1;
4894 SetLastError(0xdeadbeef);
4895 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4896 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4897 ok(!ret && GetLastError() == E_INVALIDARG,
4898 "expected E_INVALIDARG, got %08x\n", GetLastError());
4899 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
4900 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
4901 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4902 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4903 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4906 ok(size == sizeof(authorityInfoAccessWithUrl), "unexpected size %d\n",
4908 ok(!memcmp(buf, authorityInfoAccessWithUrl, size),
4909 "unexpected value\n");
4913 accessDescription[1].pszAccessMethod = oid2;
4914 accessDescription[1].AccessLocation.dwAltNameChoice =
4915 CERT_ALT_NAME_IP_ADDRESS;
4916 U(accessDescription[1].AccessLocation).IPAddress.cbData =
4917 sizeof(encodedIPAddr);
4918 U(accessDescription[1].AccessLocation).IPAddress.pbData =
4919 (LPBYTE)encodedIPAddr;
4921 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4922 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4923 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4926 ok(size == sizeof(authorityInfoAccessWithUrlAndIPAddr),
4927 "unexpected size %d\n", size);
4928 ok(!memcmp(buf, authorityInfoAccessWithUrlAndIPAddr, size),
4929 "unexpected value\n");
4935 static void compareAuthorityInfoAccess(LPCSTR header,
4936 const CERT_AUTHORITY_INFO_ACCESS *expected,
4937 const CERT_AUTHORITY_INFO_ACCESS *got)
4941 ok(expected->cAccDescr == got->cAccDescr,
4942 "%s: expected %d access descriptions, got %d\n", header,
4943 expected->cAccDescr, got->cAccDescr);
4944 for (i = 0; i < expected->cAccDescr; i++)
4946 ok(!strcmp(expected->rgAccDescr[i].pszAccessMethod,
4947 got->rgAccDescr[i].pszAccessMethod), "%s[%d]: expected %s, got %s\n",
4948 header, i, expected->rgAccDescr[i].pszAccessMethod,
4949 got->rgAccDescr[i].pszAccessMethod);
4950 compareAltNameEntry(&expected->rgAccDescr[i].AccessLocation,
4951 &got->rgAccDescr[i].AccessLocation);
4955 static void test_decodeAuthorityInfoAccess(DWORD dwEncoding)
4957 static char oid1[] = "1.2.3";
4958 static char oid2[] = "1.5.6";
4963 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
4964 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4965 (BYTE *)&buf, &size);
4966 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4969 CERT_AUTHORITY_INFO_ACCESS aia = { 0, NULL };
4971 compareAuthorityInfoAccess("empty AIA", &aia,
4972 (CERT_AUTHORITY_INFO_ACCESS *)buf);
4976 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
4977 authorityInfoAccessWithUrl, sizeof(authorityInfoAccessWithUrl),
4978 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4979 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4982 CERT_ACCESS_DESCRIPTION accessDescription;
4983 CERT_AUTHORITY_INFO_ACCESS aia;
4985 accessDescription.pszAccessMethod = oid1;
4986 accessDescription.AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
4987 U(accessDescription.AccessLocation).pwszURL = (LPWSTR)url;
4989 aia.rgAccDescr = &accessDescription;
4990 compareAuthorityInfoAccess("AIA with URL", &aia,
4991 (CERT_AUTHORITY_INFO_ACCESS *)buf);
4995 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
4996 authorityInfoAccessWithUrlAndIPAddr,
4997 sizeof(authorityInfoAccessWithUrlAndIPAddr), CRYPT_DECODE_ALLOC_FLAG,
4998 NULL, (BYTE *)&buf, &size);
4999 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5002 CERT_ACCESS_DESCRIPTION accessDescription[2];
5003 CERT_AUTHORITY_INFO_ACCESS aia;
5005 accessDescription[0].pszAccessMethod = oid1;
5006 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5007 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
5008 accessDescription[1].pszAccessMethod = oid2;
5009 accessDescription[1].AccessLocation.dwAltNameChoice =
5010 CERT_ALT_NAME_IP_ADDRESS;
5011 U(accessDescription[1].AccessLocation).IPAddress.cbData =
5012 sizeof(encodedIPAddr);
5013 U(accessDescription[1].AccessLocation).IPAddress.pbData =
5014 (LPBYTE)encodedIPAddr;
5016 aia.rgAccDescr = accessDescription;
5017 compareAuthorityInfoAccess("AIA with URL and IP addr", &aia,
5018 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5024 static const BYTE emptyCTL[] = {
5025 0x30,0x17,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5026 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5027 static const BYTE emptyCTLWithVersion1[] = {
5028 0x30,0x1a,0x02,0x01,0x01,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5029 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5030 static const BYTE ctlWithUsageIdentifier[] = {
5031 0x30,0x1b,0x30,0x04,0x06,0x02,0x2a,0x03,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
5032 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5033 static const BYTE ctlWithListIdentifier[] = {
5034 0x30,0x1a,0x30,0x00,0x04,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5035 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5036 static const BYTE ctlWithSequenceNumber[] = {
5037 0x30,0x1a,0x30,0x00,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5038 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5039 static const BYTE ctlWithThisUpdate[] = {
5040 0x30,0x15,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5041 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5042 static const BYTE ctlWithThisAndNextUpdate[] = {
5043 0x30,0x24,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5044 0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5045 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5046 static const BYTE ctlWithAlgId[] = {
5047 0x30,0x1b,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5048 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5049 static const BYTE ctlWithBogusEntry[] = {
5050 0x30,0x29,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5051 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x10,0x30,0x0e,0x04,
5052 0x01,0x01,0x31,0x09,0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,0x01 };
5053 static const BYTE ctlWithOneEntry[] = {
5054 0x30,0x2a,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5055 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x11,0x30,0x0f,0x04,
5056 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00 };
5057 static const BYTE ctlWithTwoEntries[] = {
5058 0x30,0x41,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5059 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x28,0x30,0x0f,0x04,
5060 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00,0x30,
5061 0x15,0x04,0x01,0x01,0x31,0x10,0x30,0x0e,0x06,0x02,0x2d,0x06,0x31,0x08,0x30,
5062 0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5064 static void test_encodeCTL(DWORD dwEncoding)
5066 static char oid1[] = "1.2.3";
5067 static char oid2[] = "1.5.6";
5073 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5074 CTL_ENTRY ctlEntry[2];
5075 CRYPT_ATTRIBUTE attr1, attr2;
5076 CRYPT_ATTR_BLOB value1, value2;
5078 memset(&info, 0, sizeof(info));
5079 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5080 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5081 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5084 ok(size == sizeof(emptyCTL), "unexpected size %d\n", size);
5085 ok(!memcmp(buf, emptyCTL, size), "unexpected value\n");
5090 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5091 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5092 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5095 ok(size == sizeof(emptyCTLWithVersion1), "unexpected size %d\n", size);
5096 ok(!memcmp(buf, emptyCTLWithVersion1, size), "unexpected value\n");
5101 info.SubjectUsage.cUsageIdentifier = 1;
5102 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5103 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5104 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5105 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5108 ok(size == sizeof(ctlWithUsageIdentifier), "unexpected size %d\n",
5110 ok(!memcmp(buf, ctlWithUsageIdentifier, size), "unexpected value\n");
5114 info.SubjectUsage.cUsageIdentifier = 0;
5115 info.ListIdentifier.cbData = sizeof(serialNum);
5116 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5117 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5118 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5119 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5122 ok(size == sizeof(ctlWithListIdentifier), "unexpected size %d\n", size);
5123 ok(!memcmp(buf, ctlWithListIdentifier, size), "unexpected value\n");
5127 info.ListIdentifier.cbData = 0;
5128 info.SequenceNumber.cbData = sizeof(serialNum);
5129 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5130 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5131 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5132 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5135 ok(size == sizeof(ctlWithSequenceNumber), "unexpected size %d\n",
5137 ok(!memcmp(buf, ctlWithSequenceNumber, size), "unexpected value\n");
5141 info.SequenceNumber.cbData = 0;
5142 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5143 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5144 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5145 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5148 ok(size == sizeof(ctlWithThisUpdate), "unexpected size %d\n", size);
5149 ok(!memcmp(buf, ctlWithThisUpdate, size), "unexpected value\n");
5153 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5154 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5155 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5156 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5159 ok(size == sizeof(ctlWithThisAndNextUpdate), "unexpected size %d\n",
5161 ok(!memcmp(buf, ctlWithThisAndNextUpdate, size), "unexpected value\n");
5165 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5166 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5167 info.SubjectAlgorithm.pszObjId = oid2;
5168 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5169 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5170 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5173 ok(size == sizeof(ctlWithAlgId), "unexpected size %d\n", size);
5174 ok(!memcmp(buf, ctlWithAlgId, size), "unexpected value\n");
5178 /* The value is supposed to be asn.1 encoded, so this'll fail to decode
5179 * (see tests below) but it'll encode fine.
5181 info.SubjectAlgorithm.pszObjId = NULL;
5182 value1.cbData = sizeof(serialNum);
5183 value1.pbData = (LPBYTE)serialNum;
5184 attr1.pszObjId = oid1;
5186 attr1.rgValue = &value1;
5187 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5188 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5189 ctlEntry[0].cAttribute = 1;
5190 ctlEntry[0].rgAttribute = &attr1;
5192 info.rgCTLEntry = ctlEntry;
5193 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5194 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5195 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5198 ok(size == sizeof(ctlWithBogusEntry), "unexpected size %d\n", size);
5199 ok(!memcmp(buf, ctlWithBogusEntry, size), "unexpected value\n");
5203 value1.cbData = sizeof(emptySequence);
5204 value1.pbData = (LPBYTE)emptySequence;
5205 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5206 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5207 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5210 ok(size == sizeof(ctlWithOneEntry), "unexpected size %d\n", size);
5211 ok(!memcmp(buf, ctlWithOneEntry, size), "unexpected value\n");
5215 value2.cbData = sizeof(encodedIPAddr);
5216 value2.pbData = (LPBYTE)encodedIPAddr;
5217 attr2.pszObjId = oid2;
5219 attr2.rgValue = &value2;
5220 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5221 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5222 ctlEntry[1].cAttribute = 1;
5223 ctlEntry[1].rgAttribute = &attr2;
5225 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5226 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5227 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5230 ok(size == sizeof(ctlWithTwoEntries), "unexpected size %d\n", size);
5231 ok(!memcmp(buf, ctlWithTwoEntries, size), "unexpected value\n");
5237 static void compareCTLInfo(LPCSTR header, const CTL_INFO *expected,
5238 const CTL_INFO *got)
5242 ok(expected->dwVersion == got->dwVersion,
5243 "%s: expected version %d, got %d\n", header, expected->dwVersion,
5245 ok(expected->SubjectUsage.cUsageIdentifier ==
5246 got->SubjectUsage.cUsageIdentifier,
5247 "%s: expected %d usage identifiers, got %d\n", header,
5248 expected->SubjectUsage.cUsageIdentifier,
5249 got->SubjectUsage.cUsageIdentifier);
5250 for (i = 0; i < expected->SubjectUsage.cUsageIdentifier; i++)
5251 ok(!strcmp(expected->SubjectUsage.rgpszUsageIdentifier[i],
5252 got->SubjectUsage.rgpszUsageIdentifier[i]),
5253 "%s[%d]: expected %s, got %s\n", header, i,
5254 expected->SubjectUsage.rgpszUsageIdentifier[i],
5255 got->SubjectUsage.rgpszUsageIdentifier[i]);
5256 ok(expected->ListIdentifier.cbData == got->ListIdentifier.cbData,
5257 "%s: expected list identifier of %d bytes, got %d\n", header,
5258 expected->ListIdentifier.cbData, got->ListIdentifier.cbData);
5259 if (expected->ListIdentifier.cbData)
5260 ok(!memcmp(expected->ListIdentifier.pbData, got->ListIdentifier.pbData,
5261 expected->ListIdentifier.cbData),
5262 "%s: unexpected list identifier value\n", header);
5263 ok(expected->SequenceNumber.cbData == got->SequenceNumber.cbData,
5264 "%s: expected sequence number of %d bytes, got %d\n", header,
5265 expected->SequenceNumber.cbData, got->SequenceNumber.cbData);
5266 if (expected->SequenceNumber.cbData)
5267 ok(!memcmp(expected->SequenceNumber.pbData, got->SequenceNumber.pbData,
5268 expected->SequenceNumber.cbData),
5269 "%s: unexpected sequence number value\n", header);
5270 ok(!memcmp(&expected->ThisUpdate, &got->ThisUpdate, sizeof(FILETIME)),
5271 "%s: expected this update = (%d, %d), got (%d, %d)\n", header,
5272 expected->ThisUpdate.dwLowDateTime, expected->ThisUpdate.dwHighDateTime,
5273 got->ThisUpdate.dwLowDateTime, got->ThisUpdate.dwHighDateTime);
5274 ok(!memcmp(&expected->NextUpdate, &got->NextUpdate, sizeof(FILETIME)),
5275 "%s: expected next update = (%d, %d), got (%d, %d)\n", header,
5276 expected->NextUpdate.dwLowDateTime, expected->NextUpdate.dwHighDateTime,
5277 got->NextUpdate.dwLowDateTime, got->NextUpdate.dwHighDateTime);
5278 if (expected->SubjectAlgorithm.pszObjId &&
5279 *expected->SubjectAlgorithm.pszObjId && !got->SubjectAlgorithm.pszObjId)
5280 ok(0, "%s: expected subject algorithm %s, got NULL\n", header,
5281 expected->SubjectAlgorithm.pszObjId);
5282 if (expected->SubjectAlgorithm.pszObjId && got->SubjectAlgorithm.pszObjId)
5283 ok(!strcmp(expected->SubjectAlgorithm.pszObjId,
5284 got->SubjectAlgorithm.pszObjId),
5285 "%s: expected subject algorithm %s, got %s\n", header,
5286 expected->SubjectAlgorithm.pszObjId, got->SubjectAlgorithm.pszObjId);
5287 ok(expected->SubjectAlgorithm.Parameters.cbData ==
5288 got->SubjectAlgorithm.Parameters.cbData,
5289 "%s: expected subject algorithm parameters of %d bytes, got %d\n", header,
5290 expected->SubjectAlgorithm.Parameters.cbData,
5291 got->SubjectAlgorithm.Parameters.cbData);
5292 if (expected->SubjectAlgorithm.Parameters.cbData)
5293 ok(!memcmp(expected->SubjectAlgorithm.Parameters.pbData,
5294 got->SubjectAlgorithm.Parameters.pbData,
5295 expected->SubjectAlgorithm.Parameters.cbData),
5296 "%s: unexpected subject algorithm parameter value\n", header);
5297 ok(expected->cCTLEntry == got->cCTLEntry,
5298 "%s: expected %d CTL entries, got %d\n", header, expected->cCTLEntry,
5300 for (i = 0; i < expected->cCTLEntry; i++)
5302 ok(expected->rgCTLEntry[i].SubjectIdentifier.cbData ==
5303 got->rgCTLEntry[i].SubjectIdentifier.cbData,
5304 "%s[%d]: expected subject identifier of %d bytes, got %d\n",
5305 header, i, expected->rgCTLEntry[i].SubjectIdentifier.cbData,
5306 got->rgCTLEntry[i].SubjectIdentifier.cbData);
5307 if (expected->rgCTLEntry[i].SubjectIdentifier.cbData)
5308 ok(!memcmp(expected->rgCTLEntry[i].SubjectIdentifier.pbData,
5309 got->rgCTLEntry[i].SubjectIdentifier.pbData,
5310 expected->rgCTLEntry[i].SubjectIdentifier.cbData),
5311 "%s[%d]: unexpected subject identifier value\n",
5313 for (j = 0; j < expected->rgCTLEntry[i].cAttribute; j++)
5315 ok(!strcmp(expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5316 got->rgCTLEntry[i].rgAttribute[j].pszObjId),
5317 "%s[%d][%d]: expected attribute OID %s, got %s\n", header, i, j,
5318 expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5319 got->rgCTLEntry[i].rgAttribute[j].pszObjId);
5320 for (k = 0; k < expected->rgCTLEntry[i].rgAttribute[j].cValue; k++)
5322 ok(expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData ==
5323 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5324 "%s[%d][%d][%d]: expected value of %d bytes, got %d\n",
5326 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5327 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData);
5328 if (expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData)
5330 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5331 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5332 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData),
5333 "%s[%d][%d][%d]: unexpected value\n",
5338 ok(expected->cExtension == got->cExtension,
5339 "%s: expected %d extensions, got %d\n", header, expected->cExtension,
5341 for (i = 0; i < expected->cExtension; i++)
5343 ok(!strcmp(expected->rgExtension[i].pszObjId,
5344 got->rgExtension[i].pszObjId), "%s[%d]: expected %s, got %s\n",
5345 header, i, expected->rgExtension[i].pszObjId,
5346 got->rgExtension[i].pszObjId);
5347 ok(expected->rgExtension[i].fCritical == got->rgExtension[i].fCritical,
5348 "%s[%d]: expected fCritical = %d, got %d\n", header, i,
5349 expected->rgExtension[i].fCritical, got->rgExtension[i].fCritical);
5350 ok(expected->rgExtension[i].Value.cbData ==
5351 got->rgExtension[i].Value.cbData,
5352 "%s[%d]: expected extension value to have %d bytes, got %d\n",
5353 header, i, expected->rgExtension[i].Value.cbData,
5354 got->rgExtension[i].Value.cbData);
5355 if (expected->rgExtension[i].Value.cbData)
5356 ok(!memcmp(expected->rgExtension[i].Value.pbData,
5357 got->rgExtension[i].Value.pbData,
5358 expected->rgExtension[i].Value.cbData),
5359 "%s[%d]: unexpected extension value\n", header, i);
5363 static const BYTE signedCTL[] = {
5364 0x30,0x81,0xc7,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
5365 0x81,0xb9,0x30,0x81,0xb6,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
5366 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x28,0x06,0x09,0x2a,0x86,
5367 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x1b,0x04,0x19,0x30,0x17,0x30,0x00,
5368 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5369 0x30,0x5a,0x30,0x02,0x06,0x00,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
5370 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
5371 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
5372 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5373 0x00,0x04,0x40,0xca,0xd8,0x32,0xd1,0xbd,0x97,0x61,0x54,0xd6,0x80,0xcf,0x0d,
5374 0xbd,0xa2,0x42,0xc7,0xca,0x37,0x91,0x7d,0x9d,0xac,0x8c,0xdf,0x05,0x8a,0x39,
5375 0xc6,0x07,0xc1,0x37,0xe6,0xb9,0xd1,0x0d,0x26,0xec,0xa5,0xb0,0x8a,0x51,0x26,
5376 0x2b,0x4f,0x73,0x44,0x86,0x83,0x5e,0x2b,0x6e,0xcc,0xf8,0x1b,0x85,0x53,0xe9,
5377 0x7a,0x80,0x8f,0x6b,0x42,0x19,0x93 };
5378 static const BYTE signedCTLWithCTLInnerContent[] = {
5379 0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
5380 0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
5381 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
5382 0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
5383 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5384 0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
5385 0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
5386 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
5387 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
5388 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
5389 0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
5390 0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
5391 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
5392 0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5393 0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
5394 0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
5395 0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
5396 0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
5397 0x57,0x6c,0x0b,0x47,0xb8 };
5399 static void test_decodeCTL(DWORD dwEncoding)
5401 static char oid1[] = "1.2.3";
5402 static char oid2[] = "1.5.6";
5403 static BYTE nullData[] = { 5,0 };
5409 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5410 CTL_ENTRY ctlEntry[2];
5411 CRYPT_ATTRIBUTE attr1, attr2;
5412 CRYPT_ATTR_BLOB value1, value2;
5414 memset(&info, 0, sizeof(info));
5415 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTL, sizeof(emptyCTL),
5416 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5417 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5420 compareCTLInfo("empty CTL", &info, (CTL_INFO *)buf);
5425 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTLWithVersion1,
5426 sizeof(emptyCTLWithVersion1), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
5428 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5431 compareCTLInfo("v1 CTL", &info, (CTL_INFO *)buf);
5436 info.SubjectUsage.cUsageIdentifier = 1;
5437 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5438 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithUsageIdentifier,
5439 sizeof(ctlWithUsageIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5440 (BYTE *)&buf, &size);
5441 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5444 compareCTLInfo("CTL with usage identifier", &info, (CTL_INFO *)buf);
5448 info.SubjectUsage.cUsageIdentifier = 0;
5449 info.ListIdentifier.cbData = sizeof(serialNum);
5450 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5451 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithListIdentifier,
5452 sizeof(ctlWithListIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5453 (BYTE *)&buf, &size);
5454 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5457 compareCTLInfo("CTL with list identifier", &info, (CTL_INFO *)buf);
5461 info.ListIdentifier.cbData = 0;
5462 info.SequenceNumber.cbData = sizeof(serialNum);
5463 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5464 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithSequenceNumber,
5465 sizeof(ctlWithSequenceNumber), CRYPT_DECODE_ALLOC_FLAG, NULL,
5466 (BYTE *)&buf, &size);
5467 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5470 compareCTLInfo("CTL with sequence number", &info, (CTL_INFO *)buf);
5474 info.SequenceNumber.cbData = 0;
5475 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5476 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisUpdate,
5477 sizeof(ctlWithThisUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5478 (BYTE *)&buf, &size);
5479 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5482 compareCTLInfo("CTL with this update", &info, (CTL_INFO *)buf);
5486 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5487 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisAndNextUpdate,
5488 sizeof(ctlWithThisAndNextUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5489 (BYTE *)&buf, &size);
5490 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5493 compareCTLInfo("CTL with this and next update", &info, (CTL_INFO *)buf);
5497 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5498 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5499 info.SubjectAlgorithm.pszObjId = oid2;
5500 info.SubjectAlgorithm.Parameters.cbData = sizeof(nullData);
5501 info.SubjectAlgorithm.Parameters.pbData = nullData;
5502 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithAlgId,
5503 sizeof(ctlWithAlgId), CRYPT_DECODE_ALLOC_FLAG, NULL,
5504 (BYTE *)&buf, &size);
5505 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5508 compareCTLInfo("CTL with algorithm identifier", &info, (CTL_INFO *)buf);
5512 SetLastError(0xdeadbeef);
5513 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithBogusEntry,
5514 sizeof(ctlWithBogusEntry), CRYPT_DECODE_ALLOC_FLAG, NULL,
5515 (BYTE *)&buf, &size);
5516 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD || CRYPT_E_ASN1_CORRUPT),
5517 "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n",
5519 info.SubjectAlgorithm.Parameters.cbData = 0;
5520 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5521 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5522 info.SubjectAlgorithm.pszObjId = oid2;
5523 info.SubjectAlgorithm.pszObjId = NULL;
5524 value1.cbData = sizeof(emptySequence);
5525 value1.pbData = (LPBYTE)emptySequence;
5526 attr1.pszObjId = oid1;
5528 attr1.rgValue = &value1;
5529 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5530 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5531 ctlEntry[0].cAttribute = 1;
5532 ctlEntry[0].rgAttribute = &attr1;
5534 info.rgCTLEntry = ctlEntry;
5535 SetLastError(0xdeadbeef);
5536 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithOneEntry,
5537 sizeof(ctlWithOneEntry), CRYPT_DECODE_ALLOC_FLAG, NULL,
5538 (BYTE *)&buf, &size);
5539 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5542 compareCTLInfo("CTL with one entry", &info, (CTL_INFO *)buf);
5546 value2.cbData = sizeof(encodedIPAddr);
5547 value2.pbData = (LPBYTE)encodedIPAddr;
5548 attr2.pszObjId = oid2;
5550 attr2.rgValue = &value2;
5551 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5552 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5553 ctlEntry[1].cAttribute = 1;
5554 ctlEntry[1].rgAttribute = &attr2;
5556 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithTwoEntries,
5557 sizeof(ctlWithTwoEntries), CRYPT_DECODE_ALLOC_FLAG, NULL,
5558 (BYTE *)&buf, &size);
5559 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5562 compareCTLInfo("CTL with two entries", &info, (CTL_INFO *)buf);
5566 /* A signed CTL isn't decodable, even if the inner content is a CTL */
5567 SetLastError(0xdeadbeef);
5568 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, signedCTL,
5569 sizeof(signedCTL), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5570 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5571 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5572 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5574 SetLastError(0xdeadbeef);
5575 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL,
5576 signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent),
5577 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5578 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5579 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5580 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5584 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
5585 static const BYTE emptyPKCSContentInfoExtraBytes[] = { 0x30,0x04,0x06,0x02,0x2a,
5587 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
5589 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
5590 0x03,0x02,0x01,0x01 };
5591 static BYTE bogusDER[] = { 1 };
5593 static void test_encodePKCSContentInfo(DWORD dwEncoding)
5598 CRYPT_CONTENT_INFO info = { 0 };
5599 char oid1[] = "1.2.3";
5603 /* Crashes on win9x */
5604 SetLastError(0xdeadbeef);
5605 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL,
5606 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5607 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5608 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5610 SetLastError(0xdeadbeef);
5611 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5612 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5613 ok(!ret && (GetLastError() == E_INVALIDARG ||
5614 GetLastError() == OSS_LIMITED /* Win9x */),
5615 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5616 info.pszObjId = oid1;
5617 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5618 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5619 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5622 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size);
5623 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n");
5626 info.Content.pbData = bogusDER;
5627 info.Content.cbData = sizeof(bogusDER);
5628 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5629 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5630 ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError());
5633 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size);
5634 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n");
5637 info.Content.pbData = (BYTE *)ints[0].encoded;
5638 info.Content.cbData = ints[0].encoded[1] + 2;
5639 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5640 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5643 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size);
5644 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n");
5649 static const BYTE indefiniteSignedPKCSContent[] = {
5650 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
5651 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
5652 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
5653 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
5654 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
5655 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
5656 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5657 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5658 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
5659 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5660 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5661 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
5662 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
5663 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
5664 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
5665 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
5666 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
5667 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
5668 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
5669 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5670 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5671 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
5672 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
5673 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
5674 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
5675 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
5676 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
5677 0x00,0x00,0x00,0x00,0x00,0x00 };
5679 static void test_decodePKCSContentInfo(DWORD dwEncoding)
5684 CRYPT_CONTENT_INFO *info;
5686 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5687 emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo),
5688 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5689 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5692 info = (CRYPT_CONTENT_INFO *)buf;
5694 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5696 ok(info->Content.cbData == 0, "Expected no data, got %d\n",
5697 info->Content.cbData);
5700 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5701 emptyPKCSContentInfoExtraBytes, sizeof(emptyPKCSContentInfoExtraBytes),
5702 0, NULL, NULL, &size);
5703 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5704 SetLastError(0xdeadbeef);
5705 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5706 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo),
5707 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5708 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5709 * I doubt an app depends on that.
5711 ok((!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5712 GetLastError() == CRYPT_E_ASN1_CORRUPT)) || broken(ret),
5713 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5715 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5716 intPKCSContentInfo, sizeof(intPKCSContentInfo),
5717 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5718 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5721 info = (CRYPT_CONTENT_INFO *)buf;
5723 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5725 ok(info->Content.cbData == ints[0].encoded[1] + 2,
5726 "Unexpected size %d\n", info->Content.cbData);
5727 ok(!memcmp(info->Content.pbData, ints[0].encoded,
5728 info->Content.cbData), "Unexpected value\n");
5731 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5732 indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent),
5733 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5734 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5737 info = (CRYPT_CONTENT_INFO *)buf;
5739 ok(!strcmp(info->pszObjId, szOID_RSA_signedData),
5740 "Expected %s, got %s\n", szOID_RSA_signedData, info->pszObjId);
5741 ok(info->Content.cbData == 392, "Expected 392, got %d\n",
5742 info->Content.cbData);
5747 static const BYTE emptyPKCSAttr[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
5749 static const BYTE bogusPKCSAttr[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
5751 static const BYTE intPKCSAttr[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
5754 static void test_encodePKCSAttribute(DWORD dwEncoding)
5756 CRYPT_ATTRIBUTE attr = { 0 };
5760 CRYPT_ATTR_BLOB blob;
5761 char oid[] = "1.2.3";
5765 /* Crashes on win9x */
5766 SetLastError(0xdeadbeef);
5767 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, NULL,
5768 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5769 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5770 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5772 SetLastError(0xdeadbeef);
5773 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5774 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5775 ok(!ret && (GetLastError() == E_INVALIDARG ||
5776 GetLastError() == OSS_LIMITED /* Win9x */),
5777 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5778 attr.pszObjId = oid;
5779 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5780 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5781 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5784 ok(size == sizeof(emptyPKCSAttr), "Unexpected size %d\n", size);
5785 ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n");
5788 blob.cbData = sizeof(bogusDER);
5789 blob.pbData = bogusDER;
5791 attr.rgValue = &blob;
5792 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5793 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5794 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5797 ok(size == sizeof(bogusPKCSAttr), "Unexpected size %d\n", size);
5798 ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n");
5801 blob.pbData = (BYTE *)ints[0].encoded;
5802 blob.cbData = ints[0].encoded[1] + 2;
5803 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5804 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5807 ok(size == sizeof(intPKCSAttr), "Unexpected size %d\n", size);
5808 ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n");
5813 static void test_decodePKCSAttribute(DWORD dwEncoding)
5818 CRYPT_ATTRIBUTE *attr;
5820 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5821 emptyPKCSAttr, sizeof(emptyPKCSAttr),
5822 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5823 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5826 attr = (CRYPT_ATTRIBUTE *)buf;
5828 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5830 ok(attr->cValue == 0, "Expected no value, got %d\n", attr->cValue);
5833 SetLastError(0xdeadbeef);
5834 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5835 bogusPKCSAttr, sizeof(bogusPKCSAttr),
5836 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5837 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5838 * I doubt an app depends on that.
5840 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5841 GetLastError() == CRYPT_E_ASN1_CORRUPT || OSS_MORE_INPUT /* Win9x */),
5842 "Expected CRYPT_E_ASN1_EOD, CRYPT_E_ASN1_CORRUPT, or OSS_MORE_INPUT, got %x\n",
5844 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5845 intPKCSAttr, sizeof(intPKCSAttr),
5846 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5847 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5850 attr = (CRYPT_ATTRIBUTE *)buf;
5852 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5854 ok(attr->cValue == 1, "Expected 1 value, got %d\n", attr->cValue);
5855 ok(attr->rgValue[0].cbData == ints[0].encoded[1] + 2,
5856 "Unexpected size %d\n", attr->rgValue[0].cbData);
5857 ok(!memcmp(attr->rgValue[0].pbData, ints[0].encoded,
5858 attr->rgValue[0].cbData), "Unexpected value\n");
5863 static const BYTE emptyPKCSAttributes[] = { 0x31,0x00 };
5864 static const BYTE singlePKCSAttributes[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
5865 0x2a,0x03,0x31,0x00 };
5866 static const BYTE doublePKCSAttributes[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
5867 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
5869 static void test_encodePKCSAttributes(DWORD dwEncoding)
5871 CRYPT_ATTRIBUTES attributes = { 0 };
5872 CRYPT_ATTRIBUTE attr[2] = { { 0 } };
5873 CRYPT_ATTR_BLOB blob;
5877 char oid1[] = "1.2.3", oid2[] = "1.5.6";
5879 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5880 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5881 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5884 ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %d\n", size);
5885 ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n");
5888 attributes.cAttr = 1;
5889 attributes.rgAttr = attr;
5890 SetLastError(0xdeadbeef);
5891 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5892 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5893 ok(!ret && (GetLastError() == E_INVALIDARG ||
5894 GetLastError() == OSS_LIMITED /* Win9x */),
5895 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
5896 attr[0].pszObjId = oid1;
5897 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5898 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5901 ok(size == sizeof(singlePKCSAttributes), "Unexpected size %d\n", size);
5902 ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n");
5905 attr[1].pszObjId = oid2;
5907 attr[1].rgValue = &blob;
5908 blob.pbData = (BYTE *)ints[0].encoded;
5909 blob.cbData = ints[0].encoded[1] + 2;
5910 attributes.cAttr = 2;
5911 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5912 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5913 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5916 ok(size == sizeof(doublePKCSAttributes), "Unexpected size %d\n", size);
5917 ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n");
5922 static void test_decodePKCSAttributes(DWORD dwEncoding)
5927 CRYPT_ATTRIBUTES *attributes;
5929 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5930 emptyPKCSAttributes, sizeof(emptyPKCSAttributes),
5931 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5932 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5935 attributes = (CRYPT_ATTRIBUTES *)buf;
5936 ok(attributes->cAttr == 0, "Expected no attributes, got %d\n",
5940 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5941 singlePKCSAttributes, sizeof(singlePKCSAttributes),
5942 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5943 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5946 attributes = (CRYPT_ATTRIBUTES *)buf;
5947 ok(attributes->cAttr == 1, "Expected 1 attribute, got %d\n",
5949 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5950 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5951 ok(attributes->rgAttr[0].cValue == 0,
5952 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5955 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5956 doublePKCSAttributes, sizeof(doublePKCSAttributes),
5957 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5958 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5961 attributes = (CRYPT_ATTRIBUTES *)buf;
5962 ok(attributes->cAttr == 2, "Expected 2 attributes, got %d\n",
5964 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5965 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5966 ok(attributes->rgAttr[0].cValue == 0,
5967 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5968 ok(!strcmp(attributes->rgAttr[1].pszObjId, "1.5.6"),
5969 "Expected 1.5.6, got %s\n", attributes->rgAttr[1].pszObjId);
5970 ok(attributes->rgAttr[1].cValue == 1,
5971 "Expected 1 attribute, got %d\n", attributes->rgAttr[1].cValue);
5972 ok(attributes->rgAttr[1].rgValue[0].cbData == ints[0].encoded[1] + 2,
5973 "Unexpected size %d\n", attributes->rgAttr[1].rgValue[0].cbData);
5974 ok(!memcmp(attributes->rgAttr[1].rgValue[0].pbData, ints[0].encoded,
5975 attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n");
5980 static const BYTE singleCapability[] = {
5981 0x30,0x06,0x30,0x04,0x06,0x02,0x2d,0x06 };
5982 static const BYTE twoCapabilities[] = {
5983 0x30,0x0c,0x30,0x04,0x06,0x02,0x2d,0x06,0x30,0x04,0x06,0x02,0x2a,0x03 };
5984 static const BYTE singleCapabilitywithNULL[] = {
5985 0x30,0x08,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5987 static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding)
5989 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
5993 CRYPT_SMIME_CAPABILITY capability[2];
5994 CRYPT_SMIME_CAPABILITIES capabilities;
5996 /* An empty capabilities is allowed */
5997 capabilities.cCapability = 0;
5998 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
5999 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6000 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6003 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
6004 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
6007 /* A non-empty capabilities with an empty capability (lacking an OID) is
6010 capability[0].pszObjId = NULL;
6011 capability[0].Parameters.cbData = 0;
6012 capabilities.cCapability = 1;
6013 capabilities.rgCapability = capability;
6014 SetLastError(0xdeadbeef);
6015 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6016 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6017 ok(!ret && (GetLastError() == E_INVALIDARG ||
6018 GetLastError() == OSS_LIMITED /* Win9x */),
6019 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6020 capability[0].pszObjId = oid1;
6021 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6022 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6023 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6026 ok(size == sizeof(singleCapability), "unexpected size %d\n", size);
6027 ok(!memcmp(buf, singleCapability, size), "unexpected value\n");
6030 capability[1].pszObjId = oid2;
6031 capability[1].Parameters.cbData = 0;
6032 capabilities.cCapability = 2;
6033 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6034 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6035 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6038 ok(size == sizeof(twoCapabilities), "unexpected size %d\n", size);
6039 ok(!memcmp(buf, twoCapabilities, size), "unexpected value\n");
6044 static void compareSMimeCapabilities(LPCSTR header,
6045 const CRYPT_SMIME_CAPABILITIES *expected, const CRYPT_SMIME_CAPABILITIES *got)
6049 ok(got->cCapability == expected->cCapability,
6050 "%s: expected %d capabilities, got %d\n", header, expected->cCapability,
6052 for (i = 0; i < expected->cCapability; i++)
6054 ok(!strcmp(expected->rgCapability[i].pszObjId,
6055 got->rgCapability[i].pszObjId), "%s[%d]: expected %s, got %s\n",
6056 header, i, expected->rgCapability[i].pszObjId,
6057 got->rgCapability[i].pszObjId);
6058 ok(expected->rgCapability[i].Parameters.cbData ==
6059 got->rgCapability[i].Parameters.cbData,
6060 "%s[%d]: expected %d bytes, got %d\n", header, i,
6061 expected->rgCapability[i].Parameters.cbData,
6062 got->rgCapability[i].Parameters.cbData);
6063 if (expected->rgCapability[i].Parameters.cbData)
6064 ok(!memcmp(expected->rgCapability[i].Parameters.pbData,
6065 got->rgCapability[i].Parameters.pbData,
6066 expected->rgCapability[i].Parameters.cbData),
6067 "%s[%d]: unexpected value\n", header, i);
6071 static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding)
6073 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6076 CRYPT_SMIME_CAPABILITY capability[2];
6077 CRYPT_SMIME_CAPABILITIES capabilities, *ptr;
6079 SetLastError(0xdeadbeef);
6080 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6081 emptySequence, sizeof(emptySequence),
6082 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&ptr, &size);
6083 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6086 capabilities.cCapability = 0;
6087 compareSMimeCapabilities("empty capabilities", &capabilities, ptr);
6090 SetLastError(0xdeadbeef);
6091 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6092 singleCapability, sizeof(singleCapability), CRYPT_DECODE_ALLOC_FLAG, NULL,
6093 (BYTE *)&ptr, &size);
6094 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6097 capability[0].pszObjId = oid1;
6098 capability[0].Parameters.cbData = 0;
6099 capabilities.cCapability = 1;
6100 capabilities.rgCapability = capability;
6101 compareSMimeCapabilities("single capability", &capabilities, ptr);
6104 SetLastError(0xdeadbeef);
6105 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6106 singleCapabilitywithNULL, sizeof(singleCapabilitywithNULL),
6107 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&ptr, &size);
6108 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6111 BYTE NULLparam[] = {0x05, 0x00};
6112 capability[0].pszObjId = oid1;
6113 capability[0].Parameters.cbData = 2;
6114 capability[0].Parameters.pbData = NULLparam;
6115 capabilities.cCapability = 1;
6116 capabilities.rgCapability = capability;
6117 compareSMimeCapabilities("single capability with NULL", &capabilities,
6121 SetLastError(0xdeadbeef);
6122 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6123 twoCapabilities, sizeof(twoCapabilities), CRYPT_DECODE_ALLOC_FLAG, NULL,
6124 (BYTE *)&ptr, &size);
6125 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6128 capability[0].Parameters.cbData = 0;
6129 capability[1].pszObjId = oid2;
6130 capability[1].Parameters.cbData = 0;
6131 capabilities.cCapability = 2;
6132 compareSMimeCapabilities("two capabilities", &capabilities, ptr);
6137 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
6138 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
6140 static const BYTE minimalPKCSSigner[] = {
6141 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6142 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6143 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6144 static const BYTE PKCSSignerWithSerial[] = {
6145 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6146 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6147 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
6149 static const BYTE PKCSSignerWithHashAlgo[] = {
6150 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6151 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6152 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
6154 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = {
6155 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6156 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6157 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6158 0x06,0x05,0x00,0x04,0x00 };
6159 static const BYTE PKCSSignerWithHash[] = {
6160 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6161 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6162 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6163 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
6164 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6165 static const BYTE PKCSSignerWithAuthAttr[] = {
6166 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6167 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6168 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
6169 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
6170 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
6171 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
6172 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6174 static void test_encodePKCSSignerInfo(DWORD dwEncoding)
6176 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6180 CMSG_SIGNER_INFO info = { 0 };
6181 char oid_common_name[] = szOID_COMMON_NAME;
6182 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
6183 (LPBYTE)encodedCommonName };
6184 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
6186 SetLastError(0xdeadbeef);
6187 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6188 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6189 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6191 skip("no PKCS7_SIGNER_INFO encode support\n");
6194 ok(!ret && (GetLastError() == E_INVALIDARG ||
6195 GetLastError() == OSS_LIMITED /* Win9x */),
6196 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6197 /* To be encoded, a signer must have an issuer at least, and the encoding
6198 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
6199 * see decoding tests.)
6201 info.Issuer.cbData = sizeof(encodedCommonNameNoNull);
6202 info.Issuer.pbData = encodedCommonNameNoNull;
6203 SetLastError(0xdeadbeef);
6204 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6205 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6206 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6207 ok(!ret && GetLastError() == E_INVALIDARG,
6208 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6211 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6212 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6215 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6216 if (size == sizeof(minimalPKCSSigner))
6217 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6219 ok(0, "Unexpected value\n");
6223 info.SerialNumber.cbData = sizeof(serialNum);
6224 info.SerialNumber.pbData = (BYTE *)serialNum;
6225 SetLastError(0xdeadbeef);
6226 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6227 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6228 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6229 ok(!ret && GetLastError() == E_INVALIDARG,
6230 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6233 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6234 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6237 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6239 if (size == sizeof(PKCSSignerWithSerial))
6240 ok(!memcmp(buf, PKCSSignerWithSerial, size),
6241 "Unexpected value\n");
6243 ok(0, "Unexpected value\n");
6247 info.HashAlgorithm.pszObjId = oid1;
6248 SetLastError(0xdeadbeef);
6249 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6250 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6251 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6252 ok(!ret && GetLastError() == E_INVALIDARG,
6253 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6256 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6257 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6260 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6262 if (size == sizeof(PKCSSignerWithHashAlgo))
6263 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6264 "Unexpected value\n");
6266 ok(0, "Unexpected value\n");
6270 info.HashEncryptionAlgorithm.pszObjId = oid2;
6271 SetLastError(0xdeadbeef);
6272 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6273 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6274 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6275 ok(!ret && GetLastError() == E_INVALIDARG,
6276 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6279 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6282 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6283 "Unexpected size %d\n", size);
6284 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo))
6285 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6286 "Unexpected value\n");
6288 ok(0, "Unexpected value\n");
6292 info.EncryptedHash.cbData = sizeof(hash);
6293 info.EncryptedHash.pbData = (BYTE *)hash;
6294 SetLastError(0xdeadbeef);
6295 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6296 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6297 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6298 ok(!ret && GetLastError() == E_INVALIDARG,
6299 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6302 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6305 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6307 if (size == sizeof(PKCSSignerWithHash))
6308 ok(!memcmp(buf, PKCSSignerWithHash, size),
6309 "Unexpected value\n");
6311 ok(0, "Unexpected value\n");
6315 info.AuthAttrs.cAttr = 1;
6316 info.AuthAttrs.rgAttr = &attr;
6317 SetLastError(0xdeadbeef);
6318 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6319 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6320 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6321 ok(!ret && GetLastError() == E_INVALIDARG,
6322 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6325 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6328 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
6330 if (size == sizeof(PKCSSignerWithAuthAttr))
6331 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
6332 "Unexpected value\n");
6334 ok(0, "Unexpected value\n");
6340 static void test_decodePKCSSignerInfo(DWORD dwEncoding)
6345 CMSG_SIGNER_INFO *info;
6347 /* A PKCS signer can't be decoded without a serial number. */
6348 SetLastError(0xdeadbeef);
6349 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6350 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6351 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6352 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
6353 GetLastError() == OSS_DATA_ERROR /* Win9x */),
6354 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %x\n",
6356 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6357 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6358 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6359 ok(ret || broken(GetLastError() == OSS_DATA_ERROR),
6360 "CryptDecodeObjectEx failed: %x\n", GetLastError());
6363 info = (CMSG_SIGNER_INFO *)buf;
6364 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6366 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6367 "Unexpected size %d\n", info->Issuer.cbData);
6368 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6369 info->Issuer.cbData), "Unexpected value\n");
6370 ok(info->SerialNumber.cbData == sizeof(serialNum),
6371 "Unexpected size %d\n", info->SerialNumber.cbData);
6372 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6373 "Unexpected value\n");
6376 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6377 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6378 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6381 info = (CMSG_SIGNER_INFO *)buf;
6382 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6384 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6385 "Unexpected size %d\n", info->Issuer.cbData);
6386 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6387 info->Issuer.cbData), "Unexpected value\n");
6388 ok(info->SerialNumber.cbData == sizeof(serialNum),
6389 "Unexpected size %d\n", info->SerialNumber.cbData);
6390 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6391 "Unexpected value\n");
6392 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6393 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6396 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6397 PKCSSignerWithHashAndEncryptionAlgo,
6398 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6399 NULL, (BYTE *)&buf, &size);
6402 info = (CMSG_SIGNER_INFO *)buf;
6403 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6405 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6406 "Unexpected size %d\n", info->Issuer.cbData);
6407 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6408 info->Issuer.cbData), "Unexpected value\n");
6409 ok(info->SerialNumber.cbData == sizeof(serialNum),
6410 "Unexpected size %d\n", info->SerialNumber.cbData);
6411 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6412 "Unexpected value\n");
6413 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6414 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6415 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6416 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6419 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6420 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6421 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6424 info = (CMSG_SIGNER_INFO *)buf;
6425 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6427 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6428 "Unexpected size %d\n", info->Issuer.cbData);
6429 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6430 info->Issuer.cbData), "Unexpected value\n");
6431 ok(info->SerialNumber.cbData == sizeof(serialNum),
6432 "Unexpected size %d\n", info->SerialNumber.cbData);
6433 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6434 "Unexpected value\n");
6435 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6436 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6437 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6438 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6439 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6440 info->EncryptedHash.cbData);
6441 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6442 "Unexpected value\n");
6445 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6446 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
6447 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6450 info = (CMSG_SIGNER_INFO *)buf;
6451 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n",
6452 info->AuthAttrs.cAttr);
6453 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
6454 "Expected %s, got %s\n", szOID_COMMON_NAME,
6455 info->AuthAttrs.rgAttr[0].pszObjId);
6456 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
6457 info->AuthAttrs.rgAttr[0].cValue);
6458 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
6459 sizeof(encodedCommonName), "Unexpected size %d\n",
6460 info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
6461 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
6462 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
6467 static const BYTE CMSSignerWithKeyId[] = {
6468 0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,
6469 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6471 static void test_encodeCMSSignerInfo(DWORD dwEncoding)
6476 CMSG_CMS_SIGNER_INFO info = { 0 };
6477 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6479 SetLastError(0xdeadbeef);
6480 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6481 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6482 ok(!ret, "Expected failure, got %d\n", ret);
6483 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6485 skip("no CMS_SIGNER_INFO encode support\n");
6488 ok(GetLastError() == E_INVALIDARG,
6489 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6490 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6491 SetLastError(0xdeadbeef);
6492 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6493 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6494 ok(!ret, "Expected failure, got %d\n", ret);
6495 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6497 skip("no CMS_SIGNER_INFO encode support\n");
6500 ok(GetLastError() == E_INVALIDARG,
6501 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6502 /* To be encoded, a signer must have a valid cert ID, where a valid ID may
6503 * be a key id or a issuer serial number with at least the issuer set, and
6504 * the encoding must include PKCS_7_ASN_ENCODING.
6505 * (That isn't enough to be decoded, see decoding tests.)
6507 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6508 sizeof(encodedCommonNameNoNull);
6509 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6510 SetLastError(0xdeadbeef);
6511 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6512 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6513 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6514 ok(!ret && GetLastError() == E_INVALIDARG,
6515 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6518 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6521 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6522 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6526 U(info.SignerId).IssuerSerialNumber.SerialNumber.cbData = sizeof(serialNum);
6527 U(info.SignerId).IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
6528 SetLastError(0xdeadbeef);
6529 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6530 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6531 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6532 ok(!ret && GetLastError() == E_INVALIDARG,
6533 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6536 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6539 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6541 ok(!memcmp(buf, PKCSSignerWithSerial, size), "Unexpected value\n");
6545 info.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
6546 U(info.SignerId).KeyId.cbData = sizeof(serialNum);
6547 U(info.SignerId).KeyId.pbData = (BYTE *)serialNum;
6548 SetLastError(0xdeadbeef);
6549 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6550 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6551 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6552 ok(!ret && GetLastError() == E_INVALIDARG,
6553 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6556 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6559 ok(size == sizeof(CMSSignerWithKeyId), "Unexpected size %d\n",
6561 ok(!memcmp(buf, CMSSignerWithKeyId, size), "Unexpected value\n");
6565 /* While a CERT_ID can have a hash type, that's not allowed in CMS, where
6566 * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed
6567 * (see RFC 3852, section 5.3.)
6569 info.SignerId.dwIdChoice = CERT_ID_SHA1_HASH;
6570 U(info.SignerId).HashId.cbData = sizeof(hash);
6571 U(info.SignerId).HashId.pbData = (BYTE *)hash;
6572 SetLastError(0xdeadbeef);
6573 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6574 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6575 ok(!ret && GetLastError() == E_INVALIDARG,
6576 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6577 /* Now with a hash algo */
6578 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6579 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6580 sizeof(encodedCommonNameNoNull);
6581 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6582 info.HashAlgorithm.pszObjId = oid1;
6583 SetLastError(0xdeadbeef);
6584 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6585 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6586 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6587 ok(!ret && GetLastError() == E_INVALIDARG,
6588 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6591 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6594 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6596 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6597 "Unexpected value\n");
6601 info.HashEncryptionAlgorithm.pszObjId = oid2;
6602 SetLastError(0xdeadbeef);
6603 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6604 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6605 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6606 ok(!ret && GetLastError() == E_INVALIDARG,
6607 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6610 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6613 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6614 "Unexpected size %d\n", size);
6615 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6616 "Unexpected value\n");
6620 info.EncryptedHash.cbData = sizeof(hash);
6621 info.EncryptedHash.pbData = (BYTE *)hash;
6622 SetLastError(0xdeadbeef);
6623 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6624 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6625 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6626 ok(!ret && GetLastError() == E_INVALIDARG,
6627 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6630 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6633 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6635 ok(!memcmp(buf, PKCSSignerWithHash, size), "Unexpected value\n");
6641 static void test_decodeCMSSignerInfo(DWORD dwEncoding)
6646 CMSG_CMS_SIGNER_INFO *info;
6647 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6649 /* A CMS signer can't be decoded without a serial number. */
6650 SetLastError(0xdeadbeef);
6651 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6652 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6653 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6654 ok(!ret, "expected failure\n");
6655 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6657 skip("no CMS_SIGNER_INFO decode support\n");
6660 ok(GetLastError() == CRYPT_E_ASN1_CORRUPT,
6661 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
6662 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6663 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6664 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6665 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6668 info = (CMSG_CMS_SIGNER_INFO *)buf;
6669 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6671 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6672 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6673 info->SignerId.dwIdChoice);
6674 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6675 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6676 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6677 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6678 encodedCommonNameNoNull,
6679 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6680 "Unexpected value\n");
6681 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6682 sizeof(serialNum), "Unexpected size %d\n",
6683 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6684 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6685 serialNum, sizeof(serialNum)), "Unexpected value\n");
6688 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6689 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6690 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6691 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6694 info = (CMSG_CMS_SIGNER_INFO *)buf;
6695 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6697 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6698 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6699 info->SignerId.dwIdChoice);
6700 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6701 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6702 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6703 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6704 encodedCommonNameNoNull,
6705 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6706 "Unexpected value\n");
6707 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6708 sizeof(serialNum), "Unexpected size %d\n",
6709 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6710 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6711 serialNum, sizeof(serialNum)), "Unexpected value\n");
6712 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6713 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6716 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6717 PKCSSignerWithHashAndEncryptionAlgo,
6718 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6719 NULL, (BYTE *)&buf, &size);
6720 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6723 info = (CMSG_CMS_SIGNER_INFO *)buf;
6724 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6726 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6727 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6728 info->SignerId.dwIdChoice);
6729 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6730 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6731 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6732 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6733 encodedCommonNameNoNull,
6734 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6735 "Unexpected value\n");
6736 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6737 sizeof(serialNum), "Unexpected size %d\n",
6738 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6739 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6740 serialNum, sizeof(serialNum)), "Unexpected value\n");
6741 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6742 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6743 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6744 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6747 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6748 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6749 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6750 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6753 info = (CMSG_CMS_SIGNER_INFO *)buf;
6754 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6756 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6757 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6758 info->SignerId.dwIdChoice);
6759 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6760 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6761 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6762 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6763 encodedCommonNameNoNull,
6764 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6765 "Unexpected value\n");
6766 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6767 sizeof(serialNum), "Unexpected size %d\n",
6768 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6769 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6770 serialNum, sizeof(serialNum)), "Unexpected value\n");
6771 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6772 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6773 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6774 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6775 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6776 info->EncryptedHash.cbData);
6777 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6778 "Unexpected value\n");
6781 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6782 CMSSignerWithKeyId, sizeof(CMSSignerWithKeyId),
6783 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6784 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6787 info = (CMSG_CMS_SIGNER_INFO *)buf;
6788 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6790 ok(info->SignerId.dwIdChoice == CERT_ID_KEY_IDENTIFIER,
6791 "Expected CERT_ID_KEY_IDENTIFIER, got %d\n",
6792 info->SignerId.dwIdChoice);
6793 ok(U(info->SignerId).KeyId.cbData == sizeof(serialNum),
6794 "Unexpected size %d\n", U(info->SignerId).KeyId.cbData);
6795 ok(!memcmp(U(info->SignerId).KeyId.pbData, serialNum, sizeof(serialNum)),
6796 "Unexpected value\n");
6801 static BYTE emptyDNSPermittedConstraints[] = {
6802 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
6803 static BYTE emptyDNSExcludedConstraints[] = {
6804 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
6805 static BYTE DNSExcludedConstraints[] = {
6806 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
6807 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6808 static BYTE permittedAndExcludedConstraints[] = {
6809 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6810 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
6811 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6812 static BYTE permittedAndExcludedWithMinConstraints[] = {
6813 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6814 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
6815 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6816 static BYTE permittedAndExcludedWithMinMaxConstraints[] = {
6817 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6818 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
6819 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6821 static void test_encodeNameConstraints(DWORD dwEncoding)
6824 CERT_NAME_CONSTRAINTS_INFO constraints = { 0 };
6825 CERT_GENERAL_SUBTREE permitted = { { 0 } };
6826 CERT_GENERAL_SUBTREE excluded = { { 0 } };
6830 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6831 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6832 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6834 skip("no X509_NAME_CONSTRAINTS encode support\n");
6837 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6840 ok(size == sizeof(emptySequence), "Unexpected size\n");
6841 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
6844 constraints.cPermittedSubtree = 1;
6845 constraints.rgPermittedSubtree = &permitted;
6846 SetLastError(0xdeadbeef);
6847 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6848 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6849 ok(!ret && GetLastError() == E_INVALIDARG,
6850 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6851 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
6852 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6853 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6854 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6857 ok(size == sizeof(emptyDNSPermittedConstraints), "Unexpected size\n");
6858 ok(!memcmp(buf, emptyDNSPermittedConstraints, size),
6859 "Unexpected value\n");
6862 constraints.cPermittedSubtree = 0;
6863 constraints.cExcludedSubtree = 1;
6864 constraints.rgExcludedSubtree = &excluded;
6865 excluded.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
6866 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6867 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6868 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6871 ok(size == sizeof(emptyDNSExcludedConstraints), "Unexpected size\n");
6872 ok(!memcmp(buf, emptyDNSExcludedConstraints, size),
6873 "Unexpected value\n");
6876 U(excluded.Base).pwszURL = (LPWSTR)url;
6877 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6878 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6879 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6882 ok(size == sizeof(DNSExcludedConstraints), "Unexpected size\n");
6883 ok(!memcmp(buf, DNSExcludedConstraints, size),
6884 "Unexpected value\n");
6887 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
6888 U(permitted.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6889 U(permitted.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6890 constraints.cPermittedSubtree = 1;
6891 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6892 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6893 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6896 ok(size == sizeof(permittedAndExcludedConstraints),
6897 "Unexpected size\n");
6898 ok(!memcmp(buf, permittedAndExcludedConstraints, size),
6899 "Unexpected value\n");
6902 permitted.dwMinimum = 5;
6903 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6904 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6905 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6908 ok(size == sizeof(permittedAndExcludedWithMinConstraints),
6909 "Unexpected size\n");
6910 ok(!memcmp(buf, permittedAndExcludedWithMinConstraints, size),
6911 "Unexpected value\n");
6914 permitted.fMaximum = TRUE;
6915 permitted.dwMaximum = 3;
6916 SetLastError(0xdeadbeef);
6917 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6918 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6919 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6922 ok(size == sizeof(permittedAndExcludedWithMinMaxConstraints),
6923 "Unexpected size\n");
6924 ok(!memcmp(buf, permittedAndExcludedWithMinMaxConstraints, size),
6925 "Unexpected value\n");
6930 struct EncodedNameConstraints
6932 CRYPT_DATA_BLOB encoded;
6933 CERT_NAME_CONSTRAINTS_INFO constraints;
6936 static CERT_GENERAL_SUBTREE emptyDNSSubtree = {
6937 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
6938 static CERT_GENERAL_SUBTREE DNSSubtree = {
6939 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
6940 static CERT_GENERAL_SUBTREE IPAddressSubtree = {
6941 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 0 };
6942 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree = {
6943 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, 0 };
6944 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree = {
6945 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, TRUE, 3 };
6947 struct EncodedNameConstraints encodedNameConstraints[] = {
6948 { { sizeof(emptySequence), (LPBYTE)emptySequence }, { 0 } },
6949 { { sizeof(emptyDNSPermittedConstraints), emptyDNSPermittedConstraints },
6950 { 1, &emptyDNSSubtree, 0, NULL } },
6951 { { sizeof(emptyDNSExcludedConstraints), emptyDNSExcludedConstraints },
6952 { 0, NULL, 1, &emptyDNSSubtree } },
6953 { { sizeof(DNSExcludedConstraints), DNSExcludedConstraints },
6954 { 0, NULL, 1, &DNSSubtree } },
6955 { { sizeof(permittedAndExcludedConstraints), permittedAndExcludedConstraints },
6956 { 1, &IPAddressSubtree, 1, &DNSSubtree } },
6957 { { sizeof(permittedAndExcludedWithMinConstraints),
6958 permittedAndExcludedWithMinConstraints },
6959 { 1, &IPAddressWithMinSubtree, 1, &DNSSubtree } },
6960 { { sizeof(permittedAndExcludedWithMinMaxConstraints),
6961 permittedAndExcludedWithMinMaxConstraints },
6962 { 1, &IPAddressWithMinMaxSubtree, 1, &DNSSubtree } },
6965 static void test_decodeNameConstraints(DWORD dwEncoding)
6969 CERT_NAME_CONSTRAINTS_INFO *constraints;
6971 U(DNSSubtree.Base).pwszURL = (LPWSTR)url;
6972 U(IPAddressSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6973 U(IPAddressSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6974 U(IPAddressWithMinSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6975 U(IPAddressWithMinSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6976 U(IPAddressWithMinMaxSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6977 U(IPAddressWithMinMaxSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6979 i < sizeof(encodedNameConstraints) / sizeof(encodedNameConstraints[0]);
6984 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS,
6985 encodedNameConstraints[i].encoded.pbData,
6986 encodedNameConstraints[i].encoded.cbData,
6987 CRYPT_DECODE_ALLOC_FLAG, NULL, &constraints, &size);
6988 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6990 skip("no X509_NAME_CONSTRAINTS decode support\n");
6993 ok(ret, "%d: CryptDecodeObjectEx failed: %08x\n", i, GetLastError());
6998 if (constraints->cPermittedSubtree !=
6999 encodedNameConstraints[i].constraints.cPermittedSubtree)
7000 fprintf(stderr, "%d: expected %d permitted, got %d\n", i,
7001 encodedNameConstraints[i].constraints.cPermittedSubtree,
7002 constraints->cPermittedSubtree);
7003 if (constraints->cPermittedSubtree ==
7004 encodedNameConstraints[i].constraints.cPermittedSubtree)
7006 for (j = 0; j < constraints->cPermittedSubtree; j++)
7008 compareAltNameEntry(&constraints->rgPermittedSubtree[j].Base,
7009 &encodedNameConstraints[i].constraints.rgPermittedSubtree[j].Base);
7012 if (constraints->cExcludedSubtree !=
7013 encodedNameConstraints[i].constraints.cExcludedSubtree)
7014 fprintf(stderr, "%d: expected %d excluded, got %d\n", i,
7015 encodedNameConstraints[i].constraints.cExcludedSubtree,
7016 constraints->cExcludedSubtree);
7017 if (constraints->cExcludedSubtree ==
7018 encodedNameConstraints[i].constraints.cExcludedSubtree)
7020 for (j = 0; j < constraints->cExcludedSubtree; j++)
7022 compareAltNameEntry(&constraints->rgExcludedSubtree[j].Base,
7023 &encodedNameConstraints[i].constraints.rgExcludedSubtree[j].Base);
7026 LocalFree(constraints);
7031 /* Free *pInfo with HeapFree */
7032 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
7039 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
7041 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size);
7042 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7043 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7044 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL,
7046 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7047 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7048 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL,
7050 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7051 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7052 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7053 0, NULL, NULL, &size);
7054 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7055 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7056 /* Test with no key */
7057 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7058 0, NULL, NULL, &size);
7059 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n",
7061 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
7062 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
7065 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
7066 NULL, 0, NULL, NULL, &size);
7067 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
7068 *pInfo = HeapAlloc(GetProcessHeap(), 0, size);
7071 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
7072 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size);
7073 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n",
7077 /* By default (we passed NULL as the OID) the OID is
7080 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA),
7081 "Expected %s, got %s\n", szOID_RSA_RSA,
7082 (*pInfo)->Algorithm.pszObjId);
7086 CryptDestroyKey(key);
7089 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
7090 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
7091 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
7092 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7093 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7094 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7095 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
7096 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
7097 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7098 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7099 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7100 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
7101 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
7102 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
7103 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
7104 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
7105 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
7106 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
7107 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
7108 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
7109 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
7110 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
7111 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
7112 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
7113 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
7115 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info)
7119 PCCERT_CONTEXT context;
7124 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
7125 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
7126 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
7127 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7130 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key);
7131 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7132 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7133 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key);
7134 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7135 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7136 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL,
7138 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7139 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7141 /* Export key with standard algorithm (CALG_RSA_KEYX) */
7142 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7144 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7146 dwSize = sizeof(ai);
7147 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7148 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7151 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7152 ok(ai == CALG_RSA_KEYX, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai);
7155 CryptDestroyKey(key);
7157 /* Repeat with forced algorithm */
7158 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, CALG_RSA_SIGN, 0, NULL,
7160 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7162 dwSize = sizeof(ai);
7163 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7164 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7167 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7168 ok(ai == CALG_RSA_SIGN, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai);
7171 CryptDestroyKey(key);
7173 /* Test importing a public key from a certificate context */
7174 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert,
7175 sizeof(expiredCert));
7176 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
7180 ok(!strcmp(szOID_RSA_RSA,
7181 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId),
7182 "Expected %s, got %s\n", szOID_RSA_RSA,
7183 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
7184 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING,
7185 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
7186 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7187 CryptDestroyKey(key);
7188 CertFreeCertificateContext(context);
7192 static const char cspName[] = "WineCryptTemp";
7194 static void testPortPublicKeyInfo(void)
7198 PCERT_PUBLIC_KEY_INFO info = NULL;
7200 /* Just in case a previous run failed, delete this thing */
7201 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7202 CRYPT_DELETEKEYSET);
7203 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7206 testExportPublicKey(csp, &info);
7207 testImportPublicKey(csp, info);
7209 HeapFree(GetProcessHeap(), 0, info);
7210 CryptReleaseContext(csp, 0);
7211 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7212 CRYPT_DELETEKEYSET);
7217 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
7218 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING };
7222 hCrypt32 = GetModuleHandleA("crypt32.dll");
7223 pCryptDecodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptDecodeObjectEx");
7224 pCryptEncodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptEncodeObjectEx");
7225 if (!pCryptDecodeObjectEx || !pCryptEncodeObjectEx)
7227 skip("CryptDecodeObjectEx() is not available\n");
7231 for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++)
7233 test_encodeInt(encodings[i]);
7234 test_decodeInt(encodings[i]);
7235 test_encodeEnumerated(encodings[i]);
7236 test_decodeEnumerated(encodings[i]);
7237 test_encodeFiletime(encodings[i]);
7238 test_decodeFiletime(encodings[i]);
7239 test_encodeName(encodings[i]);
7240 test_decodeName(encodings[i]);
7241 test_encodeUnicodeName(encodings[i]);
7242 test_decodeUnicodeName(encodings[i]);
7243 test_encodeNameValue(encodings[i]);
7244 test_decodeNameValue(encodings[i]);
7245 test_encodeUnicodeNameValue(encodings[i]);
7246 test_decodeUnicodeNameValue(encodings[i]);
7247 test_encodeAltName(encodings[i]);
7248 test_decodeAltName(encodings[i]);
7249 test_encodeOctets(encodings[i]);
7250 test_decodeOctets(encodings[i]);
7251 test_encodeBits(encodings[i]);
7252 test_decodeBits(encodings[i]);
7253 test_encodeBasicConstraints(encodings[i]);
7254 test_decodeBasicConstraints(encodings[i]);
7255 test_encodeRsaPublicKey(encodings[i]);
7256 test_decodeRsaPublicKey(encodings[i]);
7257 test_encodeSequenceOfAny(encodings[i]);
7258 test_decodeSequenceOfAny(encodings[i]);
7259 test_encodeExtensions(encodings[i]);
7260 test_decodeExtensions(encodings[i]);
7261 test_encodePublicKeyInfo(encodings[i]);
7262 test_decodePublicKeyInfo(encodings[i]);
7263 test_encodeCertToBeSigned(encodings[i]);
7264 test_decodeCertToBeSigned(encodings[i]);
7265 test_encodeCert(encodings[i]);
7266 test_decodeCert(encodings[i]);
7267 test_encodeCRLDistPoints(encodings[i]);
7268 test_decodeCRLDistPoints(encodings[i]);
7269 test_encodeCRLIssuingDistPoint(encodings[i]);
7270 test_decodeCRLIssuingDistPoint(encodings[i]);
7271 test_encodeCRLToBeSigned(encodings[i]);
7272 test_decodeCRLToBeSigned(encodings[i]);
7273 test_encodeEnhancedKeyUsage(encodings[i]);
7274 test_decodeEnhancedKeyUsage(encodings[i]);
7275 test_encodeAuthorityKeyId(encodings[i]);
7276 test_decodeAuthorityKeyId(encodings[i]);
7277 test_encodeAuthorityKeyId2(encodings[i]);
7278 test_decodeAuthorityKeyId2(encodings[i]);
7279 test_encodeAuthorityInfoAccess(encodings[i]);
7280 test_decodeAuthorityInfoAccess(encodings[i]);
7281 test_encodeCTL(encodings[i]);
7282 test_decodeCTL(encodings[i]);
7283 test_encodePKCSContentInfo(encodings[i]);
7284 test_decodePKCSContentInfo(encodings[i]);
7285 test_encodePKCSAttribute(encodings[i]);
7286 test_decodePKCSAttribute(encodings[i]);
7287 test_encodePKCSAttributes(encodings[i]);
7288 test_decodePKCSAttributes(encodings[i]);
7289 test_encodePKCSSMimeCapabilities(encodings[i]);
7290 test_decodePKCSSMimeCapabilities(encodings[i]);
7291 test_encodePKCSSignerInfo(encodings[i]);
7292 test_decodePKCSSignerInfo(encodings[i]);
7293 test_encodeCMSSignerInfo(encodings[i]);
7294 test_decodeCMSSignerInfo(encodings[i]);
7295 test_encodeNameConstraints(encodings[i]);
7296 test_decodeNameConstraints(encodings[i]);
7298 testPortPublicKeyInfo();