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, &buf, &bufSize);
234 ok((!ret && GetLastError() == CRYPT_E_ASN1_LARGE) ||
235 broken(ret) /* Win9x */,
236 "Expected CRYPT_E_ASN1_LARGE, got %d\n", GetLastError());
237 /* check with a DER-encoded string */
238 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, testStr, testStr[1] + 2,
239 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
240 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
241 GetLastError() == OSS_PDU_MISMATCH /* Win9x */ ),
242 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %08x\n",
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, &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, &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, &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, &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, &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, &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, &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, &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,
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, &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 broken(ret), /* Win9x and NT4 for bin38 */
667 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
672 static const char commonName[] = "Juan Lang";
673 static const char surName[] = "Lang";
675 static const BYTE emptySequence[] = { 0x30, 0 };
676 static const BYTE emptyRDNs[] = { 0x30, 0x02, 0x31, 0 };
677 static const BYTE twoRDNs[] = {
678 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
679 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
680 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0};
681 static const BYTE encodedTwoRDNs[] = {
682 0x30,0x2e,0x31,0x2c,0x30,0x2a,0x06,0x03,0x55,0x04,0x03,0x30,0x23,0x31,0x21,
683 0x30,0x0c,0x06,0x03,0x55,0x04,0x04,0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,
684 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
688 static const BYTE us[] = { 0x55, 0x53 };
689 static const BYTE minnesota[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x73, 0x6f,
691 static const BYTE minneapolis[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x61, 0x70,
692 0x6f, 0x6c, 0x69, 0x73 };
693 static const BYTE codeweavers[] = { 0x43, 0x6f, 0x64, 0x65, 0x57, 0x65, 0x61,
694 0x76, 0x65, 0x72, 0x73 };
695 static const BYTE wine[] = { 0x57, 0x69, 0x6e, 0x65, 0x20, 0x44, 0x65, 0x76,
696 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74 };
697 static const BYTE localhostAttr[] = { 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
699 static const BYTE aric[] = { 0x61, 0x72, 0x69, 0x63, 0x40, 0x63, 0x6f, 0x64,
700 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d };
702 #define RDNA(arr) oid_ ## arr, CERT_RDN_PRINTABLE_STRING, { sizeof(arr), (LPBYTE)arr }
703 #define RDNIA5(arr) oid_ ## arr, CERT_RDN_IA5_STRING, { sizeof(arr), (LPBYTE)arr }
705 static CHAR oid_us[] = "2.5.4.6",
706 oid_minnesota[] = "2.5.4.8",
707 oid_minneapolis[] = "2.5.4.7",
708 oid_codeweavers[] = "2.5.4.10",
709 oid_wine[] = "2.5.4.11",
710 oid_localhostAttr[] = "2.5.4.3",
711 oid_aric[] = "1.2.840.113549.1.9.1";
712 static CERT_RDN_ATTR rdnAttrs[] = { { RDNA(us) },
714 { RDNA(minneapolis) },
715 { RDNA(codeweavers) },
717 { RDNA(localhostAttr) },
719 static CERT_RDN_ATTR decodedRdnAttrs[] = { { RDNA(us) },
720 { RDNA(localhostAttr) },
722 { RDNA(minneapolis) },
723 { RDNA(codeweavers) },
730 static const BYTE encodedRDNAttrs[] = {
731 0x30,0x81,0x96,0x31,0x81,0x93,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
732 0x53,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x68,
733 0x6f,0x73,0x74,0x30,0x10,0x06,0x03,0x55,0x04,0x08,0x13,0x09,0x4d,0x69,0x6e,0x6e,
734 0x65,0x73,0x6f,0x74,0x61,0x30,0x12,0x06,0x03,0x55,0x04,0x07,0x13,0x0b,0x4d,0x69,
735 0x6e,0x6e,0x65,0x61,0x70,0x6f,0x6c,0x69,0x73,0x30,0x12,0x06,0x03,0x55,0x04,0x0a,
736 0x13,0x0b,0x43,0x6f,0x64,0x65,0x57,0x65,0x61,0x76,0x65,0x72,0x73,0x30,0x17,0x06,
737 0x03,0x55,0x04,0x0b,0x13,0x10,0x57,0x69,0x6e,0x65,0x20,0x44,0x65,0x76,0x65,0x6c,
738 0x6f,0x70,0x6d,0x65,0x6e,0x74,0x30,0x21,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
739 0x01,0x09,0x01,0x16,0x14,0x61,0x72,0x69,0x63,0x40,0x63,0x6f,0x64,0x65,0x77,0x65,
740 0x61,0x76,0x65,0x72,0x73,0x2e,0x63,0x6f,0x6d
743 static void test_encodeName(DWORD dwEncoding)
745 CERT_RDN_ATTR attrs[2];
748 static CHAR oid_common_name[] = szOID_COMMON_NAME,
749 oid_sur_name[] = szOID_SUR_NAME;
756 /* Test with NULL pvStructInfo (crashes on win9x) */
757 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, NULL,
758 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
759 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
760 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
762 /* Test with empty CERT_NAME_INFO */
765 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
766 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
767 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
770 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
771 "Got unexpected encoding for empty name\n");
776 /* Test with bogus CERT_RDN (crashes on win9x) */
778 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
779 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
780 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
781 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
783 /* Test with empty CERT_RDN */
785 rdn.rgRDNAttr = NULL;
788 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
789 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
790 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
793 ok(!memcmp(buf, emptyRDNs, sizeof(emptyRDNs)),
794 "Got unexpected encoding for empty RDN array\n");
799 /* Test with bogus attr array (crashes on win9x) */
801 rdn.rgRDNAttr = NULL;
802 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
803 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
804 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
805 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
807 /* oddly, a bogus OID is accepted by Windows XP; not testing.
808 attrs[0].pszObjId = "bogus";
809 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
810 attrs[0].Value.cbData = sizeof(commonName);
811 attrs[0].Value.pbData = commonName;
813 rdn.rgRDNAttr = attrs;
814 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
815 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
816 ok(!ret, "Expected failure, got success\n");
818 /* Check with two CERT_RDN_ATTRs. Note DER encoding forces the order of
819 * the encoded attributes to be swapped.
821 attrs[0].pszObjId = oid_common_name;
822 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
823 attrs[0].Value.cbData = sizeof(commonName);
824 attrs[0].Value.pbData = (BYTE *)commonName;
825 attrs[1].pszObjId = oid_sur_name;
826 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
827 attrs[1].Value.cbData = sizeof(surName);
828 attrs[1].Value.pbData = (BYTE *)surName;
830 rdn.rgRDNAttr = attrs;
831 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
832 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
833 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
836 ok(!memcmp(buf, twoRDNs, sizeof(twoRDNs)),
837 "Got unexpected encoding for two RDN array\n");
840 /* A name can be "encoded" with previously encoded RDN attrs. */
841 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
842 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
843 attrs[0].Value.cbData = sizeof(twoRDNs);
845 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
846 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
847 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
850 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
851 ok(!memcmp(buf, encodedTwoRDNs, size),
852 "Unexpected value for re-endoded two RDN array\n");
855 /* CERT_RDN_ANY_TYPE is too vague for X509_NAMEs, check the return */
857 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
858 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
859 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
860 ok(!ret && GetLastError() == E_INVALIDARG,
861 "Expected E_INVALIDARG, got %08x\n", GetLastError());
862 /* Test a more complex name */
863 rdn.cRDNAttr = sizeof(rdnAttrs) / sizeof(rdnAttrs[0]);
864 rdn.rgRDNAttr = rdnAttrs;
869 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, X509_NAME, &info,
870 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
871 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
874 ok(size == sizeof(encodedRDNAttrs), "Wrong size %d\n", size);
875 ok(!memcmp(buf, encodedRDNAttrs, size), "Unexpected value\n");
880 static WCHAR commonNameW[] = { 'J','u','a','n',' ','L','a','n','g',0 };
881 static WCHAR surNameW[] = { 'L','a','n','g',0 };
883 static const BYTE twoRDNsNoNull[] = {
884 0x30,0x21,0x31,0x1f,0x30,0x0b,0x06,0x03,0x55,0x04,0x04,0x13,0x04,0x4c,0x61,
885 0x6e,0x67,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,
886 0x20,0x4c,0x61,0x6e,0x67 };
887 static const BYTE anyType[] = {
888 0x30,0x2f,0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x1e,0x24,0x23,0x30,
889 0x21,0x31,0x0c,0x30,0x03,0x06,0x04,0x55,0x13,0x04,0x4c,0x05,0x6e,0x61,0x00,
890 0x67,0x11,0x30,0x03,0x06,0x04,0x55,0x13,0x03,0x4a,0x0a,0x61,0x75,0x20,0x6e,
891 0x61,0x4c,0x67,0x6e };
893 static void test_encodeUnicodeName(DWORD dwEncoding)
895 CERT_RDN_ATTR attrs[2];
898 static CHAR oid_common_name[] = szOID_COMMON_NAME,
899 oid_sur_name[] = szOID_SUR_NAME;
906 /* Test with NULL pvStructInfo (crashes on win9x) */
907 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, NULL,
908 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
909 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
910 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
912 /* Test with empty CERT_NAME_INFO */
915 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
916 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
917 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
920 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
921 "Got unexpected encoding for empty name\n");
924 /* Check with one CERT_RDN_ATTR, that has an invalid character for the
925 * encoding (the NULL).
927 attrs[0].pszObjId = oid_common_name;
928 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
929 attrs[0].Value.cbData = sizeof(commonNameW);
930 attrs[0].Value.pbData = (BYTE *)commonNameW;
932 rdn.rgRDNAttr = attrs;
935 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
936 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
937 ok(!ret && GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING,
938 "Expected CRYPT_E_INVALID_PRINTABLE_STRING, got %08x\n", GetLastError());
939 ok(size == 9, "Unexpected error index %08x\n", size);
940 /* Check with two NULL-terminated CERT_RDN_ATTRs. Note DER encoding
941 * forces the order of the encoded attributes to be swapped.
943 attrs[0].pszObjId = oid_common_name;
944 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
945 attrs[0].Value.cbData = 0;
946 attrs[0].Value.pbData = (BYTE *)commonNameW;
947 attrs[1].pszObjId = oid_sur_name;
948 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
949 attrs[1].Value.cbData = 0;
950 attrs[1].Value.pbData = (BYTE *)surNameW;
952 rdn.rgRDNAttr = attrs;
955 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
956 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
957 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
960 ok(!memcmp(buf, twoRDNsNoNull, sizeof(twoRDNsNoNull)),
961 "Got unexpected encoding for two RDN array\n");
964 /* A name can be "encoded" with previously encoded RDN attrs. */
965 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
966 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
967 attrs[0].Value.cbData = sizeof(twoRDNs);
969 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
970 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
971 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
974 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
975 ok(!memcmp(buf, encodedTwoRDNs, size),
976 "Unexpected value for re-endoded two RDN array\n");
979 /* Unicode names infer the type for CERT_RDN_ANY_TYPE */
981 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
982 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
983 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
984 todo_wine ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
987 ok(size == sizeof(anyType), "Unexpected size %d\n", size);
988 ok(!memcmp(buf, anyType, size), "Unexpected value\n");
993 static void compareNameValues(const CERT_NAME_VALUE *expected,
994 const CERT_NAME_VALUE *got)
996 if (expected->dwValueType == CERT_RDN_UTF8_STRING &&
997 got->dwValueType == CERT_RDN_ENCODED_BLOB)
999 win_skip("Can't handle CERT_RDN_UTF8_STRING\n");
1003 ok(got->dwValueType == expected->dwValueType,
1004 "Expected string type %d, got %d\n", expected->dwValueType,
1006 ok(got->Value.cbData == expected->Value.cbData,
1007 "String type %d: unexpected data size, got %d, expected %d\n",
1008 expected->dwValueType, got->Value.cbData, expected->Value.cbData);
1009 if (got->Value.cbData && got->Value.pbData)
1010 ok(!memcmp(got->Value.pbData, expected->Value.pbData,
1011 min(got->Value.cbData, expected->Value.cbData)),
1012 "String type %d: unexpected value\n", expected->dwValueType);
1015 static void compareRDNAttrs(const CERT_RDN_ATTR *expected,
1016 const CERT_RDN_ATTR *got)
1018 if (expected->pszObjId && strlen(expected->pszObjId))
1020 ok(got->pszObjId != NULL, "Expected OID %s, got NULL\n",
1021 expected->pszObjId);
1024 ok(!strcmp(got->pszObjId, expected->pszObjId),
1025 "Got unexpected OID %s, expected %s\n", got->pszObjId,
1026 expected->pszObjId);
1029 compareNameValues((const CERT_NAME_VALUE *)&expected->dwValueType,
1030 (const CERT_NAME_VALUE *)&got->dwValueType);
1033 static void compareRDNs(const CERT_RDN *expected, const CERT_RDN *got)
1035 ok(got->cRDNAttr == expected->cRDNAttr,
1036 "Expected %d RDN attrs, got %d\n", expected->cRDNAttr, got->cRDNAttr);
1041 for (i = 0; i < got->cRDNAttr; i++)
1042 compareRDNAttrs(&expected->rgRDNAttr[i], &got->rgRDNAttr[i]);
1046 static void compareNames(const CERT_NAME_INFO *expected,
1047 const CERT_NAME_INFO *got)
1049 ok(got->cRDN == expected->cRDN, "Expected %d RDNs, got %d\n",
1050 expected->cRDN, got->cRDN);
1055 for (i = 0; i < got->cRDN; i++)
1056 compareRDNs(&expected->rgRDN[i], &got->rgRDN[i]);
1060 static const BYTE emptyIndefiniteSequence[] = { 0x30,0x80,0x00,0x00 };
1061 static const BYTE twoRDNsExtraBytes[] = {
1062 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
1063 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1064 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0,0,0,0,0,0};
1066 static void test_decodeName(DWORD dwEncoding)
1072 CERT_NAME_INFO info = { 1, &rdn };
1074 /* test empty name */
1076 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptySequence,
1077 emptySequence[1] + 2,
1078 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1080 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1081 /* Interestingly, in Windows, if cRDN is 0, rgRGN may not be NULL. My
1082 * decoder works the same way, so only test the count.
1086 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1087 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1088 "Expected 0 RDNs in empty info, got %d\n",
1089 ((CERT_NAME_INFO *)buf)->cRDN);
1092 /* test empty name with indefinite-length encoding */
1093 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyIndefiniteSequence,
1094 sizeof(emptyIndefiniteSequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
1096 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1099 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1100 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1101 "Expected 0 RDNs in empty info, got %d\n",
1102 ((CERT_NAME_INFO *)buf)->cRDN);
1105 /* test empty RDN */
1107 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyRDNs,
1109 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1111 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1114 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1116 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1117 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1118 "Got unexpected value for empty RDN\n");
1121 /* test two RDN attrs */
1123 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNs,
1125 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1127 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1130 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1131 oid_common_name[] = szOID_COMMON_NAME;
1133 CERT_RDN_ATTR attrs[] = {
1134 { oid_sur_name, CERT_RDN_PRINTABLE_STRING, { sizeof(surName),
1135 (BYTE *)surName } },
1136 { oid_common_name, CERT_RDN_PRINTABLE_STRING, { sizeof(commonName),
1137 (BYTE *)commonName } },
1140 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1141 rdn.rgRDNAttr = attrs;
1142 compareNames(&info, (CERT_NAME_INFO *)buf);
1145 /* test that two RDN attrs with extra bytes succeeds */
1147 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNsExtraBytes,
1148 sizeof(twoRDNsExtraBytes), 0, NULL, NULL, &bufSize);
1149 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1150 /* And, a slightly more complicated name */
1153 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME, encodedRDNAttrs,
1154 sizeof(encodedRDNAttrs), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1155 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1158 rdn.cRDNAttr = sizeof(decodedRdnAttrs) / sizeof(decodedRdnAttrs[0]);
1159 rdn.rgRDNAttr = decodedRdnAttrs;
1160 compareNames(&info, (CERT_NAME_INFO *)buf);
1165 static void test_decodeUnicodeName(DWORD dwEncoding)
1171 CERT_NAME_INFO info = { 1, &rdn };
1173 /* test empty name */
1175 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptySequence,
1176 emptySequence[1] + 2,
1177 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1179 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1182 ok(bufSize == sizeof(CERT_NAME_INFO),
1183 "Got wrong bufSize %d\n", bufSize);
1184 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1185 "Expected 0 RDNs in empty info, got %d\n",
1186 ((CERT_NAME_INFO *)buf)->cRDN);
1189 /* test empty RDN */
1191 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptyRDNs,
1193 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1195 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1198 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1200 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1201 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1202 "Got unexpected value for empty RDN\n");
1205 /* test two RDN attrs */
1207 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, twoRDNsNoNull,
1208 sizeof(twoRDNsNoNull),
1209 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1211 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1214 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1215 oid_common_name[] = szOID_COMMON_NAME;
1217 CERT_RDN_ATTR attrs[] = {
1218 { oid_sur_name, CERT_RDN_PRINTABLE_STRING,
1219 { lstrlenW(surNameW) * sizeof(WCHAR), (BYTE *)surNameW } },
1220 { oid_common_name, CERT_RDN_PRINTABLE_STRING,
1221 { lstrlenW(commonNameW) * sizeof(WCHAR), (BYTE *)commonNameW } },
1224 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1225 rdn.rgRDNAttr = attrs;
1226 compareNames(&info, (CERT_NAME_INFO *)buf);
1231 struct EncodedNameValue
1233 CERT_NAME_VALUE value;
1234 const BYTE *encoded;
1238 static const char bogusIA5[] = "\x80";
1239 static const char bogusPrintable[] = "~";
1240 static const char bogusNumeric[] = "A";
1241 static const BYTE bin42[] = { 0x16,0x02,0x80,0x00 };
1242 static const BYTE bin43[] = { 0x13,0x02,0x7e,0x00 };
1243 static const BYTE bin44[] = { 0x12,0x02,0x41,0x00 };
1244 static BYTE octetCommonNameValue[] = {
1245 0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1246 static BYTE numericCommonNameValue[] = {
1247 0x12,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1248 static BYTE printableCommonNameValue[] = {
1249 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1250 static BYTE t61CommonNameValue[] = {
1251 0x14,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1252 static BYTE videotexCommonNameValue[] = {
1253 0x15,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1254 static BYTE ia5CommonNameValue[] = {
1255 0x16,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1256 static BYTE graphicCommonNameValue[] = {
1257 0x19,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1258 static BYTE visibleCommonNameValue[] = {
1259 0x1a,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1260 static BYTE generalCommonNameValue[] = {
1261 0x1b,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1262 static BYTE bmpCommonNameValue[] = {
1263 0x1e,0x14,0x00,0x4a,0x00,0x75,0x00,0x61,0x00,0x6e,0x00,0x20,0x00,0x4c,0x00,
1264 0x61,0x00,0x6e,0x00,0x67,0x00,0x00 };
1265 static BYTE utf8CommonNameValue[] = {
1266 0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1268 static struct EncodedNameValue nameValues[] = {
1269 { { CERT_RDN_OCTET_STRING, { sizeof(commonName), (BYTE *)commonName } },
1270 octetCommonNameValue, sizeof(octetCommonNameValue) },
1271 { { CERT_RDN_NUMERIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1272 numericCommonNameValue, sizeof(numericCommonNameValue) },
1273 { { CERT_RDN_PRINTABLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1274 printableCommonNameValue, sizeof(printableCommonNameValue) },
1275 { { CERT_RDN_T61_STRING, { sizeof(commonName), (BYTE *)commonName } },
1276 t61CommonNameValue, sizeof(t61CommonNameValue) },
1277 { { CERT_RDN_VIDEOTEX_STRING, { sizeof(commonName), (BYTE *)commonName } },
1278 videotexCommonNameValue, sizeof(videotexCommonNameValue) },
1279 { { CERT_RDN_IA5_STRING, { sizeof(commonName), (BYTE *)commonName } },
1280 ia5CommonNameValue, sizeof(ia5CommonNameValue) },
1281 { { CERT_RDN_GRAPHIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1282 graphicCommonNameValue, sizeof(graphicCommonNameValue) },
1283 { { CERT_RDN_VISIBLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1284 visibleCommonNameValue, sizeof(visibleCommonNameValue) },
1285 { { CERT_RDN_GENERAL_STRING, { sizeof(commonName), (BYTE *)commonName } },
1286 generalCommonNameValue, sizeof(generalCommonNameValue) },
1287 { { CERT_RDN_BMP_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1288 bmpCommonNameValue, sizeof(bmpCommonNameValue) },
1289 { { CERT_RDN_UTF8_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1290 utf8CommonNameValue, sizeof(utf8CommonNameValue) },
1291 /* The following tests succeed under Windows, but really should fail,
1292 * they contain characters that are illegal for the encoding. I'm
1293 * including them to justify my lazy encoding.
1295 { { CERT_RDN_IA5_STRING, { sizeof(bogusIA5), (BYTE *)bogusIA5 } }, bin42,
1297 { { CERT_RDN_PRINTABLE_STRING, { sizeof(bogusPrintable),
1298 (BYTE *)bogusPrintable } }, bin43, sizeof(bin43) },
1299 { { CERT_RDN_NUMERIC_STRING, { sizeof(bogusNumeric), (BYTE *)bogusNumeric } },
1300 bin44, sizeof(bin44) },
1303 static void test_encodeNameValue(DWORD dwEncoding)
1308 CERT_NAME_VALUE value = { 0, { 0, NULL } };
1310 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1311 value.Value.pbData = printableCommonNameValue;
1312 value.Value.cbData = sizeof(printableCommonNameValue);
1313 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, &value,
1314 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1315 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1318 ok(size == sizeof(printableCommonNameValue), "Unexpected size %d\n",
1320 ok(!memcmp(buf, printableCommonNameValue, size),
1321 "Unexpected encoding\n");
1324 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1326 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE,
1327 &nameValues[i].value, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1328 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH) /* NT4/Win9x */,
1329 "Type %d: CryptEncodeObjectEx failed: %08x\n",
1330 nameValues[i].value.dwValueType, GetLastError());
1333 ok(size == nameValues[i].encodedSize,
1334 "Expected size %d, got %d\n", nameValues[i].encodedSize, size);
1335 ok(!memcmp(buf, nameValues[i].encoded, size),
1336 "Got unexpected encoding\n");
1342 static void test_decodeNameValue(DWORD dwEncoding)
1349 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1351 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE,
1352 nameValues[i].encoded, nameValues[i].encoded[1] + 2,
1353 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1355 ok(ret, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
1356 nameValues[i].value.dwValueType, GetLastError());
1359 compareNameValues(&nameValues[i].value,
1360 (const CERT_NAME_VALUE *)buf);
1366 static const BYTE emptyURL[] = { 0x30, 0x02, 0x86, 0x00 };
1367 static const BYTE emptyURLExtraBytes[] = { 0x30, 0x02, 0x86, 0x00, 0, 0, 0 };
1368 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e',
1369 'h','q','.','o','r','g',0 };
1370 static const BYTE encodedURL[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74,
1371 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e,
1373 static const WCHAR nihongoURL[] = { 'h','t','t','p',':','/','/',0x226f,
1375 static const WCHAR dnsName[] = { 'w','i','n','e','h','q','.','o','r','g',0 };
1376 static const BYTE encodedDnsName[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69,
1377 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
1378 static const BYTE localhost[] = { 127, 0, 0, 1 };
1379 static const BYTE encodedIPAddr[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00,
1381 static const unsigned char encodedCommonName[] = {
1382 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0};
1383 static const BYTE encodedOidName[] = { 0x30,0x04,0x88,0x02,0x2a,0x03 };
1384 static const BYTE encodedDirectoryName[] = {
1385 0x30,0x19,0xa4,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1386 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1388 static void test_encodeAltName(DWORD dwEncoding)
1390 CERT_ALT_NAME_INFO info = { 0 };
1391 CERT_ALT_NAME_ENTRY entry = { 0 };
1395 char oid[] = "1.2.3";
1397 /* Test with empty info */
1398 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1399 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1402 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
1403 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
1406 /* Test with an empty entry */
1408 info.rgAltEntry = &entry;
1409 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1410 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1411 ok(!ret && GetLastError() == E_INVALIDARG,
1412 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1413 /* Test with an empty pointer */
1414 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
1415 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1416 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1419 ok(size == sizeof(emptyURL), "Wrong size %d\n", size);
1420 ok(!memcmp(buf, emptyURL, size), "Unexpected value\n");
1423 /* Test with a real URL */
1424 U(entry).pwszURL = (LPWSTR)url;
1425 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1426 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1429 ok(size == sizeof(encodedURL), "Wrong size %d\n", size);
1430 ok(!memcmp(buf, encodedURL, size), "Unexpected value\n");
1433 /* Now with the URL containing an invalid IA5 char */
1434 U(entry).pwszURL = (LPWSTR)nihongoURL;
1435 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1436 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1437 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
1438 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
1439 /* The first invalid character is at index 7 */
1440 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
1441 "Expected invalid char at index 7, got %d\n",
1442 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
1443 /* Now with the URL missing a scheme */
1444 U(entry).pwszURL = (LPWSTR)dnsName;
1445 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1446 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1447 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1450 /* This succeeds, but it shouldn't, so don't worry about conforming */
1453 /* Now with a DNS name */
1454 entry.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
1455 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1456 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1457 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1460 ok(size == sizeof(encodedDnsName), "Wrong size %d\n", size);
1461 ok(!memcmp(buf, encodedDnsName, size), "Unexpected value\n");
1464 /* Test with an IP address */
1465 entry.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
1466 U(entry).IPAddress.cbData = sizeof(localhost);
1467 U(entry).IPAddress.pbData = (LPBYTE)localhost;
1468 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1469 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1472 ok(size == sizeof(encodedIPAddr), "Wrong size %d\n", size);
1473 ok(!memcmp(buf, encodedIPAddr, size), "Unexpected value\n");
1477 entry.dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID;
1478 U(entry).pszRegisteredID = oid;
1479 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1480 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1483 ok(size == sizeof(encodedOidName), "Wrong size %d\n", size);
1484 ok(!memcmp(buf, encodedOidName, size), "Unexpected value\n");
1487 /* Test with directory name */
1488 entry.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
1489 U(entry).DirectoryName.cbData = sizeof(encodedCommonName);
1490 U(entry).DirectoryName.pbData = (LPBYTE)encodedCommonName;
1491 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1492 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1495 ok(size == sizeof(encodedDirectoryName), "Wrong size %d\n", size);
1496 ok(!memcmp(buf, encodedDirectoryName, size), "Unexpected value\n");
1501 static void test_decodeAltName(DWORD dwEncoding)
1503 static const BYTE unimplementedType[] = { 0x30, 0x06, 0x85, 0x04, 0x7f,
1505 static const BYTE bogusType[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00,
1510 CERT_ALT_NAME_INFO *info;
1512 /* Test some bogus ones first */
1513 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1514 unimplementedType, sizeof(unimplementedType), CRYPT_DECODE_ALLOC_FLAG,
1515 NULL, &buf, &bufSize);
1516 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
1517 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1518 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
1520 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1521 bogusType, sizeof(bogusType), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
1523 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
1524 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1525 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
1527 /* Now expected cases */
1528 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptySequence,
1529 emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1530 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1533 info = (CERT_ALT_NAME_INFO *)buf;
1535 ok(info->cAltEntry == 0, "Expected 0 entries, got %d\n",
1539 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptyURL,
1540 emptyURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1541 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1544 info = (CERT_ALT_NAME_INFO *)buf;
1546 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1548 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1549 "Expected CERT_ALT_NAME_URL, got %d\n",
1550 info->rgAltEntry[0].dwAltNameChoice);
1551 ok(U(info->rgAltEntry[0]).pwszURL == NULL || !*U(info->rgAltEntry[0]).pwszURL,
1552 "Expected empty URL\n");
1555 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1556 emptyURLExtraBytes, sizeof(emptyURLExtraBytes), 0, NULL, NULL, &bufSize);
1557 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1558 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedURL,
1559 encodedURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1560 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1563 info = (CERT_ALT_NAME_INFO *)buf;
1565 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1567 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1568 "Expected CERT_ALT_NAME_URL, got %d\n",
1569 info->rgAltEntry[0].dwAltNameChoice);
1570 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszURL, url), "Unexpected URL\n");
1573 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedDnsName,
1574 encodedDnsName[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1575 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1578 info = (CERT_ALT_NAME_INFO *)buf;
1580 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1582 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1583 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1584 info->rgAltEntry[0].dwAltNameChoice);
1585 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszDNSName, dnsName),
1586 "Unexpected DNS name\n");
1589 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedIPAddr,
1590 encodedIPAddr[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1591 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1594 info = (CERT_ALT_NAME_INFO *)buf;
1596 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1598 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS,
1599 "Expected CERT_ALT_NAME_IP_ADDRESS, got %d\n",
1600 info->rgAltEntry[0].dwAltNameChoice);
1601 ok(U(info->rgAltEntry[0]).IPAddress.cbData == sizeof(localhost),
1602 "Unexpected IP address length %d\n",
1603 U(info->rgAltEntry[0]).IPAddress.cbData);
1604 ok(!memcmp(U(info->rgAltEntry[0]).IPAddress.pbData, localhost,
1605 sizeof(localhost)), "Unexpected IP address value\n");
1608 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedOidName,
1609 sizeof(encodedOidName), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1610 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1613 info = (CERT_ALT_NAME_INFO *)buf;
1615 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1617 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_REGISTERED_ID,
1618 "Expected CERT_ALT_NAME_REGISTERED_ID, got %d\n",
1619 info->rgAltEntry[0].dwAltNameChoice);
1620 ok(!strcmp(U(info->rgAltEntry[0]).pszRegisteredID, "1.2.3"),
1621 "Expected OID 1.2.3, got %s\n", U(info->rgAltEntry[0]).pszRegisteredID);
1624 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1625 encodedDirectoryName, sizeof(encodedDirectoryName),
1626 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1627 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1630 info = (CERT_ALT_NAME_INFO *)buf;
1632 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1634 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME,
1635 "Expected CERT_ALT_NAME_DIRECTORY_NAME, got %d\n",
1636 info->rgAltEntry[0].dwAltNameChoice);
1637 ok(U(info->rgAltEntry[0]).DirectoryName.cbData ==
1638 sizeof(encodedCommonName), "Unexpected directory name length %d\n",
1639 U(info->rgAltEntry[0]).DirectoryName.cbData);
1640 ok(!memcmp(U(info->rgAltEntry[0]).DirectoryName.pbData,
1641 encodedCommonName, sizeof(encodedCommonName)),
1642 "Unexpected directory name value\n");
1647 struct UnicodeExpectedError
1655 static const WCHAR oneW[] = { '1',0 };
1656 static const WCHAR aW[] = { 'a',0 };
1657 static const WCHAR quoteW[] = { '"', 0 };
1659 static struct UnicodeExpectedError unicodeErrors[] = {
1660 { CERT_RDN_ANY_TYPE, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1661 { CERT_RDN_ENCODED_BLOB, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1662 { CERT_RDN_OCTET_STRING, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1663 { CERT_RDN_NUMERIC_STRING, aW, 0, CRYPT_E_INVALID_NUMERIC_STRING },
1664 { CERT_RDN_PRINTABLE_STRING, quoteW, 0, CRYPT_E_INVALID_PRINTABLE_STRING },
1665 { CERT_RDN_IA5_STRING, nihongoURL, 7, CRYPT_E_INVALID_IA5_STRING },
1668 struct UnicodeExpectedResult
1672 CRYPT_DATA_BLOB encoded;
1675 static BYTE oneNumeric[] = { 0x12, 0x01, 0x31 };
1676 static BYTE onePrintable[] = { 0x13, 0x01, 0x31 };
1677 static BYTE oneTeletex[] = { 0x14, 0x01, 0x31 };
1678 static BYTE oneVideotex[] = { 0x15, 0x01, 0x31 };
1679 static BYTE oneIA5[] = { 0x16, 0x01, 0x31 };
1680 static BYTE oneGraphic[] = { 0x19, 0x01, 0x31 };
1681 static BYTE oneVisible[] = { 0x1a, 0x01, 0x31 };
1682 static BYTE oneUniversal[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 };
1683 static BYTE oneGeneral[] = { 0x1b, 0x01, 0x31 };
1684 static BYTE oneBMP[] = { 0x1e, 0x02, 0x00, 0x31 };
1685 static BYTE oneUTF8[] = { 0x0c, 0x01, 0x31 };
1686 static BYTE nihongoT61[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,
1688 static BYTE nihongoGeneral[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1690 static BYTE nihongoBMP[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,
1691 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
1692 static BYTE nihongoUTF8[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1693 0xe2,0x89,0xaf,0xe5,0x9d,0x9b };
1695 static struct UnicodeExpectedResult unicodeResults[] = {
1696 { CERT_RDN_NUMERIC_STRING, oneW, { sizeof(oneNumeric), oneNumeric } },
1697 { CERT_RDN_PRINTABLE_STRING, oneW, { sizeof(onePrintable), onePrintable } },
1698 { CERT_RDN_TELETEX_STRING, oneW, { sizeof(oneTeletex), oneTeletex } },
1699 { CERT_RDN_VIDEOTEX_STRING, oneW, { sizeof(oneVideotex), oneVideotex } },
1700 { CERT_RDN_IA5_STRING, oneW, { sizeof(oneIA5), oneIA5 } },
1701 { CERT_RDN_GRAPHIC_STRING, oneW, { sizeof(oneGraphic), oneGraphic } },
1702 { CERT_RDN_VISIBLE_STRING, oneW, { sizeof(oneVisible), oneVisible } },
1703 { CERT_RDN_UNIVERSAL_STRING, oneW, { sizeof(oneUniversal), oneUniversal } },
1704 { CERT_RDN_GENERAL_STRING, oneW, { sizeof(oneGeneral), oneGeneral } },
1705 { CERT_RDN_BMP_STRING, oneW, { sizeof(oneBMP), oneBMP } },
1706 { CERT_RDN_UTF8_STRING, oneW, { sizeof(oneUTF8), oneUTF8 } },
1707 { CERT_RDN_BMP_STRING, nihongoURL, { sizeof(nihongoBMP), nihongoBMP } },
1708 { CERT_RDN_UTF8_STRING, nihongoURL, { sizeof(nihongoUTF8), nihongoUTF8 } },
1711 static struct UnicodeExpectedResult unicodeWeirdness[] = {
1712 { CERT_RDN_TELETEX_STRING, nihongoURL, { sizeof(nihongoT61), nihongoT61 } },
1713 { CERT_RDN_GENERAL_STRING, nihongoURL, { sizeof(nihongoGeneral), nihongoGeneral } },
1716 static void test_encodeUnicodeNameValue(DWORD dwEncoding)
1721 CERT_NAME_VALUE value;
1725 /* Crashes on win9x */
1726 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, NULL,
1727 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1728 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1729 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1731 /* Have to have a string of some sort */
1732 value.dwValueType = 0; /* aka CERT_RDN_ANY_TYPE */
1733 value.Value.pbData = NULL;
1734 value.Value.cbData = 0;
1735 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1736 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1737 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1738 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1739 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1740 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1741 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1742 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1743 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1744 value.dwValueType = CERT_RDN_ANY_TYPE;
1745 value.Value.pbData = (LPBYTE)oneW;
1746 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1747 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1748 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1749 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1750 value.Value.cbData = sizeof(oneW);
1751 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1752 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1753 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1754 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1755 /* An encoded string with specified length isn't good enough either */
1756 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1757 value.Value.pbData = oneUniversal;
1758 value.Value.cbData = sizeof(oneUniversal);
1759 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1760 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1761 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1762 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1763 /* More failure checking */
1764 value.Value.cbData = 0;
1765 for (i = 0; i < sizeof(unicodeErrors) / sizeof(unicodeErrors[0]); i++)
1767 value.Value.pbData = (LPBYTE)unicodeErrors[i].str;
1768 value.dwValueType = unicodeErrors[i].valueType;
1769 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1770 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1771 ok(!ret && GetLastError() == unicodeErrors[i].error,
1772 "Value type %d: expected %08x, got %08x\n", value.dwValueType,
1773 unicodeErrors[i].error, GetLastError());
1774 ok(size == unicodeErrors[i].errorIndex,
1775 "Expected error index %d, got %d\n", unicodeErrors[i].errorIndex,
1778 /* cbData can be zero if the string is NULL-terminated */
1779 value.Value.cbData = 0;
1780 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1782 value.Value.pbData = (LPBYTE)unicodeResults[i].str;
1783 value.dwValueType = unicodeResults[i].valueType;
1784 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1785 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1786 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
1787 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1790 ok(size == unicodeResults[i].encoded.cbData,
1791 "Value type %d: expected size %d, got %d\n",
1792 value.dwValueType, unicodeResults[i].encoded.cbData, size);
1793 ok(!memcmp(unicodeResults[i].encoded.pbData, buf, size),
1794 "Value type %d: unexpected value\n", value.dwValueType);
1798 /* These "encode," but they do so by truncating each unicode character
1799 * rather than properly encoding it. Kept separate from the proper results,
1800 * because the encoded forms won't decode to their original strings.
1802 for (i = 0; i < sizeof(unicodeWeirdness) / sizeof(unicodeWeirdness[0]); i++)
1804 value.Value.pbData = (LPBYTE)unicodeWeirdness[i].str;
1805 value.dwValueType = unicodeWeirdness[i].valueType;
1806 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1807 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1808 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1811 ok(size == unicodeWeirdness[i].encoded.cbData,
1812 "Value type %d: expected size %d, got %d\n",
1813 value.dwValueType, unicodeWeirdness[i].encoded.cbData, size);
1814 ok(!memcmp(unicodeWeirdness[i].encoded.pbData, buf, size),
1815 "Value type %d: unexpected value\n", value.dwValueType);
1821 static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
1823 if (n <= 0) return 0;
1824 while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
1825 return *str1 - *str2;
1828 static void test_decodeUnicodeNameValue(DWORD dwEncoding)
1832 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1838 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE,
1839 unicodeResults[i].encoded.pbData, unicodeResults[i].encoded.cbData,
1840 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
1841 ok(ret || broken(GetLastError() == CRYPT_E_NOT_CHAR_STRING /* Win9x */),
1842 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1845 PCERT_NAME_VALUE value = (PCERT_NAME_VALUE)buf;
1847 ok(value->dwValueType == unicodeResults[i].valueType,
1848 "Expected value type %d, got %d\n", unicodeResults[i].valueType,
1849 value->dwValueType);
1850 ok(!strncmpW((LPWSTR)value->Value.pbData, unicodeResults[i].str,
1851 value->Value.cbData / sizeof(WCHAR)),
1852 "Unexpected decoded value for index %d (value type %d)\n", i,
1853 unicodeResults[i].valueType);
1859 struct encodedOctets
1862 const BYTE *encoded;
1865 static const unsigned char bin46[] = { 'h','i',0 };
1866 static const unsigned char bin47[] = { 0x04,0x02,'h','i',0 };
1867 static const unsigned char bin48[] = {
1868 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1869 static const unsigned char bin49[] = {
1870 0x04,0x0f,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1871 static const unsigned char bin50[] = { 0 };
1872 static const unsigned char bin51[] = { 0x04,0x00,0 };
1874 static const struct encodedOctets octets[] = {
1880 static void test_encodeOctets(DWORD dwEncoding)
1882 CRYPT_DATA_BLOB blob;
1885 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1891 blob.cbData = strlen((const char*)octets[i].val);
1892 blob.pbData = (BYTE*)octets[i].val;
1893 ret = pCryptEncodeObjectEx(dwEncoding, X509_OCTET_STRING, &blob,
1894 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1895 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
1899 "Got unexpected type %d for octet string (expected 4)\n", buf[0]);
1900 ok(buf[1] == octets[i].encoded[1], "Got length %d, expected %d\n",
1901 buf[1], octets[i].encoded[1]);
1902 ok(!memcmp(buf + 1, octets[i].encoded + 1,
1903 octets[i].encoded[1] + 1), "Got unexpected value\n");
1909 static void test_decodeOctets(DWORD dwEncoding)
1913 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1919 ret = pCryptDecodeObjectEx(dwEncoding, X509_OCTET_STRING,
1920 octets[i].encoded, octets[i].encoded[1] + 2,
1921 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1922 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1923 ok(bufSize >= sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1],
1924 "Expected size >= %d, got %d\n",
1925 (int)sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1], bufSize);
1926 ok(buf != NULL, "Expected allocated buffer\n");
1929 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)buf;
1932 ok(!memcmp(blob->pbData, octets[i].val, blob->cbData),
1933 "Unexpected value\n");
1939 static const BYTE bytesToEncode[] = { 0xff, 0xff };
1944 const BYTE *encoded;
1946 const BYTE *decoded;
1949 static const unsigned char bin52[] = { 0x03,0x03,0x00,0xff,0xff };
1950 static const unsigned char bin53[] = { 0xff,0xff };
1951 static const unsigned char bin54[] = { 0x03,0x03,0x01,0xff,0xfe };
1952 static const unsigned char bin55[] = { 0xff,0xfe };
1953 static const unsigned char bin56[] = { 0x03,0x02,0x01,0xfe };
1954 static const unsigned char bin57[] = { 0xfe };
1955 static const unsigned char bin58[] = { 0x03,0x01,0x00 };
1957 static const struct encodedBits bits[] = {
1958 /* normal test cases */
1959 { 0, bin52, 2, bin53 },
1960 { 1, bin54, 2, bin55 },
1961 /* strange test case, showing cUnusedBits >= 8 is allowed */
1962 { 9, bin56, 1, bin57 },
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, &buf, &bufSize);
1981 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1984 ok(bufSize == bits[i].encoded[1] + 2,
1985 "%d: Got unexpected size %d, expected %d\n", i, bufSize,
1986 bits[i].encoded[1] + 2);
1987 ok(!memcmp(buf, bits[i].encoded, bits[i].encoded[1] + 2),
1988 "%d: Unexpected value\n", i);
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, &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, &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, &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, &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, &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, &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, &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,
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 encodedCommonName, encodedCommonName[1] + 2,
2197 CRYPT_DECODE_ALLOC_FLAG, NULL, &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,
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, &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, &buf, &bufSize);
2286 ok(!ret && GetLastError() == E_INVALIDARG,
2287 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2288 /* Now with a bogus reserved field */
2289 hdr->bType = PUBLICKEYBLOB;
2291 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2292 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2295 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2296 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2297 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2300 /* Now with a bogus blob version */
2303 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2304 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2307 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2308 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2309 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2312 /* And with a bogus alg ID */
2313 hdr->bVersion = CUR_BLOB_VERSION;
2314 hdr->aiKeyAlg = CALG_DES;
2315 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2316 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2319 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2320 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2321 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2324 /* Check a couple of RSA-related OIDs */
2325 hdr->aiKeyAlg = CALG_RSA_KEYX;
2326 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_RSA,
2327 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2328 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2329 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2330 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2331 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2332 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2333 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2334 /* Finally, all valid */
2335 hdr->aiKeyAlg = CALG_RSA_KEYX;
2336 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2338 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2339 rsaPubKeys[i].modulus, rsaPubKeys[i].modulusLen);
2340 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2341 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2342 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2345 ok(bufSize == rsaPubKeys[i].encoded[1] + 2,
2346 "Expected size %d, got %d\n", rsaPubKeys[i].encoded[1] + 2,
2348 ok(!memcmp(buf, rsaPubKeys[i].encoded, bufSize),
2349 "Unexpected value\n");
2355 static void test_decodeRsaPublicKey(DWORD dwEncoding)
2362 /* Try with a bad length */
2363 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2364 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1],
2365 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2366 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
2367 GetLastError() == OSS_MORE_INPUT /* Win9x/NT4 */),
2368 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n",
2370 /* Try with a couple of RSA-related OIDs */
2371 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_RSA,
2372 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2373 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2374 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2375 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2376 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2377 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2378 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2379 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2380 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2381 /* Now try success cases */
2382 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2385 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2386 rsaPubKeys[i].encoded, rsaPubKeys[i].encoded[1] + 2,
2387 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2388 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2391 BLOBHEADER *hdr = (BLOBHEADER *)buf;
2392 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER));
2394 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2395 rsaPubKeys[i].decodedModulusLen,
2396 "Wrong size %d\n", bufSize);
2397 ok(hdr->bType == PUBLICKEYBLOB,
2398 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB,
2400 ok(hdr->bVersion == CUR_BLOB_VERSION,
2401 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
2402 CUR_BLOB_VERSION, hdr->bVersion);
2403 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n",
2405 ok(hdr->aiKeyAlg == CALG_RSA_KEYX,
2406 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg);
2407 ok(rsaPubKey->magic == 0x31415352,
2408 "Expected magic RSA1, got %08x\n", rsaPubKey->magic);
2409 ok(rsaPubKey->bitlen == rsaPubKeys[i].decodedModulusLen * 8,
2410 "Wrong bit len %d\n", rsaPubKey->bitlen);
2411 ok(rsaPubKey->pubexp == 65537, "Expected pubexp 65537, got %d\n",
2413 ok(!memcmp(buf + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2414 rsaPubKeys[i].modulus, rsaPubKeys[i].decodedModulusLen),
2415 "Unexpected modulus\n");
2421 static const BYTE intSequence[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01,
2422 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02,
2423 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2425 static const BYTE mixedSequence[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
2426 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f,
2427 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02,
2428 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2430 static void test_encodeSequenceOfAny(DWORD dwEncoding)
2432 CRYPT_DER_BLOB blobs[sizeof(ints) / sizeof(ints[0])];
2433 CRYPT_SEQUENCE_OF_ANY seq;
2439 /* Encode a homogeneous sequence */
2440 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
2442 blobs[i].cbData = ints[i].encoded[1] + 2;
2443 blobs[i].pbData = (BYTE *)ints[i].encoded;
2445 seq.cValue = sizeof(ints) / sizeof(ints[0]);
2446 seq.rgValue = blobs;
2448 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2449 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2450 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2453 ok(bufSize == sizeof(intSequence), "Wrong size %d\n", bufSize);
2454 ok(!memcmp(buf, intSequence, intSequence[1] + 2), "Unexpected value\n");
2457 /* Change the type of the first element in the sequence, and give it
2460 blobs[0].cbData = times[0].encodedTime[1] + 2;
2461 blobs[0].pbData = (BYTE *)times[0].encodedTime;
2462 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2463 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2464 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2467 ok(bufSize == sizeof(mixedSequence), "Wrong size %d\n", bufSize);
2468 ok(!memcmp(buf, mixedSequence, mixedSequence[1] + 2),
2469 "Unexpected value\n");
2474 static void test_decodeSequenceOfAny(DWORD dwEncoding)
2480 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, intSequence,
2481 intSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2482 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2485 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2488 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2489 "Wrong elements %d\n", seq->cValue);
2490 for (i = 0; i < min(seq->cValue, sizeof(ints) / sizeof(ints[0])); i++)
2492 ok(seq->rgValue[i].cbData == ints[i].encoded[1] + 2,
2493 "Expected %d bytes, got %d\n", ints[i].encoded[1] + 2,
2494 seq->rgValue[i].cbData);
2495 ok(!memcmp(seq->rgValue[i].pbData, ints[i].encoded,
2496 ints[i].encoded[1] + 2), "Unexpected value\n");
2500 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, mixedSequence,
2501 mixedSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
2503 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2506 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2508 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2509 "Wrong elements %d\n", seq->cValue);
2510 /* Just check the first element since it's all that changed */
2511 ok(seq->rgValue[0].cbData == times[0].encodedTime[1] + 2,
2512 "Expected %d bytes, got %d\n", times[0].encodedTime[1] + 2,
2513 seq->rgValue[0].cbData);
2514 ok(!memcmp(seq->rgValue[0].pbData, times[0].encodedTime,
2515 times[0].encodedTime[1] + 2), "Unexpected value\n");
2520 struct encodedExtensions
2522 CERT_EXTENSIONS exts;
2523 const BYTE *encoded;
2526 static BYTE crit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2527 static BYTE noncrit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2528 static CHAR oid_basic_constraints2[] = szOID_BASIC_CONSTRAINTS2;
2529 static CERT_EXTENSION criticalExt =
2530 { oid_basic_constraints2, TRUE, { 8, crit_ext_data } };
2531 static CERT_EXTENSION nonCriticalExt =
2532 { oid_basic_constraints2, FALSE, { 8, noncrit_ext_data } };
2533 static CHAR oid_short[] = "1.1";
2534 static CERT_EXTENSION extWithShortOid =
2535 { oid_short, FALSE, { 0, NULL } };
2537 static const BYTE ext0[] = { 0x30,0x00 };
2538 static const BYTE ext1[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2539 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2540 static const BYTE ext2[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2541 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2542 static const BYTE ext3[] = { 0x30,0x07,0x30,0x05,0x06,0x01,0x29,0x04,0x00 };
2544 static const struct encodedExtensions exts[] = {
2545 { { 0, NULL }, ext0 },
2546 { { 1, &criticalExt }, ext1 },
2547 { { 1, &nonCriticalExt }, ext2 },
2548 { { 1, &extWithShortOid }, ext3 }
2551 static void test_encodeExtensions(DWORD dwEncoding)
2555 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2561 ret = pCryptEncodeObjectEx(dwEncoding, X509_EXTENSIONS, &exts[i].exts,
2562 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2563 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2566 ok(bufSize == exts[i].encoded[1] + 2,
2567 "Expected %d bytes, got %d\n", exts[i].encoded[1] + 2, bufSize);
2568 ok(!memcmp(buf, exts[i].encoded, exts[i].encoded[1] + 2),
2569 "Unexpected value\n");
2575 static void test_decodeExtensions(DWORD dwEncoding)
2579 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2585 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS,
2586 exts[i].encoded, exts[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2587 NULL, &buf, &bufSize);
2588 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2591 CERT_EXTENSIONS *ext = (CERT_EXTENSIONS *)buf;
2594 ok(ext->cExtension == exts[i].exts.cExtension,
2595 "Expected %d extensions, see %d\n", exts[i].exts.cExtension,
2597 for (j = 0; j < min(ext->cExtension, exts[i].exts.cExtension); j++)
2599 ok(!strcmp(ext->rgExtension[j].pszObjId,
2600 exts[i].exts.rgExtension[j].pszObjId),
2601 "Expected OID %s, got %s\n",
2602 exts[i].exts.rgExtension[j].pszObjId,
2603 ext->rgExtension[j].pszObjId);
2604 ok(!memcmp(ext->rgExtension[j].Value.pbData,
2605 exts[i].exts.rgExtension[j].Value.pbData,
2606 exts[i].exts.rgExtension[j].Value.cbData),
2607 "Unexpected value\n");
2614 /* MS encodes public key info with a NULL if the algorithm identifier's
2615 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2616 * it encodes them by omitting the algorithm parameters. It accepts either
2617 * form for decoding.
2619 struct encodedPublicKey
2621 CERT_PUBLIC_KEY_INFO info;
2622 const BYTE *encoded;
2623 const BYTE *encodedNoNull;
2624 CERT_PUBLIC_KEY_INFO decoded;
2627 static const BYTE aKey[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2629 static const BYTE params[] = { 0x02, 0x01, 0x01 };
2631 static const unsigned char bin64[] = {
2632 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2633 static const unsigned char bin65[] = {
2634 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2635 static const unsigned char bin66[] = {
2636 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2637 static const unsigned char bin67[] = {
2638 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2639 static const unsigned char bin68[] = {
2640 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,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 bin69[] = {
2643 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2644 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2645 static const unsigned char bin70[] = {
2646 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2647 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2649 static const unsigned char bin71[] = {
2650 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2651 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2653 static unsigned char bin72[] = { 0x05,0x00};
2655 static CHAR oid_bogus[] = "1.2.3",
2656 oid_rsa[] = szOID_RSA;
2658 static const struct encodedPublicKey pubKeys[] = {
2659 /* with a bogus OID */
2660 { { { oid_bogus, { 0, NULL } }, { 0, NULL, 0 } },
2662 { { oid_bogus, { 2, bin72 } }, { 0, NULL, 0 } } },
2663 /* some normal keys */
2664 { { { oid_rsa, { 0, NULL } }, { 0, NULL, 0} },
2666 { { oid_rsa, { 2, bin72 } }, { 0, NULL, 0 } } },
2667 { { { oid_rsa, { 0, NULL } }, { sizeof(aKey), (BYTE *)aKey, 0} },
2669 { { oid_rsa, { 2, bin72 } }, { sizeof(aKey), (BYTE *)aKey, 0} } },
2670 /* with add'l parameters--note they must be DER-encoded */
2671 { { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2672 (BYTE *)aKey, 0 } },
2674 { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2675 (BYTE *)aKey, 0 } } },
2678 static void test_encodePublicKeyInfo(DWORD dwEncoding)
2682 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2688 ret = pCryptEncodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2689 &pubKeys[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf,
2691 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2692 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2695 ok(bufSize == pubKeys[i].encoded[1] + 2,
2696 "Expected %d bytes, got %d\n", pubKeys[i].encoded[1] + 2, bufSize);
2697 if (bufSize == pubKeys[i].encoded[1] + 2)
2698 ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2),
2699 "Unexpected value\n");
2705 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO *expected,
2706 const CERT_PUBLIC_KEY_INFO *got)
2708 ok(!strcmp(expected->Algorithm.pszObjId, got->Algorithm.pszObjId),
2709 "Expected OID %s, got %s\n", expected->Algorithm.pszObjId,
2710 got->Algorithm.pszObjId);
2711 ok(expected->Algorithm.Parameters.cbData ==
2712 got->Algorithm.Parameters.cbData,
2713 "Expected parameters of %d bytes, got %d\n",
2714 expected->Algorithm.Parameters.cbData, got->Algorithm.Parameters.cbData);
2715 if (expected->Algorithm.Parameters.cbData)
2716 ok(!memcmp(expected->Algorithm.Parameters.pbData,
2717 got->Algorithm.Parameters.pbData, got->Algorithm.Parameters.cbData),
2718 "Unexpected algorithm parameters\n");
2719 ok(expected->PublicKey.cbData == got->PublicKey.cbData,
2720 "Expected public key of %d bytes, got %d\n",
2721 expected->PublicKey.cbData, got->PublicKey.cbData);
2722 if (expected->PublicKey.cbData)
2723 ok(!memcmp(expected->PublicKey.pbData, got->PublicKey.pbData,
2724 got->PublicKey.cbData), "Unexpected public key value\n");
2727 static void test_decodePublicKeyInfo(DWORD dwEncoding)
2729 static const BYTE bogusPubKeyInfo[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
2730 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
2731 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
2732 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2738 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2740 /* The NULL form decodes to the decoded member */
2741 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2742 pubKeys[i].encoded, pubKeys[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2743 NULL, &buf, &bufSize);
2744 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2747 comparePublicKeyInfo(&pubKeys[i].decoded,
2748 (CERT_PUBLIC_KEY_INFO *)buf);
2751 /* The non-NULL form decodes to the original */
2752 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2753 pubKeys[i].encodedNoNull, pubKeys[i].encodedNoNull[1] + 2,
2754 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2755 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2758 comparePublicKeyInfo(&pubKeys[i].info, (CERT_PUBLIC_KEY_INFO *)buf);
2762 /* Test with bogus (not valid DER) parameters */
2763 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2764 bogusPubKeyInfo, bogusPubKeyInfo[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2765 NULL, &buf, &bufSize);
2766 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2767 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2768 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2772 static const BYTE v1Cert[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
2773 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2774 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
2775 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
2776 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2777 static const BYTE v2Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02,
2778 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2779 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2780 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2781 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2782 static const BYTE v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2783 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2784 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2785 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2786 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2787 static const BYTE v4Cert[] = {
2788 0x30,0x38,0xa0,0x03,0x02,0x01,0x03,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,
2789 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
2790 0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
2791 0x30,0x30,0x30,0x5a,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00 };
2792 static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
2793 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2794 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2795 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2796 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2797 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2798 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2799 static const BYTE v1CertWithSerial[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
2800 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2801 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2802 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2803 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2804 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2805 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2806 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2807 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
2808 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
2809 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
2810 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
2811 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
2812 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
2813 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
2814 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
2815 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2816 static const BYTE v1CertWithPubKey[] = {
2817 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2818 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2819 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2820 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2821 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2822 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2823 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2824 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2825 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
2826 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
2828 static const BYTE v1CertWithPubKeyNoNull[] = {
2829 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2830 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2831 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2832 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2833 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2834 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2835 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2836 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2837 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
2838 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2839 static const BYTE v1CertWithSubjectKeyId[] = {
2840 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2841 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2842 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2843 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2844 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2845 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2846 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
2847 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2848 0x4c,0x61,0x6e,0x67,0x00 };
2849 static const BYTE v1CertWithIssuerUniqueId[] = {
2850 0x30,0x38,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
2851 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
2852 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
2853 0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x81,0x02,0x00,0x01 };
2854 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueId[] = {
2855 0x30,0x81,0x99,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2856 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2857 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2858 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2859 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2860 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2861 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2862 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2863 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,
2864 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
2865 0x01,0x01,0xff,0x02,0x01,0x01 };
2866 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull[] = {
2867 0x30,0x81,0x97,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2868 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2869 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2870 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2871 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2872 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2873 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2874 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2875 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
2876 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
2877 0xff,0x02,0x01,0x01 };
2879 static const BYTE serialNum[] = { 0x01 };
2881 static void test_encodeCertToBeSigned(DWORD dwEncoding)
2886 CERT_INFO info = { 0 };
2887 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2888 static char oid_subject_key_identifier[] = szOID_SUBJECT_KEY_IDENTIFIER;
2893 /* Test with NULL pvStructInfo (crashes on win9x) */
2894 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL,
2895 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
2896 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2897 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2899 /* Test with a V1 cert */
2900 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2901 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
2902 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2903 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2906 ok(size == v1Cert[1] + 2, "Expected size %d, got %d\n",
2907 v1Cert[1] + 2, size);
2908 ok(!memcmp(buf, v1Cert, size), "Got unexpected value\n");
2912 info.dwVersion = CERT_V2;
2913 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2914 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
2915 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2916 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2919 ok(size == sizeof(v2Cert), "Wrong size %d\n", size);
2920 ok(!memcmp(buf, v2Cert, size), "Got unexpected value\n");
2924 info.dwVersion = CERT_V3;
2925 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2926 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
2927 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2928 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2931 ok(size == sizeof(v3Cert), "Wrong size %d\n", size);
2932 ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n");
2936 info.dwVersion = 3; /* Not a typo, CERT_V3 is 2 */
2937 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2938 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
2941 ok(size == sizeof(v4Cert), "Wrong size %d\n", size);
2942 ok(!memcmp(buf, v4Cert, size), "Unexpected value\n");
2945 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
2946 * API doesn't prevent it)
2948 info.dwVersion = CERT_V1;
2949 info.cExtension = 1;
2950 info.rgExtension = &criticalExt;
2951 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2952 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
2953 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2954 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2957 ok(size == sizeof(v1CertWithConstraints), "Wrong size %d\n", size);
2958 ok(!memcmp(buf, v1CertWithConstraints, size), "Got unexpected value\n");
2961 /* test v1 cert with a serial number */
2962 info.SerialNumber.cbData = sizeof(serialNum);
2963 info.SerialNumber.pbData = (BYTE *)serialNum;
2964 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2965 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
2968 ok(size == sizeof(v1CertWithSerial), "Wrong size %d\n", size);
2969 ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n");
2972 /* Test v1 cert with an issuer name, serial number, and issuer unique id */
2973 info.dwVersion = CERT_V1;
2974 info.cExtension = 0;
2975 info.IssuerUniqueId.cbData = sizeof(serialNum);
2976 info.IssuerUniqueId.pbData = (BYTE *)serialNum;
2977 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2978 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
2979 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2982 ok(size == sizeof(v1CertWithIssuerUniqueId), "Wrong size %d\n", size);
2983 ok(!memcmp(buf, v1CertWithIssuerUniqueId, size),
2984 "Got unexpected value\n");
2987 /* Test v1 cert with an issuer name, a subject name, and a serial number */
2988 info.IssuerUniqueId.cbData = 0;
2989 info.IssuerUniqueId.pbData = NULL;
2990 info.cExtension = 1;
2991 info.rgExtension = &criticalExt;
2992 info.Issuer.cbData = sizeof(encodedCommonName);
2993 info.Issuer.pbData = (BYTE *)encodedCommonName;
2994 info.Subject.cbData = sizeof(encodedCommonName);
2995 info.Subject.pbData = (BYTE *)encodedCommonName;
2996 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2997 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3000 ok(size == sizeof(bigCert), "Wrong size %d\n", size);
3001 ok(!memcmp(buf, bigCert, size), "Got unexpected value\n");
3004 /* Add a public key */
3005 info.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3006 info.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
3007 info.SubjectPublicKeyInfo.PublicKey.pbData = (LPBYTE)aKey;
3008 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3009 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3012 ok(size == sizeof(v1CertWithPubKey) ||
3013 size == sizeof(v1CertWithPubKeyNoNull), "Wrong size %d\n", size);
3014 if (size == sizeof(v1CertWithPubKey))
3015 ok(!memcmp(buf, v1CertWithPubKey, size), "Got unexpected value\n");
3016 else if (size == sizeof(v1CertWithPubKeyNoNull))
3017 ok(!memcmp(buf, v1CertWithPubKeyNoNull, size),
3018 "Got unexpected value\n");
3021 /* Again add an issuer unique id */
3022 info.IssuerUniqueId.cbData = sizeof(serialNum);
3023 info.IssuerUniqueId.pbData = (BYTE *)serialNum;
3024 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3025 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3026 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3029 ok(size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId) ||
3030 size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull),
3031 "Wrong size %d\n", size);
3032 if (size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId))
3033 ok(!memcmp(buf, v1CertWithSubjectIssuerSerialAndIssuerUniqueId,
3034 size), "unexpected value\n");
3036 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull))
3038 v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull, size),
3039 "unexpected value\n");
3042 /* Remove the public key, and add a subject key identifier extension */
3043 info.IssuerUniqueId.cbData = 0;
3044 info.IssuerUniqueId.pbData = NULL;
3045 info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
3046 info.SubjectPublicKeyInfo.PublicKey.cbData = 0;
3047 info.SubjectPublicKeyInfo.PublicKey.pbData = NULL;
3048 ext.pszObjId = oid_subject_key_identifier;
3049 ext.fCritical = FALSE;
3050 ext.Value.cbData = sizeof(octetCommonNameValue);
3051 ext.Value.pbData = octetCommonNameValue;
3052 info.cExtension = 1;
3053 info.rgExtension = &ext;
3054 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3055 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3058 ok(size == sizeof(v1CertWithSubjectKeyId), "Wrong size %d\n", size);
3059 ok(!memcmp(buf, v1CertWithSubjectKeyId, size), "Unexpected value\n");
3064 static void test_decodeCertToBeSigned(DWORD dwEncoding)
3066 static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert, v4Cert,
3067 v1CertWithConstraints, v1CertWithSerial, v1CertWithIssuerUniqueId };
3072 /* Test with NULL pbEncoded */
3073 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 0,
3074 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3075 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
3076 GetLastError() == OSS_BAD_ARG /* Win9x */),
3077 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
3080 /* Crashes on win9x */
3081 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 1,
3082 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3083 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3084 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3086 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT or
3087 * CRYPT_E_ASN1_BADTAG, because at a minimum a cert must have a non-zero
3088 * serial number, an issuer, a subject, and a public key.
3090 for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++)
3092 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3093 corruptCerts[i], corruptCerts[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3095 ok(!ret, "Expected failure\n");
3097 /* The following succeeds, even though v1 certs are not allowed to have
3100 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3101 v1CertWithSubjectKeyId, sizeof(v1CertWithSubjectKeyId),
3102 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3103 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3106 CERT_INFO *info = (CERT_INFO *)buf;
3108 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3109 ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %d\n",
3111 ok(info->cExtension == 1, "expected 1 extension, got %d\n",
3115 /* The following also succeeds, even though V1 certs are not allowed to
3116 * have issuer unique ids.
3118 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3119 v1CertWithSubjectIssuerSerialAndIssuerUniqueId,
3120 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId),
3121 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3123 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3126 CERT_INFO *info = (CERT_INFO *)buf;
3128 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3129 ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %d\n",
3131 ok(info->IssuerUniqueId.cbData == sizeof(serialNum),
3132 "unexpected issuer unique id size %d\n", info->IssuerUniqueId.cbData);
3133 ok(!memcmp(info->IssuerUniqueId.pbData, serialNum, sizeof(serialNum)),
3134 "unexpected issuer unique id value\n");
3137 /* Now check with serial number, subject and issuer specified */
3138 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert,
3139 sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3140 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3143 CERT_INFO *info = (CERT_INFO *)buf;
3145 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3146 ok(info->SerialNumber.cbData == 1,
3147 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3148 ok(*info->SerialNumber.pbData == *serialNum,
3149 "Expected serial number %d, got %d\n", *serialNum,
3150 *info->SerialNumber.pbData);
3151 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3152 "Wrong size %d\n", info->Issuer.cbData);
3153 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3154 "Unexpected issuer\n");
3155 ok(info->Subject.cbData == sizeof(encodedCommonName),
3156 "Wrong size %d\n", info->Subject.cbData);
3157 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3158 info->Subject.cbData), "Unexpected subject\n");
3161 /* Check again with pub key specified */
3162 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3163 v1CertWithPubKey, sizeof(v1CertWithPubKey), CRYPT_DECODE_ALLOC_FLAG, NULL,
3165 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3168 CERT_INFO *info = (CERT_INFO *)buf;
3170 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3171 ok(info->SerialNumber.cbData == 1,
3172 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3173 ok(*info->SerialNumber.pbData == *serialNum,
3174 "Expected serial number %d, got %d\n", *serialNum,
3175 *info->SerialNumber.pbData);
3176 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3177 "Wrong size %d\n", info->Issuer.cbData);
3178 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3179 "Unexpected issuer\n");
3180 ok(info->Subject.cbData == sizeof(encodedCommonName),
3181 "Wrong size %d\n", info->Subject.cbData);
3182 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3183 info->Subject.cbData), "Unexpected subject\n");
3184 ok(!strcmp(info->SubjectPublicKeyInfo.Algorithm.pszObjId,
3185 szOID_RSA_RSA), "Expected szOID_RSA_RSA, got %s\n",
3186 info->SubjectPublicKeyInfo.Algorithm.pszObjId);
3187 ok(info->SubjectPublicKeyInfo.PublicKey.cbData == sizeof(aKey),
3188 "Wrong size %d\n", info->SubjectPublicKeyInfo.PublicKey.cbData);
3189 ok(!memcmp(info->SubjectPublicKeyInfo.PublicKey.pbData, aKey,
3190 sizeof(aKey)), "Unexpected public key\n");
3195 static const BYTE hash[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
3198 static const BYTE signedBigCert[] = {
3199 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
3200 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
3201 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
3202 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3203 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
3204 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
3205 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
3206 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
3207 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
3208 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3209 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
3210 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
3212 static void test_encodeCert(DWORD dwEncoding)
3214 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
3215 * also that bigCert is a NULL-terminated string, so don't count its
3216 * last byte (otherwise the signed cert won't decode.)
3218 CERT_SIGNED_CONTENT_INFO info = { { sizeof(bigCert), (BYTE *)bigCert },
3219 { NULL, { 0, NULL } }, { sizeof(hash), (BYTE *)hash, 0 } };
3224 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT, &info,
3225 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
3226 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3229 ok(bufSize == sizeof(signedBigCert), "Wrong size %d\n", bufSize);
3230 ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n");
3235 static void test_decodeCert(DWORD dwEncoding)
3241 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert,
3242 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3243 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3246 CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf;
3248 ok(info->ToBeSigned.cbData == sizeof(bigCert),
3249 "Wrong cert size %d\n", info->ToBeSigned.cbData);
3250 ok(!memcmp(info->ToBeSigned.pbData, bigCert, info->ToBeSigned.cbData),
3251 "Unexpected cert\n");
3252 ok(info->Signature.cbData == sizeof(hash),
3253 "Wrong signature size %d\n", info->Signature.cbData);
3254 ok(!memcmp(info->Signature.pbData, hash, info->Signature.cbData),
3255 "Unexpected signature\n");
3258 /* A signed cert decodes as a CERT_INFO too */
3259 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCert,
3260 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3261 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3264 CERT_INFO *info = (CERT_INFO *)buf;
3266 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3267 ok(info->SerialNumber.cbData == 1,
3268 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3269 ok(*info->SerialNumber.pbData == *serialNum,
3270 "Expected serial number %d, got %d\n", *serialNum,
3271 *info->SerialNumber.pbData);
3272 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3273 "Wrong size %d\n", info->Issuer.cbData);
3274 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3275 "Unexpected issuer\n");
3276 ok(info->Subject.cbData == sizeof(encodedCommonName),
3277 "Wrong size %d\n", info->Subject.cbData);
3278 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3279 info->Subject.cbData), "Unexpected subject\n");
3284 static const BYTE emptyDistPoint[] = { 0x30, 0x02, 0x30, 0x00 };
3285 static const BYTE distPointWithUrl[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3286 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3287 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3288 static const BYTE distPointWithReason[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3290 static const BYTE distPointWithIssuer[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3291 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3292 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3293 static const BYTE distPointWithUrlAndIssuer[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3294 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3295 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3296 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3297 0x2e, 0x6f, 0x72, 0x67 };
3298 static const BYTE crlReason = CRL_REASON_KEY_COMPROMISE |
3299 CRL_REASON_AFFILIATION_CHANGED;
3301 static void test_encodeCRLDistPoints(DWORD dwEncoding)
3303 CRL_DIST_POINTS_INFO info = { 0 };
3304 CRL_DIST_POINT point = { { 0 } };
3305 CERT_ALT_NAME_ENTRY entry = { 0 };
3310 /* Test with an empty info */
3311 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3312 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3313 ok(!ret && GetLastError() == E_INVALIDARG,
3314 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3315 /* Test with one empty dist point */
3316 info.cDistPoint = 1;
3317 info.rgDistPoint = &point;
3318 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3319 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3320 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3323 ok(size == sizeof(emptyDistPoint), "Wrong size %d\n", size);
3324 ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n");
3327 /* A dist point with an invalid name */
3328 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3329 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3330 U(entry).pwszURL = (LPWSTR)nihongoURL;
3331 U(point.DistPointName).FullName.cAltEntry = 1;
3332 U(point.DistPointName).FullName.rgAltEntry = &entry;
3333 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3334 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3335 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
3336 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
3337 /* The first invalid character is at index 7 */
3338 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
3339 "Expected invalid char at index 7, got %d\n",
3340 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
3341 /* A dist point with (just) a valid name */
3342 U(entry).pwszURL = (LPWSTR)url;
3343 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3344 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3345 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3348 ok(size == sizeof(distPointWithUrl), "Wrong size %d\n", size);
3349 ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n");
3352 /* A dist point with (just) reason flags */
3353 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3354 point.ReasonFlags.cbData = sizeof(crlReason);
3355 point.ReasonFlags.pbData = (LPBYTE)&crlReason;
3356 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3357 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3358 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3361 ok(size == sizeof(distPointWithReason), "Wrong size %d\n", size);
3362 ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n");
3365 /* A dist point with just an issuer */
3366 point.ReasonFlags.cbData = 0;
3367 point.CRLIssuer.cAltEntry = 1;
3368 point.CRLIssuer.rgAltEntry = &entry;
3369 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3370 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3371 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3374 ok(size == sizeof(distPointWithIssuer), "Wrong size %d\n", size);
3375 ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n");
3378 /* A dist point with both a name and an issuer */
3379 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3380 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3381 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3382 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3385 ok(size == sizeof(distPointWithUrlAndIssuer),
3386 "Wrong size %d\n", size);
3387 ok(!memcmp(buf, distPointWithUrlAndIssuer, size), "Unexpected value\n");
3392 static void test_decodeCRLDistPoints(DWORD dwEncoding)
3397 PCRL_DIST_POINTS_INFO info;
3398 PCRL_DIST_POINT point;
3399 PCERT_ALT_NAME_ENTRY entry;
3401 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3402 emptyDistPoint, emptyDistPoint[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3404 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3407 info = (PCRL_DIST_POINTS_INFO)buf;
3408 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3409 "Wrong size %d\n", size);
3410 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3412 point = info->rgDistPoint;
3413 ok(point->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_NO_NAME,
3414 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3415 point->DistPointName.dwDistPointNameChoice);
3416 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3417 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3420 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3421 distPointWithUrl, distPointWithUrl[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3423 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3426 info = (PCRL_DIST_POINTS_INFO)buf;
3427 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3428 "Wrong size %d\n", size);
3429 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3431 point = info->rgDistPoint;
3432 ok(point->DistPointName.dwDistPointNameChoice ==
3433 CRL_DIST_POINT_FULL_NAME,
3434 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3435 point->DistPointName.dwDistPointNameChoice);
3436 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3437 "Expected 1 name entry, got %d\n",
3438 U(point->DistPointName).FullName.cAltEntry);
3439 entry = U(point->DistPointName).FullName.rgAltEntry;
3440 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3441 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3442 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3443 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3444 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3447 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3448 distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
3450 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3453 info = (PCRL_DIST_POINTS_INFO)buf;
3454 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3455 "Wrong size %d\n", size);
3456 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3458 point = info->rgDistPoint;
3459 ok(point->DistPointName.dwDistPointNameChoice ==
3460 CRL_DIST_POINT_NO_NAME,
3461 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3462 point->DistPointName.dwDistPointNameChoice);
3463 ok(point->ReasonFlags.cbData == sizeof(crlReason),
3464 "Expected reason length\n");
3465 ok(!memcmp(point->ReasonFlags.pbData, &crlReason, sizeof(crlReason)),
3466 "Unexpected reason\n");
3467 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3470 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3471 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2,
3472 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3473 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3476 info = (PCRL_DIST_POINTS_INFO)buf;
3477 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3478 "Wrong size %d\n", size);
3479 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3481 point = info->rgDistPoint;
3482 ok(point->DistPointName.dwDistPointNameChoice ==
3483 CRL_DIST_POINT_FULL_NAME,
3484 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3485 point->DistPointName.dwDistPointNameChoice);
3486 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3487 "Expected 1 name entry, got %d\n",
3488 U(point->DistPointName).FullName.cAltEntry);
3489 entry = U(point->DistPointName).FullName.rgAltEntry;
3490 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3491 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3492 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3493 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3494 ok(point->CRLIssuer.cAltEntry == 1,
3495 "Expected 1 issuer entry, got %d\n", point->CRLIssuer.cAltEntry);
3496 entry = point->CRLIssuer.rgAltEntry;
3497 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3498 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3499 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3504 static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3505 static const BYTE emptyNameIDP[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3506 static const BYTE urlIDP[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3507 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3510 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding)
3515 CRL_ISSUING_DIST_POINT point = { { 0 } };
3516 CERT_ALT_NAME_ENTRY entry;
3518 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, NULL,
3519 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3520 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3522 skip("no X509_ISSUING_DIST_POINT encode support\n");
3525 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3526 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3527 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3528 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3529 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3532 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
3533 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
3536 /* nonsensical flags */
3537 point.fOnlyContainsUserCerts = TRUE;
3538 point.fOnlyContainsCACerts = TRUE;
3539 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3540 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3541 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3544 ok(size == sizeof(badFlagsIDP), "Unexpected size %d\n", size);
3545 ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n");
3548 /* unimplemented name type */
3549 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3550 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_ISSUER_RDN_NAME;
3551 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3552 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3553 ok(!ret && GetLastError() == E_INVALIDARG,
3554 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3556 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3557 U(point.DistPointName).FullName.cAltEntry = 0;
3558 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3559 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3560 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3563 ok(size == sizeof(emptyNameIDP), "Unexpected size %d\n", size);
3564 ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n");
3567 /* name with URL entry */
3568 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3569 U(entry).pwszURL = (LPWSTR)url;
3570 U(point.DistPointName).FullName.cAltEntry = 1;
3571 U(point.DistPointName).FullName.rgAltEntry = &entry;
3572 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3573 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3574 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3577 ok(size == sizeof(urlIDP), "Unexpected size %d\n", size);
3578 ok(!memcmp(buf, urlIDP, size), "Unexpected value\n");
3583 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY *expected,
3584 const CERT_ALT_NAME_ENTRY *got)
3586 ok(expected->dwAltNameChoice == got->dwAltNameChoice,
3587 "Expected name choice %d, got %d\n", expected->dwAltNameChoice,
3588 got->dwAltNameChoice);
3589 if (expected->dwAltNameChoice == got->dwAltNameChoice)
3591 switch (got->dwAltNameChoice)
3593 case CERT_ALT_NAME_RFC822_NAME:
3594 case CERT_ALT_NAME_DNS_NAME:
3595 case CERT_ALT_NAME_EDI_PARTY_NAME:
3596 case CERT_ALT_NAME_URL:
3597 case CERT_ALT_NAME_REGISTERED_ID:
3598 ok((!U(*expected).pwszURL && !U(*got).pwszURL) ||
3599 (!U(*expected).pwszURL && !lstrlenW(U(*got).pwszURL)) ||
3600 (!U(*got).pwszURL && !lstrlenW(U(*expected).pwszURL)) ||
3601 !lstrcmpW(U(*expected).pwszURL, U(*got).pwszURL),
3602 "Unexpected name\n");
3604 case CERT_ALT_NAME_X400_ADDRESS:
3605 case CERT_ALT_NAME_DIRECTORY_NAME:
3606 case CERT_ALT_NAME_IP_ADDRESS:
3607 ok(U(*got).IPAddress.cbData == U(*expected).IPAddress.cbData,
3608 "Unexpected IP address length %d\n", U(*got).IPAddress.cbData);
3609 ok(!memcmp(U(*got).IPAddress.pbData, U(*got).IPAddress.pbData,
3610 U(*got).IPAddress.cbData), "Unexpected value\n");
3616 static void compareAltNameInfo(const CERT_ALT_NAME_INFO *expected,
3617 const CERT_ALT_NAME_INFO *got)
3621 ok(expected->cAltEntry == got->cAltEntry, "Expected %d entries, got %d\n",
3622 expected->cAltEntry, got->cAltEntry);
3623 for (i = 0; i < min(expected->cAltEntry, got->cAltEntry); i++)
3624 compareAltNameEntry(&expected->rgAltEntry[i], &got->rgAltEntry[i]);
3627 static void compareDistPointName(const CRL_DIST_POINT_NAME *expected,
3628 const CRL_DIST_POINT_NAME *got)
3630 ok(got->dwDistPointNameChoice == expected->dwDistPointNameChoice,
3631 "Unexpected name choice %d\n", got->dwDistPointNameChoice);
3632 if (got->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME)
3633 compareAltNameInfo(&(U(*expected).FullName), &(U(*got).FullName));
3636 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT *expected,
3637 const CRL_ISSUING_DIST_POINT *got)
3639 compareDistPointName(&expected->DistPointName, &got->DistPointName);
3640 ok(got->fOnlyContainsUserCerts == expected->fOnlyContainsUserCerts,
3641 "Unexpected fOnlyContainsUserCerts\n");
3642 ok(got->fOnlyContainsCACerts == expected->fOnlyContainsCACerts,
3643 "Unexpected fOnlyContainsCACerts\n");
3644 ok(got->OnlySomeReasonFlags.cbData == expected->OnlySomeReasonFlags.cbData,
3645 "Unexpected reason flags\n");
3646 ok(got->fIndirectCRL == expected->fIndirectCRL,
3647 "Unexpected fIndirectCRL\n");
3650 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding)
3655 CRL_ISSUING_DIST_POINT point = { { 0 } };
3657 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3658 emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3660 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3662 skip("no X509_ISSUING_DIST_POINT decode support\n");
3665 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3668 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3671 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3672 badFlagsIDP, badFlagsIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3674 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3677 point.fOnlyContainsUserCerts = point.fOnlyContainsCACerts = TRUE;
3678 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3681 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3682 emptyNameIDP, emptyNameIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3684 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3687 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3688 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3689 U(point.DistPointName).FullName.cAltEntry = 0;
3690 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3693 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3694 urlIDP, urlIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3695 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3698 CERT_ALT_NAME_ENTRY entry;
3700 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3701 U(entry).pwszURL = (LPWSTR)url;
3702 U(point.DistPointName).FullName.cAltEntry = 1;
3703 U(point.DistPointName).FullName.rgAltEntry = &entry;
3704 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3709 static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3710 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3712 static const BYTE v2CRL[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3713 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3714 0x30, 0x30, 0x30, 0x30, 0x5a };
3715 static const BYTE v1CRLWithIssuer[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3716 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3717 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3718 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3720 static const BYTE v1CRLWithIssuerAndEmptyEntry[] = { 0x30, 0x43, 0x30, 0x02,
3721 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3722 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3723 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3724 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3725 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3726 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3727 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3728 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3729 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3730 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3731 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3732 static const BYTE v1CRLWithEntryExt[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3733 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3734 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3735 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3736 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3737 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3738 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3739 static const BYTE v1CRLWithExt[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3740 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3741 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3742 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
3743 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3744 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
3745 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3746 static const BYTE v2CRLWithExt[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
3747 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
3748 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
3749 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
3750 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
3751 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
3752 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3753 static const BYTE v2CRLWithIssuingDistPoint[] = { 0x30,0x5c,0x02,0x01,0x01,
3754 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
3755 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
3756 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
3757 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3758 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
3759 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3761 static void test_encodeCRLToBeSigned(DWORD dwEncoding)
3765 static CHAR oid_issuing_dist_point[] = szOID_ISSUING_DIST_POINT;
3767 CRL_INFO info = { 0 };
3768 CRL_ENTRY entry = { { 0 }, { 0 }, 0, 0 };
3771 /* Test with a V1 CRL */
3772 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3773 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3774 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3775 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3778 ok(size == sizeof(v1CRL), "Wrong size %d\n", size);
3779 ok(!memcmp(buf, v1CRL, size), "Got unexpected value\n");
3783 info.dwVersion = CRL_V2;
3784 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3785 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3786 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3787 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3790 ok(size == v2CRL[1] + 2, "Expected size %d, got %d\n",
3791 v2CRL[1] + 2, size);
3792 ok(!memcmp(buf, v2CRL, size), "Got unexpected value\n");
3795 /* v1 CRL with a name */
3796 info.dwVersion = CRL_V1;
3797 info.Issuer.cbData = sizeof(encodedCommonName);
3798 info.Issuer.pbData = (BYTE *)encodedCommonName;
3799 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3800 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3801 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3804 ok(size == sizeof(v1CRLWithIssuer), "Wrong size %d\n", size);
3805 ok(!memcmp(buf, v1CRLWithIssuer, size), "Got unexpected value\n");
3810 /* v1 CRL with a name and a NULL entry pointer (crashes on win9x) */
3812 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3813 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3814 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3815 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3817 /* now set an empty entry */
3819 info.rgCRLEntry = &entry;
3820 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3821 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3824 ok(size == sizeof(v1CRLWithIssuerAndEmptyEntry),
3825 "Wrong size %d\n", size);
3826 ok(!memcmp(buf, v1CRLWithIssuerAndEmptyEntry, size),
3827 "Got unexpected value\n");
3830 /* an entry with a serial number */
3831 entry.SerialNumber.cbData = sizeof(serialNum);
3832 entry.SerialNumber.pbData = (BYTE *)serialNum;
3833 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3834 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3837 ok(size == sizeof(v1CRLWithIssuerAndEntry),
3838 "Wrong size %d\n", size);
3839 ok(!memcmp(buf, v1CRLWithIssuerAndEntry, size),
3840 "Got unexpected value\n");
3843 /* an entry with an extension */
3844 entry.cExtension = 1;
3845 entry.rgExtension = &criticalExt;
3846 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3847 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3848 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3851 ok(size == sizeof(v1CRLWithEntryExt), "Wrong size %d\n", size);
3852 ok(!memcmp(buf, v1CRLWithEntryExt, size), "Got unexpected value\n");
3855 /* a CRL with an extension */
3856 entry.cExtension = 0;
3857 info.cExtension = 1;
3858 info.rgExtension = &criticalExt;
3859 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3860 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3861 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3864 ok(size == sizeof(v1CRLWithExt), "Wrong size %d\n", size);
3865 ok(!memcmp(buf, v1CRLWithExt, size), "Got unexpected value\n");
3868 /* a v2 CRL with an extension, this time non-critical */
3869 info.dwVersion = CRL_V2;
3870 info.rgExtension = &nonCriticalExt;
3871 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3872 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3873 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3876 ok(size == sizeof(v2CRLWithExt), "Wrong size %d\n", size);
3877 ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n");
3880 /* a v2 CRL with an issuing dist point extension */
3881 ext.pszObjId = oid_issuing_dist_point;
3882 ext.fCritical = TRUE;
3883 ext.Value.cbData = sizeof(urlIDP);
3884 ext.Value.pbData = (LPBYTE)urlIDP;
3885 entry.rgExtension = &ext;
3886 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3887 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3888 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3891 ok(size == sizeof(v2CRLWithIssuingDistPoint), "Wrong size %d\n", size);
3892 ok(!memcmp(buf, v2CRLWithIssuingDistPoint, size), "Unexpected value\n");
3897 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
3898 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
3899 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
3900 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
3901 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
3902 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
3903 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
3904 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
3905 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
3906 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
3907 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
3908 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
3909 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
3910 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
3911 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
3912 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
3913 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
3914 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
3915 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
3916 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
3917 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
3918 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
3919 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
3920 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
3921 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
3922 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
3923 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
3924 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
3925 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
3926 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
3927 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
3928 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
3929 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
3930 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
3932 static const BYTE verisignCRLWithLotsOfEntries[] = {
3933 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
3934 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
3935 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
3936 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
3937 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
3938 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
3939 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
3940 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
3941 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
3942 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
3943 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
3944 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
3945 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
3946 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
3947 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
3948 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
3949 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3950 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
3951 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
3952 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3953 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
3954 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
3955 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
3956 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
3957 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
3958 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
3959 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
3960 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
3961 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
3962 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
3963 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3964 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
3965 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
3966 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3967 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
3968 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
3969 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
3970 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
3971 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
3972 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
3973 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
3974 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
3975 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
3976 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
3977 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
3978 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
3979 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
3980 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
3981 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
3982 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
3983 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
3984 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
3985 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
3986 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
3987 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3988 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
3989 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
3990 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
3991 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
3992 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
3993 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
3994 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
3995 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
3996 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
3997 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
3998 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
3999 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
4000 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
4001 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
4002 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
4003 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
4004 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
4005 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
4006 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
4007 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
4008 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
4009 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
4010 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
4011 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
4012 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
4013 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
4014 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
4015 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
4016 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
4017 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
4018 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
4019 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
4020 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
4021 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
4022 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
4023 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
4024 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
4025 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
4026 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
4027 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
4028 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
4029 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
4030 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
4031 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
4032 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
4033 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
4034 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
4035 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
4036 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
4037 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
4038 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
4039 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
4040 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
4041 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
4042 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
4043 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
4044 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
4045 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
4046 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
4047 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
4048 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
4049 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
4050 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
4051 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
4052 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
4053 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
4054 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
4055 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
4056 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
4057 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
4058 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
4059 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
4060 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
4061 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
4062 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
4063 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
4064 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
4065 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
4066 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
4067 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
4068 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
4069 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
4070 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
4071 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
4072 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
4073 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
4074 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
4075 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
4076 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
4077 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
4078 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
4079 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
4080 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
4081 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
4082 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
4083 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
4084 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
4085 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
4086 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
4087 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
4088 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
4089 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
4090 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
4091 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
4092 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
4093 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
4094 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
4095 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
4096 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
4097 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
4098 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
4099 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
4100 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
4101 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
4102 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
4103 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
4104 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
4105 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
4106 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
4107 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
4108 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
4109 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
4110 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
4111 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
4112 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
4113 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
4114 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
4115 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
4116 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
4117 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
4118 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
4119 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
4120 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
4121 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
4122 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
4123 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
4124 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
4125 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
4126 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
4127 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
4128 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
4129 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
4130 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
4131 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
4132 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
4133 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
4134 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
4135 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
4136 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
4137 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
4138 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
4139 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
4140 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
4141 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
4142 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
4143 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
4144 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
4145 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
4146 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
4147 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
4148 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
4149 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
4150 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
4151 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
4152 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
4153 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
4154 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
4155 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
4156 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
4157 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
4158 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
4159 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
4160 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
4161 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
4162 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
4163 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
4164 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
4165 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
4166 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
4167 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
4168 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
4169 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
4170 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
4171 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
4172 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
4173 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
4174 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
4175 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
4176 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
4177 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
4178 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
4179 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
4180 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
4181 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
4182 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
4183 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
4184 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
4185 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
4186 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
4187 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
4188 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
4189 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
4190 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
4191 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
4192 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
4193 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
4194 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
4195 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
4196 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
4197 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
4198 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
4199 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
4200 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
4201 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
4202 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
4203 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
4204 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
4205 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
4206 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
4207 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
4208 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
4209 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
4210 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
4211 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
4212 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
4213 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
4214 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
4215 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
4216 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
4217 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
4218 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
4219 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
4220 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
4221 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
4222 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
4223 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
4224 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
4225 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
4226 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
4227 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
4228 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
4229 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
4230 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
4231 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
4232 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
4233 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
4234 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
4235 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
4236 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4237 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4238 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4239 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4240 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4241 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4242 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4243 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4244 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4245 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4246 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4247 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4248 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4249 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4250 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4251 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4252 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4253 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4254 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4255 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4256 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4257 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4258 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4259 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4260 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4261 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4262 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4263 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4264 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4265 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4266 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4267 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4268 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4269 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4270 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4271 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4272 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4273 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4274 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4275 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4276 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4277 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4278 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4279 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4280 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4281 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4282 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4283 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4284 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4285 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4286 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4287 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4288 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4289 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4290 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4291 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4292 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4293 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4294 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4295 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4296 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4297 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4298 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4299 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4300 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4301 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4302 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4303 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4304 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4305 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4306 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4307 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4308 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4309 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4310 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4311 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4312 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4313 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4314 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4315 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4316 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4317 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4318 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4319 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4320 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4321 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4322 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4323 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4324 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4325 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4326 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4327 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4328 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4329 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4330 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4331 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4332 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4333 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4334 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4335 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4336 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4337 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4338 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4339 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4340 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4341 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4342 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4343 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4344 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4345 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4346 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4347 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4348 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4349 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4350 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4351 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4352 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4353 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4354 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4355 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4356 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4357 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4358 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4359 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4360 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4361 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4362 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4363 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4364 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4365 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4366 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4367 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4368 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4369 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4370 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4371 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4372 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4373 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4374 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4375 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4376 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4377 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4378 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4379 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4380 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4381 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4382 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4383 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4384 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4385 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4386 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4387 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4388 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4389 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4390 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4391 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4392 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4393 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4394 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4395 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4396 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4397 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4398 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4399 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4400 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4401 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4402 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4403 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4404 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4405 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4406 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4407 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4408 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4409 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4410 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4411 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4412 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4413 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4414 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4415 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4416 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4417 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4418 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4419 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4420 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4421 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4422 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4423 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4424 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4425 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4426 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4427 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4428 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4429 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4430 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4431 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4432 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4433 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4434 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4435 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4436 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4437 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4438 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4439 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4440 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4442 static void test_decodeCRLToBeSigned(DWORD dwEncoding)
4444 static const BYTE *corruptCRLs[] = { v1CRL, v2CRL };
4449 for (i = 0; i < sizeof(corruptCRLs) / sizeof(corruptCRLs[0]); i++)
4451 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4452 corruptCRLs[i], corruptCRLs[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4454 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4455 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4456 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4459 /* at a minimum, a CRL must contain an issuer: */
4460 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4461 v1CRLWithIssuer, v1CRLWithIssuer[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4463 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4466 CRL_INFO *info = (CRL_INFO *)buf;
4468 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4469 ok(info->cCRLEntry == 0, "Expected 0 CRL entries, got %d\n",
4471 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4472 "Wrong issuer size %d\n", info->Issuer.cbData);
4473 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4474 "Unexpected issuer\n");
4477 /* check decoding with an empty CRL entry */
4478 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4479 v1CRLWithIssuerAndEmptyEntry, v1CRLWithIssuerAndEmptyEntry[1] + 2,
4480 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4481 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4482 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4483 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4485 /* with a real CRL entry */
4486 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4487 v1CRLWithIssuerAndEntry, v1CRLWithIssuerAndEntry[1] + 2,
4488 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4489 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4492 CRL_INFO *info = (CRL_INFO *)buf;
4495 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4496 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4498 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4499 entry = info->rgCRLEntry;
4500 ok(entry->SerialNumber.cbData == 1,
4501 "Expected serial number size 1, got %d\n",
4502 entry->SerialNumber.cbData);
4503 ok(*entry->SerialNumber.pbData == *serialNum,
4504 "Expected serial number %d, got %d\n", *serialNum,
4505 *entry->SerialNumber.pbData);
4506 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4507 "Wrong issuer size %d\n", info->Issuer.cbData);
4508 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4509 "Unexpected issuer\n");
4512 /* a real CRL from verisign that has extensions */
4513 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4514 verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG,
4516 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4519 CRL_INFO *info = (CRL_INFO *)buf;
4522 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4523 ok(info->cCRLEntry == 3, "Expected 3 CRL entries, got %d\n",
4525 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4526 entry = info->rgCRLEntry;
4527 ok(info->cExtension == 2, "Expected 2 extensions, got %d\n",
4531 /* another real CRL from verisign that has lots of entries */
4532 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4533 verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries),
4534 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4535 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4538 CRL_INFO *info = (CRL_INFO *)buf;
4540 ok(size >= sizeof(CRL_INFO), "Got size %d\n", size);
4541 ok(info->cCRLEntry == 209, "Expected 209 CRL entries, got %d\n",
4543 ok(info->cExtension == 0, "Expected 0 extensions, got %d\n",
4547 /* and finally, with an extension */
4548 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4549 v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4551 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4554 CRL_INFO *info = (CRL_INFO *)buf;
4557 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4558 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4560 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4561 entry = info->rgCRLEntry;
4562 ok(entry->SerialNumber.cbData == 1,
4563 "Expected serial number size 1, got %d\n",
4564 entry->SerialNumber.cbData);
4565 ok(*entry->SerialNumber.pbData == *serialNum,
4566 "Expected serial number %d, got %d\n", *serialNum,
4567 *entry->SerialNumber.pbData);
4568 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4569 "Wrong issuer size %d\n", info->Issuer.cbData);
4570 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4571 "Unexpected issuer\n");
4572 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4576 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4577 v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4579 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4582 CRL_INFO *info = (CRL_INFO *)buf;
4584 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4588 /* And again, with an issuing dist point */
4589 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4590 v2CRLWithIssuingDistPoint, sizeof(v2CRLWithIssuingDistPoint),
4591 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4592 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4595 CRL_INFO *info = (CRL_INFO *)buf;
4597 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4603 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
4604 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
4605 static const BYTE encodedUsage[] = {
4606 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4607 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4608 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4610 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding)
4615 CERT_ENHKEY_USAGE usage;
4617 /* Test with empty usage */
4618 usage.cUsageIdentifier = 0;
4619 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4620 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4621 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4624 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
4625 ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n");
4628 /* Test with a few usages */
4629 usage.cUsageIdentifier = sizeof(keyUsages) / sizeof(keyUsages[0]);
4630 usage.rgpszUsageIdentifier = (LPSTR *)keyUsages;
4631 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4632 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4633 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4636 ok(size == sizeof(encodedUsage), "Wrong size %d\n", size);
4637 ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n");
4642 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding)
4648 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4649 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4651 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4654 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4656 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4657 "Wrong size %d\n", size);
4658 ok(usage->cUsageIdentifier == 0, "Expected 0 CRL entries, got %d\n",
4659 usage->cUsageIdentifier);
4662 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4663 encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL,
4665 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4668 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4671 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4672 "Wrong size %d\n", size);
4673 ok(usage->cUsageIdentifier == sizeof(keyUsages) / sizeof(keyUsages[0]),
4674 "Wrong CRL entries count %d\n", usage->cUsageIdentifier);
4675 for (i = 0; i < usage->cUsageIdentifier; i++)
4676 ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]),
4677 "Expected OID %s, got %s\n", keyUsages[i],
4678 usage->rgpszUsageIdentifier[i]);
4683 static BYTE keyId[] = { 1,2,3,4 };
4684 static const BYTE authorityKeyIdWithId[] = {
4685 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4686 static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4687 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4688 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4689 static const BYTE authorityKeyIdWithSerial[] = { 0x30,0x03,0x82,0x01,0x01 };
4691 static void test_encodeAuthorityKeyId(DWORD dwEncoding)
4693 CERT_AUTHORITY_KEY_ID_INFO info = { { 0 } };
4698 /* Test with empty id */
4699 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4700 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4701 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4704 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4705 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4708 /* With just a key id */
4709 info.KeyId.cbData = sizeof(keyId);
4710 info.KeyId.pbData = keyId;
4711 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4712 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4713 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4716 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", size);
4717 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4720 /* With just an issuer */
4721 info.KeyId.cbData = 0;
4722 info.CertIssuer.cbData = sizeof(encodedCommonName);
4723 info.CertIssuer.pbData = (BYTE *)encodedCommonName;
4724 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4725 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4726 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4729 ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %d\n",
4731 ok(!memcmp(buf, authorityKeyIdWithIssuer, size), "Unexpected value\n");
4734 /* With just a serial number */
4735 info.CertIssuer.cbData = 0;
4736 info.CertSerialNumber.cbData = sizeof(serialNum);
4737 info.CertSerialNumber.pbData = (BYTE *)serialNum;
4738 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4739 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4740 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4743 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4745 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4750 static void test_decodeAuthorityKeyId(DWORD dwEncoding)
4756 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4757 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4759 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4762 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4764 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4766 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4767 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4768 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4771 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4772 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4773 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4774 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4777 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4779 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4781 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4782 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4783 "Unexpected key id\n");
4784 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4785 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4788 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4789 authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer),
4790 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4791 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4794 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4796 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4798 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4799 ok(info->CertIssuer.cbData == sizeof(encodedCommonName),
4800 "Unexpected issuer len\n");
4801 ok(!memcmp(info->CertIssuer.pbData, encodedCommonName,
4802 sizeof(encodedCommonName)), "Unexpected issuer\n");
4803 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4806 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4807 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4808 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4809 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4812 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4814 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4816 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4817 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4818 ok(info->CertSerialNumber.cbData == sizeof(serialNum),
4819 "Unexpected serial number len\n");
4820 ok(!memcmp(info->CertSerialNumber.pbData, serialNum, sizeof(serialNum)),
4821 "Unexpected serial number\n");
4826 static const BYTE authorityKeyIdWithIssuerUrl[] = { 0x30,0x15,0xa1,0x13,0x86,
4827 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
4830 static void test_encodeAuthorityKeyId2(DWORD dwEncoding)
4832 CERT_AUTHORITY_KEY_ID2_INFO info = { { 0 } };
4833 CERT_ALT_NAME_ENTRY entry = { 0 };
4838 /* Test with empty id */
4839 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4840 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4841 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4844 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4845 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4848 /* With just a key id */
4849 info.KeyId.cbData = sizeof(keyId);
4850 info.KeyId.pbData = keyId;
4851 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4852 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4853 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4856 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n",
4858 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4861 /* With a bogus issuer name */
4862 info.KeyId.cbData = 0;
4863 info.AuthorityCertIssuer.cAltEntry = 1;
4864 info.AuthorityCertIssuer.rgAltEntry = &entry;
4865 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4866 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4867 ok(!ret && GetLastError() == E_INVALIDARG,
4868 "Expected E_INVALIDARG, got %08x\n", GetLastError());
4869 /* With an issuer name */
4870 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
4871 U(entry).pwszURL = (LPWSTR)url;
4872 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4873 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4874 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4877 ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %d\n",
4879 ok(!memcmp(buf, authorityKeyIdWithIssuerUrl, size),
4880 "Unexpected value\n");
4883 /* With just a serial number */
4884 info.AuthorityCertIssuer.cAltEntry = 0;
4885 info.AuthorityCertSerialNumber.cbData = sizeof(serialNum);
4886 info.AuthorityCertSerialNumber.pbData = (BYTE *)serialNum;
4887 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4888 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4889 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4892 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4894 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4899 static void test_decodeAuthorityKeyId2(DWORD dwEncoding)
4905 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4906 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4908 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4911 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4913 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4915 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4916 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4917 "Expected no issuer name entries\n");
4918 ok(info->AuthorityCertSerialNumber.cbData == 0,
4919 "Expected no serial number\n");
4922 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4923 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4924 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4925 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4928 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4930 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4932 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4933 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4934 "Unexpected key id\n");
4935 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4936 "Expected no issuer name entries\n");
4937 ok(info->AuthorityCertSerialNumber.cbData == 0,
4938 "Expected no serial number\n");
4941 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4942 authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl),
4943 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4944 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4947 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4949 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4951 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4952 ok(info->AuthorityCertIssuer.cAltEntry == 1,
4953 "Expected 1 issuer entry, got %d\n",
4954 info->AuthorityCertIssuer.cAltEntry);
4955 ok(info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice ==
4956 CERT_ALT_NAME_URL, "Expected CERT_ALT_NAME_URL, got %d\n",
4957 info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice);
4958 ok(!lstrcmpW(U(info->AuthorityCertIssuer.rgAltEntry[0]).pwszURL,
4959 url), "Unexpected URL\n");
4960 ok(info->AuthorityCertSerialNumber.cbData == 0,
4961 "Expected no serial number\n");
4964 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4965 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4966 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4967 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4970 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4972 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4974 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4975 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4976 "Expected no issuer name entries\n");
4977 ok(info->AuthorityCertSerialNumber.cbData == sizeof(serialNum),
4978 "Unexpected serial number len\n");
4979 ok(!memcmp(info->AuthorityCertSerialNumber.pbData, serialNum,
4980 sizeof(serialNum)), "Unexpected serial number\n");
4985 static const BYTE authorityInfoAccessWithUrl[] = {
4986 0x30,0x19,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
4987 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
4988 static const BYTE authorityInfoAccessWithUrlAndIPAddr[] = {
4989 0x30,0x29,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
4990 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x0e,0x06,
4991 0x02,0x2d,0x06,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
4993 static void test_encodeAuthorityInfoAccess(DWORD dwEncoding)
4995 static char oid1[] = "1.2.3";
4996 static char oid2[] = "1.5.6";
5000 CERT_ACCESS_DESCRIPTION accessDescription[2];
5001 CERT_AUTHORITY_INFO_ACCESS aia;
5003 memset(accessDescription, 0, sizeof(accessDescription));
5005 aia.rgAccDescr = NULL;
5006 /* Having no access descriptions is allowed */
5007 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5008 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5009 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5012 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
5013 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
5017 /* It can't have an empty access method */
5019 aia.rgAccDescr = accessDescription;
5020 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5021 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5022 ok(!ret && (GetLastError() == E_INVALIDARG ||
5023 GetLastError() == OSS_LIMITED /* Win9x */),
5024 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
5025 /* It can't have an empty location */
5026 accessDescription[0].pszAccessMethod = oid1;
5027 SetLastError(0xdeadbeef);
5028 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5029 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5030 ok(!ret && GetLastError() == E_INVALIDARG,
5031 "expected E_INVALIDARG, got %08x\n", GetLastError());
5032 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5033 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
5034 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5035 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5036 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5039 ok(size == sizeof(authorityInfoAccessWithUrl), "unexpected size %d\n",
5041 ok(!memcmp(buf, authorityInfoAccessWithUrl, size),
5042 "unexpected value\n");
5046 accessDescription[1].pszAccessMethod = oid2;
5047 accessDescription[1].AccessLocation.dwAltNameChoice =
5048 CERT_ALT_NAME_IP_ADDRESS;
5049 U(accessDescription[1].AccessLocation).IPAddress.cbData =
5050 sizeof(encodedIPAddr);
5051 U(accessDescription[1].AccessLocation).IPAddress.pbData =
5052 (LPBYTE)encodedIPAddr;
5054 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5055 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5056 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5059 ok(size == sizeof(authorityInfoAccessWithUrlAndIPAddr),
5060 "unexpected size %d\n", size);
5061 ok(!memcmp(buf, authorityInfoAccessWithUrlAndIPAddr, size),
5062 "unexpected value\n");
5068 static void compareAuthorityInfoAccess(LPCSTR header,
5069 const CERT_AUTHORITY_INFO_ACCESS *expected,
5070 const CERT_AUTHORITY_INFO_ACCESS *got)
5074 ok(expected->cAccDescr == got->cAccDescr,
5075 "%s: expected %d access descriptions, got %d\n", header,
5076 expected->cAccDescr, got->cAccDescr);
5077 for (i = 0; i < expected->cAccDescr; i++)
5079 ok(!strcmp(expected->rgAccDescr[i].pszAccessMethod,
5080 got->rgAccDescr[i].pszAccessMethod), "%s[%d]: expected %s, got %s\n",
5081 header, i, expected->rgAccDescr[i].pszAccessMethod,
5082 got->rgAccDescr[i].pszAccessMethod);
5083 compareAltNameEntry(&expected->rgAccDescr[i].AccessLocation,
5084 &got->rgAccDescr[i].AccessLocation);
5088 static void test_decodeAuthorityInfoAccess(DWORD dwEncoding)
5090 static char oid1[] = "1.2.3";
5091 static char oid2[] = "1.5.6";
5096 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5097 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
5099 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5102 CERT_AUTHORITY_INFO_ACCESS aia = { 0, NULL };
5104 compareAuthorityInfoAccess("empty AIA", &aia,
5105 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5109 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5110 authorityInfoAccessWithUrl, sizeof(authorityInfoAccessWithUrl),
5111 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5112 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5115 CERT_ACCESS_DESCRIPTION accessDescription;
5116 CERT_AUTHORITY_INFO_ACCESS aia;
5118 accessDescription.pszAccessMethod = oid1;
5119 accessDescription.AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5120 U(accessDescription.AccessLocation).pwszURL = (LPWSTR)url;
5122 aia.rgAccDescr = &accessDescription;
5123 compareAuthorityInfoAccess("AIA with URL", &aia,
5124 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5128 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5129 authorityInfoAccessWithUrlAndIPAddr,
5130 sizeof(authorityInfoAccessWithUrlAndIPAddr), CRYPT_DECODE_ALLOC_FLAG,
5132 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5135 CERT_ACCESS_DESCRIPTION accessDescription[2];
5136 CERT_AUTHORITY_INFO_ACCESS aia;
5138 accessDescription[0].pszAccessMethod = oid1;
5139 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5140 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
5141 accessDescription[1].pszAccessMethod = oid2;
5142 accessDescription[1].AccessLocation.dwAltNameChoice =
5143 CERT_ALT_NAME_IP_ADDRESS;
5144 U(accessDescription[1].AccessLocation).IPAddress.cbData =
5145 sizeof(encodedIPAddr);
5146 U(accessDescription[1].AccessLocation).IPAddress.pbData =
5147 (LPBYTE)encodedIPAddr;
5149 aia.rgAccDescr = accessDescription;
5150 compareAuthorityInfoAccess("AIA with URL and IP addr", &aia,
5151 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5157 static const BYTE emptyCTL[] = {
5158 0x30,0x17,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5159 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5160 static const BYTE emptyCTLWithVersion1[] = {
5161 0x30,0x1a,0x02,0x01,0x01,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5162 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5163 static const BYTE ctlWithUsageIdentifier[] = {
5164 0x30,0x1b,0x30,0x04,0x06,0x02,0x2a,0x03,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
5165 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5166 static const BYTE ctlWithListIdentifier[] = {
5167 0x30,0x1a,0x30,0x00,0x04,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5168 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5169 static const BYTE ctlWithSequenceNumber[] = {
5170 0x30,0x1a,0x30,0x00,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5171 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5172 static const BYTE ctlWithThisUpdate[] = {
5173 0x30,0x15,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5174 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5175 static const BYTE ctlWithThisAndNextUpdate[] = {
5176 0x30,0x24,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5177 0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5178 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5179 static const BYTE ctlWithAlgId[] = {
5180 0x30,0x1b,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5181 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5182 static const BYTE ctlWithBogusEntry[] = {
5183 0x30,0x29,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5184 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x10,0x30,0x0e,0x04,
5185 0x01,0x01,0x31,0x09,0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,0x01 };
5186 static const BYTE ctlWithOneEntry[] = {
5187 0x30,0x2a,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5188 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x11,0x30,0x0f,0x04,
5189 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00 };
5190 static const BYTE ctlWithTwoEntries[] = {
5191 0x30,0x41,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5192 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x28,0x30,0x0f,0x04,
5193 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00,0x30,
5194 0x15,0x04,0x01,0x01,0x31,0x10,0x30,0x0e,0x06,0x02,0x2d,0x06,0x31,0x08,0x30,
5195 0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5197 static void test_encodeCTL(DWORD dwEncoding)
5199 static char oid1[] = "1.2.3";
5200 static char oid2[] = "1.5.6";
5206 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5207 CTL_ENTRY ctlEntry[2];
5208 CRYPT_ATTRIBUTE attr1, attr2;
5209 CRYPT_ATTR_BLOB value1, value2;
5211 memset(&info, 0, sizeof(info));
5212 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5213 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5214 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5217 ok(size == sizeof(emptyCTL), "unexpected size %d\n", size);
5218 ok(!memcmp(buf, emptyCTL, size), "unexpected value\n");
5223 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5224 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5225 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5228 ok(size == sizeof(emptyCTLWithVersion1), "unexpected size %d\n", size);
5229 ok(!memcmp(buf, emptyCTLWithVersion1, size), "unexpected value\n");
5234 info.SubjectUsage.cUsageIdentifier = 1;
5235 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5236 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5237 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5238 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5241 ok(size == sizeof(ctlWithUsageIdentifier), "unexpected size %d\n",
5243 ok(!memcmp(buf, ctlWithUsageIdentifier, size), "unexpected value\n");
5247 info.SubjectUsage.cUsageIdentifier = 0;
5248 info.ListIdentifier.cbData = sizeof(serialNum);
5249 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5250 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5251 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5252 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5255 ok(size == sizeof(ctlWithListIdentifier), "unexpected size %d\n", size);
5256 ok(!memcmp(buf, ctlWithListIdentifier, size), "unexpected value\n");
5260 info.ListIdentifier.cbData = 0;
5261 info.SequenceNumber.cbData = sizeof(serialNum);
5262 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5263 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5264 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5265 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5268 ok(size == sizeof(ctlWithSequenceNumber), "unexpected size %d\n",
5270 ok(!memcmp(buf, ctlWithSequenceNumber, size), "unexpected value\n");
5274 info.SequenceNumber.cbData = 0;
5275 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5276 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5277 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5278 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5281 ok(size == sizeof(ctlWithThisUpdate), "unexpected size %d\n", size);
5282 ok(!memcmp(buf, ctlWithThisUpdate, size), "unexpected value\n");
5286 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5287 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5288 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5289 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5292 ok(size == sizeof(ctlWithThisAndNextUpdate), "unexpected size %d\n",
5294 ok(!memcmp(buf, ctlWithThisAndNextUpdate, size), "unexpected value\n");
5298 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5299 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5300 info.SubjectAlgorithm.pszObjId = oid2;
5301 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5302 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5303 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5306 ok(size == sizeof(ctlWithAlgId), "unexpected size %d\n", size);
5307 ok(!memcmp(buf, ctlWithAlgId, size), "unexpected value\n");
5311 /* The value is supposed to be asn.1 encoded, so this'll fail to decode
5312 * (see tests below) but it'll encode fine.
5314 info.SubjectAlgorithm.pszObjId = NULL;
5315 value1.cbData = sizeof(serialNum);
5316 value1.pbData = (LPBYTE)serialNum;
5317 attr1.pszObjId = oid1;
5319 attr1.rgValue = &value1;
5320 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5321 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5322 ctlEntry[0].cAttribute = 1;
5323 ctlEntry[0].rgAttribute = &attr1;
5325 info.rgCTLEntry = ctlEntry;
5326 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5327 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5328 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5331 ok(size == sizeof(ctlWithBogusEntry), "unexpected size %d\n", size);
5332 ok(!memcmp(buf, ctlWithBogusEntry, size), "unexpected value\n");
5336 value1.cbData = sizeof(emptySequence);
5337 value1.pbData = (LPBYTE)emptySequence;
5338 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5339 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5340 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5343 ok(size == sizeof(ctlWithOneEntry), "unexpected size %d\n", size);
5344 ok(!memcmp(buf, ctlWithOneEntry, size), "unexpected value\n");
5348 value2.cbData = sizeof(encodedIPAddr);
5349 value2.pbData = (LPBYTE)encodedIPAddr;
5350 attr2.pszObjId = oid2;
5352 attr2.rgValue = &value2;
5353 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5354 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5355 ctlEntry[1].cAttribute = 1;
5356 ctlEntry[1].rgAttribute = &attr2;
5358 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5359 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5360 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5363 ok(size == sizeof(ctlWithTwoEntries), "unexpected size %d\n", size);
5364 ok(!memcmp(buf, ctlWithTwoEntries, size), "unexpected value\n");
5370 static void compareCTLInfo(LPCSTR header, const CTL_INFO *expected,
5371 const CTL_INFO *got)
5375 ok(expected->dwVersion == got->dwVersion,
5376 "%s: expected version %d, got %d\n", header, expected->dwVersion,
5378 ok(expected->SubjectUsage.cUsageIdentifier ==
5379 got->SubjectUsage.cUsageIdentifier,
5380 "%s: expected %d usage identifiers, got %d\n", header,
5381 expected->SubjectUsage.cUsageIdentifier,
5382 got->SubjectUsage.cUsageIdentifier);
5383 for (i = 0; i < expected->SubjectUsage.cUsageIdentifier; i++)
5384 ok(!strcmp(expected->SubjectUsage.rgpszUsageIdentifier[i],
5385 got->SubjectUsage.rgpszUsageIdentifier[i]),
5386 "%s[%d]: expected %s, got %s\n", header, i,
5387 expected->SubjectUsage.rgpszUsageIdentifier[i],
5388 got->SubjectUsage.rgpszUsageIdentifier[i]);
5389 ok(expected->ListIdentifier.cbData == got->ListIdentifier.cbData,
5390 "%s: expected list identifier of %d bytes, got %d\n", header,
5391 expected->ListIdentifier.cbData, got->ListIdentifier.cbData);
5392 if (expected->ListIdentifier.cbData)
5393 ok(!memcmp(expected->ListIdentifier.pbData, got->ListIdentifier.pbData,
5394 expected->ListIdentifier.cbData),
5395 "%s: unexpected list identifier value\n", header);
5396 ok(expected->SequenceNumber.cbData == got->SequenceNumber.cbData,
5397 "%s: expected sequence number of %d bytes, got %d\n", header,
5398 expected->SequenceNumber.cbData, got->SequenceNumber.cbData);
5399 if (expected->SequenceNumber.cbData)
5400 ok(!memcmp(expected->SequenceNumber.pbData, got->SequenceNumber.pbData,
5401 expected->SequenceNumber.cbData),
5402 "%s: unexpected sequence number value\n", header);
5403 ok(!memcmp(&expected->ThisUpdate, &got->ThisUpdate, sizeof(FILETIME)),
5404 "%s: expected this update = (%d, %d), got (%d, %d)\n", header,
5405 expected->ThisUpdate.dwLowDateTime, expected->ThisUpdate.dwHighDateTime,
5406 got->ThisUpdate.dwLowDateTime, got->ThisUpdate.dwHighDateTime);
5407 ok(!memcmp(&expected->NextUpdate, &got->NextUpdate, sizeof(FILETIME)),
5408 "%s: expected next update = (%d, %d), got (%d, %d)\n", header,
5409 expected->NextUpdate.dwLowDateTime, expected->NextUpdate.dwHighDateTime,
5410 got->NextUpdate.dwLowDateTime, got->NextUpdate.dwHighDateTime);
5411 if (expected->SubjectAlgorithm.pszObjId &&
5412 *expected->SubjectAlgorithm.pszObjId && !got->SubjectAlgorithm.pszObjId)
5413 ok(0, "%s: expected subject algorithm %s, got NULL\n", header,
5414 expected->SubjectAlgorithm.pszObjId);
5415 if (expected->SubjectAlgorithm.pszObjId && got->SubjectAlgorithm.pszObjId)
5416 ok(!strcmp(expected->SubjectAlgorithm.pszObjId,
5417 got->SubjectAlgorithm.pszObjId),
5418 "%s: expected subject algorithm %s, got %s\n", header,
5419 expected->SubjectAlgorithm.pszObjId, got->SubjectAlgorithm.pszObjId);
5420 ok(expected->SubjectAlgorithm.Parameters.cbData ==
5421 got->SubjectAlgorithm.Parameters.cbData,
5422 "%s: expected subject algorithm parameters of %d bytes, got %d\n", header,
5423 expected->SubjectAlgorithm.Parameters.cbData,
5424 got->SubjectAlgorithm.Parameters.cbData);
5425 if (expected->SubjectAlgorithm.Parameters.cbData)
5426 ok(!memcmp(expected->SubjectAlgorithm.Parameters.pbData,
5427 got->SubjectAlgorithm.Parameters.pbData,
5428 expected->SubjectAlgorithm.Parameters.cbData),
5429 "%s: unexpected subject algorithm parameter value\n", header);
5430 ok(expected->cCTLEntry == got->cCTLEntry,
5431 "%s: expected %d CTL entries, got %d\n", header, expected->cCTLEntry,
5433 for (i = 0; i < expected->cCTLEntry; i++)
5435 ok(expected->rgCTLEntry[i].SubjectIdentifier.cbData ==
5436 got->rgCTLEntry[i].SubjectIdentifier.cbData,
5437 "%s[%d]: expected subject identifier of %d bytes, got %d\n",
5438 header, i, expected->rgCTLEntry[i].SubjectIdentifier.cbData,
5439 got->rgCTLEntry[i].SubjectIdentifier.cbData);
5440 if (expected->rgCTLEntry[i].SubjectIdentifier.cbData)
5441 ok(!memcmp(expected->rgCTLEntry[i].SubjectIdentifier.pbData,
5442 got->rgCTLEntry[i].SubjectIdentifier.pbData,
5443 expected->rgCTLEntry[i].SubjectIdentifier.cbData),
5444 "%s[%d]: unexpected subject identifier value\n",
5446 for (j = 0; j < expected->rgCTLEntry[i].cAttribute; j++)
5448 ok(!strcmp(expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5449 got->rgCTLEntry[i].rgAttribute[j].pszObjId),
5450 "%s[%d][%d]: expected attribute OID %s, got %s\n", header, i, j,
5451 expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5452 got->rgCTLEntry[i].rgAttribute[j].pszObjId);
5453 for (k = 0; k < expected->rgCTLEntry[i].rgAttribute[j].cValue; k++)
5455 ok(expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData ==
5456 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5457 "%s[%d][%d][%d]: expected value of %d bytes, got %d\n",
5459 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5460 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData);
5461 if (expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData)
5463 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5464 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5465 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData),
5466 "%s[%d][%d][%d]: unexpected value\n",
5471 ok(expected->cExtension == got->cExtension,
5472 "%s: expected %d extensions, got %d\n", header, expected->cExtension,
5474 for (i = 0; i < expected->cExtension; i++)
5476 ok(!strcmp(expected->rgExtension[i].pszObjId,
5477 got->rgExtension[i].pszObjId), "%s[%d]: expected %s, got %s\n",
5478 header, i, expected->rgExtension[i].pszObjId,
5479 got->rgExtension[i].pszObjId);
5480 ok(expected->rgExtension[i].fCritical == got->rgExtension[i].fCritical,
5481 "%s[%d]: expected fCritical = %d, got %d\n", header, i,
5482 expected->rgExtension[i].fCritical, got->rgExtension[i].fCritical);
5483 ok(expected->rgExtension[i].Value.cbData ==
5484 got->rgExtension[i].Value.cbData,
5485 "%s[%d]: expected extension value to have %d bytes, got %d\n",
5486 header, i, expected->rgExtension[i].Value.cbData,
5487 got->rgExtension[i].Value.cbData);
5488 if (expected->rgExtension[i].Value.cbData)
5489 ok(!memcmp(expected->rgExtension[i].Value.pbData,
5490 got->rgExtension[i].Value.pbData,
5491 expected->rgExtension[i].Value.cbData),
5492 "%s[%d]: unexpected extension value\n", header, i);
5496 static const BYTE signedCTL[] = {
5497 0x30,0x81,0xc7,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
5498 0x81,0xb9,0x30,0x81,0xb6,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
5499 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x28,0x06,0x09,0x2a,0x86,
5500 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x1b,0x04,0x19,0x30,0x17,0x30,0x00,
5501 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5502 0x30,0x5a,0x30,0x02,0x06,0x00,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
5503 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
5504 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
5505 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5506 0x00,0x04,0x40,0xca,0xd8,0x32,0xd1,0xbd,0x97,0x61,0x54,0xd6,0x80,0xcf,0x0d,
5507 0xbd,0xa2,0x42,0xc7,0xca,0x37,0x91,0x7d,0x9d,0xac,0x8c,0xdf,0x05,0x8a,0x39,
5508 0xc6,0x07,0xc1,0x37,0xe6,0xb9,0xd1,0x0d,0x26,0xec,0xa5,0xb0,0x8a,0x51,0x26,
5509 0x2b,0x4f,0x73,0x44,0x86,0x83,0x5e,0x2b,0x6e,0xcc,0xf8,0x1b,0x85,0x53,0xe9,
5510 0x7a,0x80,0x8f,0x6b,0x42,0x19,0x93 };
5511 static const BYTE signedCTLWithCTLInnerContent[] = {
5512 0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
5513 0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
5514 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
5515 0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
5516 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5517 0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
5518 0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
5519 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
5520 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
5521 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
5522 0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
5523 0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
5524 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
5525 0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5526 0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
5527 0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
5528 0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
5529 0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
5530 0x57,0x6c,0x0b,0x47,0xb8 };
5532 static void test_decodeCTL(DWORD dwEncoding)
5534 static char oid1[] = "1.2.3";
5535 static char oid2[] = "1.5.6";
5536 static BYTE nullData[] = { 5,0 };
5542 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5543 CTL_ENTRY ctlEntry[2];
5544 CRYPT_ATTRIBUTE attr1, attr2;
5545 CRYPT_ATTR_BLOB value1, value2;
5547 memset(&info, 0, sizeof(info));
5548 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTL, sizeof(emptyCTL),
5549 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5550 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5553 compareCTLInfo("empty CTL", &info, (CTL_INFO *)buf);
5558 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTLWithVersion1,
5559 sizeof(emptyCTLWithVersion1), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
5561 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5564 compareCTLInfo("v1 CTL", &info, (CTL_INFO *)buf);
5569 info.SubjectUsage.cUsageIdentifier = 1;
5570 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5571 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithUsageIdentifier,
5572 sizeof(ctlWithUsageIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5574 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5577 compareCTLInfo("CTL with usage identifier", &info, (CTL_INFO *)buf);
5581 info.SubjectUsage.cUsageIdentifier = 0;
5582 info.ListIdentifier.cbData = sizeof(serialNum);
5583 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5584 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithListIdentifier,
5585 sizeof(ctlWithListIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5586 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5589 compareCTLInfo("CTL with list identifier", &info, (CTL_INFO *)buf);
5593 info.ListIdentifier.cbData = 0;
5594 info.SequenceNumber.cbData = sizeof(serialNum);
5595 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5596 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithSequenceNumber,
5597 sizeof(ctlWithSequenceNumber), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5598 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5601 compareCTLInfo("CTL with sequence number", &info, (CTL_INFO *)buf);
5605 info.SequenceNumber.cbData = 0;
5606 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5607 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisUpdate,
5608 sizeof(ctlWithThisUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5609 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5612 compareCTLInfo("CTL with this update", &info, (CTL_INFO *)buf);
5616 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5617 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisAndNextUpdate,
5618 sizeof(ctlWithThisAndNextUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5620 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5623 compareCTLInfo("CTL with this and next update", &info, (CTL_INFO *)buf);
5627 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5628 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5629 info.SubjectAlgorithm.pszObjId = oid2;
5630 info.SubjectAlgorithm.Parameters.cbData = sizeof(nullData);
5631 info.SubjectAlgorithm.Parameters.pbData = nullData;
5632 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithAlgId,
5633 sizeof(ctlWithAlgId), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5634 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5637 compareCTLInfo("CTL with algorithm identifier", &info, (CTL_INFO *)buf);
5641 SetLastError(0xdeadbeef);
5642 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithBogusEntry,
5643 sizeof(ctlWithBogusEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5645 (GetLastError() == CRYPT_E_ASN1_EOD ||
5646 GetLastError() == CRYPT_E_ASN1_CORRUPT ||
5647 GetLastError() == OSS_MORE_INPUT), /* Win9x */
5648 "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n",
5650 info.SubjectAlgorithm.Parameters.cbData = 0;
5651 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5652 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5653 info.SubjectAlgorithm.pszObjId = oid2;
5654 info.SubjectAlgorithm.pszObjId = NULL;
5655 value1.cbData = sizeof(emptySequence);
5656 value1.pbData = (LPBYTE)emptySequence;
5657 attr1.pszObjId = oid1;
5659 attr1.rgValue = &value1;
5660 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5661 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5662 ctlEntry[0].cAttribute = 1;
5663 ctlEntry[0].rgAttribute = &attr1;
5665 info.rgCTLEntry = ctlEntry;
5666 SetLastError(0xdeadbeef);
5667 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithOneEntry,
5668 sizeof(ctlWithOneEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5669 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5672 compareCTLInfo("CTL with one entry", &info, (CTL_INFO *)buf);
5676 value2.cbData = sizeof(encodedIPAddr);
5677 value2.pbData = (LPBYTE)encodedIPAddr;
5678 attr2.pszObjId = oid2;
5680 attr2.rgValue = &value2;
5681 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5682 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5683 ctlEntry[1].cAttribute = 1;
5684 ctlEntry[1].rgAttribute = &attr2;
5686 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithTwoEntries,
5687 sizeof(ctlWithTwoEntries), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5688 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5691 compareCTLInfo("CTL with two entries", &info, (CTL_INFO *)buf);
5695 /* A signed CTL isn't decodable, even if the inner content is a CTL */
5696 SetLastError(0xdeadbeef);
5697 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, signedCTL,
5698 sizeof(signedCTL), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5699 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5700 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5701 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5703 SetLastError(0xdeadbeef);
5704 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL,
5705 signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent),
5706 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5707 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5708 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5709 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5713 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
5714 static const BYTE emptyPKCSContentInfoExtraBytes[] = { 0x30,0x04,0x06,0x02,0x2a,
5716 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
5718 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
5719 0x03,0x02,0x01,0x01 };
5720 static BYTE bogusDER[] = { 1 };
5722 static void test_encodePKCSContentInfo(DWORD dwEncoding)
5727 CRYPT_CONTENT_INFO info = { 0 };
5728 char oid1[] = "1.2.3";
5732 /* Crashes on win9x */
5733 SetLastError(0xdeadbeef);
5734 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL,
5735 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5736 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5737 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5739 SetLastError(0xdeadbeef);
5740 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5741 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5742 ok(!ret && (GetLastError() == E_INVALIDARG ||
5743 GetLastError() == OSS_LIMITED /* Win9x */),
5744 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5745 info.pszObjId = oid1;
5746 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5747 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5748 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5751 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size);
5752 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n");
5755 info.Content.pbData = bogusDER;
5756 info.Content.cbData = sizeof(bogusDER);
5757 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5758 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5759 ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError());
5762 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size);
5763 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n");
5766 info.Content.pbData = (BYTE *)ints[0].encoded;
5767 info.Content.cbData = ints[0].encoded[1] + 2;
5768 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5769 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5772 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size);
5773 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n");
5778 static const BYTE indefiniteSignedPKCSContent[] = {
5779 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
5780 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
5781 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
5782 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
5783 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
5784 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
5785 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5786 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5787 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
5788 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5789 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5790 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
5791 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
5792 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
5793 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
5794 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
5795 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
5796 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
5797 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
5798 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5799 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5800 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
5801 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
5802 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
5803 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
5804 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
5805 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
5806 0x00,0x00,0x00,0x00,0x00,0x00 };
5808 static void test_decodePKCSContentInfo(DWORD dwEncoding)
5813 CRYPT_CONTENT_INFO *info;
5815 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5816 emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo),
5817 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5818 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5821 info = (CRYPT_CONTENT_INFO *)buf;
5823 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5825 ok(info->Content.cbData == 0, "Expected no data, got %d\n",
5826 info->Content.cbData);
5829 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5830 emptyPKCSContentInfoExtraBytes, sizeof(emptyPKCSContentInfoExtraBytes),
5831 0, NULL, NULL, &size);
5832 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5833 SetLastError(0xdeadbeef);
5834 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5835 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo),
5836 CRYPT_DECODE_ALLOC_FLAG, NULL, &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)) || broken(ret),
5842 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5844 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5845 intPKCSContentInfo, sizeof(intPKCSContentInfo),
5846 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5847 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5850 info = (CRYPT_CONTENT_INFO *)buf;
5852 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5854 ok(info->Content.cbData == ints[0].encoded[1] + 2,
5855 "Unexpected size %d\n", info->Content.cbData);
5856 ok(!memcmp(info->Content.pbData, ints[0].encoded,
5857 info->Content.cbData), "Unexpected value\n");
5860 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5861 indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent),
5862 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5863 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5866 info = (CRYPT_CONTENT_INFO *)buf;
5868 ok(!strcmp(info->pszObjId, szOID_RSA_signedData),
5869 "Expected %s, got %s\n", szOID_RSA_signedData, info->pszObjId);
5870 ok(info->Content.cbData == 392, "Expected 392, got %d\n",
5871 info->Content.cbData);
5876 static const BYTE emptyPKCSAttr[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
5878 static const BYTE bogusPKCSAttr[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
5880 static const BYTE intPKCSAttr[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
5883 static void test_encodePKCSAttribute(DWORD dwEncoding)
5885 CRYPT_ATTRIBUTE attr = { 0 };
5889 CRYPT_ATTR_BLOB blob;
5890 char oid[] = "1.2.3";
5894 /* Crashes on win9x */
5895 SetLastError(0xdeadbeef);
5896 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, NULL,
5897 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5898 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5899 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5901 SetLastError(0xdeadbeef);
5902 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5903 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5904 ok(!ret && (GetLastError() == E_INVALIDARG ||
5905 GetLastError() == OSS_LIMITED /* Win9x */),
5906 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5907 attr.pszObjId = oid;
5908 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5909 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5910 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5913 ok(size == sizeof(emptyPKCSAttr), "Unexpected size %d\n", size);
5914 ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n");
5917 blob.cbData = sizeof(bogusDER);
5918 blob.pbData = bogusDER;
5920 attr.rgValue = &blob;
5921 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5922 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5923 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5926 ok(size == sizeof(bogusPKCSAttr), "Unexpected size %d\n", size);
5927 ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n");
5930 blob.pbData = (BYTE *)ints[0].encoded;
5931 blob.cbData = ints[0].encoded[1] + 2;
5932 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5933 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5936 ok(size == sizeof(intPKCSAttr), "Unexpected size %d\n", size);
5937 ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n");
5942 static void test_decodePKCSAttribute(DWORD dwEncoding)
5947 CRYPT_ATTRIBUTE *attr;
5949 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5950 emptyPKCSAttr, sizeof(emptyPKCSAttr),
5951 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5952 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5955 attr = (CRYPT_ATTRIBUTE *)buf;
5957 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5959 ok(attr->cValue == 0, "Expected no value, got %d\n", attr->cValue);
5962 SetLastError(0xdeadbeef);
5963 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5964 bogusPKCSAttr, sizeof(bogusPKCSAttr),
5965 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5966 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5967 * I doubt an app depends on that.
5969 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5970 GetLastError() == CRYPT_E_ASN1_CORRUPT ||
5971 GetLastError() == OSS_MORE_INPUT /* Win9x */),
5972 "Expected CRYPT_E_ASN1_EOD, CRYPT_E_ASN1_CORRUPT, or OSS_MORE_INPUT, got %x\n",
5974 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5975 intPKCSAttr, sizeof(intPKCSAttr),
5976 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5977 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5980 attr = (CRYPT_ATTRIBUTE *)buf;
5982 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5984 ok(attr->cValue == 1, "Expected 1 value, got %d\n", attr->cValue);
5985 ok(attr->rgValue[0].cbData == ints[0].encoded[1] + 2,
5986 "Unexpected size %d\n", attr->rgValue[0].cbData);
5987 ok(!memcmp(attr->rgValue[0].pbData, ints[0].encoded,
5988 attr->rgValue[0].cbData), "Unexpected value\n");
5993 static const BYTE emptyPKCSAttributes[] = { 0x31,0x00 };
5994 static const BYTE singlePKCSAttributes[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
5995 0x2a,0x03,0x31,0x00 };
5996 static const BYTE doublePKCSAttributes[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
5997 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
5999 static void test_encodePKCSAttributes(DWORD dwEncoding)
6001 CRYPT_ATTRIBUTES attributes = { 0 };
6002 CRYPT_ATTRIBUTE attr[2] = { { 0 } };
6003 CRYPT_ATTR_BLOB blob;
6007 char oid1[] = "1.2.3", oid2[] = "1.5.6";
6009 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6010 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6011 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6014 ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %d\n", size);
6015 ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n");
6018 attributes.cAttr = 1;
6019 attributes.rgAttr = attr;
6020 SetLastError(0xdeadbeef);
6021 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6022 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6023 ok(!ret && (GetLastError() == E_INVALIDARG ||
6024 GetLastError() == OSS_LIMITED /* Win9x */),
6025 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6026 attr[0].pszObjId = oid1;
6027 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6028 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6031 ok(size == sizeof(singlePKCSAttributes), "Unexpected size %d\n", size);
6032 ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n");
6035 attr[1].pszObjId = oid2;
6037 attr[1].rgValue = &blob;
6038 blob.pbData = (BYTE *)ints[0].encoded;
6039 blob.cbData = ints[0].encoded[1] + 2;
6040 attributes.cAttr = 2;
6041 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6042 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6043 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6046 ok(size == sizeof(doublePKCSAttributes), "Unexpected size %d\n", size);
6047 ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n");
6052 static void test_decodePKCSAttributes(DWORD dwEncoding)
6057 CRYPT_ATTRIBUTES *attributes;
6059 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6060 emptyPKCSAttributes, sizeof(emptyPKCSAttributes),
6061 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6062 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6065 attributes = (CRYPT_ATTRIBUTES *)buf;
6066 ok(attributes->cAttr == 0, "Expected no attributes, got %d\n",
6070 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6071 singlePKCSAttributes, sizeof(singlePKCSAttributes),
6072 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6073 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6076 attributes = (CRYPT_ATTRIBUTES *)buf;
6077 ok(attributes->cAttr == 1, "Expected 1 attribute, got %d\n",
6079 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
6080 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
6081 ok(attributes->rgAttr[0].cValue == 0,
6082 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
6085 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6086 doublePKCSAttributes, sizeof(doublePKCSAttributes),
6087 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6088 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6091 attributes = (CRYPT_ATTRIBUTES *)buf;
6092 ok(attributes->cAttr == 2, "Expected 2 attributes, got %d\n",
6094 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
6095 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
6096 ok(attributes->rgAttr[0].cValue == 0,
6097 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
6098 ok(!strcmp(attributes->rgAttr[1].pszObjId, "1.5.6"),
6099 "Expected 1.5.6, got %s\n", attributes->rgAttr[1].pszObjId);
6100 ok(attributes->rgAttr[1].cValue == 1,
6101 "Expected 1 attribute, got %d\n", attributes->rgAttr[1].cValue);
6102 ok(attributes->rgAttr[1].rgValue[0].cbData == ints[0].encoded[1] + 2,
6103 "Unexpected size %d\n", attributes->rgAttr[1].rgValue[0].cbData);
6104 ok(!memcmp(attributes->rgAttr[1].rgValue[0].pbData, ints[0].encoded,
6105 attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n");
6110 static const BYTE singleCapability[] = {
6111 0x30,0x06,0x30,0x04,0x06,0x02,0x2d,0x06 };
6112 static const BYTE twoCapabilities[] = {
6113 0x30,0x0c,0x30,0x04,0x06,0x02,0x2d,0x06,0x30,0x04,0x06,0x02,0x2a,0x03 };
6114 static const BYTE singleCapabilitywithNULL[] = {
6115 0x30,0x08,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
6117 static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding)
6119 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6123 CRYPT_SMIME_CAPABILITY capability[2];
6124 CRYPT_SMIME_CAPABILITIES capabilities;
6126 /* An empty capabilities is allowed */
6127 capabilities.cCapability = 0;
6128 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6129 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6130 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6133 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
6134 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
6137 /* A non-empty capabilities with an empty capability (lacking an OID) is
6140 capability[0].pszObjId = NULL;
6141 capability[0].Parameters.cbData = 0;
6142 capabilities.cCapability = 1;
6143 capabilities.rgCapability = capability;
6144 SetLastError(0xdeadbeef);
6145 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6146 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6147 ok(!ret && (GetLastError() == E_INVALIDARG ||
6148 GetLastError() == OSS_LIMITED /* Win9x */),
6149 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6150 capability[0].pszObjId = oid1;
6151 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6152 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6153 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6156 ok(size == sizeof(singleCapability), "unexpected size %d\n", size);
6157 ok(!memcmp(buf, singleCapability, size), "unexpected value\n");
6160 capability[1].pszObjId = oid2;
6161 capability[1].Parameters.cbData = 0;
6162 capabilities.cCapability = 2;
6163 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6164 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6165 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6168 ok(size == sizeof(twoCapabilities), "unexpected size %d\n", size);
6169 ok(!memcmp(buf, twoCapabilities, size), "unexpected value\n");
6174 static void compareSMimeCapabilities(LPCSTR header,
6175 const CRYPT_SMIME_CAPABILITIES *expected, const CRYPT_SMIME_CAPABILITIES *got)
6179 ok(got->cCapability == expected->cCapability,
6180 "%s: expected %d capabilities, got %d\n", header, expected->cCapability,
6182 for (i = 0; i < expected->cCapability; i++)
6184 ok(!strcmp(expected->rgCapability[i].pszObjId,
6185 got->rgCapability[i].pszObjId), "%s[%d]: expected %s, got %s\n",
6186 header, i, expected->rgCapability[i].pszObjId,
6187 got->rgCapability[i].pszObjId);
6188 ok(expected->rgCapability[i].Parameters.cbData ==
6189 got->rgCapability[i].Parameters.cbData,
6190 "%s[%d]: expected %d bytes, got %d\n", header, i,
6191 expected->rgCapability[i].Parameters.cbData,
6192 got->rgCapability[i].Parameters.cbData);
6193 if (expected->rgCapability[i].Parameters.cbData)
6194 ok(!memcmp(expected->rgCapability[i].Parameters.pbData,
6195 got->rgCapability[i].Parameters.pbData,
6196 expected->rgCapability[i].Parameters.cbData),
6197 "%s[%d]: unexpected value\n", header, i);
6201 static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding)
6203 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6206 CRYPT_SMIME_CAPABILITY capability[2];
6207 CRYPT_SMIME_CAPABILITIES capabilities, *ptr;
6209 SetLastError(0xdeadbeef);
6210 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6211 emptySequence, sizeof(emptySequence),
6212 CRYPT_DECODE_ALLOC_FLAG, NULL, &ptr, &size);
6213 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6216 capabilities.cCapability = 0;
6217 compareSMimeCapabilities("empty capabilities", &capabilities, ptr);
6220 SetLastError(0xdeadbeef);
6221 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6222 singleCapability, sizeof(singleCapability), CRYPT_DECODE_ALLOC_FLAG, NULL,
6224 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6227 capability[0].pszObjId = oid1;
6228 capability[0].Parameters.cbData = 0;
6229 capabilities.cCapability = 1;
6230 capabilities.rgCapability = capability;
6231 compareSMimeCapabilities("single capability", &capabilities, ptr);
6234 SetLastError(0xdeadbeef);
6235 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6236 singleCapabilitywithNULL, sizeof(singleCapabilitywithNULL),
6237 CRYPT_DECODE_ALLOC_FLAG, NULL, &ptr, &size);
6238 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6241 BYTE NULLparam[] = {0x05, 0x00};
6242 capability[0].pszObjId = oid1;
6243 capability[0].Parameters.cbData = 2;
6244 capability[0].Parameters.pbData = NULLparam;
6245 capabilities.cCapability = 1;
6246 capabilities.rgCapability = capability;
6247 compareSMimeCapabilities("single capability with NULL", &capabilities,
6251 SetLastError(0xdeadbeef);
6252 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6253 twoCapabilities, sizeof(twoCapabilities), CRYPT_DECODE_ALLOC_FLAG, NULL,
6255 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6258 capability[0].Parameters.cbData = 0;
6259 capability[1].pszObjId = oid2;
6260 capability[1].Parameters.cbData = 0;
6261 capabilities.cCapability = 2;
6262 compareSMimeCapabilities("two capabilities", &capabilities, ptr);
6267 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
6268 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
6270 static const BYTE minimalPKCSSigner[] = {
6271 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6272 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6273 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6274 static const BYTE PKCSSignerWithSerial[] = {
6275 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6276 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6277 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
6279 static const BYTE PKCSSignerWithHashAlgo[] = {
6280 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6281 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6282 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
6284 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = {
6285 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6286 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6287 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6288 0x06,0x05,0x00,0x04,0x00 };
6289 static const BYTE PKCSSignerWithHash[] = {
6290 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6291 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6292 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6293 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
6294 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6295 static const BYTE PKCSSignerWithAuthAttr[] = {
6296 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6297 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6298 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
6299 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
6300 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
6301 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
6302 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6304 static void test_encodePKCSSignerInfo(DWORD dwEncoding)
6306 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6310 CMSG_SIGNER_INFO info = { 0 };
6311 char oid_common_name[] = szOID_COMMON_NAME;
6312 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
6313 (LPBYTE)encodedCommonName };
6314 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
6316 SetLastError(0xdeadbeef);
6317 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6318 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6319 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6321 skip("no PKCS7_SIGNER_INFO encode support\n");
6324 ok(!ret && (GetLastError() == E_INVALIDARG ||
6325 GetLastError() == OSS_LIMITED /* Win9x */),
6326 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6327 /* To be encoded, a signer must have an issuer at least, and the encoding
6328 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
6329 * see decoding tests.)
6331 info.Issuer.cbData = sizeof(encodedCommonNameNoNull);
6332 info.Issuer.pbData = encodedCommonNameNoNull;
6333 SetLastError(0xdeadbeef);
6334 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6335 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6336 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6337 ok(!ret && GetLastError() == E_INVALIDARG,
6338 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6341 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6342 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6345 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6346 if (size == sizeof(minimalPKCSSigner))
6347 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6349 ok(0, "Unexpected value\n");
6353 info.SerialNumber.cbData = sizeof(serialNum);
6354 info.SerialNumber.pbData = (BYTE *)serialNum;
6355 SetLastError(0xdeadbeef);
6356 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6357 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6358 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6359 ok(!ret && GetLastError() == E_INVALIDARG,
6360 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6363 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6364 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6367 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6369 if (size == sizeof(PKCSSignerWithSerial))
6370 ok(!memcmp(buf, PKCSSignerWithSerial, size),
6371 "Unexpected value\n");
6373 ok(0, "Unexpected value\n");
6377 info.HashAlgorithm.pszObjId = oid1;
6378 SetLastError(0xdeadbeef);
6379 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6380 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6381 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6382 ok(!ret && GetLastError() == E_INVALIDARG,
6383 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6386 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6387 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6390 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6392 if (size == sizeof(PKCSSignerWithHashAlgo))
6393 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6394 "Unexpected value\n");
6396 ok(0, "Unexpected value\n");
6400 info.HashEncryptionAlgorithm.pszObjId = oid2;
6401 SetLastError(0xdeadbeef);
6402 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6403 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6404 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6405 ok(!ret && GetLastError() == E_INVALIDARG,
6406 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6409 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6412 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6413 "Unexpected size %d\n", size);
6414 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo))
6415 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6416 "Unexpected value\n");
6418 ok(0, "Unexpected value\n");
6422 info.EncryptedHash.cbData = sizeof(hash);
6423 info.EncryptedHash.pbData = (BYTE *)hash;
6424 SetLastError(0xdeadbeef);
6425 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6426 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6427 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6428 ok(!ret && GetLastError() == E_INVALIDARG,
6429 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6432 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6435 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6437 if (size == sizeof(PKCSSignerWithHash))
6438 ok(!memcmp(buf, PKCSSignerWithHash, size),
6439 "Unexpected value\n");
6441 ok(0, "Unexpected value\n");
6445 info.AuthAttrs.cAttr = 1;
6446 info.AuthAttrs.rgAttr = &attr;
6447 SetLastError(0xdeadbeef);
6448 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6449 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6450 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6451 ok(!ret && GetLastError() == E_INVALIDARG,
6452 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6455 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6458 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
6460 if (size == sizeof(PKCSSignerWithAuthAttr))
6461 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
6462 "Unexpected value\n");
6464 ok(0, "Unexpected value\n");
6470 static void test_decodePKCSSignerInfo(DWORD dwEncoding)
6475 CMSG_SIGNER_INFO *info;
6477 /* A PKCS signer can't be decoded without a serial number. */
6478 SetLastError(0xdeadbeef);
6479 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6480 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6481 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6482 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
6483 GetLastError() == OSS_DATA_ERROR /* Win9x */),
6484 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %x\n",
6486 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6487 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6488 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6489 ok(ret || broken(GetLastError() == OSS_DATA_ERROR),
6490 "CryptDecodeObjectEx failed: %x\n", GetLastError());
6493 info = (CMSG_SIGNER_INFO *)buf;
6494 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6496 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6497 "Unexpected size %d\n", info->Issuer.cbData);
6498 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6499 info->Issuer.cbData), "Unexpected value\n");
6500 ok(info->SerialNumber.cbData == sizeof(serialNum),
6501 "Unexpected size %d\n", info->SerialNumber.cbData);
6502 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6503 "Unexpected value\n");
6506 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6507 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6508 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6511 info = (CMSG_SIGNER_INFO *)buf;
6512 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6514 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6515 "Unexpected size %d\n", info->Issuer.cbData);
6516 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6517 info->Issuer.cbData), "Unexpected value\n");
6518 ok(info->SerialNumber.cbData == sizeof(serialNum),
6519 "Unexpected size %d\n", info->SerialNumber.cbData);
6520 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6521 "Unexpected value\n");
6522 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6523 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6526 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6527 PKCSSignerWithHashAndEncryptionAlgo,
6528 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6532 info = (CMSG_SIGNER_INFO *)buf;
6533 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6535 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6536 "Unexpected size %d\n", info->Issuer.cbData);
6537 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6538 info->Issuer.cbData), "Unexpected value\n");
6539 ok(info->SerialNumber.cbData == sizeof(serialNum),
6540 "Unexpected size %d\n", info->SerialNumber.cbData);
6541 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6542 "Unexpected value\n");
6543 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6544 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6545 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6546 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6549 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6550 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6551 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6554 info = (CMSG_SIGNER_INFO *)buf;
6555 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6557 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6558 "Unexpected size %d\n", info->Issuer.cbData);
6559 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6560 info->Issuer.cbData), "Unexpected value\n");
6561 ok(info->SerialNumber.cbData == sizeof(serialNum),
6562 "Unexpected size %d\n", info->SerialNumber.cbData);
6563 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6564 "Unexpected value\n");
6565 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6566 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6567 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6568 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6569 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6570 info->EncryptedHash.cbData);
6571 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6572 "Unexpected value\n");
6575 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6576 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
6577 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6580 info = (CMSG_SIGNER_INFO *)buf;
6581 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n",
6582 info->AuthAttrs.cAttr);
6583 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
6584 "Expected %s, got %s\n", szOID_COMMON_NAME,
6585 info->AuthAttrs.rgAttr[0].pszObjId);
6586 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
6587 info->AuthAttrs.rgAttr[0].cValue);
6588 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
6589 sizeof(encodedCommonName), "Unexpected size %d\n",
6590 info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
6591 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
6592 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
6597 static const BYTE CMSSignerWithKeyId[] = {
6598 0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,
6599 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6601 static void test_encodeCMSSignerInfo(DWORD dwEncoding)
6606 CMSG_CMS_SIGNER_INFO info = { 0 };
6607 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6609 SetLastError(0xdeadbeef);
6610 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6611 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6612 ok(!ret, "Expected failure, got %d\n", ret);
6613 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6615 skip("no CMS_SIGNER_INFO encode support\n");
6618 ok(GetLastError() == E_INVALIDARG,
6619 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6620 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6621 SetLastError(0xdeadbeef);
6622 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6623 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6624 ok(!ret, "Expected failure, got %d\n", ret);
6625 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6627 skip("no CMS_SIGNER_INFO encode support\n");
6630 ok(GetLastError() == E_INVALIDARG,
6631 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6632 /* To be encoded, a signer must have a valid cert ID, where a valid ID may
6633 * be a key id or a issuer serial number with at least the issuer set, and
6634 * the encoding must include PKCS_7_ASN_ENCODING.
6635 * (That isn't enough to be decoded, see decoding tests.)
6637 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6638 sizeof(encodedCommonNameNoNull);
6639 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6640 SetLastError(0xdeadbeef);
6641 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6642 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6643 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6644 ok(!ret && GetLastError() == E_INVALIDARG,
6645 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6648 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6651 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6652 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6656 U(info.SignerId).IssuerSerialNumber.SerialNumber.cbData = sizeof(serialNum);
6657 U(info.SignerId).IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
6658 SetLastError(0xdeadbeef);
6659 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6660 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6661 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6662 ok(!ret && GetLastError() == E_INVALIDARG,
6663 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6666 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6669 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6671 ok(!memcmp(buf, PKCSSignerWithSerial, size), "Unexpected value\n");
6675 info.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
6676 U(info.SignerId).KeyId.cbData = sizeof(serialNum);
6677 U(info.SignerId).KeyId.pbData = (BYTE *)serialNum;
6678 SetLastError(0xdeadbeef);
6679 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6680 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6681 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6682 ok(!ret && GetLastError() == E_INVALIDARG,
6683 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6686 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6689 ok(size == sizeof(CMSSignerWithKeyId), "Unexpected size %d\n",
6691 ok(!memcmp(buf, CMSSignerWithKeyId, size), "Unexpected value\n");
6695 /* While a CERT_ID can have a hash type, that's not allowed in CMS, where
6696 * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed
6697 * (see RFC 3852, section 5.3.)
6699 info.SignerId.dwIdChoice = CERT_ID_SHA1_HASH;
6700 U(info.SignerId).HashId.cbData = sizeof(hash);
6701 U(info.SignerId).HashId.pbData = (BYTE *)hash;
6702 SetLastError(0xdeadbeef);
6703 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6704 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6705 ok(!ret && GetLastError() == E_INVALIDARG,
6706 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6707 /* Now with a hash algo */
6708 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6709 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6710 sizeof(encodedCommonNameNoNull);
6711 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6712 info.HashAlgorithm.pszObjId = oid1;
6713 SetLastError(0xdeadbeef);
6714 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6715 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6716 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6717 ok(!ret && GetLastError() == E_INVALIDARG,
6718 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6721 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6724 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6726 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6727 "Unexpected value\n");
6731 info.HashEncryptionAlgorithm.pszObjId = oid2;
6732 SetLastError(0xdeadbeef);
6733 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6734 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6735 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6736 ok(!ret && GetLastError() == E_INVALIDARG,
6737 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6740 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6743 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6744 "Unexpected size %d\n", size);
6745 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6746 "Unexpected value\n");
6750 info.EncryptedHash.cbData = sizeof(hash);
6751 info.EncryptedHash.pbData = (BYTE *)hash;
6752 SetLastError(0xdeadbeef);
6753 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6754 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6755 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6756 ok(!ret && GetLastError() == E_INVALIDARG,
6757 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6760 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6763 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6765 ok(!memcmp(buf, PKCSSignerWithHash, size), "Unexpected value\n");
6771 static void test_decodeCMSSignerInfo(DWORD dwEncoding)
6776 CMSG_CMS_SIGNER_INFO *info;
6777 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6779 /* A CMS signer can't be decoded without a serial number. */
6780 SetLastError(0xdeadbeef);
6781 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6782 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6783 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6784 ok(!ret, "expected failure\n");
6785 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6787 skip("no CMS_SIGNER_INFO decode support\n");
6790 ok(GetLastError() == CRYPT_E_ASN1_CORRUPT,
6791 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
6792 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6793 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6794 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6795 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6798 info = (CMSG_CMS_SIGNER_INFO *)buf;
6799 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6801 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6802 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6803 info->SignerId.dwIdChoice);
6804 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6805 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6806 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6807 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6808 encodedCommonNameNoNull,
6809 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6810 "Unexpected value\n");
6811 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6812 sizeof(serialNum), "Unexpected size %d\n",
6813 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6814 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6815 serialNum, sizeof(serialNum)), "Unexpected value\n");
6818 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6819 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6820 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6821 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6824 info = (CMSG_CMS_SIGNER_INFO *)buf;
6825 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6827 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6828 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6829 info->SignerId.dwIdChoice);
6830 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6831 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6832 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6833 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6834 encodedCommonNameNoNull,
6835 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6836 "Unexpected value\n");
6837 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6838 sizeof(serialNum), "Unexpected size %d\n",
6839 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6840 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6841 serialNum, sizeof(serialNum)), "Unexpected value\n");
6842 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6843 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6846 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6847 PKCSSignerWithHashAndEncryptionAlgo,
6848 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6850 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6853 info = (CMSG_CMS_SIGNER_INFO *)buf;
6854 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6856 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6857 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6858 info->SignerId.dwIdChoice);
6859 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6860 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6861 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6862 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6863 encodedCommonNameNoNull,
6864 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6865 "Unexpected value\n");
6866 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6867 sizeof(serialNum), "Unexpected size %d\n",
6868 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6869 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6870 serialNum, sizeof(serialNum)), "Unexpected value\n");
6871 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6872 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6873 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6874 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6877 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6878 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6879 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6880 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6883 info = (CMSG_CMS_SIGNER_INFO *)buf;
6884 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6886 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6887 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6888 info->SignerId.dwIdChoice);
6889 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6890 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6891 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6892 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6893 encodedCommonNameNoNull,
6894 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6895 "Unexpected value\n");
6896 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6897 sizeof(serialNum), "Unexpected size %d\n",
6898 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6899 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6900 serialNum, sizeof(serialNum)), "Unexpected value\n");
6901 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6902 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6903 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6904 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6905 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6906 info->EncryptedHash.cbData);
6907 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6908 "Unexpected value\n");
6911 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6912 CMSSignerWithKeyId, sizeof(CMSSignerWithKeyId),
6913 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6914 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6917 info = (CMSG_CMS_SIGNER_INFO *)buf;
6918 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6920 ok(info->SignerId.dwIdChoice == CERT_ID_KEY_IDENTIFIER,
6921 "Expected CERT_ID_KEY_IDENTIFIER, got %d\n",
6922 info->SignerId.dwIdChoice);
6923 ok(U(info->SignerId).KeyId.cbData == sizeof(serialNum),
6924 "Unexpected size %d\n", U(info->SignerId).KeyId.cbData);
6925 ok(!memcmp(U(info->SignerId).KeyId.pbData, serialNum, sizeof(serialNum)),
6926 "Unexpected value\n");
6931 static BYTE emptyDNSPermittedConstraints[] = {
6932 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
6933 static BYTE emptyDNSExcludedConstraints[] = {
6934 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
6935 static BYTE DNSExcludedConstraints[] = {
6936 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
6937 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6938 static BYTE permittedAndExcludedConstraints[] = {
6939 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6940 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
6941 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6942 static BYTE permittedAndExcludedWithMinConstraints[] = {
6943 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6944 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
6945 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6946 static BYTE permittedAndExcludedWithMinMaxConstraints[] = {
6947 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6948 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
6949 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6951 static void test_encodeNameConstraints(DWORD dwEncoding)
6954 CERT_NAME_CONSTRAINTS_INFO constraints = { 0 };
6955 CERT_GENERAL_SUBTREE permitted = { { 0 } };
6956 CERT_GENERAL_SUBTREE excluded = { { 0 } };
6960 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6961 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6962 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6964 skip("no X509_NAME_CONSTRAINTS encode support\n");
6967 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6970 ok(size == sizeof(emptySequence), "Unexpected size\n");
6971 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
6974 constraints.cPermittedSubtree = 1;
6975 constraints.rgPermittedSubtree = &permitted;
6976 SetLastError(0xdeadbeef);
6977 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6978 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6979 ok(!ret && GetLastError() == E_INVALIDARG,
6980 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6981 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
6982 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6983 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6984 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6987 ok(size == sizeof(emptyDNSPermittedConstraints), "Unexpected size\n");
6988 ok(!memcmp(buf, emptyDNSPermittedConstraints, size),
6989 "Unexpected value\n");
6992 constraints.cPermittedSubtree = 0;
6993 constraints.cExcludedSubtree = 1;
6994 constraints.rgExcludedSubtree = &excluded;
6995 excluded.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
6996 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6997 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6998 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7001 ok(size == sizeof(emptyDNSExcludedConstraints), "Unexpected size\n");
7002 ok(!memcmp(buf, emptyDNSExcludedConstraints, size),
7003 "Unexpected value\n");
7006 U(excluded.Base).pwszURL = (LPWSTR)url;
7007 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7008 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7009 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7012 ok(size == sizeof(DNSExcludedConstraints), "Unexpected size\n");
7013 ok(!memcmp(buf, DNSExcludedConstraints, size),
7014 "Unexpected value\n");
7017 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
7018 U(permitted.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7019 U(permitted.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7020 constraints.cPermittedSubtree = 1;
7021 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7022 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7023 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7026 ok(size == sizeof(permittedAndExcludedConstraints),
7027 "Unexpected size\n");
7028 ok(!memcmp(buf, permittedAndExcludedConstraints, size),
7029 "Unexpected value\n");
7032 permitted.dwMinimum = 5;
7033 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7034 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7035 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7038 ok(size == sizeof(permittedAndExcludedWithMinConstraints),
7039 "Unexpected size\n");
7040 ok(!memcmp(buf, permittedAndExcludedWithMinConstraints, size),
7041 "Unexpected value\n");
7044 permitted.fMaximum = TRUE;
7045 permitted.dwMaximum = 3;
7046 SetLastError(0xdeadbeef);
7047 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7048 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7049 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7052 ok(size == sizeof(permittedAndExcludedWithMinMaxConstraints),
7053 "Unexpected size\n");
7054 ok(!memcmp(buf, permittedAndExcludedWithMinMaxConstraints, size),
7055 "Unexpected value\n");
7060 struct EncodedNameConstraints
7062 CRYPT_DATA_BLOB encoded;
7063 CERT_NAME_CONSTRAINTS_INFO constraints;
7066 static CERT_GENERAL_SUBTREE emptyDNSSubtree = {
7067 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
7068 static CERT_GENERAL_SUBTREE DNSSubtree = {
7069 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
7070 static CERT_GENERAL_SUBTREE IPAddressSubtree = {
7071 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 0 };
7072 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree = {
7073 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, 0 };
7074 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree = {
7075 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, TRUE, 3 };
7077 struct EncodedNameConstraints encodedNameConstraints[] = {
7078 { { sizeof(emptySequence), (LPBYTE)emptySequence }, { 0 } },
7079 { { sizeof(emptyDNSPermittedConstraints), emptyDNSPermittedConstraints },
7080 { 1, &emptyDNSSubtree, 0, NULL } },
7081 { { sizeof(emptyDNSExcludedConstraints), emptyDNSExcludedConstraints },
7082 { 0, NULL, 1, &emptyDNSSubtree } },
7083 { { sizeof(DNSExcludedConstraints), DNSExcludedConstraints },
7084 { 0, NULL, 1, &DNSSubtree } },
7085 { { sizeof(permittedAndExcludedConstraints), permittedAndExcludedConstraints },
7086 { 1, &IPAddressSubtree, 1, &DNSSubtree } },
7087 { { sizeof(permittedAndExcludedWithMinConstraints),
7088 permittedAndExcludedWithMinConstraints },
7089 { 1, &IPAddressWithMinSubtree, 1, &DNSSubtree } },
7090 { { sizeof(permittedAndExcludedWithMinMaxConstraints),
7091 permittedAndExcludedWithMinMaxConstraints },
7092 { 1, &IPAddressWithMinMaxSubtree, 1, &DNSSubtree } },
7095 static void test_decodeNameConstraints(DWORD dwEncoding)
7099 CERT_NAME_CONSTRAINTS_INFO *constraints;
7101 U(DNSSubtree.Base).pwszURL = (LPWSTR)url;
7102 U(IPAddressSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7103 U(IPAddressSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7104 U(IPAddressWithMinSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7105 U(IPAddressWithMinSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7106 U(IPAddressWithMinMaxSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7107 U(IPAddressWithMinMaxSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7109 i < sizeof(encodedNameConstraints) / sizeof(encodedNameConstraints[0]);
7114 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS,
7115 encodedNameConstraints[i].encoded.pbData,
7116 encodedNameConstraints[i].encoded.cbData,
7117 CRYPT_DECODE_ALLOC_FLAG, NULL, &constraints, &size);
7118 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7120 skip("no X509_NAME_CONSTRAINTS decode support\n");
7123 ok(ret, "%d: CryptDecodeObjectEx failed: %08x\n", i, GetLastError());
7128 if (constraints->cPermittedSubtree !=
7129 encodedNameConstraints[i].constraints.cPermittedSubtree)
7130 fprintf(stderr, "%d: expected %d permitted, got %d\n", i,
7131 encodedNameConstraints[i].constraints.cPermittedSubtree,
7132 constraints->cPermittedSubtree);
7133 if (constraints->cPermittedSubtree ==
7134 encodedNameConstraints[i].constraints.cPermittedSubtree)
7136 for (j = 0; j < constraints->cPermittedSubtree; j++)
7138 compareAltNameEntry(&constraints->rgPermittedSubtree[j].Base,
7139 &encodedNameConstraints[i].constraints.rgPermittedSubtree[j].Base);
7142 if (constraints->cExcludedSubtree !=
7143 encodedNameConstraints[i].constraints.cExcludedSubtree)
7144 fprintf(stderr, "%d: expected %d excluded, got %d\n", i,
7145 encodedNameConstraints[i].constraints.cExcludedSubtree,
7146 constraints->cExcludedSubtree);
7147 if (constraints->cExcludedSubtree ==
7148 encodedNameConstraints[i].constraints.cExcludedSubtree)
7150 for (j = 0; j < constraints->cExcludedSubtree; j++)
7152 compareAltNameEntry(&constraints->rgExcludedSubtree[j].Base,
7153 &encodedNameConstraints[i].constraints.rgExcludedSubtree[j].Base);
7156 LocalFree(constraints);
7161 static WCHAR noticeText[] = { 'T','h','i','s',' ','i','s',' ','a',' ',
7162 'n','o','t','i','c','e',0 };
7163 static const BYTE noticeWithDisplayText[] = {
7164 0x30,0x22,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,0x00,
7165 0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,0x74,
7166 0x00,0x69,0x00,0x63,0x00,0x65
7168 static char org[] = "Wine";
7169 static int noticeNumbers[] = { 2,3 };
7170 static BYTE noticeWithReference[] = {
7171 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7172 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7173 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7174 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7177 static void test_encodePolicyQualifierUserNotice(DWORD dwEncoding)
7182 CERT_POLICY_QUALIFIER_USER_NOTICE notice;
7183 CERT_POLICY_QUALIFIER_NOTICE_REFERENCE reference;
7185 memset(¬ice, 0, sizeof(notice));
7186 ret = pCryptEncodeObjectEx(dwEncoding,
7187 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, ¬ice, CRYPT_ENCODE_ALLOC_FLAG,
7189 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7191 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE encode support\n");
7194 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7197 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size);
7198 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
7201 notice.pszDisplayText = noticeText;
7202 ret = pCryptEncodeObjectEx(dwEncoding,
7203 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, ¬ice, CRYPT_ENCODE_ALLOC_FLAG,
7205 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7208 ok(sizeof(noticeWithDisplayText) == size, "unexpected size %d\n", size);
7209 ok(!memcmp(buf, noticeWithDisplayText, size), "unexpected value\n");
7212 reference.pszOrganization = org;
7213 reference.cNoticeNumbers = 2;
7214 reference.rgNoticeNumbers = noticeNumbers;
7215 notice.pNoticeReference = &reference;
7216 ret = pCryptEncodeObjectEx(dwEncoding,
7217 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, ¬ice, CRYPT_ENCODE_ALLOC_FLAG,
7219 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7222 ok(sizeof(noticeWithReference) == size, "unexpected size %d\n", size);
7223 ok(!memcmp(buf, noticeWithReference, size), "unexpected value\n");
7228 static void test_decodePolicyQualifierUserNotice(DWORD dwEncoding)
7231 CERT_POLICY_QUALIFIER_USER_NOTICE *notice;
7234 ret = pCryptDecodeObjectEx(dwEncoding,
7235 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7236 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7238 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7240 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE decode support\n");
7243 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7246 ok(notice->pszDisplayText == NULL, "unexpected display text\n");
7247 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7250 ret = pCryptDecodeObjectEx(dwEncoding,
7251 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7252 noticeWithDisplayText, sizeof(noticeWithDisplayText),
7253 CRYPT_DECODE_ALLOC_FLAG, NULL, ¬ice, &size);
7254 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7257 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7258 "unexpected display text\n");
7259 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7262 ret = pCryptDecodeObjectEx(dwEncoding,
7263 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7264 noticeWithReference, sizeof(noticeWithReference),
7265 CRYPT_DECODE_ALLOC_FLAG, NULL, ¬ice, &size);
7266 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7269 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7270 "unexpected display text\n");
7271 ok(notice->pNoticeReference != NULL, "expected a notice reference\n");
7272 if (notice->pNoticeReference)
7274 ok(!strcmp(notice->pNoticeReference->pszOrganization, org),
7275 "unexpected organization %s\n",
7276 notice->pNoticeReference->pszOrganization);
7277 ok(notice->pNoticeReference->cNoticeNumbers == 2,
7278 "expected 2 notice numbers, got %d\n",
7279 notice->pNoticeReference->cNoticeNumbers);
7280 ok(notice->pNoticeReference->rgNoticeNumbers[0] == noticeNumbers[0],
7281 "unexpected notice number %d\n",
7282 notice->pNoticeReference->rgNoticeNumbers[0]);
7283 ok(notice->pNoticeReference->rgNoticeNumbers[1] == noticeNumbers[1],
7284 "unexpected notice number %d\n",
7285 notice->pNoticeReference->rgNoticeNumbers[1]);
7291 static char oid_any_policy[] = "2.5.29.32.0";
7292 static const BYTE policiesWithAnyPolicy[] = {
7293 0x30,0x08,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00
7295 static char oid1[] = "1.2.3";
7296 static char oid_user_notice[] = "1.3.6.1.5.5.7.2.2";
7297 static const BYTE twoPolicies[] = {
7298 0x30,0x50,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00,0x30,0x46,0x06,0x02,0x2a,
7299 0x03,0x30,0x40,0x30,0x3e,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x02,
7300 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7301 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7302 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7303 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7306 static void test_encodeCertPolicies(DWORD dwEncoding)
7309 CERT_POLICIES_INFO info;
7310 CERT_POLICY_INFO policy[2];
7311 CERT_POLICY_QUALIFIER_INFO qualifier;
7315 memset(&info, 0, sizeof(info));
7316 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7317 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7318 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7321 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size);
7322 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
7325 memset(policy, 0, sizeof(policy));
7326 info.cPolicyInfo = 1;
7327 info.rgPolicyInfo = policy;
7328 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7329 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7330 ok(!ret && (GetLastError() == E_INVALIDARG ||
7331 GetLastError() == OSS_LIMITED /* Win9x/NT4 */),
7332 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
7333 policy[0].pszPolicyIdentifier = oid_any_policy;
7334 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7335 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7336 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7339 ok(sizeof(policiesWithAnyPolicy) == size, "unexpected size %d\n", size);
7340 ok(!memcmp(buf, policiesWithAnyPolicy, size), "unexpected value\n");
7343 policy[1].pszPolicyIdentifier = oid1;
7344 memset(&qualifier, 0, sizeof(qualifier));
7345 qualifier.pszPolicyQualifierId = oid_user_notice;
7346 qualifier.Qualifier.cbData = sizeof(noticeWithReference);
7347 qualifier.Qualifier.pbData = noticeWithReference;
7348 policy[1].cPolicyQualifier = 1;
7349 policy[1].rgPolicyQualifier = &qualifier;
7350 info.cPolicyInfo = 2;
7351 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7352 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7353 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7356 ok(sizeof(twoPolicies) == size, "unexpected size %d\n", size);
7357 ok(!memcmp(buf, twoPolicies, size), "unexpected value\n");
7362 static void test_decodeCertPolicies(DWORD dwEncoding)
7365 CERT_POLICIES_INFO *info;
7368 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7369 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7371 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7374 ok(info->cPolicyInfo == 0, "unexpected policy info %d\n",
7378 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7379 policiesWithAnyPolicy, sizeof(policiesWithAnyPolicy),
7380 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7381 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7384 ok(info->cPolicyInfo == 1, "unexpected policy info %d\n",
7386 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy),
7387 "unexpected policy id %s\n",
7388 info->rgPolicyInfo[0].pszPolicyIdentifier);
7389 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0,
7390 "unexpected policy qualifier count %d\n",
7391 info->rgPolicyInfo[0].cPolicyQualifier);
7394 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7395 twoPolicies, sizeof(twoPolicies),
7396 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7397 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7400 ok(info->cPolicyInfo == 2, "unexpected policy info %d\n",
7402 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy),
7403 "unexpected policy id %s\n",
7404 info->rgPolicyInfo[0].pszPolicyIdentifier);
7405 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0,
7406 "unexpected policy qualifier count %d\n",
7407 info->rgPolicyInfo[0].cPolicyQualifier);
7408 ok(!strcmp(info->rgPolicyInfo[1].pszPolicyIdentifier, oid1),
7409 "unexpected policy id %s\n",
7410 info->rgPolicyInfo[1].pszPolicyIdentifier);
7411 ok(info->rgPolicyInfo[1].cPolicyQualifier == 1,
7412 "unexpected policy qualifier count %d\n",
7413 info->rgPolicyInfo[1].cPolicyQualifier);
7415 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId,
7416 oid_user_notice), "unexpected policy qualifier id %s\n",
7417 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId);
7418 ok(info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData ==
7419 sizeof(noticeWithReference), "unexpected qualifier size %d\n",
7420 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData);
7422 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.pbData,
7423 noticeWithReference, sizeof(noticeWithReference)),
7424 "unexpected qualifier value\n");
7429 /* Free *pInfo with HeapFree */
7430 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
7437 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
7439 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size);
7440 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7441 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7442 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL,
7444 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7445 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7446 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL,
7448 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7449 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7450 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7451 0, NULL, NULL, &size);
7452 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7453 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7454 /* Test with no key */
7455 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7456 0, NULL, NULL, &size);
7457 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n",
7459 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
7460 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
7463 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
7464 NULL, 0, NULL, NULL, &size);
7465 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
7466 *pInfo = HeapAlloc(GetProcessHeap(), 0, size);
7469 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
7470 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size);
7471 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n",
7475 /* By default (we passed NULL as the OID) the OID is
7478 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA),
7479 "Expected %s, got %s\n", szOID_RSA_RSA,
7480 (*pInfo)->Algorithm.pszObjId);
7484 CryptDestroyKey(key);
7487 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
7488 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
7489 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
7490 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7491 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7492 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7493 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
7494 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
7495 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7496 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7497 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7498 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
7499 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
7500 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
7501 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
7502 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
7503 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
7504 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
7505 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
7506 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
7507 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
7508 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
7509 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
7510 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
7511 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
7513 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info)
7517 PCCERT_CONTEXT context;
7522 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
7523 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
7524 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
7525 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7528 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key);
7529 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7530 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7531 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key);
7532 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7533 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7534 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL,
7536 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7537 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7539 /* Export key with standard algorithm (CALG_RSA_KEYX) */
7540 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7542 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7544 dwSize = sizeof(ai);
7545 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7546 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7549 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7550 ok(ai == CALG_RSA_KEYX, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai);
7553 CryptDestroyKey(key);
7555 /* Repeat with forced algorithm */
7556 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, CALG_RSA_SIGN, 0, NULL,
7558 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7560 dwSize = sizeof(ai);
7561 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7562 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7565 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7566 ok(ai == CALG_RSA_SIGN, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai);
7569 CryptDestroyKey(key);
7571 /* Test importing a public key from a certificate context */
7572 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert,
7573 sizeof(expiredCert));
7574 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
7578 ok(!strcmp(szOID_RSA_RSA,
7579 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId),
7580 "Expected %s, got %s\n", szOID_RSA_RSA,
7581 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
7582 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING,
7583 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
7584 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7585 CryptDestroyKey(key);
7586 CertFreeCertificateContext(context);
7590 static const char cspName[] = "WineCryptTemp";
7592 static void testPortPublicKeyInfo(void)
7596 PCERT_PUBLIC_KEY_INFO info = NULL;
7598 /* Just in case a previous run failed, delete this thing */
7599 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7600 CRYPT_DELETEKEYSET);
7601 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7604 testExportPublicKey(csp, &info);
7605 testImportPublicKey(csp, info);
7607 HeapFree(GetProcessHeap(), 0, info);
7608 CryptReleaseContext(csp, 0);
7609 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7610 CRYPT_DELETEKEYSET);
7615 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
7616 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING };
7620 hCrypt32 = GetModuleHandleA("crypt32.dll");
7621 pCryptDecodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptDecodeObjectEx");
7622 pCryptEncodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptEncodeObjectEx");
7623 if (!pCryptDecodeObjectEx || !pCryptEncodeObjectEx)
7625 win_skip("CryptDecodeObjectEx() is not available\n");
7629 for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++)
7631 test_encodeInt(encodings[i]);
7632 test_decodeInt(encodings[i]);
7633 test_encodeEnumerated(encodings[i]);
7634 test_decodeEnumerated(encodings[i]);
7635 test_encodeFiletime(encodings[i]);
7636 test_decodeFiletime(encodings[i]);
7637 test_encodeName(encodings[i]);
7638 test_decodeName(encodings[i]);
7639 test_encodeUnicodeName(encodings[i]);
7640 test_decodeUnicodeName(encodings[i]);
7641 test_encodeNameValue(encodings[i]);
7642 test_decodeNameValue(encodings[i]);
7643 test_encodeUnicodeNameValue(encodings[i]);
7644 test_decodeUnicodeNameValue(encodings[i]);
7645 test_encodeAltName(encodings[i]);
7646 test_decodeAltName(encodings[i]);
7647 test_encodeOctets(encodings[i]);
7648 test_decodeOctets(encodings[i]);
7649 test_encodeBits(encodings[i]);
7650 test_decodeBits(encodings[i]);
7651 test_encodeBasicConstraints(encodings[i]);
7652 test_decodeBasicConstraints(encodings[i]);
7653 test_encodeRsaPublicKey(encodings[i]);
7654 test_decodeRsaPublicKey(encodings[i]);
7655 test_encodeSequenceOfAny(encodings[i]);
7656 test_decodeSequenceOfAny(encodings[i]);
7657 test_encodeExtensions(encodings[i]);
7658 test_decodeExtensions(encodings[i]);
7659 test_encodePublicKeyInfo(encodings[i]);
7660 test_decodePublicKeyInfo(encodings[i]);
7661 test_encodeCertToBeSigned(encodings[i]);
7662 test_decodeCertToBeSigned(encodings[i]);
7663 test_encodeCert(encodings[i]);
7664 test_decodeCert(encodings[i]);
7665 test_encodeCRLDistPoints(encodings[i]);
7666 test_decodeCRLDistPoints(encodings[i]);
7667 test_encodeCRLIssuingDistPoint(encodings[i]);
7668 test_decodeCRLIssuingDistPoint(encodings[i]);
7669 test_encodeCRLToBeSigned(encodings[i]);
7670 test_decodeCRLToBeSigned(encodings[i]);
7671 test_encodeEnhancedKeyUsage(encodings[i]);
7672 test_decodeEnhancedKeyUsage(encodings[i]);
7673 test_encodeAuthorityKeyId(encodings[i]);
7674 test_decodeAuthorityKeyId(encodings[i]);
7675 test_encodeAuthorityKeyId2(encodings[i]);
7676 test_decodeAuthorityKeyId2(encodings[i]);
7677 test_encodeAuthorityInfoAccess(encodings[i]);
7678 test_decodeAuthorityInfoAccess(encodings[i]);
7679 test_encodeCTL(encodings[i]);
7680 test_decodeCTL(encodings[i]);
7681 test_encodePKCSContentInfo(encodings[i]);
7682 test_decodePKCSContentInfo(encodings[i]);
7683 test_encodePKCSAttribute(encodings[i]);
7684 test_decodePKCSAttribute(encodings[i]);
7685 test_encodePKCSAttributes(encodings[i]);
7686 test_decodePKCSAttributes(encodings[i]);
7687 test_encodePKCSSMimeCapabilities(encodings[i]);
7688 test_decodePKCSSMimeCapabilities(encodings[i]);
7689 test_encodePKCSSignerInfo(encodings[i]);
7690 test_decodePKCSSignerInfo(encodings[i]);
7691 test_encodeCMSSignerInfo(encodings[i]);
7692 test_decodeCMSSignerInfo(encodings[i]);
7693 test_encodeNameConstraints(encodings[i]);
7694 test_decodeNameConstraints(encodings[i]);
7695 test_encodePolicyQualifierUserNotice(encodings[i]);
7696 test_decodePolicyQualifierUserNotice(encodings[i]);
7697 test_encodeCertPolicies(encodings[i]);
7698 test_decodeCertPolicies(encodings[i]);
7700 testPortPublicKeyInfo();