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);
3122 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3125 CERT_INFO *info = (CERT_INFO *)buf;
3127 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3128 ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %d\n",
3130 ok(info->IssuerUniqueId.cbData == sizeof(serialNum),
3131 "unexpected issuer unique id size %d\n", info->IssuerUniqueId.cbData);
3132 ok(!memcmp(info->IssuerUniqueId.pbData, serialNum, sizeof(serialNum)),
3133 "unexpected issuer unique id value\n");
3136 /* Now check with serial number, subject and issuer specified */
3137 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert,
3138 sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3139 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3142 CERT_INFO *info = (CERT_INFO *)buf;
3144 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3145 ok(info->SerialNumber.cbData == 1,
3146 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3147 ok(*info->SerialNumber.pbData == *serialNum,
3148 "Expected serial number %d, got %d\n", *serialNum,
3149 *info->SerialNumber.pbData);
3150 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3151 "Wrong size %d\n", info->Issuer.cbData);
3152 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3153 "Unexpected issuer\n");
3154 ok(info->Subject.cbData == sizeof(encodedCommonName),
3155 "Wrong size %d\n", info->Subject.cbData);
3156 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3157 info->Subject.cbData), "Unexpected subject\n");
3160 /* Check again with pub key specified */
3161 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3162 v1CertWithPubKey, sizeof(v1CertWithPubKey), CRYPT_DECODE_ALLOC_FLAG, NULL,
3164 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3167 CERT_INFO *info = (CERT_INFO *)buf;
3169 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3170 ok(info->SerialNumber.cbData == 1,
3171 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3172 ok(*info->SerialNumber.pbData == *serialNum,
3173 "Expected serial number %d, got %d\n", *serialNum,
3174 *info->SerialNumber.pbData);
3175 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3176 "Wrong size %d\n", info->Issuer.cbData);
3177 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3178 "Unexpected issuer\n");
3179 ok(info->Subject.cbData == sizeof(encodedCommonName),
3180 "Wrong size %d\n", info->Subject.cbData);
3181 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3182 info->Subject.cbData), "Unexpected subject\n");
3183 ok(!strcmp(info->SubjectPublicKeyInfo.Algorithm.pszObjId,
3184 szOID_RSA_RSA), "Expected szOID_RSA_RSA, got %s\n",
3185 info->SubjectPublicKeyInfo.Algorithm.pszObjId);
3186 ok(info->SubjectPublicKeyInfo.PublicKey.cbData == sizeof(aKey),
3187 "Wrong size %d\n", info->SubjectPublicKeyInfo.PublicKey.cbData);
3188 ok(!memcmp(info->SubjectPublicKeyInfo.PublicKey.pbData, aKey,
3189 sizeof(aKey)), "Unexpected public key\n");
3194 static const BYTE hash[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
3197 static const BYTE signedBigCert[] = {
3198 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
3199 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
3200 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
3201 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3202 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
3203 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
3204 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
3205 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
3206 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
3207 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3208 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
3209 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
3211 static void test_encodeCert(DWORD dwEncoding)
3213 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
3214 * also that bigCert is a NULL-terminated string, so don't count its
3215 * last byte (otherwise the signed cert won't decode.)
3217 CERT_SIGNED_CONTENT_INFO info = { { sizeof(bigCert), (BYTE *)bigCert },
3218 { NULL, { 0, NULL } }, { sizeof(hash), (BYTE *)hash, 0 } };
3223 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT, &info,
3224 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
3225 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3228 ok(bufSize == sizeof(signedBigCert), "Wrong size %d\n", bufSize);
3229 ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n");
3234 static void test_decodeCert(DWORD dwEncoding)
3240 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert,
3241 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3242 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3245 CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf;
3247 ok(info->ToBeSigned.cbData == sizeof(bigCert),
3248 "Wrong cert size %d\n", info->ToBeSigned.cbData);
3249 ok(!memcmp(info->ToBeSigned.pbData, bigCert, info->ToBeSigned.cbData),
3250 "Unexpected cert\n");
3251 ok(info->Signature.cbData == sizeof(hash),
3252 "Wrong signature size %d\n", info->Signature.cbData);
3253 ok(!memcmp(info->Signature.pbData, hash, info->Signature.cbData),
3254 "Unexpected signature\n");
3257 /* A signed cert decodes as a CERT_INFO too */
3258 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCert,
3259 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3260 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3263 CERT_INFO *info = (CERT_INFO *)buf;
3265 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3266 ok(info->SerialNumber.cbData == 1,
3267 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3268 ok(*info->SerialNumber.pbData == *serialNum,
3269 "Expected serial number %d, got %d\n", *serialNum,
3270 *info->SerialNumber.pbData);
3271 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3272 "Wrong size %d\n", info->Issuer.cbData);
3273 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3274 "Unexpected issuer\n");
3275 ok(info->Subject.cbData == sizeof(encodedCommonName),
3276 "Wrong size %d\n", info->Subject.cbData);
3277 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3278 info->Subject.cbData), "Unexpected subject\n");
3283 static const BYTE emptyDistPoint[] = { 0x30, 0x02, 0x30, 0x00 };
3284 static const BYTE distPointWithUrl[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3285 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3286 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3287 static const BYTE distPointWithReason[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3289 static const BYTE distPointWithIssuer[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3290 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3291 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3292 static const BYTE distPointWithUrlAndIssuer[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3293 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3294 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3295 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3296 0x2e, 0x6f, 0x72, 0x67 };
3297 static const BYTE crlReason = CRL_REASON_KEY_COMPROMISE |
3298 CRL_REASON_AFFILIATION_CHANGED;
3300 static void test_encodeCRLDistPoints(DWORD dwEncoding)
3302 CRL_DIST_POINTS_INFO info = { 0 };
3303 CRL_DIST_POINT point = { { 0 } };
3304 CERT_ALT_NAME_ENTRY entry = { 0 };
3309 /* Test with an empty info */
3310 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3311 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3312 ok(!ret && GetLastError() == E_INVALIDARG,
3313 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3314 /* Test with one empty dist point */
3315 info.cDistPoint = 1;
3316 info.rgDistPoint = &point;
3317 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3318 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3319 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3322 ok(size == sizeof(emptyDistPoint), "Wrong size %d\n", size);
3323 ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n");
3326 /* A dist point with an invalid name */
3327 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3328 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3329 U(entry).pwszURL = (LPWSTR)nihongoURL;
3330 U(point.DistPointName).FullName.cAltEntry = 1;
3331 U(point.DistPointName).FullName.rgAltEntry = &entry;
3332 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3333 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3334 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
3335 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
3336 /* The first invalid character is at index 7 */
3337 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
3338 "Expected invalid char at index 7, got %d\n",
3339 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
3340 /* A dist point with (just) a valid name */
3341 U(entry).pwszURL = (LPWSTR)url;
3342 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3343 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3344 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3347 ok(size == sizeof(distPointWithUrl), "Wrong size %d\n", size);
3348 ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n");
3351 /* A dist point with (just) reason flags */
3352 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3353 point.ReasonFlags.cbData = sizeof(crlReason);
3354 point.ReasonFlags.pbData = (LPBYTE)&crlReason;
3355 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3356 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3357 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3360 ok(size == sizeof(distPointWithReason), "Wrong size %d\n", size);
3361 ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n");
3364 /* A dist point with just an issuer */
3365 point.ReasonFlags.cbData = 0;
3366 point.CRLIssuer.cAltEntry = 1;
3367 point.CRLIssuer.rgAltEntry = &entry;
3368 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3369 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3370 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3373 ok(size == sizeof(distPointWithIssuer), "Wrong size %d\n", size);
3374 ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n");
3377 /* A dist point with both a name and an issuer */
3378 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3379 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3380 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3381 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3384 ok(size == sizeof(distPointWithUrlAndIssuer),
3385 "Wrong size %d\n", size);
3386 ok(!memcmp(buf, distPointWithUrlAndIssuer, size), "Unexpected value\n");
3391 static void test_decodeCRLDistPoints(DWORD dwEncoding)
3396 PCRL_DIST_POINTS_INFO info;
3397 PCRL_DIST_POINT point;
3398 PCERT_ALT_NAME_ENTRY entry;
3400 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3401 emptyDistPoint, emptyDistPoint[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3403 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3406 info = (PCRL_DIST_POINTS_INFO)buf;
3407 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3408 "Wrong size %d\n", size);
3409 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3411 point = info->rgDistPoint;
3412 ok(point->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_NO_NAME,
3413 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3414 point->DistPointName.dwDistPointNameChoice);
3415 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3416 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3419 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3420 distPointWithUrl, distPointWithUrl[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3422 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3425 info = (PCRL_DIST_POINTS_INFO)buf;
3426 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3427 "Wrong size %d\n", size);
3428 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3430 point = info->rgDistPoint;
3431 ok(point->DistPointName.dwDistPointNameChoice ==
3432 CRL_DIST_POINT_FULL_NAME,
3433 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3434 point->DistPointName.dwDistPointNameChoice);
3435 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3436 "Expected 1 name entry, got %d\n",
3437 U(point->DistPointName).FullName.cAltEntry);
3438 entry = U(point->DistPointName).FullName.rgAltEntry;
3439 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3440 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3441 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3442 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3443 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3446 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3447 distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
3449 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3452 info = (PCRL_DIST_POINTS_INFO)buf;
3453 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3454 "Wrong size %d\n", size);
3455 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3457 point = info->rgDistPoint;
3458 ok(point->DistPointName.dwDistPointNameChoice ==
3459 CRL_DIST_POINT_NO_NAME,
3460 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3461 point->DistPointName.dwDistPointNameChoice);
3462 ok(point->ReasonFlags.cbData == sizeof(crlReason),
3463 "Expected reason length\n");
3464 ok(!memcmp(point->ReasonFlags.pbData, &crlReason, sizeof(crlReason)),
3465 "Unexpected reason\n");
3466 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3469 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3470 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2,
3471 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3472 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3475 info = (PCRL_DIST_POINTS_INFO)buf;
3476 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3477 "Wrong size %d\n", size);
3478 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3480 point = info->rgDistPoint;
3481 ok(point->DistPointName.dwDistPointNameChoice ==
3482 CRL_DIST_POINT_FULL_NAME,
3483 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3484 point->DistPointName.dwDistPointNameChoice);
3485 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3486 "Expected 1 name entry, got %d\n",
3487 U(point->DistPointName).FullName.cAltEntry);
3488 entry = U(point->DistPointName).FullName.rgAltEntry;
3489 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3490 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3491 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3492 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3493 ok(point->CRLIssuer.cAltEntry == 1,
3494 "Expected 1 issuer entry, got %d\n", point->CRLIssuer.cAltEntry);
3495 entry = point->CRLIssuer.rgAltEntry;
3496 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3497 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3498 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3503 static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3504 static const BYTE emptyNameIDP[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3505 static const BYTE urlIDP[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3506 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3509 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding)
3514 CRL_ISSUING_DIST_POINT point = { { 0 } };
3515 CERT_ALT_NAME_ENTRY entry;
3517 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, NULL,
3518 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3519 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3521 skip("no X509_ISSUING_DIST_POINT encode support\n");
3524 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3525 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3526 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3527 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3528 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3531 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
3532 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
3535 /* nonsensical flags */
3536 point.fOnlyContainsUserCerts = TRUE;
3537 point.fOnlyContainsCACerts = TRUE;
3538 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3539 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3540 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3543 ok(size == sizeof(badFlagsIDP), "Unexpected size %d\n", size);
3544 ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n");
3547 /* unimplemented name type */
3548 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3549 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_ISSUER_RDN_NAME;
3550 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3551 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3552 ok(!ret && GetLastError() == E_INVALIDARG,
3553 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3555 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3556 U(point.DistPointName).FullName.cAltEntry = 0;
3557 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3558 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3559 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3562 ok(size == sizeof(emptyNameIDP), "Unexpected size %d\n", size);
3563 ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n");
3566 /* name with URL entry */
3567 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3568 U(entry).pwszURL = (LPWSTR)url;
3569 U(point.DistPointName).FullName.cAltEntry = 1;
3570 U(point.DistPointName).FullName.rgAltEntry = &entry;
3571 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3572 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3573 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3576 ok(size == sizeof(urlIDP), "Unexpected size %d\n", size);
3577 ok(!memcmp(buf, urlIDP, size), "Unexpected value\n");
3582 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY *expected,
3583 const CERT_ALT_NAME_ENTRY *got)
3585 ok(expected->dwAltNameChoice == got->dwAltNameChoice,
3586 "Expected name choice %d, got %d\n", expected->dwAltNameChoice,
3587 got->dwAltNameChoice);
3588 if (expected->dwAltNameChoice == got->dwAltNameChoice)
3590 switch (got->dwAltNameChoice)
3592 case CERT_ALT_NAME_RFC822_NAME:
3593 case CERT_ALT_NAME_DNS_NAME:
3594 case CERT_ALT_NAME_EDI_PARTY_NAME:
3595 case CERT_ALT_NAME_URL:
3596 case CERT_ALT_NAME_REGISTERED_ID:
3597 ok((!U(*expected).pwszURL && !U(*got).pwszURL) ||
3598 (!U(*expected).pwszURL && !lstrlenW(U(*got).pwszURL)) ||
3599 (!U(*got).pwszURL && !lstrlenW(U(*expected).pwszURL)) ||
3600 !lstrcmpW(U(*expected).pwszURL, U(*got).pwszURL),
3601 "Unexpected name\n");
3603 case CERT_ALT_NAME_X400_ADDRESS:
3604 case CERT_ALT_NAME_DIRECTORY_NAME:
3605 case CERT_ALT_NAME_IP_ADDRESS:
3606 ok(U(*got).IPAddress.cbData == U(*expected).IPAddress.cbData,
3607 "Unexpected IP address length %d\n", U(*got).IPAddress.cbData);
3608 ok(!memcmp(U(*got).IPAddress.pbData, U(*got).IPAddress.pbData,
3609 U(*got).IPAddress.cbData), "Unexpected value\n");
3615 static void compareAltNameInfo(const CERT_ALT_NAME_INFO *expected,
3616 const CERT_ALT_NAME_INFO *got)
3620 ok(expected->cAltEntry == got->cAltEntry, "Expected %d entries, got %d\n",
3621 expected->cAltEntry, got->cAltEntry);
3622 for (i = 0; i < min(expected->cAltEntry, got->cAltEntry); i++)
3623 compareAltNameEntry(&expected->rgAltEntry[i], &got->rgAltEntry[i]);
3626 static void compareDistPointName(const CRL_DIST_POINT_NAME *expected,
3627 const CRL_DIST_POINT_NAME *got)
3629 ok(got->dwDistPointNameChoice == expected->dwDistPointNameChoice,
3630 "Unexpected name choice %d\n", got->dwDistPointNameChoice);
3631 if (got->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME)
3632 compareAltNameInfo(&(U(*expected).FullName), &(U(*got).FullName));
3635 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT *expected,
3636 const CRL_ISSUING_DIST_POINT *got)
3638 compareDistPointName(&expected->DistPointName, &got->DistPointName);
3639 ok(got->fOnlyContainsUserCerts == expected->fOnlyContainsUserCerts,
3640 "Unexpected fOnlyContainsUserCerts\n");
3641 ok(got->fOnlyContainsCACerts == expected->fOnlyContainsCACerts,
3642 "Unexpected fOnlyContainsCACerts\n");
3643 ok(got->OnlySomeReasonFlags.cbData == expected->OnlySomeReasonFlags.cbData,
3644 "Unexpected reason flags\n");
3645 ok(got->fIndirectCRL == expected->fIndirectCRL,
3646 "Unexpected fIndirectCRL\n");
3649 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding)
3654 CRL_ISSUING_DIST_POINT point = { { 0 } };
3656 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3657 emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3659 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3661 skip("no X509_ISSUING_DIST_POINT decode support\n");
3664 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3667 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3670 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3671 badFlagsIDP, badFlagsIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3673 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3676 point.fOnlyContainsUserCerts = point.fOnlyContainsCACerts = TRUE;
3677 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3680 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3681 emptyNameIDP, emptyNameIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3683 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3686 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3687 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3688 U(point.DistPointName).FullName.cAltEntry = 0;
3689 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3692 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3693 urlIDP, urlIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3694 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3697 CERT_ALT_NAME_ENTRY entry;
3699 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3700 U(entry).pwszURL = (LPWSTR)url;
3701 U(point.DistPointName).FullName.cAltEntry = 1;
3702 U(point.DistPointName).FullName.rgAltEntry = &entry;
3703 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3708 static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3709 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3711 static const BYTE v2CRL[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3712 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3713 0x30, 0x30, 0x30, 0x30, 0x5a };
3714 static const BYTE v1CRLWithIssuer[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3715 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3716 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3717 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3719 static const BYTE v1CRLWithIssuerAndEmptyEntry[] = { 0x30, 0x43, 0x30, 0x02,
3720 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3721 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3722 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3723 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3724 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3725 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3726 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3727 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3728 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3729 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3730 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3731 static const BYTE v1CRLWithEntryExt[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3732 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3733 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3734 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3735 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3736 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3737 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3738 static const BYTE v1CRLWithExt[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3739 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3740 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3741 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
3742 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3743 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
3744 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3745 static const BYTE v2CRLWithExt[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
3746 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
3747 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
3748 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
3749 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
3750 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
3751 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3752 static const BYTE v2CRLWithIssuingDistPoint[] = { 0x30,0x5c,0x02,0x01,0x01,
3753 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
3754 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
3755 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
3756 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3757 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
3758 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3760 static void test_encodeCRLToBeSigned(DWORD dwEncoding)
3764 static CHAR oid_issuing_dist_point[] = szOID_ISSUING_DIST_POINT;
3766 CRL_INFO info = { 0 };
3767 CRL_ENTRY entry = { { 0 }, { 0 }, 0, 0 };
3770 /* Test with a V1 CRL */
3771 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3772 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3773 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3774 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3777 ok(size == sizeof(v1CRL), "Wrong size %d\n", size);
3778 ok(!memcmp(buf, v1CRL, size), "Got unexpected value\n");
3782 info.dwVersion = CRL_V2;
3783 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3784 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3785 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3786 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3789 ok(size == v2CRL[1] + 2, "Expected size %d, got %d\n",
3790 v2CRL[1] + 2, size);
3791 ok(!memcmp(buf, v2CRL, size), "Got unexpected value\n");
3794 /* v1 CRL with a name */
3795 info.dwVersion = CRL_V1;
3796 info.Issuer.cbData = sizeof(encodedCommonName);
3797 info.Issuer.pbData = (BYTE *)encodedCommonName;
3798 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3799 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3800 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3803 ok(size == sizeof(v1CRLWithIssuer), "Wrong size %d\n", size);
3804 ok(!memcmp(buf, v1CRLWithIssuer, size), "Got unexpected value\n");
3809 /* v1 CRL with a name and a NULL entry pointer (crashes on win9x) */
3811 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3812 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3813 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3814 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3816 /* now set an empty entry */
3818 info.rgCRLEntry = &entry;
3819 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3820 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3823 ok(size == sizeof(v1CRLWithIssuerAndEmptyEntry),
3824 "Wrong size %d\n", size);
3825 ok(!memcmp(buf, v1CRLWithIssuerAndEmptyEntry, size),
3826 "Got unexpected value\n");
3829 /* an entry with a serial number */
3830 entry.SerialNumber.cbData = sizeof(serialNum);
3831 entry.SerialNumber.pbData = (BYTE *)serialNum;
3832 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3833 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3836 ok(size == sizeof(v1CRLWithIssuerAndEntry),
3837 "Wrong size %d\n", size);
3838 ok(!memcmp(buf, v1CRLWithIssuerAndEntry, size),
3839 "Got unexpected value\n");
3842 /* an entry with an extension */
3843 entry.cExtension = 1;
3844 entry.rgExtension = &criticalExt;
3845 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3846 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3847 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3850 ok(size == sizeof(v1CRLWithEntryExt), "Wrong size %d\n", size);
3851 ok(!memcmp(buf, v1CRLWithEntryExt, size), "Got unexpected value\n");
3854 /* a CRL with an extension */
3855 entry.cExtension = 0;
3856 info.cExtension = 1;
3857 info.rgExtension = &criticalExt;
3858 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3859 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3860 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3863 ok(size == sizeof(v1CRLWithExt), "Wrong size %d\n", size);
3864 ok(!memcmp(buf, v1CRLWithExt, size), "Got unexpected value\n");
3867 /* a v2 CRL with an extension, this time non-critical */
3868 info.dwVersion = CRL_V2;
3869 info.rgExtension = &nonCriticalExt;
3870 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3871 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3872 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3875 ok(size == sizeof(v2CRLWithExt), "Wrong size %d\n", size);
3876 ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n");
3879 /* a v2 CRL with an issuing dist point extension */
3880 ext.pszObjId = oid_issuing_dist_point;
3881 ext.fCritical = TRUE;
3882 ext.Value.cbData = sizeof(urlIDP);
3883 ext.Value.pbData = (LPBYTE)urlIDP;
3884 entry.rgExtension = &ext;
3885 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3886 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3887 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3890 ok(size == sizeof(v2CRLWithIssuingDistPoint), "Wrong size %d\n", size);
3891 ok(!memcmp(buf, v2CRLWithIssuingDistPoint, size), "Unexpected value\n");
3896 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
3897 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
3898 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
3899 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
3900 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
3901 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
3902 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
3903 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
3904 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
3905 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
3906 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
3907 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
3908 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
3909 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
3910 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
3911 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
3912 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
3913 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
3914 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
3915 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
3916 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
3917 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
3918 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
3919 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
3920 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
3921 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
3922 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
3923 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
3924 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
3925 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
3926 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
3927 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
3928 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
3929 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
3931 static const BYTE verisignCRLWithLotsOfEntries[] = {
3932 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
3933 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
3934 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
3935 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
3936 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
3937 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
3938 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
3939 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
3940 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
3941 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
3942 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
3943 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
3944 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
3945 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
3946 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
3947 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
3948 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3949 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
3950 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
3951 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3952 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
3953 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
3954 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
3955 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
3956 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
3957 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
3958 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
3959 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
3960 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
3961 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
3962 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3963 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
3964 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
3965 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3966 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
3967 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
3968 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
3969 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
3970 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
3971 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
3972 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
3973 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
3974 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
3975 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
3976 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
3977 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
3978 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
3979 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
3980 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
3981 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
3982 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
3983 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
3984 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
3985 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
3986 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3987 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
3988 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
3989 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
3990 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
3991 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
3992 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
3993 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
3994 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
3995 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
3996 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
3997 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
3998 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
3999 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
4000 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
4001 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
4002 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
4003 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
4004 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
4005 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
4006 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
4007 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
4008 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
4009 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
4010 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
4011 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
4012 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
4013 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
4014 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
4015 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
4016 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
4017 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
4018 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
4019 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
4020 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
4021 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
4022 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
4023 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
4024 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
4025 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
4026 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
4027 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
4028 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
4029 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
4030 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
4031 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
4032 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
4033 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
4034 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
4035 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
4036 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
4037 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
4038 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
4039 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
4040 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
4041 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
4042 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
4043 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
4044 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
4045 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
4046 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
4047 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
4048 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
4049 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
4050 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
4051 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
4052 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
4053 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
4054 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
4055 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
4056 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
4057 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
4058 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
4059 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
4060 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
4061 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
4062 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
4063 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
4064 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
4065 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
4066 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
4067 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
4068 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
4069 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
4070 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
4071 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
4072 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
4073 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
4074 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
4075 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
4076 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
4077 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
4078 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
4079 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
4080 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
4081 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
4082 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
4083 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
4084 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
4085 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
4086 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
4087 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
4088 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
4089 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
4090 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
4091 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
4092 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
4093 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
4094 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
4095 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
4096 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
4097 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
4098 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
4099 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
4100 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
4101 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
4102 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
4103 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
4104 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
4105 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
4106 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
4107 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
4108 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
4109 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
4110 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
4111 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
4112 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
4113 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
4114 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
4115 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
4116 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
4117 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
4118 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
4119 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
4120 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
4121 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
4122 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
4123 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
4124 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
4125 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
4126 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
4127 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
4128 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
4129 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
4130 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
4131 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
4132 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
4133 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
4134 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
4135 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
4136 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
4137 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
4138 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
4139 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
4140 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
4141 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
4142 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
4143 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
4144 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
4145 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
4146 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
4147 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
4148 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
4149 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
4150 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
4151 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
4152 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
4153 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
4154 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
4155 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
4156 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
4157 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
4158 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
4159 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
4160 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
4161 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
4162 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
4163 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
4164 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
4165 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
4166 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
4167 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
4168 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
4169 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
4170 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
4171 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
4172 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
4173 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
4174 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
4175 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
4176 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
4177 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
4178 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
4179 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
4180 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
4181 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
4182 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
4183 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
4184 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
4185 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
4186 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
4187 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
4188 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
4189 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
4190 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
4191 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
4192 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
4193 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
4194 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
4195 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
4196 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
4197 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
4198 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
4199 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
4200 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
4201 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
4202 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
4203 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
4204 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
4205 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
4206 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
4207 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
4208 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
4209 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
4210 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
4211 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
4212 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
4213 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
4214 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
4215 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
4216 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
4217 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
4218 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
4219 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
4220 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
4221 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
4222 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
4223 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
4224 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
4225 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
4226 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
4227 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
4228 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
4229 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
4230 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
4231 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
4232 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
4233 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
4234 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
4235 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4236 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4237 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4238 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4239 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4240 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4241 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4242 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4243 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4244 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4245 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4246 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4247 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4248 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4249 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4250 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4251 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4252 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4253 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4254 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4255 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4256 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4257 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4258 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4259 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4260 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4261 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4262 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4263 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4264 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4265 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4266 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4267 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4268 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4269 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4270 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4271 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4272 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4273 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4274 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4275 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4276 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4277 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4278 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4279 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4280 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4281 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4282 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4283 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4284 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4285 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4286 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4287 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4288 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4289 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4290 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4291 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4292 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4293 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4294 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4295 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4296 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4297 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4298 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4299 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4300 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4301 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4302 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4303 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4304 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4305 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4306 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4307 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4308 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4309 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4310 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4311 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4312 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4313 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4314 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4315 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4316 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4317 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4318 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4319 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4320 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4321 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4322 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4323 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4324 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4325 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4326 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4327 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4328 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4329 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4330 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4331 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4332 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4333 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4334 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4335 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4336 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4337 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4338 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4339 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4340 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4341 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4342 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4343 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4344 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4345 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4346 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4347 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4348 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4349 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4350 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4351 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4352 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4353 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4354 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4355 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4356 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4357 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4358 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4359 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4360 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4361 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4362 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4363 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4364 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4365 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4366 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4367 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4368 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4369 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4370 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4371 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4372 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4373 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4374 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4375 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4376 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4377 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4378 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4379 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4380 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4381 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4382 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4383 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4384 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4385 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4386 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4387 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4388 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4389 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4390 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4391 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4392 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4393 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4394 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4395 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4396 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4397 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4398 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4399 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4400 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4401 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4402 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4403 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4404 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4405 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4406 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4407 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4408 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4409 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4410 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4411 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4412 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4413 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4414 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4415 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4416 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4417 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4418 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4419 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4420 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4421 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4422 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4423 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4424 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4425 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4426 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4427 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4428 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4429 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4430 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4431 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4432 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4433 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4434 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4435 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4436 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4437 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4438 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4439 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4441 static void test_decodeCRLToBeSigned(DWORD dwEncoding)
4443 static const BYTE *corruptCRLs[] = { v1CRL, v2CRL };
4448 for (i = 0; i < sizeof(corruptCRLs) / sizeof(corruptCRLs[0]); i++)
4450 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4451 corruptCRLs[i], corruptCRLs[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4453 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4454 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4455 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4458 /* at a minimum, a CRL must contain an issuer: */
4459 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4460 v1CRLWithIssuer, v1CRLWithIssuer[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4462 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4465 CRL_INFO *info = (CRL_INFO *)buf;
4467 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4468 ok(info->cCRLEntry == 0, "Expected 0 CRL entries, got %d\n",
4470 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4471 "Wrong issuer size %d\n", info->Issuer.cbData);
4472 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4473 "Unexpected issuer\n");
4476 /* check decoding with an empty CRL entry */
4477 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4478 v1CRLWithIssuerAndEmptyEntry, v1CRLWithIssuerAndEmptyEntry[1] + 2,
4479 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4480 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4481 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4482 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4484 /* with a real CRL entry */
4485 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4486 v1CRLWithIssuerAndEntry, v1CRLWithIssuerAndEntry[1] + 2,
4487 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4488 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4491 CRL_INFO *info = (CRL_INFO *)buf;
4494 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4495 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4497 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4498 entry = info->rgCRLEntry;
4499 ok(entry->SerialNumber.cbData == 1,
4500 "Expected serial number size 1, got %d\n",
4501 entry->SerialNumber.cbData);
4502 ok(*entry->SerialNumber.pbData == *serialNum,
4503 "Expected serial number %d, got %d\n", *serialNum,
4504 *entry->SerialNumber.pbData);
4505 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4506 "Wrong issuer size %d\n", info->Issuer.cbData);
4507 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4508 "Unexpected issuer\n");
4511 /* a real CRL from verisign that has extensions */
4512 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4513 verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG,
4515 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4518 CRL_INFO *info = (CRL_INFO *)buf;
4521 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4522 ok(info->cCRLEntry == 3, "Expected 3 CRL entries, got %d\n",
4524 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4525 entry = info->rgCRLEntry;
4526 ok(info->cExtension == 2, "Expected 2 extensions, got %d\n",
4530 /* another real CRL from verisign that has lots of entries */
4531 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4532 verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries),
4533 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4534 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4537 CRL_INFO *info = (CRL_INFO *)buf;
4539 ok(size >= sizeof(CRL_INFO), "Got size %d\n", size);
4540 ok(info->cCRLEntry == 209, "Expected 209 CRL entries, got %d\n",
4542 ok(info->cExtension == 0, "Expected 0 extensions, got %d\n",
4546 /* and finally, with an extension */
4547 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4548 v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4550 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4553 CRL_INFO *info = (CRL_INFO *)buf;
4556 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4557 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4559 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4560 entry = info->rgCRLEntry;
4561 ok(entry->SerialNumber.cbData == 1,
4562 "Expected serial number size 1, got %d\n",
4563 entry->SerialNumber.cbData);
4564 ok(*entry->SerialNumber.pbData == *serialNum,
4565 "Expected serial number %d, got %d\n", *serialNum,
4566 *entry->SerialNumber.pbData);
4567 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4568 "Wrong issuer size %d\n", info->Issuer.cbData);
4569 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4570 "Unexpected issuer\n");
4571 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4575 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4576 v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4578 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4581 CRL_INFO *info = (CRL_INFO *)buf;
4583 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4587 /* And again, with an issuing dist point */
4588 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4589 v2CRLWithIssuingDistPoint, sizeof(v2CRLWithIssuingDistPoint),
4590 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4591 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4594 CRL_INFO *info = (CRL_INFO *)buf;
4596 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4602 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
4603 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
4604 static const BYTE encodedUsage[] = {
4605 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4606 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4607 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4609 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding)
4614 CERT_ENHKEY_USAGE usage;
4616 /* Test with empty usage */
4617 usage.cUsageIdentifier = 0;
4618 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4619 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4620 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4623 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
4624 ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n");
4627 /* Test with a few usages */
4628 usage.cUsageIdentifier = sizeof(keyUsages) / sizeof(keyUsages[0]);
4629 usage.rgpszUsageIdentifier = (LPSTR *)keyUsages;
4630 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4631 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4632 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4635 ok(size == sizeof(encodedUsage), "Wrong size %d\n", size);
4636 ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n");
4641 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding)
4647 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4648 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4650 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4653 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4655 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4656 "Wrong size %d\n", size);
4657 ok(usage->cUsageIdentifier == 0, "Expected 0 CRL entries, got %d\n",
4658 usage->cUsageIdentifier);
4661 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4662 encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL,
4664 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4667 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4670 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4671 "Wrong size %d\n", size);
4672 ok(usage->cUsageIdentifier == sizeof(keyUsages) / sizeof(keyUsages[0]),
4673 "Wrong CRL entries count %d\n", usage->cUsageIdentifier);
4674 for (i = 0; i < usage->cUsageIdentifier; i++)
4675 ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]),
4676 "Expected OID %s, got %s\n", keyUsages[i],
4677 usage->rgpszUsageIdentifier[i]);
4682 static BYTE keyId[] = { 1,2,3,4 };
4683 static const BYTE authorityKeyIdWithId[] = {
4684 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4685 static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4686 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4687 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4688 static const BYTE authorityKeyIdWithSerial[] = { 0x30,0x03,0x82,0x01,0x01 };
4690 static void test_encodeAuthorityKeyId(DWORD dwEncoding)
4692 CERT_AUTHORITY_KEY_ID_INFO info = { { 0 } };
4697 /* Test with empty id */
4698 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4699 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4700 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4703 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4704 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4707 /* With just a key id */
4708 info.KeyId.cbData = sizeof(keyId);
4709 info.KeyId.pbData = keyId;
4710 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4711 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4712 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4715 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", size);
4716 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4719 /* With just an issuer */
4720 info.KeyId.cbData = 0;
4721 info.CertIssuer.cbData = sizeof(encodedCommonName);
4722 info.CertIssuer.pbData = (BYTE *)encodedCommonName;
4723 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4724 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4725 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4728 ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %d\n",
4730 ok(!memcmp(buf, authorityKeyIdWithIssuer, size), "Unexpected value\n");
4733 /* With just a serial number */
4734 info.CertIssuer.cbData = 0;
4735 info.CertSerialNumber.cbData = sizeof(serialNum);
4736 info.CertSerialNumber.pbData = (BYTE *)serialNum;
4737 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4738 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4739 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4742 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4744 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4749 static void test_decodeAuthorityKeyId(DWORD dwEncoding)
4755 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4756 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4758 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4761 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4763 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4765 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4766 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4767 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4770 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4771 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4772 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4773 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4776 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4778 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4780 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4781 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4782 "Unexpected key id\n");
4783 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4784 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4787 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4788 authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer),
4789 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4790 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4793 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4795 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4797 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4798 ok(info->CertIssuer.cbData == sizeof(encodedCommonName),
4799 "Unexpected issuer len\n");
4800 ok(!memcmp(info->CertIssuer.pbData, encodedCommonName,
4801 sizeof(encodedCommonName)), "Unexpected issuer\n");
4802 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4805 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4806 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4807 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4808 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4811 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4813 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4815 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4816 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4817 ok(info->CertSerialNumber.cbData == sizeof(serialNum),
4818 "Unexpected serial number len\n");
4819 ok(!memcmp(info->CertSerialNumber.pbData, serialNum, sizeof(serialNum)),
4820 "Unexpected serial number\n");
4825 static const BYTE authorityKeyIdWithIssuerUrl[] = { 0x30,0x15,0xa1,0x13,0x86,
4826 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
4829 static void test_encodeAuthorityKeyId2(DWORD dwEncoding)
4831 CERT_AUTHORITY_KEY_ID2_INFO info = { { 0 } };
4832 CERT_ALT_NAME_ENTRY entry = { 0 };
4837 /* Test with empty id */
4838 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4839 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4840 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4843 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4844 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4847 /* With just a key id */
4848 info.KeyId.cbData = sizeof(keyId);
4849 info.KeyId.pbData = keyId;
4850 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4851 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4852 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4855 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n",
4857 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4860 /* With a bogus issuer name */
4861 info.KeyId.cbData = 0;
4862 info.AuthorityCertIssuer.cAltEntry = 1;
4863 info.AuthorityCertIssuer.rgAltEntry = &entry;
4864 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4865 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4866 ok(!ret && GetLastError() == E_INVALIDARG,
4867 "Expected E_INVALIDARG, got %08x\n", GetLastError());
4868 /* With an issuer name */
4869 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
4870 U(entry).pwszURL = (LPWSTR)url;
4871 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4872 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4873 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4876 ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %d\n",
4878 ok(!memcmp(buf, authorityKeyIdWithIssuerUrl, size),
4879 "Unexpected value\n");
4882 /* With just a serial number */
4883 info.AuthorityCertIssuer.cAltEntry = 0;
4884 info.AuthorityCertSerialNumber.cbData = sizeof(serialNum);
4885 info.AuthorityCertSerialNumber.pbData = (BYTE *)serialNum;
4886 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4887 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4888 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4891 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4893 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4898 static void test_decodeAuthorityKeyId2(DWORD dwEncoding)
4904 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4905 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4907 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4910 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4912 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4914 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4915 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4916 "Expected no issuer name entries\n");
4917 ok(info->AuthorityCertSerialNumber.cbData == 0,
4918 "Expected no serial number\n");
4921 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4922 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4923 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4924 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4927 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4929 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4931 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4932 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4933 "Unexpected key id\n");
4934 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4935 "Expected no issuer name entries\n");
4936 ok(info->AuthorityCertSerialNumber.cbData == 0,
4937 "Expected no serial number\n");
4940 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4941 authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl),
4942 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4943 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4946 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4948 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4950 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4951 ok(info->AuthorityCertIssuer.cAltEntry == 1,
4952 "Expected 1 issuer entry, got %d\n",
4953 info->AuthorityCertIssuer.cAltEntry);
4954 ok(info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice ==
4955 CERT_ALT_NAME_URL, "Expected CERT_ALT_NAME_URL, got %d\n",
4956 info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice);
4957 ok(!lstrcmpW(U(info->AuthorityCertIssuer.rgAltEntry[0]).pwszURL,
4958 url), "Unexpected URL\n");
4959 ok(info->AuthorityCertSerialNumber.cbData == 0,
4960 "Expected no serial number\n");
4963 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4964 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4965 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4966 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4969 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4971 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4973 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4974 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4975 "Expected no issuer name entries\n");
4976 ok(info->AuthorityCertSerialNumber.cbData == sizeof(serialNum),
4977 "Unexpected serial number len\n");
4978 ok(!memcmp(info->AuthorityCertSerialNumber.pbData, serialNum,
4979 sizeof(serialNum)), "Unexpected serial number\n");
4984 static const BYTE authorityInfoAccessWithUrl[] = {
4985 0x30,0x19,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
4986 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
4987 static const BYTE authorityInfoAccessWithUrlAndIPAddr[] = {
4988 0x30,0x29,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
4989 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x0e,0x06,
4990 0x02,0x2d,0x06,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
4992 static void test_encodeAuthorityInfoAccess(DWORD dwEncoding)
4994 static char oid1[] = "1.2.3";
4995 static char oid2[] = "1.5.6";
4999 CERT_ACCESS_DESCRIPTION accessDescription[2];
5000 CERT_AUTHORITY_INFO_ACCESS aia;
5002 memset(accessDescription, 0, sizeof(accessDescription));
5004 aia.rgAccDescr = NULL;
5005 /* Having no access descriptions is allowed */
5006 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5007 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5008 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5011 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
5012 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
5016 /* It can't have an empty access method */
5018 aia.rgAccDescr = accessDescription;
5019 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5020 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5021 ok(!ret && (GetLastError() == E_INVALIDARG ||
5022 GetLastError() == OSS_LIMITED /* Win9x */),
5023 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
5024 /* It can't have an empty location */
5025 accessDescription[0].pszAccessMethod = oid1;
5026 SetLastError(0xdeadbeef);
5027 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5028 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5029 ok(!ret && GetLastError() == E_INVALIDARG,
5030 "expected E_INVALIDARG, got %08x\n", GetLastError());
5031 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5032 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
5033 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5034 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5035 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5038 ok(size == sizeof(authorityInfoAccessWithUrl), "unexpected size %d\n",
5040 ok(!memcmp(buf, authorityInfoAccessWithUrl, size),
5041 "unexpected value\n");
5045 accessDescription[1].pszAccessMethod = oid2;
5046 accessDescription[1].AccessLocation.dwAltNameChoice =
5047 CERT_ALT_NAME_IP_ADDRESS;
5048 U(accessDescription[1].AccessLocation).IPAddress.cbData =
5049 sizeof(encodedIPAddr);
5050 U(accessDescription[1].AccessLocation).IPAddress.pbData =
5051 (LPBYTE)encodedIPAddr;
5053 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5054 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5055 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5058 ok(size == sizeof(authorityInfoAccessWithUrlAndIPAddr),
5059 "unexpected size %d\n", size);
5060 ok(!memcmp(buf, authorityInfoAccessWithUrlAndIPAddr, size),
5061 "unexpected value\n");
5067 static void compareAuthorityInfoAccess(LPCSTR header,
5068 const CERT_AUTHORITY_INFO_ACCESS *expected,
5069 const CERT_AUTHORITY_INFO_ACCESS *got)
5073 ok(expected->cAccDescr == got->cAccDescr,
5074 "%s: expected %d access descriptions, got %d\n", header,
5075 expected->cAccDescr, got->cAccDescr);
5076 for (i = 0; i < expected->cAccDescr; i++)
5078 ok(!strcmp(expected->rgAccDescr[i].pszAccessMethod,
5079 got->rgAccDescr[i].pszAccessMethod), "%s[%d]: expected %s, got %s\n",
5080 header, i, expected->rgAccDescr[i].pszAccessMethod,
5081 got->rgAccDescr[i].pszAccessMethod);
5082 compareAltNameEntry(&expected->rgAccDescr[i].AccessLocation,
5083 &got->rgAccDescr[i].AccessLocation);
5087 static void test_decodeAuthorityInfoAccess(DWORD dwEncoding)
5089 static char oid1[] = "1.2.3";
5090 static char oid2[] = "1.5.6";
5095 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5096 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
5098 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5101 CERT_AUTHORITY_INFO_ACCESS aia = { 0, NULL };
5103 compareAuthorityInfoAccess("empty AIA", &aia,
5104 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5108 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5109 authorityInfoAccessWithUrl, sizeof(authorityInfoAccessWithUrl),
5110 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5111 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5114 CERT_ACCESS_DESCRIPTION accessDescription;
5115 CERT_AUTHORITY_INFO_ACCESS aia;
5117 accessDescription.pszAccessMethod = oid1;
5118 accessDescription.AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5119 U(accessDescription.AccessLocation).pwszURL = (LPWSTR)url;
5121 aia.rgAccDescr = &accessDescription;
5122 compareAuthorityInfoAccess("AIA with URL", &aia,
5123 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5127 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5128 authorityInfoAccessWithUrlAndIPAddr,
5129 sizeof(authorityInfoAccessWithUrlAndIPAddr), CRYPT_DECODE_ALLOC_FLAG,
5131 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5134 CERT_ACCESS_DESCRIPTION accessDescription[2];
5135 CERT_AUTHORITY_INFO_ACCESS aia;
5137 accessDescription[0].pszAccessMethod = oid1;
5138 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5139 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
5140 accessDescription[1].pszAccessMethod = oid2;
5141 accessDescription[1].AccessLocation.dwAltNameChoice =
5142 CERT_ALT_NAME_IP_ADDRESS;
5143 U(accessDescription[1].AccessLocation).IPAddress.cbData =
5144 sizeof(encodedIPAddr);
5145 U(accessDescription[1].AccessLocation).IPAddress.pbData =
5146 (LPBYTE)encodedIPAddr;
5148 aia.rgAccDescr = accessDescription;
5149 compareAuthorityInfoAccess("AIA with URL and IP addr", &aia,
5150 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5156 static const BYTE emptyCTL[] = {
5157 0x30,0x17,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5158 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5159 static const BYTE emptyCTLWithVersion1[] = {
5160 0x30,0x1a,0x02,0x01,0x01,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5161 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5162 static const BYTE ctlWithUsageIdentifier[] = {
5163 0x30,0x1b,0x30,0x04,0x06,0x02,0x2a,0x03,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
5164 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5165 static const BYTE ctlWithListIdentifier[] = {
5166 0x30,0x1a,0x30,0x00,0x04,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5167 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5168 static const BYTE ctlWithSequenceNumber[] = {
5169 0x30,0x1a,0x30,0x00,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5170 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5171 static const BYTE ctlWithThisUpdate[] = {
5172 0x30,0x15,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5173 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5174 static const BYTE ctlWithThisAndNextUpdate[] = {
5175 0x30,0x24,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5176 0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5177 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5178 static const BYTE ctlWithAlgId[] = {
5179 0x30,0x1b,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5180 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5181 static const BYTE ctlWithBogusEntry[] = {
5182 0x30,0x29,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5183 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x10,0x30,0x0e,0x04,
5184 0x01,0x01,0x31,0x09,0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,0x01 };
5185 static const BYTE ctlWithOneEntry[] = {
5186 0x30,0x2a,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5187 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x11,0x30,0x0f,0x04,
5188 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00 };
5189 static const BYTE ctlWithTwoEntries[] = {
5190 0x30,0x41,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5191 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x28,0x30,0x0f,0x04,
5192 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00,0x30,
5193 0x15,0x04,0x01,0x01,0x31,0x10,0x30,0x0e,0x06,0x02,0x2d,0x06,0x31,0x08,0x30,
5194 0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5196 static void test_encodeCTL(DWORD dwEncoding)
5198 static char oid1[] = "1.2.3";
5199 static char oid2[] = "1.5.6";
5205 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5206 CTL_ENTRY ctlEntry[2];
5207 CRYPT_ATTRIBUTE attr1, attr2;
5208 CRYPT_ATTR_BLOB value1, value2;
5210 memset(&info, 0, sizeof(info));
5211 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5212 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5213 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5216 ok(size == sizeof(emptyCTL), "unexpected size %d\n", size);
5217 ok(!memcmp(buf, emptyCTL, size), "unexpected value\n");
5222 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5223 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5224 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5227 ok(size == sizeof(emptyCTLWithVersion1), "unexpected size %d\n", size);
5228 ok(!memcmp(buf, emptyCTLWithVersion1, size), "unexpected value\n");
5233 info.SubjectUsage.cUsageIdentifier = 1;
5234 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5235 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5236 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5237 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5240 ok(size == sizeof(ctlWithUsageIdentifier), "unexpected size %d\n",
5242 ok(!memcmp(buf, ctlWithUsageIdentifier, size), "unexpected value\n");
5246 info.SubjectUsage.cUsageIdentifier = 0;
5247 info.ListIdentifier.cbData = sizeof(serialNum);
5248 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5249 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5250 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5251 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5254 ok(size == sizeof(ctlWithListIdentifier), "unexpected size %d\n", size);
5255 ok(!memcmp(buf, ctlWithListIdentifier, size), "unexpected value\n");
5259 info.ListIdentifier.cbData = 0;
5260 info.SequenceNumber.cbData = sizeof(serialNum);
5261 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5262 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5263 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5264 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5267 ok(size == sizeof(ctlWithSequenceNumber), "unexpected size %d\n",
5269 ok(!memcmp(buf, ctlWithSequenceNumber, size), "unexpected value\n");
5273 info.SequenceNumber.cbData = 0;
5274 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5275 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5276 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5277 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5280 ok(size == sizeof(ctlWithThisUpdate), "unexpected size %d\n", size);
5281 ok(!memcmp(buf, ctlWithThisUpdate, size), "unexpected value\n");
5285 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5286 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5287 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5288 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5291 ok(size == sizeof(ctlWithThisAndNextUpdate), "unexpected size %d\n",
5293 ok(!memcmp(buf, ctlWithThisAndNextUpdate, size), "unexpected value\n");
5297 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5298 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5299 info.SubjectAlgorithm.pszObjId = oid2;
5300 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5301 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5302 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5305 ok(size == sizeof(ctlWithAlgId), "unexpected size %d\n", size);
5306 ok(!memcmp(buf, ctlWithAlgId, size), "unexpected value\n");
5310 /* The value is supposed to be asn.1 encoded, so this'll fail to decode
5311 * (see tests below) but it'll encode fine.
5313 info.SubjectAlgorithm.pszObjId = NULL;
5314 value1.cbData = sizeof(serialNum);
5315 value1.pbData = (LPBYTE)serialNum;
5316 attr1.pszObjId = oid1;
5318 attr1.rgValue = &value1;
5319 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5320 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5321 ctlEntry[0].cAttribute = 1;
5322 ctlEntry[0].rgAttribute = &attr1;
5324 info.rgCTLEntry = ctlEntry;
5325 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5326 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5327 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5330 ok(size == sizeof(ctlWithBogusEntry), "unexpected size %d\n", size);
5331 ok(!memcmp(buf, ctlWithBogusEntry, size), "unexpected value\n");
5335 value1.cbData = sizeof(emptySequence);
5336 value1.pbData = (LPBYTE)emptySequence;
5337 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5338 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5339 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5342 ok(size == sizeof(ctlWithOneEntry), "unexpected size %d\n", size);
5343 ok(!memcmp(buf, ctlWithOneEntry, size), "unexpected value\n");
5347 value2.cbData = sizeof(encodedIPAddr);
5348 value2.pbData = (LPBYTE)encodedIPAddr;
5349 attr2.pszObjId = oid2;
5351 attr2.rgValue = &value2;
5352 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5353 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5354 ctlEntry[1].cAttribute = 1;
5355 ctlEntry[1].rgAttribute = &attr2;
5357 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5358 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5359 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5362 ok(size == sizeof(ctlWithTwoEntries), "unexpected size %d\n", size);
5363 ok(!memcmp(buf, ctlWithTwoEntries, size), "unexpected value\n");
5369 static void compareCTLInfo(LPCSTR header, const CTL_INFO *expected,
5370 const CTL_INFO *got)
5374 ok(expected->dwVersion == got->dwVersion,
5375 "%s: expected version %d, got %d\n", header, expected->dwVersion,
5377 ok(expected->SubjectUsage.cUsageIdentifier ==
5378 got->SubjectUsage.cUsageIdentifier,
5379 "%s: expected %d usage identifiers, got %d\n", header,
5380 expected->SubjectUsage.cUsageIdentifier,
5381 got->SubjectUsage.cUsageIdentifier);
5382 for (i = 0; i < expected->SubjectUsage.cUsageIdentifier; i++)
5383 ok(!strcmp(expected->SubjectUsage.rgpszUsageIdentifier[i],
5384 got->SubjectUsage.rgpszUsageIdentifier[i]),
5385 "%s[%d]: expected %s, got %s\n", header, i,
5386 expected->SubjectUsage.rgpszUsageIdentifier[i],
5387 got->SubjectUsage.rgpszUsageIdentifier[i]);
5388 ok(expected->ListIdentifier.cbData == got->ListIdentifier.cbData,
5389 "%s: expected list identifier of %d bytes, got %d\n", header,
5390 expected->ListIdentifier.cbData, got->ListIdentifier.cbData);
5391 if (expected->ListIdentifier.cbData)
5392 ok(!memcmp(expected->ListIdentifier.pbData, got->ListIdentifier.pbData,
5393 expected->ListIdentifier.cbData),
5394 "%s: unexpected list identifier value\n", header);
5395 ok(expected->SequenceNumber.cbData == got->SequenceNumber.cbData,
5396 "%s: expected sequence number of %d bytes, got %d\n", header,
5397 expected->SequenceNumber.cbData, got->SequenceNumber.cbData);
5398 if (expected->SequenceNumber.cbData)
5399 ok(!memcmp(expected->SequenceNumber.pbData, got->SequenceNumber.pbData,
5400 expected->SequenceNumber.cbData),
5401 "%s: unexpected sequence number value\n", header);
5402 ok(!memcmp(&expected->ThisUpdate, &got->ThisUpdate, sizeof(FILETIME)),
5403 "%s: expected this update = (%d, %d), got (%d, %d)\n", header,
5404 expected->ThisUpdate.dwLowDateTime, expected->ThisUpdate.dwHighDateTime,
5405 got->ThisUpdate.dwLowDateTime, got->ThisUpdate.dwHighDateTime);
5406 ok(!memcmp(&expected->NextUpdate, &got->NextUpdate, sizeof(FILETIME)),
5407 "%s: expected next update = (%d, %d), got (%d, %d)\n", header,
5408 expected->NextUpdate.dwLowDateTime, expected->NextUpdate.dwHighDateTime,
5409 got->NextUpdate.dwLowDateTime, got->NextUpdate.dwHighDateTime);
5410 if (expected->SubjectAlgorithm.pszObjId &&
5411 *expected->SubjectAlgorithm.pszObjId && !got->SubjectAlgorithm.pszObjId)
5412 ok(0, "%s: expected subject algorithm %s, got NULL\n", header,
5413 expected->SubjectAlgorithm.pszObjId);
5414 if (expected->SubjectAlgorithm.pszObjId && got->SubjectAlgorithm.pszObjId)
5415 ok(!strcmp(expected->SubjectAlgorithm.pszObjId,
5416 got->SubjectAlgorithm.pszObjId),
5417 "%s: expected subject algorithm %s, got %s\n", header,
5418 expected->SubjectAlgorithm.pszObjId, got->SubjectAlgorithm.pszObjId);
5419 ok(expected->SubjectAlgorithm.Parameters.cbData ==
5420 got->SubjectAlgorithm.Parameters.cbData,
5421 "%s: expected subject algorithm parameters of %d bytes, got %d\n", header,
5422 expected->SubjectAlgorithm.Parameters.cbData,
5423 got->SubjectAlgorithm.Parameters.cbData);
5424 if (expected->SubjectAlgorithm.Parameters.cbData)
5425 ok(!memcmp(expected->SubjectAlgorithm.Parameters.pbData,
5426 got->SubjectAlgorithm.Parameters.pbData,
5427 expected->SubjectAlgorithm.Parameters.cbData),
5428 "%s: unexpected subject algorithm parameter value\n", header);
5429 ok(expected->cCTLEntry == got->cCTLEntry,
5430 "%s: expected %d CTL entries, got %d\n", header, expected->cCTLEntry,
5432 for (i = 0; i < expected->cCTLEntry; i++)
5434 ok(expected->rgCTLEntry[i].SubjectIdentifier.cbData ==
5435 got->rgCTLEntry[i].SubjectIdentifier.cbData,
5436 "%s[%d]: expected subject identifier of %d bytes, got %d\n",
5437 header, i, expected->rgCTLEntry[i].SubjectIdentifier.cbData,
5438 got->rgCTLEntry[i].SubjectIdentifier.cbData);
5439 if (expected->rgCTLEntry[i].SubjectIdentifier.cbData)
5440 ok(!memcmp(expected->rgCTLEntry[i].SubjectIdentifier.pbData,
5441 got->rgCTLEntry[i].SubjectIdentifier.pbData,
5442 expected->rgCTLEntry[i].SubjectIdentifier.cbData),
5443 "%s[%d]: unexpected subject identifier value\n",
5445 for (j = 0; j < expected->rgCTLEntry[i].cAttribute; j++)
5447 ok(!strcmp(expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5448 got->rgCTLEntry[i].rgAttribute[j].pszObjId),
5449 "%s[%d][%d]: expected attribute OID %s, got %s\n", header, i, j,
5450 expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5451 got->rgCTLEntry[i].rgAttribute[j].pszObjId);
5452 for (k = 0; k < expected->rgCTLEntry[i].rgAttribute[j].cValue; k++)
5454 ok(expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData ==
5455 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5456 "%s[%d][%d][%d]: expected value of %d bytes, got %d\n",
5458 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5459 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData);
5460 if (expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData)
5462 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5463 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5464 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData),
5465 "%s[%d][%d][%d]: unexpected value\n",
5470 ok(expected->cExtension == got->cExtension,
5471 "%s: expected %d extensions, got %d\n", header, expected->cExtension,
5473 for (i = 0; i < expected->cExtension; i++)
5475 ok(!strcmp(expected->rgExtension[i].pszObjId,
5476 got->rgExtension[i].pszObjId), "%s[%d]: expected %s, got %s\n",
5477 header, i, expected->rgExtension[i].pszObjId,
5478 got->rgExtension[i].pszObjId);
5479 ok(expected->rgExtension[i].fCritical == got->rgExtension[i].fCritical,
5480 "%s[%d]: expected fCritical = %d, got %d\n", header, i,
5481 expected->rgExtension[i].fCritical, got->rgExtension[i].fCritical);
5482 ok(expected->rgExtension[i].Value.cbData ==
5483 got->rgExtension[i].Value.cbData,
5484 "%s[%d]: expected extension value to have %d bytes, got %d\n",
5485 header, i, expected->rgExtension[i].Value.cbData,
5486 got->rgExtension[i].Value.cbData);
5487 if (expected->rgExtension[i].Value.cbData)
5488 ok(!memcmp(expected->rgExtension[i].Value.pbData,
5489 got->rgExtension[i].Value.pbData,
5490 expected->rgExtension[i].Value.cbData),
5491 "%s[%d]: unexpected extension value\n", header, i);
5495 static const BYTE signedCTL[] = {
5496 0x30,0x81,0xc7,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
5497 0x81,0xb9,0x30,0x81,0xb6,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
5498 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x28,0x06,0x09,0x2a,0x86,
5499 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x1b,0x04,0x19,0x30,0x17,0x30,0x00,
5500 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5501 0x30,0x5a,0x30,0x02,0x06,0x00,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
5502 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
5503 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
5504 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5505 0x00,0x04,0x40,0xca,0xd8,0x32,0xd1,0xbd,0x97,0x61,0x54,0xd6,0x80,0xcf,0x0d,
5506 0xbd,0xa2,0x42,0xc7,0xca,0x37,0x91,0x7d,0x9d,0xac,0x8c,0xdf,0x05,0x8a,0x39,
5507 0xc6,0x07,0xc1,0x37,0xe6,0xb9,0xd1,0x0d,0x26,0xec,0xa5,0xb0,0x8a,0x51,0x26,
5508 0x2b,0x4f,0x73,0x44,0x86,0x83,0x5e,0x2b,0x6e,0xcc,0xf8,0x1b,0x85,0x53,0xe9,
5509 0x7a,0x80,0x8f,0x6b,0x42,0x19,0x93 };
5510 static const BYTE signedCTLWithCTLInnerContent[] = {
5511 0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
5512 0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
5513 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
5514 0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
5515 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5516 0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
5517 0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
5518 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
5519 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
5520 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
5521 0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
5522 0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
5523 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
5524 0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5525 0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
5526 0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
5527 0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
5528 0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
5529 0x57,0x6c,0x0b,0x47,0xb8 };
5531 static void test_decodeCTL(DWORD dwEncoding)
5533 static char oid1[] = "1.2.3";
5534 static char oid2[] = "1.5.6";
5535 static BYTE nullData[] = { 5,0 };
5541 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5542 CTL_ENTRY ctlEntry[2];
5543 CRYPT_ATTRIBUTE attr1, attr2;
5544 CRYPT_ATTR_BLOB value1, value2;
5546 memset(&info, 0, sizeof(info));
5547 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTL, sizeof(emptyCTL),
5548 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5549 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5552 compareCTLInfo("empty CTL", &info, (CTL_INFO *)buf);
5557 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTLWithVersion1,
5558 sizeof(emptyCTLWithVersion1), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
5560 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5563 compareCTLInfo("v1 CTL", &info, (CTL_INFO *)buf);
5568 info.SubjectUsage.cUsageIdentifier = 1;
5569 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5570 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithUsageIdentifier,
5571 sizeof(ctlWithUsageIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5573 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5576 compareCTLInfo("CTL with usage identifier", &info, (CTL_INFO *)buf);
5580 info.SubjectUsage.cUsageIdentifier = 0;
5581 info.ListIdentifier.cbData = sizeof(serialNum);
5582 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5583 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithListIdentifier,
5584 sizeof(ctlWithListIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5585 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5588 compareCTLInfo("CTL with list identifier", &info, (CTL_INFO *)buf);
5592 info.ListIdentifier.cbData = 0;
5593 info.SequenceNumber.cbData = sizeof(serialNum);
5594 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5595 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithSequenceNumber,
5596 sizeof(ctlWithSequenceNumber), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5597 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5600 compareCTLInfo("CTL with sequence number", &info, (CTL_INFO *)buf);
5604 info.SequenceNumber.cbData = 0;
5605 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5606 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisUpdate,
5607 sizeof(ctlWithThisUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5608 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5611 compareCTLInfo("CTL with this update", &info, (CTL_INFO *)buf);
5615 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5616 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisAndNextUpdate,
5617 sizeof(ctlWithThisAndNextUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5619 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5622 compareCTLInfo("CTL with this and next update", &info, (CTL_INFO *)buf);
5626 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5627 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5628 info.SubjectAlgorithm.pszObjId = oid2;
5629 info.SubjectAlgorithm.Parameters.cbData = sizeof(nullData);
5630 info.SubjectAlgorithm.Parameters.pbData = nullData;
5631 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithAlgId,
5632 sizeof(ctlWithAlgId), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5633 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5636 compareCTLInfo("CTL with algorithm identifier", &info, (CTL_INFO *)buf);
5640 SetLastError(0xdeadbeef);
5641 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithBogusEntry,
5642 sizeof(ctlWithBogusEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5644 (GetLastError() == CRYPT_E_ASN1_EOD ||
5645 GetLastError() == CRYPT_E_ASN1_CORRUPT ||
5646 GetLastError() == OSS_MORE_INPUT), /* Win9x */
5647 "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n",
5649 info.SubjectAlgorithm.Parameters.cbData = 0;
5650 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5651 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5652 info.SubjectAlgorithm.pszObjId = oid2;
5653 info.SubjectAlgorithm.pszObjId = NULL;
5654 value1.cbData = sizeof(emptySequence);
5655 value1.pbData = (LPBYTE)emptySequence;
5656 attr1.pszObjId = oid1;
5658 attr1.rgValue = &value1;
5659 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5660 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5661 ctlEntry[0].cAttribute = 1;
5662 ctlEntry[0].rgAttribute = &attr1;
5664 info.rgCTLEntry = ctlEntry;
5665 SetLastError(0xdeadbeef);
5666 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithOneEntry,
5667 sizeof(ctlWithOneEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5668 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5671 compareCTLInfo("CTL with one entry", &info, (CTL_INFO *)buf);
5675 value2.cbData = sizeof(encodedIPAddr);
5676 value2.pbData = (LPBYTE)encodedIPAddr;
5677 attr2.pszObjId = oid2;
5679 attr2.rgValue = &value2;
5680 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5681 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5682 ctlEntry[1].cAttribute = 1;
5683 ctlEntry[1].rgAttribute = &attr2;
5685 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithTwoEntries,
5686 sizeof(ctlWithTwoEntries), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5687 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5690 compareCTLInfo("CTL with two entries", &info, (CTL_INFO *)buf);
5694 /* A signed CTL isn't decodable, even if the inner content is a CTL */
5695 SetLastError(0xdeadbeef);
5696 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, signedCTL,
5697 sizeof(signedCTL), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5698 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5699 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5700 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5702 SetLastError(0xdeadbeef);
5703 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL,
5704 signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent),
5705 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5706 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5707 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5708 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5712 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
5713 static const BYTE emptyPKCSContentInfoExtraBytes[] = { 0x30,0x04,0x06,0x02,0x2a,
5715 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
5717 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
5718 0x03,0x02,0x01,0x01 };
5719 static BYTE bogusDER[] = { 1 };
5721 static void test_encodePKCSContentInfo(DWORD dwEncoding)
5726 CRYPT_CONTENT_INFO info = { 0 };
5727 char oid1[] = "1.2.3";
5731 /* Crashes on win9x */
5732 SetLastError(0xdeadbeef);
5733 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL,
5734 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5735 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5736 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5738 SetLastError(0xdeadbeef);
5739 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5740 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5741 ok(!ret && (GetLastError() == E_INVALIDARG ||
5742 GetLastError() == OSS_LIMITED /* Win9x */),
5743 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5744 info.pszObjId = oid1;
5745 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5746 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5747 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5750 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size);
5751 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n");
5754 info.Content.pbData = bogusDER;
5755 info.Content.cbData = sizeof(bogusDER);
5756 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5757 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5758 ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError());
5761 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size);
5762 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n");
5765 info.Content.pbData = (BYTE *)ints[0].encoded;
5766 info.Content.cbData = ints[0].encoded[1] + 2;
5767 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5768 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5771 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size);
5772 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n");
5777 static const BYTE indefiniteSignedPKCSContent[] = {
5778 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
5779 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
5780 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
5781 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
5782 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
5783 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
5784 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5785 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5786 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
5787 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5788 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5789 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
5790 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
5791 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
5792 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
5793 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
5794 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
5795 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
5796 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
5797 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5798 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5799 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
5800 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
5801 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
5802 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
5803 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
5804 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
5805 0x00,0x00,0x00,0x00,0x00,0x00 };
5807 static void test_decodePKCSContentInfo(DWORD dwEncoding)
5812 CRYPT_CONTENT_INFO *info;
5814 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5815 emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo),
5816 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5817 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5820 info = (CRYPT_CONTENT_INFO *)buf;
5822 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5824 ok(info->Content.cbData == 0, "Expected no data, got %d\n",
5825 info->Content.cbData);
5828 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5829 emptyPKCSContentInfoExtraBytes, sizeof(emptyPKCSContentInfoExtraBytes),
5830 0, NULL, NULL, &size);
5831 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5832 SetLastError(0xdeadbeef);
5833 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5834 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo),
5835 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5836 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5837 * I doubt an app depends on that.
5839 ok((!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5840 GetLastError() == CRYPT_E_ASN1_CORRUPT)) || broken(ret),
5841 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5843 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5844 intPKCSContentInfo, sizeof(intPKCSContentInfo),
5845 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5846 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5849 info = (CRYPT_CONTENT_INFO *)buf;
5851 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5853 ok(info->Content.cbData == ints[0].encoded[1] + 2,
5854 "Unexpected size %d\n", info->Content.cbData);
5855 ok(!memcmp(info->Content.pbData, ints[0].encoded,
5856 info->Content.cbData), "Unexpected value\n");
5859 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5860 indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent),
5861 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5862 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5865 info = (CRYPT_CONTENT_INFO *)buf;
5867 ok(!strcmp(info->pszObjId, szOID_RSA_signedData),
5868 "Expected %s, got %s\n", szOID_RSA_signedData, info->pszObjId);
5869 ok(info->Content.cbData == 392, "Expected 392, got %d\n",
5870 info->Content.cbData);
5875 static const BYTE emptyPKCSAttr[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
5877 static const BYTE bogusPKCSAttr[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
5879 static const BYTE intPKCSAttr[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
5882 static void test_encodePKCSAttribute(DWORD dwEncoding)
5884 CRYPT_ATTRIBUTE attr = { 0 };
5888 CRYPT_ATTR_BLOB blob;
5889 char oid[] = "1.2.3";
5893 /* Crashes on win9x */
5894 SetLastError(0xdeadbeef);
5895 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, NULL,
5896 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5897 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5898 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5900 SetLastError(0xdeadbeef);
5901 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5902 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5903 ok(!ret && (GetLastError() == E_INVALIDARG ||
5904 GetLastError() == OSS_LIMITED /* Win9x */),
5905 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5906 attr.pszObjId = oid;
5907 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5908 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5909 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5912 ok(size == sizeof(emptyPKCSAttr), "Unexpected size %d\n", size);
5913 ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n");
5916 blob.cbData = sizeof(bogusDER);
5917 blob.pbData = bogusDER;
5919 attr.rgValue = &blob;
5920 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5921 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5922 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5925 ok(size == sizeof(bogusPKCSAttr), "Unexpected size %d\n", size);
5926 ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n");
5929 blob.pbData = (BYTE *)ints[0].encoded;
5930 blob.cbData = ints[0].encoded[1] + 2;
5931 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5932 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5935 ok(size == sizeof(intPKCSAttr), "Unexpected size %d\n", size);
5936 ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n");
5941 static void test_decodePKCSAttribute(DWORD dwEncoding)
5946 CRYPT_ATTRIBUTE *attr;
5948 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5949 emptyPKCSAttr, sizeof(emptyPKCSAttr),
5950 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5951 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5954 attr = (CRYPT_ATTRIBUTE *)buf;
5956 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5958 ok(attr->cValue == 0, "Expected no value, got %d\n", attr->cValue);
5961 SetLastError(0xdeadbeef);
5962 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5963 bogusPKCSAttr, sizeof(bogusPKCSAttr),
5964 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5965 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5966 * I doubt an app depends on that.
5968 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5969 GetLastError() == CRYPT_E_ASN1_CORRUPT ||
5970 GetLastError() == OSS_MORE_INPUT /* Win9x */),
5971 "Expected CRYPT_E_ASN1_EOD, CRYPT_E_ASN1_CORRUPT, or OSS_MORE_INPUT, got %x\n",
5973 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5974 intPKCSAttr, sizeof(intPKCSAttr),
5975 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5976 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5979 attr = (CRYPT_ATTRIBUTE *)buf;
5981 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5983 ok(attr->cValue == 1, "Expected 1 value, got %d\n", attr->cValue);
5984 ok(attr->rgValue[0].cbData == ints[0].encoded[1] + 2,
5985 "Unexpected size %d\n", attr->rgValue[0].cbData);
5986 ok(!memcmp(attr->rgValue[0].pbData, ints[0].encoded,
5987 attr->rgValue[0].cbData), "Unexpected value\n");
5992 static const BYTE emptyPKCSAttributes[] = { 0x31,0x00 };
5993 static const BYTE singlePKCSAttributes[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
5994 0x2a,0x03,0x31,0x00 };
5995 static const BYTE doublePKCSAttributes[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
5996 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
5998 static void test_encodePKCSAttributes(DWORD dwEncoding)
6000 CRYPT_ATTRIBUTES attributes = { 0 };
6001 CRYPT_ATTRIBUTE attr[2] = { { 0 } };
6002 CRYPT_ATTR_BLOB blob;
6006 char oid1[] = "1.2.3", oid2[] = "1.5.6";
6008 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6009 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6010 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6013 ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %d\n", size);
6014 ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n");
6017 attributes.cAttr = 1;
6018 attributes.rgAttr = attr;
6019 SetLastError(0xdeadbeef);
6020 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6021 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6022 ok(!ret && (GetLastError() == E_INVALIDARG ||
6023 GetLastError() == OSS_LIMITED /* Win9x */),
6024 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6025 attr[0].pszObjId = oid1;
6026 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6027 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6030 ok(size == sizeof(singlePKCSAttributes), "Unexpected size %d\n", size);
6031 ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n");
6034 attr[1].pszObjId = oid2;
6036 attr[1].rgValue = &blob;
6037 blob.pbData = (BYTE *)ints[0].encoded;
6038 blob.cbData = ints[0].encoded[1] + 2;
6039 attributes.cAttr = 2;
6040 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6041 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6042 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6045 ok(size == sizeof(doublePKCSAttributes), "Unexpected size %d\n", size);
6046 ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n");
6051 static void test_decodePKCSAttributes(DWORD dwEncoding)
6056 CRYPT_ATTRIBUTES *attributes;
6058 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6059 emptyPKCSAttributes, sizeof(emptyPKCSAttributes),
6060 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6061 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6064 attributes = (CRYPT_ATTRIBUTES *)buf;
6065 ok(attributes->cAttr == 0, "Expected no attributes, got %d\n",
6069 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6070 singlePKCSAttributes, sizeof(singlePKCSAttributes),
6071 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6072 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6075 attributes = (CRYPT_ATTRIBUTES *)buf;
6076 ok(attributes->cAttr == 1, "Expected 1 attribute, got %d\n",
6078 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
6079 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
6080 ok(attributes->rgAttr[0].cValue == 0,
6081 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
6084 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6085 doublePKCSAttributes, sizeof(doublePKCSAttributes),
6086 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6087 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6090 attributes = (CRYPT_ATTRIBUTES *)buf;
6091 ok(attributes->cAttr == 2, "Expected 2 attributes, got %d\n",
6093 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
6094 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
6095 ok(attributes->rgAttr[0].cValue == 0,
6096 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
6097 ok(!strcmp(attributes->rgAttr[1].pszObjId, "1.5.6"),
6098 "Expected 1.5.6, got %s\n", attributes->rgAttr[1].pszObjId);
6099 ok(attributes->rgAttr[1].cValue == 1,
6100 "Expected 1 attribute, got %d\n", attributes->rgAttr[1].cValue);
6101 ok(attributes->rgAttr[1].rgValue[0].cbData == ints[0].encoded[1] + 2,
6102 "Unexpected size %d\n", attributes->rgAttr[1].rgValue[0].cbData);
6103 ok(!memcmp(attributes->rgAttr[1].rgValue[0].pbData, ints[0].encoded,
6104 attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n");
6109 static const BYTE singleCapability[] = {
6110 0x30,0x06,0x30,0x04,0x06,0x02,0x2d,0x06 };
6111 static const BYTE twoCapabilities[] = {
6112 0x30,0x0c,0x30,0x04,0x06,0x02,0x2d,0x06,0x30,0x04,0x06,0x02,0x2a,0x03 };
6113 static const BYTE singleCapabilitywithNULL[] = {
6114 0x30,0x08,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
6116 static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding)
6118 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6122 CRYPT_SMIME_CAPABILITY capability[2];
6123 CRYPT_SMIME_CAPABILITIES capabilities;
6125 /* An empty capabilities is allowed */
6126 capabilities.cCapability = 0;
6127 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6128 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6129 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6132 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
6133 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
6136 /* A non-empty capabilities with an empty capability (lacking an OID) is
6139 capability[0].pszObjId = NULL;
6140 capability[0].Parameters.cbData = 0;
6141 capabilities.cCapability = 1;
6142 capabilities.rgCapability = capability;
6143 SetLastError(0xdeadbeef);
6144 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6145 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6146 ok(!ret && (GetLastError() == E_INVALIDARG ||
6147 GetLastError() == OSS_LIMITED /* Win9x */),
6148 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6149 capability[0].pszObjId = oid1;
6150 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6151 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6152 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6155 ok(size == sizeof(singleCapability), "unexpected size %d\n", size);
6156 ok(!memcmp(buf, singleCapability, size), "unexpected value\n");
6159 capability[1].pszObjId = oid2;
6160 capability[1].Parameters.cbData = 0;
6161 capabilities.cCapability = 2;
6162 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6163 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6164 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6167 ok(size == sizeof(twoCapabilities), "unexpected size %d\n", size);
6168 ok(!memcmp(buf, twoCapabilities, size), "unexpected value\n");
6173 static void compareSMimeCapabilities(LPCSTR header,
6174 const CRYPT_SMIME_CAPABILITIES *expected, const CRYPT_SMIME_CAPABILITIES *got)
6178 ok(got->cCapability == expected->cCapability,
6179 "%s: expected %d capabilities, got %d\n", header, expected->cCapability,
6181 for (i = 0; i < expected->cCapability; i++)
6183 ok(!strcmp(expected->rgCapability[i].pszObjId,
6184 got->rgCapability[i].pszObjId), "%s[%d]: expected %s, got %s\n",
6185 header, i, expected->rgCapability[i].pszObjId,
6186 got->rgCapability[i].pszObjId);
6187 ok(expected->rgCapability[i].Parameters.cbData ==
6188 got->rgCapability[i].Parameters.cbData,
6189 "%s[%d]: expected %d bytes, got %d\n", header, i,
6190 expected->rgCapability[i].Parameters.cbData,
6191 got->rgCapability[i].Parameters.cbData);
6192 if (expected->rgCapability[i].Parameters.cbData)
6193 ok(!memcmp(expected->rgCapability[i].Parameters.pbData,
6194 got->rgCapability[i].Parameters.pbData,
6195 expected->rgCapability[i].Parameters.cbData),
6196 "%s[%d]: unexpected value\n", header, i);
6200 static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding)
6202 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6205 CRYPT_SMIME_CAPABILITY capability[2];
6206 CRYPT_SMIME_CAPABILITIES capabilities, *ptr;
6208 SetLastError(0xdeadbeef);
6209 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6210 emptySequence, sizeof(emptySequence),
6211 CRYPT_DECODE_ALLOC_FLAG, NULL, &ptr, &size);
6212 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6215 capabilities.cCapability = 0;
6216 compareSMimeCapabilities("empty capabilities", &capabilities, ptr);
6219 SetLastError(0xdeadbeef);
6220 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6221 singleCapability, sizeof(singleCapability), CRYPT_DECODE_ALLOC_FLAG, NULL,
6223 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6226 capability[0].pszObjId = oid1;
6227 capability[0].Parameters.cbData = 0;
6228 capabilities.cCapability = 1;
6229 capabilities.rgCapability = capability;
6230 compareSMimeCapabilities("single capability", &capabilities, ptr);
6233 SetLastError(0xdeadbeef);
6234 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6235 singleCapabilitywithNULL, sizeof(singleCapabilitywithNULL),
6236 CRYPT_DECODE_ALLOC_FLAG, NULL, &ptr, &size);
6237 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6240 BYTE NULLparam[] = {0x05, 0x00};
6241 capability[0].pszObjId = oid1;
6242 capability[0].Parameters.cbData = 2;
6243 capability[0].Parameters.pbData = NULLparam;
6244 capabilities.cCapability = 1;
6245 capabilities.rgCapability = capability;
6246 compareSMimeCapabilities("single capability with NULL", &capabilities,
6250 SetLastError(0xdeadbeef);
6251 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6252 twoCapabilities, sizeof(twoCapabilities), CRYPT_DECODE_ALLOC_FLAG, NULL,
6254 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6257 capability[0].Parameters.cbData = 0;
6258 capability[1].pszObjId = oid2;
6259 capability[1].Parameters.cbData = 0;
6260 capabilities.cCapability = 2;
6261 compareSMimeCapabilities("two capabilities", &capabilities, ptr);
6266 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
6267 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
6269 static const BYTE minimalPKCSSigner[] = {
6270 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6271 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6272 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6273 static const BYTE PKCSSignerWithSerial[] = {
6274 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6275 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6276 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
6278 static const BYTE PKCSSignerWithHashAlgo[] = {
6279 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6280 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6281 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
6283 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = {
6284 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6285 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6286 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6287 0x06,0x05,0x00,0x04,0x00 };
6288 static const BYTE PKCSSignerWithHash[] = {
6289 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6290 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6291 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6292 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
6293 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6294 static const BYTE PKCSSignerWithAuthAttr[] = {
6295 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6296 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6297 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
6298 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
6299 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
6300 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
6301 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6303 static void test_encodePKCSSignerInfo(DWORD dwEncoding)
6305 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6309 CMSG_SIGNER_INFO info = { 0 };
6310 char oid_common_name[] = szOID_COMMON_NAME;
6311 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
6312 (LPBYTE)encodedCommonName };
6313 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
6315 SetLastError(0xdeadbeef);
6316 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6317 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6318 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6320 skip("no PKCS7_SIGNER_INFO encode support\n");
6323 ok(!ret && (GetLastError() == E_INVALIDARG ||
6324 GetLastError() == OSS_LIMITED /* Win9x */),
6325 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6326 /* To be encoded, a signer must have an issuer at least, and the encoding
6327 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
6328 * see decoding tests.)
6330 info.Issuer.cbData = sizeof(encodedCommonNameNoNull);
6331 info.Issuer.pbData = encodedCommonNameNoNull;
6332 SetLastError(0xdeadbeef);
6333 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6334 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6335 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6336 ok(!ret && GetLastError() == E_INVALIDARG,
6337 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6340 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6341 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6344 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6345 if (size == sizeof(minimalPKCSSigner))
6346 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6348 ok(0, "Unexpected value\n");
6352 info.SerialNumber.cbData = sizeof(serialNum);
6353 info.SerialNumber.pbData = (BYTE *)serialNum;
6354 SetLastError(0xdeadbeef);
6355 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6356 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6357 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6358 ok(!ret && GetLastError() == E_INVALIDARG,
6359 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6362 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6363 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6366 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6368 if (size == sizeof(PKCSSignerWithSerial))
6369 ok(!memcmp(buf, PKCSSignerWithSerial, size),
6370 "Unexpected value\n");
6372 ok(0, "Unexpected value\n");
6376 info.HashAlgorithm.pszObjId = oid1;
6377 SetLastError(0xdeadbeef);
6378 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6379 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6380 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6381 ok(!ret && GetLastError() == E_INVALIDARG,
6382 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6385 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6386 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6389 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6391 if (size == sizeof(PKCSSignerWithHashAlgo))
6392 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6393 "Unexpected value\n");
6395 ok(0, "Unexpected value\n");
6399 info.HashEncryptionAlgorithm.pszObjId = oid2;
6400 SetLastError(0xdeadbeef);
6401 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6402 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6403 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6404 ok(!ret && GetLastError() == E_INVALIDARG,
6405 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6408 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6411 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6412 "Unexpected size %d\n", size);
6413 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo))
6414 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6415 "Unexpected value\n");
6417 ok(0, "Unexpected value\n");
6421 info.EncryptedHash.cbData = sizeof(hash);
6422 info.EncryptedHash.pbData = (BYTE *)hash;
6423 SetLastError(0xdeadbeef);
6424 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6425 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6426 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6427 ok(!ret && GetLastError() == E_INVALIDARG,
6428 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6431 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6434 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6436 if (size == sizeof(PKCSSignerWithHash))
6437 ok(!memcmp(buf, PKCSSignerWithHash, size),
6438 "Unexpected value\n");
6440 ok(0, "Unexpected value\n");
6444 info.AuthAttrs.cAttr = 1;
6445 info.AuthAttrs.rgAttr = &attr;
6446 SetLastError(0xdeadbeef);
6447 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6448 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6449 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6450 ok(!ret && GetLastError() == E_INVALIDARG,
6451 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6454 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6457 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
6459 if (size == sizeof(PKCSSignerWithAuthAttr))
6460 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
6461 "Unexpected value\n");
6463 ok(0, "Unexpected value\n");
6469 static void test_decodePKCSSignerInfo(DWORD dwEncoding)
6474 CMSG_SIGNER_INFO *info;
6476 /* A PKCS signer can't be decoded without a serial number. */
6477 SetLastError(0xdeadbeef);
6478 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6479 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6480 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6481 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
6482 GetLastError() == OSS_DATA_ERROR /* Win9x */),
6483 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %x\n",
6485 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6486 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6487 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6488 ok(ret || broken(GetLastError() == OSS_DATA_ERROR),
6489 "CryptDecodeObjectEx failed: %x\n", GetLastError());
6492 info = (CMSG_SIGNER_INFO *)buf;
6493 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6495 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6496 "Unexpected size %d\n", info->Issuer.cbData);
6497 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6498 info->Issuer.cbData), "Unexpected value\n");
6499 ok(info->SerialNumber.cbData == sizeof(serialNum),
6500 "Unexpected size %d\n", info->SerialNumber.cbData);
6501 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6502 "Unexpected value\n");
6505 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6506 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6507 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6510 info = (CMSG_SIGNER_INFO *)buf;
6511 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6513 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6514 "Unexpected size %d\n", info->Issuer.cbData);
6515 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6516 info->Issuer.cbData), "Unexpected value\n");
6517 ok(info->SerialNumber.cbData == sizeof(serialNum),
6518 "Unexpected size %d\n", info->SerialNumber.cbData);
6519 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6520 "Unexpected value\n");
6521 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6522 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6525 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6526 PKCSSignerWithHashAndEncryptionAlgo,
6527 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6531 info = (CMSG_SIGNER_INFO *)buf;
6532 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6534 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6535 "Unexpected size %d\n", info->Issuer.cbData);
6536 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6537 info->Issuer.cbData), "Unexpected value\n");
6538 ok(info->SerialNumber.cbData == sizeof(serialNum),
6539 "Unexpected size %d\n", info->SerialNumber.cbData);
6540 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6541 "Unexpected value\n");
6542 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6543 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6544 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6545 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6548 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6549 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6550 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6553 info = (CMSG_SIGNER_INFO *)buf;
6554 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6556 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6557 "Unexpected size %d\n", info->Issuer.cbData);
6558 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6559 info->Issuer.cbData), "Unexpected value\n");
6560 ok(info->SerialNumber.cbData == sizeof(serialNum),
6561 "Unexpected size %d\n", info->SerialNumber.cbData);
6562 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6563 "Unexpected value\n");
6564 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6565 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6566 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6567 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6568 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6569 info->EncryptedHash.cbData);
6570 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6571 "Unexpected value\n");
6574 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6575 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
6576 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6579 info = (CMSG_SIGNER_INFO *)buf;
6580 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n",
6581 info->AuthAttrs.cAttr);
6582 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
6583 "Expected %s, got %s\n", szOID_COMMON_NAME,
6584 info->AuthAttrs.rgAttr[0].pszObjId);
6585 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
6586 info->AuthAttrs.rgAttr[0].cValue);
6587 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
6588 sizeof(encodedCommonName), "Unexpected size %d\n",
6589 info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
6590 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
6591 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
6596 static const BYTE CMSSignerWithKeyId[] = {
6597 0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,
6598 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6600 static void test_encodeCMSSignerInfo(DWORD dwEncoding)
6605 CMSG_CMS_SIGNER_INFO info = { 0 };
6606 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6608 SetLastError(0xdeadbeef);
6609 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6610 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6611 ok(!ret, "Expected failure, got %d\n", ret);
6612 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6614 skip("no CMS_SIGNER_INFO encode support\n");
6617 ok(GetLastError() == E_INVALIDARG,
6618 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6619 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6620 SetLastError(0xdeadbeef);
6621 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6622 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6623 ok(!ret, "Expected failure, got %d\n", ret);
6624 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6626 skip("no CMS_SIGNER_INFO encode support\n");
6629 ok(GetLastError() == E_INVALIDARG,
6630 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6631 /* To be encoded, a signer must have a valid cert ID, where a valid ID may
6632 * be a key id or a issuer serial number with at least the issuer set, and
6633 * the encoding must include PKCS_7_ASN_ENCODING.
6634 * (That isn't enough to be decoded, see decoding tests.)
6636 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6637 sizeof(encodedCommonNameNoNull);
6638 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6639 SetLastError(0xdeadbeef);
6640 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6641 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6642 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6643 ok(!ret && GetLastError() == E_INVALIDARG,
6644 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6647 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6650 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6651 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6655 U(info.SignerId).IssuerSerialNumber.SerialNumber.cbData = sizeof(serialNum);
6656 U(info.SignerId).IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
6657 SetLastError(0xdeadbeef);
6658 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6659 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6660 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6661 ok(!ret && GetLastError() == E_INVALIDARG,
6662 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6665 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6668 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6670 ok(!memcmp(buf, PKCSSignerWithSerial, size), "Unexpected value\n");
6674 info.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
6675 U(info.SignerId).KeyId.cbData = sizeof(serialNum);
6676 U(info.SignerId).KeyId.pbData = (BYTE *)serialNum;
6677 SetLastError(0xdeadbeef);
6678 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6679 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6680 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6681 ok(!ret && GetLastError() == E_INVALIDARG,
6682 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6685 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6688 ok(size == sizeof(CMSSignerWithKeyId), "Unexpected size %d\n",
6690 ok(!memcmp(buf, CMSSignerWithKeyId, size), "Unexpected value\n");
6694 /* While a CERT_ID can have a hash type, that's not allowed in CMS, where
6695 * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed
6696 * (see RFC 3852, section 5.3.)
6698 info.SignerId.dwIdChoice = CERT_ID_SHA1_HASH;
6699 U(info.SignerId).HashId.cbData = sizeof(hash);
6700 U(info.SignerId).HashId.pbData = (BYTE *)hash;
6701 SetLastError(0xdeadbeef);
6702 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6703 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6704 ok(!ret && GetLastError() == E_INVALIDARG,
6705 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6706 /* Now with a hash algo */
6707 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6708 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6709 sizeof(encodedCommonNameNoNull);
6710 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6711 info.HashAlgorithm.pszObjId = oid1;
6712 SetLastError(0xdeadbeef);
6713 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6714 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6715 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6716 ok(!ret && GetLastError() == E_INVALIDARG,
6717 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6720 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6723 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6725 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6726 "Unexpected value\n");
6730 info.HashEncryptionAlgorithm.pszObjId = oid2;
6731 SetLastError(0xdeadbeef);
6732 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6733 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6734 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6735 ok(!ret && GetLastError() == E_INVALIDARG,
6736 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6739 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6742 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6743 "Unexpected size %d\n", size);
6744 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6745 "Unexpected value\n");
6749 info.EncryptedHash.cbData = sizeof(hash);
6750 info.EncryptedHash.pbData = (BYTE *)hash;
6751 SetLastError(0xdeadbeef);
6752 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6753 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6754 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6755 ok(!ret && GetLastError() == E_INVALIDARG,
6756 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6759 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6762 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6764 ok(!memcmp(buf, PKCSSignerWithHash, size), "Unexpected value\n");
6770 static void test_decodeCMSSignerInfo(DWORD dwEncoding)
6775 CMSG_CMS_SIGNER_INFO *info;
6776 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6778 /* A CMS signer can't be decoded without a serial number. */
6779 SetLastError(0xdeadbeef);
6780 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6781 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6782 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6783 ok(!ret, "expected failure\n");
6784 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6786 skip("no CMS_SIGNER_INFO decode support\n");
6789 ok(GetLastError() == CRYPT_E_ASN1_CORRUPT,
6790 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
6791 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6792 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6793 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6794 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6797 info = (CMSG_CMS_SIGNER_INFO *)buf;
6798 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6800 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6801 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6802 info->SignerId.dwIdChoice);
6803 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6804 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6805 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6806 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6807 encodedCommonNameNoNull,
6808 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6809 "Unexpected value\n");
6810 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6811 sizeof(serialNum), "Unexpected size %d\n",
6812 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6813 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6814 serialNum, sizeof(serialNum)), "Unexpected value\n");
6817 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6818 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6819 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6820 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6823 info = (CMSG_CMS_SIGNER_INFO *)buf;
6824 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6826 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6827 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6828 info->SignerId.dwIdChoice);
6829 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6830 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6831 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6832 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6833 encodedCommonNameNoNull,
6834 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6835 "Unexpected value\n");
6836 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6837 sizeof(serialNum), "Unexpected size %d\n",
6838 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6839 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6840 serialNum, sizeof(serialNum)), "Unexpected value\n");
6841 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6842 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6845 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6846 PKCSSignerWithHashAndEncryptionAlgo,
6847 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6849 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6852 info = (CMSG_CMS_SIGNER_INFO *)buf;
6853 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6855 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6856 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6857 info->SignerId.dwIdChoice);
6858 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6859 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6860 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6861 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6862 encodedCommonNameNoNull,
6863 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6864 "Unexpected value\n");
6865 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6866 sizeof(serialNum), "Unexpected size %d\n",
6867 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6868 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6869 serialNum, sizeof(serialNum)), "Unexpected value\n");
6870 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6871 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6872 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6873 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6876 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6877 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6878 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6879 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6882 info = (CMSG_CMS_SIGNER_INFO *)buf;
6883 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6885 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6886 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6887 info->SignerId.dwIdChoice);
6888 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6889 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6890 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6891 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6892 encodedCommonNameNoNull,
6893 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6894 "Unexpected value\n");
6895 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6896 sizeof(serialNum), "Unexpected size %d\n",
6897 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6898 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6899 serialNum, sizeof(serialNum)), "Unexpected value\n");
6900 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6901 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6902 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6903 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6904 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6905 info->EncryptedHash.cbData);
6906 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6907 "Unexpected value\n");
6910 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6911 CMSSignerWithKeyId, sizeof(CMSSignerWithKeyId),
6912 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6913 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6916 info = (CMSG_CMS_SIGNER_INFO *)buf;
6917 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6919 ok(info->SignerId.dwIdChoice == CERT_ID_KEY_IDENTIFIER,
6920 "Expected CERT_ID_KEY_IDENTIFIER, got %d\n",
6921 info->SignerId.dwIdChoice);
6922 ok(U(info->SignerId).KeyId.cbData == sizeof(serialNum),
6923 "Unexpected size %d\n", U(info->SignerId).KeyId.cbData);
6924 ok(!memcmp(U(info->SignerId).KeyId.pbData, serialNum, sizeof(serialNum)),
6925 "Unexpected value\n");
6930 static BYTE emptyDNSPermittedConstraints[] = {
6931 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
6932 static BYTE emptyDNSExcludedConstraints[] = {
6933 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
6934 static BYTE DNSExcludedConstraints[] = {
6935 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
6936 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6937 static BYTE permittedAndExcludedConstraints[] = {
6938 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6939 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
6940 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6941 static BYTE permittedAndExcludedWithMinConstraints[] = {
6942 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6943 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
6944 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6945 static BYTE permittedAndExcludedWithMinMaxConstraints[] = {
6946 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6947 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
6948 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6950 static void test_encodeNameConstraints(DWORD dwEncoding)
6953 CERT_NAME_CONSTRAINTS_INFO constraints = { 0 };
6954 CERT_GENERAL_SUBTREE permitted = { { 0 } };
6955 CERT_GENERAL_SUBTREE excluded = { { 0 } };
6959 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6960 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6961 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6963 skip("no X509_NAME_CONSTRAINTS encode support\n");
6966 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6969 ok(size == sizeof(emptySequence), "Unexpected size\n");
6970 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
6973 constraints.cPermittedSubtree = 1;
6974 constraints.rgPermittedSubtree = &permitted;
6975 SetLastError(0xdeadbeef);
6976 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6977 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6978 ok(!ret && GetLastError() == E_INVALIDARG,
6979 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6980 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
6981 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6982 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6983 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6986 ok(size == sizeof(emptyDNSPermittedConstraints), "Unexpected size\n");
6987 ok(!memcmp(buf, emptyDNSPermittedConstraints, size),
6988 "Unexpected value\n");
6991 constraints.cPermittedSubtree = 0;
6992 constraints.cExcludedSubtree = 1;
6993 constraints.rgExcludedSubtree = &excluded;
6994 excluded.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
6995 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6996 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6997 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7000 ok(size == sizeof(emptyDNSExcludedConstraints), "Unexpected size\n");
7001 ok(!memcmp(buf, emptyDNSExcludedConstraints, size),
7002 "Unexpected value\n");
7005 U(excluded.Base).pwszURL = (LPWSTR)url;
7006 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7007 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7008 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7011 ok(size == sizeof(DNSExcludedConstraints), "Unexpected size\n");
7012 ok(!memcmp(buf, DNSExcludedConstraints, size),
7013 "Unexpected value\n");
7016 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
7017 U(permitted.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7018 U(permitted.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7019 constraints.cPermittedSubtree = 1;
7020 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7021 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7022 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7025 ok(size == sizeof(permittedAndExcludedConstraints),
7026 "Unexpected size\n");
7027 ok(!memcmp(buf, permittedAndExcludedConstraints, size),
7028 "Unexpected value\n");
7031 permitted.dwMinimum = 5;
7032 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7033 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7034 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7037 ok(size == sizeof(permittedAndExcludedWithMinConstraints),
7038 "Unexpected size\n");
7039 ok(!memcmp(buf, permittedAndExcludedWithMinConstraints, size),
7040 "Unexpected value\n");
7043 permitted.fMaximum = TRUE;
7044 permitted.dwMaximum = 3;
7045 SetLastError(0xdeadbeef);
7046 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7047 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7048 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7051 ok(size == sizeof(permittedAndExcludedWithMinMaxConstraints),
7052 "Unexpected size\n");
7053 ok(!memcmp(buf, permittedAndExcludedWithMinMaxConstraints, size),
7054 "Unexpected value\n");
7059 struct EncodedNameConstraints
7061 CRYPT_DATA_BLOB encoded;
7062 CERT_NAME_CONSTRAINTS_INFO constraints;
7065 static CERT_GENERAL_SUBTREE emptyDNSSubtree = {
7066 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
7067 static CERT_GENERAL_SUBTREE DNSSubtree = {
7068 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
7069 static CERT_GENERAL_SUBTREE IPAddressSubtree = {
7070 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 0 };
7071 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree = {
7072 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, 0 };
7073 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree = {
7074 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, TRUE, 3 };
7076 struct EncodedNameConstraints encodedNameConstraints[] = {
7077 { { sizeof(emptySequence), (LPBYTE)emptySequence }, { 0 } },
7078 { { sizeof(emptyDNSPermittedConstraints), emptyDNSPermittedConstraints },
7079 { 1, &emptyDNSSubtree, 0, NULL } },
7080 { { sizeof(emptyDNSExcludedConstraints), emptyDNSExcludedConstraints },
7081 { 0, NULL, 1, &emptyDNSSubtree } },
7082 { { sizeof(DNSExcludedConstraints), DNSExcludedConstraints },
7083 { 0, NULL, 1, &DNSSubtree } },
7084 { { sizeof(permittedAndExcludedConstraints), permittedAndExcludedConstraints },
7085 { 1, &IPAddressSubtree, 1, &DNSSubtree } },
7086 { { sizeof(permittedAndExcludedWithMinConstraints),
7087 permittedAndExcludedWithMinConstraints },
7088 { 1, &IPAddressWithMinSubtree, 1, &DNSSubtree } },
7089 { { sizeof(permittedAndExcludedWithMinMaxConstraints),
7090 permittedAndExcludedWithMinMaxConstraints },
7091 { 1, &IPAddressWithMinMaxSubtree, 1, &DNSSubtree } },
7094 static void test_decodeNameConstraints(DWORD dwEncoding)
7098 CERT_NAME_CONSTRAINTS_INFO *constraints;
7100 U(DNSSubtree.Base).pwszURL = (LPWSTR)url;
7101 U(IPAddressSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7102 U(IPAddressSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7103 U(IPAddressWithMinSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7104 U(IPAddressWithMinSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7105 U(IPAddressWithMinMaxSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7106 U(IPAddressWithMinMaxSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7108 i < sizeof(encodedNameConstraints) / sizeof(encodedNameConstraints[0]);
7113 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS,
7114 encodedNameConstraints[i].encoded.pbData,
7115 encodedNameConstraints[i].encoded.cbData,
7116 CRYPT_DECODE_ALLOC_FLAG, NULL, &constraints, &size);
7117 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7119 skip("no X509_NAME_CONSTRAINTS decode support\n");
7122 ok(ret, "%d: CryptDecodeObjectEx failed: %08x\n", i, GetLastError());
7127 if (constraints->cPermittedSubtree !=
7128 encodedNameConstraints[i].constraints.cPermittedSubtree)
7129 fprintf(stderr, "%d: expected %d permitted, got %d\n", i,
7130 encodedNameConstraints[i].constraints.cPermittedSubtree,
7131 constraints->cPermittedSubtree);
7132 if (constraints->cPermittedSubtree ==
7133 encodedNameConstraints[i].constraints.cPermittedSubtree)
7135 for (j = 0; j < constraints->cPermittedSubtree; j++)
7137 compareAltNameEntry(&constraints->rgPermittedSubtree[j].Base,
7138 &encodedNameConstraints[i].constraints.rgPermittedSubtree[j].Base);
7141 if (constraints->cExcludedSubtree !=
7142 encodedNameConstraints[i].constraints.cExcludedSubtree)
7143 fprintf(stderr, "%d: expected %d excluded, got %d\n", i,
7144 encodedNameConstraints[i].constraints.cExcludedSubtree,
7145 constraints->cExcludedSubtree);
7146 if (constraints->cExcludedSubtree ==
7147 encodedNameConstraints[i].constraints.cExcludedSubtree)
7149 for (j = 0; j < constraints->cExcludedSubtree; j++)
7151 compareAltNameEntry(&constraints->rgExcludedSubtree[j].Base,
7152 &encodedNameConstraints[i].constraints.rgExcludedSubtree[j].Base);
7155 LocalFree(constraints);
7160 static WCHAR noticeText[] = { 'T','h','i','s',' ','i','s',' ','a',' ',
7161 'n','o','t','i','c','e',0 };
7162 static const BYTE noticeWithDisplayText[] = {
7163 0x30,0x22,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,0x00,
7164 0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,0x74,
7165 0x00,0x69,0x00,0x63,0x00,0x65
7167 static char org[] = "Wine";
7168 static int noticeNumbers[] = { 2,3 };
7169 static BYTE noticeWithReference[] = {
7170 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7171 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7172 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7173 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7176 static void test_encodePolicyQualifierUserNotice(DWORD dwEncoding)
7181 CERT_POLICY_QUALIFIER_USER_NOTICE notice;
7182 CERT_POLICY_QUALIFIER_NOTICE_REFERENCE reference;
7184 memset(¬ice, 0, sizeof(notice));
7185 ret = pCryptEncodeObjectEx(dwEncoding,
7186 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, ¬ice, CRYPT_ENCODE_ALLOC_FLAG,
7188 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7190 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE encode support\n");
7193 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7196 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size);
7197 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
7200 notice.pszDisplayText = noticeText;
7201 ret = pCryptEncodeObjectEx(dwEncoding,
7202 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, ¬ice, CRYPT_ENCODE_ALLOC_FLAG,
7204 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7207 ok(sizeof(noticeWithDisplayText) == size, "unexpected size %d\n", size);
7208 ok(!memcmp(buf, noticeWithDisplayText, size), "unexpected value\n");
7211 reference.pszOrganization = org;
7212 reference.cNoticeNumbers = 2;
7213 reference.rgNoticeNumbers = noticeNumbers;
7214 notice.pNoticeReference = &reference;
7215 ret = pCryptEncodeObjectEx(dwEncoding,
7216 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, ¬ice, CRYPT_ENCODE_ALLOC_FLAG,
7218 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7221 ok(sizeof(noticeWithReference) == size, "unexpected size %d\n", size);
7222 ok(!memcmp(buf, noticeWithReference, size), "unexpected value\n");
7227 static void test_decodePolicyQualifierUserNotice(DWORD dwEncoding)
7230 CERT_POLICY_QUALIFIER_USER_NOTICE *notice;
7233 ret = pCryptDecodeObjectEx(dwEncoding,
7234 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7235 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7237 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7239 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE decode support\n");
7242 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7245 ok(notice->pszDisplayText == NULL, "unexpected display text\n");
7246 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7249 ret = pCryptDecodeObjectEx(dwEncoding,
7250 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7251 noticeWithDisplayText, sizeof(noticeWithDisplayText),
7252 CRYPT_DECODE_ALLOC_FLAG, NULL, ¬ice, &size);
7253 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7256 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7257 "unexpected display text\n");
7258 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7261 ret = pCryptDecodeObjectEx(dwEncoding,
7262 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7263 noticeWithReference, sizeof(noticeWithReference),
7264 CRYPT_DECODE_ALLOC_FLAG, NULL, ¬ice, &size);
7265 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7268 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7269 "unexpected display text\n");
7270 ok(notice->pNoticeReference != NULL, "expected a notice reference\n");
7271 if (notice->pNoticeReference)
7273 ok(!strcmp(notice->pNoticeReference->pszOrganization, org),
7274 "unexpected organization %s\n",
7275 notice->pNoticeReference->pszOrganization);
7276 ok(notice->pNoticeReference->cNoticeNumbers == 2,
7277 "expected 2 notice numbers, got %d\n",
7278 notice->pNoticeReference->cNoticeNumbers);
7279 ok(notice->pNoticeReference->rgNoticeNumbers[0] == noticeNumbers[0],
7280 "unexpected notice number %d\n",
7281 notice->pNoticeReference->rgNoticeNumbers[0]);
7282 ok(notice->pNoticeReference->rgNoticeNumbers[1] == noticeNumbers[1],
7283 "unexpected notice number %d\n",
7284 notice->pNoticeReference->rgNoticeNumbers[1]);
7290 static char oid_any_policy[] = "2.5.29.32.0";
7291 static const BYTE policiesWithAnyPolicy[] = {
7292 0x30,0x08,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00
7294 static char oid1[] = "1.2.3";
7295 static char oid_user_notice[] = "1.3.6.1.5.5.7.2.2";
7296 static const BYTE twoPolicies[] = {
7297 0x30,0x50,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00,0x30,0x46,0x06,0x02,0x2a,
7298 0x03,0x30,0x40,0x30,0x3e,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x02,
7299 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7300 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7301 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7302 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7305 static void test_encodeCertPolicies(DWORD dwEncoding)
7308 CERT_POLICIES_INFO info;
7309 CERT_POLICY_INFO policy[2];
7310 CERT_POLICY_QUALIFIER_INFO qualifier;
7314 memset(&info, 0, sizeof(info));
7315 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7316 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7317 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7320 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size);
7321 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
7324 memset(policy, 0, sizeof(policy));
7325 info.cPolicyInfo = 1;
7326 info.rgPolicyInfo = policy;
7327 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7328 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7329 ok(!ret && (GetLastError() == E_INVALIDARG ||
7330 GetLastError() == OSS_LIMITED /* Win9x/NT4 */),
7331 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
7332 policy[0].pszPolicyIdentifier = oid_any_policy;
7333 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7334 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7335 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7338 ok(sizeof(policiesWithAnyPolicy) == size, "unexpected size %d\n", size);
7339 ok(!memcmp(buf, policiesWithAnyPolicy, size), "unexpected value\n");
7342 policy[1].pszPolicyIdentifier = oid1;
7343 memset(&qualifier, 0, sizeof(qualifier));
7344 qualifier.pszPolicyQualifierId = oid_user_notice;
7345 qualifier.Qualifier.cbData = sizeof(noticeWithReference);
7346 qualifier.Qualifier.pbData = noticeWithReference;
7347 policy[1].cPolicyQualifier = 1;
7348 policy[1].rgPolicyQualifier = &qualifier;
7349 info.cPolicyInfo = 2;
7350 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7351 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7352 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7355 ok(sizeof(twoPolicies) == size, "unexpected size %d\n", size);
7356 ok(!memcmp(buf, twoPolicies, size), "unexpected value\n");
7361 static void test_decodeCertPolicies(DWORD dwEncoding)
7364 CERT_POLICIES_INFO *info;
7367 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7368 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7370 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7373 ok(info->cPolicyInfo == 0, "unexpected policy info %d\n",
7377 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7378 policiesWithAnyPolicy, sizeof(policiesWithAnyPolicy),
7379 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7380 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7383 ok(info->cPolicyInfo == 1, "unexpected policy info %d\n",
7385 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy),
7386 "unexpected policy id %s\n",
7387 info->rgPolicyInfo[0].pszPolicyIdentifier);
7388 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0,
7389 "unexpected policy qualifier count %d\n",
7390 info->rgPolicyInfo[0].cPolicyQualifier);
7393 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7394 twoPolicies, sizeof(twoPolicies),
7395 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7396 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7399 ok(info->cPolicyInfo == 2, "unexpected policy info %d\n",
7401 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy),
7402 "unexpected policy id %s\n",
7403 info->rgPolicyInfo[0].pszPolicyIdentifier);
7404 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0,
7405 "unexpected policy qualifier count %d\n",
7406 info->rgPolicyInfo[0].cPolicyQualifier);
7407 ok(!strcmp(info->rgPolicyInfo[1].pszPolicyIdentifier, oid1),
7408 "unexpected policy id %s\n",
7409 info->rgPolicyInfo[1].pszPolicyIdentifier);
7410 ok(info->rgPolicyInfo[1].cPolicyQualifier == 1,
7411 "unexpected policy qualifier count %d\n",
7412 info->rgPolicyInfo[1].cPolicyQualifier);
7414 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId,
7415 oid_user_notice), "unexpected policy qualifier id %s\n",
7416 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId);
7417 ok(info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData ==
7418 sizeof(noticeWithReference), "unexpected qualifier size %d\n",
7419 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData);
7421 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.pbData,
7422 noticeWithReference, sizeof(noticeWithReference)),
7423 "unexpected qualifier value\n");
7428 static const BYTE policyMappingWithOneMapping[] = {
7429 0x30,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04 };
7430 static const BYTE policyMappingWithTwoMappings[] = {
7431 0x30,0x14,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04,0x30,0x08,0x06,
7432 0x02,0x2b,0x04,0x06,0x02,0x55,0x06 };
7433 static const LPCSTR mappingOids[] = { X509_POLICY_MAPPINGS,
7434 szOID_POLICY_MAPPINGS, szOID_LEGACY_POLICY_MAPPINGS };
7436 static void test_encodeCertPolicyMappings(DWORD dwEncoding)
7438 static char oid2[] = "2.3.4";
7439 static char oid3[] = "1.3.4";
7440 static char oid4[] = "2.5.6";
7442 CERT_POLICY_MAPPINGS_INFO info = { 0 };
7443 CERT_POLICY_MAPPING mapping[2];
7447 /* Each of the mapping OIDs is equivalent, so check with all of them */
7448 for (i = 0; i < sizeof(mappingOids) / sizeof(mappingOids[0]); i++)
7450 memset(&info, 0, sizeof(info));
7451 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7452 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7453 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7456 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
7457 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
7458 "unexpected value\n");
7461 mapping[0].pszIssuerDomainPolicy = NULL;
7462 mapping[0].pszSubjectDomainPolicy = NULL;
7463 info.cPolicyMapping = 1;
7464 info.rgPolicyMapping = mapping;
7465 SetLastError(0xdeadbeef);
7466 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7467 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7468 ok(!ret && GetLastError() == E_INVALIDARG,
7469 "expected E_INVALIDARG, got %08x\n", GetLastError());
7470 mapping[0].pszIssuerDomainPolicy = oid1;
7471 mapping[0].pszSubjectDomainPolicy = oid2;
7472 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7473 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7474 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7477 ok(size == sizeof(policyMappingWithOneMapping),
7478 "unexpected size %d\n", size);
7479 ok(!memcmp(buf, policyMappingWithOneMapping, size),
7480 "unexpected value\n");
7483 mapping[1].pszIssuerDomainPolicy = oid3;
7484 mapping[1].pszSubjectDomainPolicy = oid4;
7485 info.cPolicyMapping = 2;
7486 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7487 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7488 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7491 ok(size == sizeof(policyMappingWithTwoMappings),
7492 "unexpected size %d\n", size);
7493 ok(!memcmp(buf, policyMappingWithTwoMappings, size),
7494 "unexpected value\n");
7500 static void test_decodeCertPolicyMappings(DWORD dwEncoding)
7503 CERT_POLICY_MAPPINGS_INFO *info;
7506 /* Each of the mapping OIDs is equivalent, so check with all of them */
7507 for (i = 0; i < sizeof(mappingOids) / sizeof(mappingOids[0]); i++)
7509 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7510 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7512 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7515 ok(info->cPolicyMapping == 0,
7516 "expected 0 policy mappings, got %d\n", info->cPolicyMapping);
7519 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7520 policyMappingWithOneMapping, sizeof(policyMappingWithOneMapping),
7521 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7522 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7525 ok(info->cPolicyMapping == 1,
7526 "expected 1 policy mappings, got %d\n", info->cPolicyMapping);
7527 ok(!strcmp(info->rgPolicyMapping[0].pszIssuerDomainPolicy, "1.2.3"),
7528 "unexpected issuer policy %s\n",
7529 info->rgPolicyMapping[0].pszIssuerDomainPolicy);
7530 ok(!strcmp(info->rgPolicyMapping[0].pszSubjectDomainPolicy,
7531 "2.3.4"), "unexpected subject policy %s\n",
7532 info->rgPolicyMapping[0].pszSubjectDomainPolicy);
7535 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7536 policyMappingWithTwoMappings, sizeof(policyMappingWithTwoMappings),
7537 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7538 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7541 ok(info->cPolicyMapping == 2,
7542 "expected 2 policy mappings, got %d\n", info->cPolicyMapping);
7543 ok(!strcmp(info->rgPolicyMapping[0].pszIssuerDomainPolicy, "1.2.3"),
7544 "unexpected issuer policy %s\n",
7545 info->rgPolicyMapping[0].pszIssuerDomainPolicy);
7546 ok(!strcmp(info->rgPolicyMapping[0].pszSubjectDomainPolicy,
7547 "2.3.4"), "unexpected subject policy %s\n",
7548 info->rgPolicyMapping[0].pszSubjectDomainPolicy);
7549 ok(!strcmp(info->rgPolicyMapping[1].pszIssuerDomainPolicy, "1.3.4"),
7550 "unexpected issuer policy %s\n",
7551 info->rgPolicyMapping[1].pszIssuerDomainPolicy);
7552 ok(!strcmp(info->rgPolicyMapping[1].pszSubjectDomainPolicy,
7553 "2.5.6"), "unexpected subject policy %s\n",
7554 info->rgPolicyMapping[1].pszSubjectDomainPolicy);
7560 static const BYTE policyConstraintsWithRequireExplicit[] = {
7561 0x30,0x03,0x80,0x01,0x00 };
7562 static const BYTE policyConstraintsWithInhibitMapping[] = {
7563 0x30,0x03,0x81,0x01,0x01 };
7564 static const BYTE policyConstraintsWithBoth[] = {
7565 0x30,0x06,0x80,0x01,0x01,0x81,0x01,0x01 };
7567 static void test_encodeCertPolicyConstraints(DWORD dwEncoding)
7569 CERT_POLICY_CONSTRAINTS_INFO info = { 0 };
7574 /* Even though RFC 5280 explicitly states CAs must not issue empty
7575 * policy constraints (section 4.2.1.11), the API doesn't prevent it.
7577 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7578 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7580 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7583 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
7584 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
7585 "unexpected value\n");
7588 /* If fRequireExplicitPolicy is set but dwRequireExplicitPolicySkipCerts
7589 * is not, then a skip of 0 is encoded.
7591 info.fRequireExplicitPolicy = TRUE;
7592 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7593 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7594 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7597 ok(size == sizeof(policyConstraintsWithRequireExplicit),
7598 "unexpected size %d\n", size);
7599 ok(!memcmp(buf, policyConstraintsWithRequireExplicit,
7600 sizeof(policyConstraintsWithRequireExplicit)), "unexpected value\n");
7603 /* With inhibit policy mapping */
7604 info.fRequireExplicitPolicy = FALSE;
7605 info.dwRequireExplicitPolicySkipCerts = 0;
7606 info.fInhibitPolicyMapping = TRUE;
7607 info.dwInhibitPolicyMappingSkipCerts = 1;
7608 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7609 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7610 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7613 ok(size == sizeof(policyConstraintsWithInhibitMapping),
7614 "unexpected size %d\n", size);
7615 ok(!memcmp(buf, policyConstraintsWithInhibitMapping,
7616 sizeof(policyConstraintsWithInhibitMapping)), "unexpected value\n");
7620 info.fRequireExplicitPolicy = TRUE;
7621 info.dwRequireExplicitPolicySkipCerts = 1;
7622 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7623 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7624 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7627 ok(size == sizeof(policyConstraintsWithBoth), "unexpected size %d\n",
7629 ok(!memcmp(buf, policyConstraintsWithBoth,
7630 sizeof(policyConstraintsWithBoth)), "unexpected value\n");
7636 static void test_decodeCertPolicyConstraints(DWORD dwEncoding)
7638 CERT_POLICY_CONSTRAINTS_INFO *info;
7642 /* Again, even though CAs must not issue such constraints, they can be
7645 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7646 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7649 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7652 ok(!info->fRequireExplicitPolicy,
7653 "expected require explicit = FALSE\n");
7654 ok(!info->fInhibitPolicyMapping,
7655 "expected implicit mapping = FALSE\n");
7658 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7659 policyConstraintsWithRequireExplicit,
7660 sizeof(policyConstraintsWithRequireExplicit), CRYPT_DECODE_ALLOC_FLAG,
7661 NULL, &info, &size);
7662 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7665 ok(info->fRequireExplicitPolicy,
7666 "expected require explicit = TRUE\n");
7667 ok(info->dwRequireExplicitPolicySkipCerts == 0, "expected 0, got %d\n",
7668 info->dwRequireExplicitPolicySkipCerts);
7669 ok(!info->fInhibitPolicyMapping,
7670 "expected implicit mapping = FALSE\n");
7673 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7674 policyConstraintsWithInhibitMapping,
7675 sizeof(policyConstraintsWithInhibitMapping), CRYPT_DECODE_ALLOC_FLAG,
7676 NULL, &info, &size);
7677 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7680 ok(!info->fRequireExplicitPolicy,
7681 "expected require explicit = FALSE\n");
7682 ok(info->fInhibitPolicyMapping,
7683 "expected implicit mapping = TRUE\n");
7684 ok(info->dwInhibitPolicyMappingSkipCerts == 1, "expected 1, got %d\n",
7685 info->dwInhibitPolicyMappingSkipCerts);
7688 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7689 policyConstraintsWithBoth, sizeof(policyConstraintsWithBoth),
7690 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7691 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7694 ok(info->fRequireExplicitPolicy,
7695 "expected require explicit = TRUE\n");
7696 ok(info->dwRequireExplicitPolicySkipCerts == 1, "expected 1, got %d\n",
7697 info->dwRequireExplicitPolicySkipCerts);
7698 ok(info->fInhibitPolicyMapping,
7699 "expected implicit mapping = TRUE\n");
7700 ok(info->dwInhibitPolicyMappingSkipCerts == 1, "expected 1, got %d\n",
7701 info->dwInhibitPolicyMappingSkipCerts);
7707 /* Free *pInfo with HeapFree */
7708 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
7715 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
7717 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size);
7718 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7719 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7720 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL,
7722 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7723 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7724 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL,
7726 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7727 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7728 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7729 0, NULL, NULL, &size);
7730 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7731 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7732 /* Test with no key */
7733 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7734 0, NULL, NULL, &size);
7735 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n",
7737 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
7738 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
7741 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
7742 NULL, 0, NULL, NULL, &size);
7743 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
7744 *pInfo = HeapAlloc(GetProcessHeap(), 0, size);
7747 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
7748 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size);
7749 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n",
7753 /* By default (we passed NULL as the OID) the OID is
7756 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA),
7757 "Expected %s, got %s\n", szOID_RSA_RSA,
7758 (*pInfo)->Algorithm.pszObjId);
7762 CryptDestroyKey(key);
7765 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
7766 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
7767 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
7768 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7769 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7770 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7771 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
7772 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
7773 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7774 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7775 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7776 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
7777 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
7778 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
7779 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
7780 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
7781 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
7782 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
7783 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
7784 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
7785 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
7786 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
7787 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
7788 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
7789 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
7791 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info)
7795 PCCERT_CONTEXT context;
7800 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
7801 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
7802 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
7803 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7806 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key);
7807 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7808 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7809 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key);
7810 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7811 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7812 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL,
7814 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7815 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7817 /* Export key with standard algorithm (CALG_RSA_KEYX) */
7818 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7820 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7822 dwSize = sizeof(ai);
7823 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7824 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7827 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7828 ok(ai == CALG_RSA_KEYX, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai);
7831 CryptDestroyKey(key);
7833 /* Repeat with forced algorithm */
7834 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, CALG_RSA_SIGN, 0, NULL,
7836 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7838 dwSize = sizeof(ai);
7839 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7840 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7843 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7844 ok(ai == CALG_RSA_SIGN, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai);
7847 CryptDestroyKey(key);
7849 /* Test importing a public key from a certificate context */
7850 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert,
7851 sizeof(expiredCert));
7852 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
7856 ok(!strcmp(szOID_RSA_RSA,
7857 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId),
7858 "Expected %s, got %s\n", szOID_RSA_RSA,
7859 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
7860 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING,
7861 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
7862 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7863 CryptDestroyKey(key);
7864 CertFreeCertificateContext(context);
7868 static const char cspName[] = "WineCryptTemp";
7870 static void testPortPublicKeyInfo(void)
7874 PCERT_PUBLIC_KEY_INFO info = NULL;
7876 /* Just in case a previous run failed, delete this thing */
7877 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7878 CRYPT_DELETEKEYSET);
7879 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7882 testExportPublicKey(csp, &info);
7883 testImportPublicKey(csp, info);
7885 HeapFree(GetProcessHeap(), 0, info);
7886 CryptReleaseContext(csp, 0);
7887 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7888 CRYPT_DELETEKEYSET);
7893 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
7894 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING };
7898 hCrypt32 = GetModuleHandleA("crypt32.dll");
7899 pCryptDecodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptDecodeObjectEx");
7900 pCryptEncodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptEncodeObjectEx");
7901 if (!pCryptDecodeObjectEx || !pCryptEncodeObjectEx)
7903 win_skip("CryptDecodeObjectEx() is not available\n");
7907 for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++)
7909 test_encodeInt(encodings[i]);
7910 test_decodeInt(encodings[i]);
7911 test_encodeEnumerated(encodings[i]);
7912 test_decodeEnumerated(encodings[i]);
7913 test_encodeFiletime(encodings[i]);
7914 test_decodeFiletime(encodings[i]);
7915 test_encodeName(encodings[i]);
7916 test_decodeName(encodings[i]);
7917 test_encodeUnicodeName(encodings[i]);
7918 test_decodeUnicodeName(encodings[i]);
7919 test_encodeNameValue(encodings[i]);
7920 test_decodeNameValue(encodings[i]);
7921 test_encodeUnicodeNameValue(encodings[i]);
7922 test_decodeUnicodeNameValue(encodings[i]);
7923 test_encodeAltName(encodings[i]);
7924 test_decodeAltName(encodings[i]);
7925 test_encodeOctets(encodings[i]);
7926 test_decodeOctets(encodings[i]);
7927 test_encodeBits(encodings[i]);
7928 test_decodeBits(encodings[i]);
7929 test_encodeBasicConstraints(encodings[i]);
7930 test_decodeBasicConstraints(encodings[i]);
7931 test_encodeRsaPublicKey(encodings[i]);
7932 test_decodeRsaPublicKey(encodings[i]);
7933 test_encodeSequenceOfAny(encodings[i]);
7934 test_decodeSequenceOfAny(encodings[i]);
7935 test_encodeExtensions(encodings[i]);
7936 test_decodeExtensions(encodings[i]);
7937 test_encodePublicKeyInfo(encodings[i]);
7938 test_decodePublicKeyInfo(encodings[i]);
7939 test_encodeCertToBeSigned(encodings[i]);
7940 test_decodeCertToBeSigned(encodings[i]);
7941 test_encodeCert(encodings[i]);
7942 test_decodeCert(encodings[i]);
7943 test_encodeCRLDistPoints(encodings[i]);
7944 test_decodeCRLDistPoints(encodings[i]);
7945 test_encodeCRLIssuingDistPoint(encodings[i]);
7946 test_decodeCRLIssuingDistPoint(encodings[i]);
7947 test_encodeCRLToBeSigned(encodings[i]);
7948 test_decodeCRLToBeSigned(encodings[i]);
7949 test_encodeEnhancedKeyUsage(encodings[i]);
7950 test_decodeEnhancedKeyUsage(encodings[i]);
7951 test_encodeAuthorityKeyId(encodings[i]);
7952 test_decodeAuthorityKeyId(encodings[i]);
7953 test_encodeAuthorityKeyId2(encodings[i]);
7954 test_decodeAuthorityKeyId2(encodings[i]);
7955 test_encodeAuthorityInfoAccess(encodings[i]);
7956 test_decodeAuthorityInfoAccess(encodings[i]);
7957 test_encodeCTL(encodings[i]);
7958 test_decodeCTL(encodings[i]);
7959 test_encodePKCSContentInfo(encodings[i]);
7960 test_decodePKCSContentInfo(encodings[i]);
7961 test_encodePKCSAttribute(encodings[i]);
7962 test_decodePKCSAttribute(encodings[i]);
7963 test_encodePKCSAttributes(encodings[i]);
7964 test_decodePKCSAttributes(encodings[i]);
7965 test_encodePKCSSMimeCapabilities(encodings[i]);
7966 test_decodePKCSSMimeCapabilities(encodings[i]);
7967 test_encodePKCSSignerInfo(encodings[i]);
7968 test_decodePKCSSignerInfo(encodings[i]);
7969 test_encodeCMSSignerInfo(encodings[i]);
7970 test_decodeCMSSignerInfo(encodings[i]);
7971 test_encodeNameConstraints(encodings[i]);
7972 test_decodeNameConstraints(encodings[i]);
7973 test_encodePolicyQualifierUserNotice(encodings[i]);
7974 test_decodePolicyQualifierUserNotice(encodings[i]);
7975 test_encodeCertPolicies(encodings[i]);
7976 test_decodeCertPolicies(encodings[i]);
7977 test_encodeCertPolicyMappings(encodings[i]);
7978 test_decodeCertPolicyMappings(encodings[i]);
7979 test_encodeCertPolicyConstraints(encodings[i]);
7980 test_decodeCertPolicyConstraints(encodings[i]);
7982 testPortPublicKeyInfo();