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 };
1267 static char embedded_null[] = "foo\0com";
1268 static BYTE ia5EmbeddedNull[] = {
1269 0x16,0x07,0x66,0x6f,0x6f,0x00,0x63,0x6f,0x6d };
1271 static struct EncodedNameValue nameValues[] = {
1272 { { CERT_RDN_OCTET_STRING, { sizeof(commonName), (BYTE *)commonName } },
1273 octetCommonNameValue, sizeof(octetCommonNameValue) },
1274 { { CERT_RDN_NUMERIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1275 numericCommonNameValue, sizeof(numericCommonNameValue) },
1276 { { CERT_RDN_PRINTABLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1277 printableCommonNameValue, sizeof(printableCommonNameValue) },
1278 { { CERT_RDN_T61_STRING, { sizeof(commonName), (BYTE *)commonName } },
1279 t61CommonNameValue, sizeof(t61CommonNameValue) },
1280 { { CERT_RDN_VIDEOTEX_STRING, { sizeof(commonName), (BYTE *)commonName } },
1281 videotexCommonNameValue, sizeof(videotexCommonNameValue) },
1282 { { CERT_RDN_IA5_STRING, { sizeof(commonName), (BYTE *)commonName } },
1283 ia5CommonNameValue, sizeof(ia5CommonNameValue) },
1284 { { CERT_RDN_GRAPHIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1285 graphicCommonNameValue, sizeof(graphicCommonNameValue) },
1286 { { CERT_RDN_VISIBLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1287 visibleCommonNameValue, sizeof(visibleCommonNameValue) },
1288 { { CERT_RDN_GENERAL_STRING, { sizeof(commonName), (BYTE *)commonName } },
1289 generalCommonNameValue, sizeof(generalCommonNameValue) },
1290 { { CERT_RDN_BMP_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1291 bmpCommonNameValue, sizeof(bmpCommonNameValue) },
1292 { { CERT_RDN_UTF8_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1293 utf8CommonNameValue, sizeof(utf8CommonNameValue) },
1294 /* The following tests succeed under Windows, but really should fail,
1295 * they contain characters that are illegal for the encoding. I'm
1296 * including them to justify my lazy encoding.
1298 { { CERT_RDN_IA5_STRING, { sizeof(bogusIA5), (BYTE *)bogusIA5 } }, bin42,
1300 { { CERT_RDN_PRINTABLE_STRING, { sizeof(bogusPrintable),
1301 (BYTE *)bogusPrintable } }, bin43, sizeof(bin43) },
1302 { { CERT_RDN_NUMERIC_STRING, { sizeof(bogusNumeric), (BYTE *)bogusNumeric } },
1303 bin44, sizeof(bin44) },
1305 /* This is kept separate, because the decoding doesn't return to the original
1308 static struct EncodedNameValue embeddedNullNameValue = {
1309 { CERT_RDN_IA5_STRING, { sizeof(embedded_null) - 1, (BYTE *)embedded_null } },
1310 ia5EmbeddedNull, sizeof(ia5EmbeddedNull) };
1312 static void test_encodeNameValue(DWORD dwEncoding)
1317 CERT_NAME_VALUE value = { 0, { 0, NULL } };
1319 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1320 value.Value.pbData = printableCommonNameValue;
1321 value.Value.cbData = sizeof(printableCommonNameValue);
1322 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, &value,
1323 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1324 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1327 ok(size == sizeof(printableCommonNameValue), "Unexpected size %d\n",
1329 ok(!memcmp(buf, printableCommonNameValue, size),
1330 "Unexpected encoding\n");
1333 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1335 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE,
1336 &nameValues[i].value, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1337 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH) /* NT4/Win9x */,
1338 "Type %d: CryptEncodeObjectEx failed: %08x\n",
1339 nameValues[i].value.dwValueType, GetLastError());
1342 ok(size == nameValues[i].encodedSize,
1343 "Expected size %d, got %d\n", nameValues[i].encodedSize, size);
1344 ok(!memcmp(buf, nameValues[i].encoded, size),
1345 "Got unexpected encoding\n");
1349 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE,
1350 &embeddedNullNameValue.value, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1351 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH) /* NT4/Win9x */,
1352 "Type %d: CryptEncodeObjectEx failed: %08x\n",
1353 embeddedNullNameValue.value.dwValueType, GetLastError());
1356 ok(size == embeddedNullNameValue.encodedSize,
1357 "Expected size %d, got %d\n", embeddedNullNameValue.encodedSize, size);
1358 ok(!memcmp(buf, embeddedNullNameValue.encoded, size),
1359 "Got unexpected encoding\n");
1364 static void test_decodeNameValue(DWORD dwEncoding)
1371 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1373 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE,
1374 nameValues[i].encoded, nameValues[i].encoded[1] + 2,
1375 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1377 ok(ret, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
1378 nameValues[i].value.dwValueType, GetLastError());
1381 compareNameValues(&nameValues[i].value,
1382 (const CERT_NAME_VALUE *)buf);
1386 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE,
1387 embeddedNullNameValue.encoded, embeddedNullNameValue.encodedSize,
1388 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1390 /* Some Windows versions disallow name values with embedded NULLs, so
1391 * either success or failure is acceptable.
1395 CERT_NAME_VALUE rdnEncodedValue = { CERT_RDN_ENCODED_BLOB,
1396 { sizeof(ia5EmbeddedNull), ia5EmbeddedNull } };
1397 CERT_NAME_VALUE embeddedNullValue = { CERT_RDN_IA5_STRING,
1398 { sizeof(embedded_null) - 1, (BYTE *)embedded_null } };
1399 const CERT_NAME_VALUE *got = (const CERT_NAME_VALUE *)buf,
1402 /* Some Windows versions decode name values with embedded NULLs,
1403 * others leave them encoded, even with the same version of crypt32.
1406 ok(got->dwValueType == CERT_RDN_ENCODED_BLOB ||
1407 got->dwValueType == CERT_RDN_IA5_STRING,
1408 "Expected CERT_RDN_ENCODED_BLOB or CERT_RDN_IA5_STRING, got %d\n",
1410 if (got->dwValueType == CERT_RDN_ENCODED_BLOB)
1411 expected = &rdnEncodedValue;
1412 else if (got->dwValueType == CERT_RDN_IA5_STRING)
1413 expected = &embeddedNullValue;
1416 ok(got->Value.cbData == expected->Value.cbData,
1417 "String type %d: unexpected data size, got %d, expected %d\n",
1418 got->dwValueType, got->Value.cbData, expected->Value.cbData);
1419 if (got->Value.cbData && got->Value.pbData)
1420 ok(!memcmp(got->Value.pbData, expected->Value.pbData,
1421 min(got->Value.cbData, expected->Value.cbData)),
1422 "String type %d: unexpected value\n", expected->dwValueType);
1428 static const BYTE emptyURL[] = { 0x30, 0x02, 0x86, 0x00 };
1429 static const BYTE emptyURLExtraBytes[] = { 0x30, 0x02, 0x86, 0x00, 0, 0, 0 };
1430 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e',
1431 'h','q','.','o','r','g',0 };
1432 static const BYTE encodedURL[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74,
1433 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e,
1435 static const WCHAR nihongoURL[] = { 'h','t','t','p',':','/','/',0x226f,
1437 static const WCHAR dnsName[] = { 'w','i','n','e','h','q','.','o','r','g',0 };
1438 static const BYTE encodedDnsName[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69,
1439 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
1440 static const BYTE localhost[] = { 127, 0, 0, 1 };
1441 static const BYTE encodedIPAddr[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00,
1443 static const unsigned char encodedCommonName[] = {
1444 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0};
1445 static const BYTE encodedOidName[] = { 0x30,0x04,0x88,0x02,0x2a,0x03 };
1446 static const BYTE encodedDirectoryName[] = {
1447 0x30,0x19,0xa4,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1448 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1450 static void test_encodeAltName(DWORD dwEncoding)
1452 CERT_ALT_NAME_INFO info = { 0 };
1453 CERT_ALT_NAME_ENTRY entry = { 0 };
1457 char oid[] = "1.2.3";
1459 /* Test with empty info */
1460 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1461 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1464 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
1465 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
1468 /* Test with an empty entry */
1470 info.rgAltEntry = &entry;
1471 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1472 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1473 ok(!ret && GetLastError() == E_INVALIDARG,
1474 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1475 /* Test with an empty pointer */
1476 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
1477 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1478 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1481 ok(size == sizeof(emptyURL), "Wrong size %d\n", size);
1482 ok(!memcmp(buf, emptyURL, size), "Unexpected value\n");
1485 /* Test with a real URL */
1486 U(entry).pwszURL = (LPWSTR)url;
1487 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1488 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1491 ok(size == sizeof(encodedURL), "Wrong size %d\n", size);
1492 ok(!memcmp(buf, encodedURL, size), "Unexpected value\n");
1495 /* Now with the URL containing an invalid IA5 char */
1496 U(entry).pwszURL = (LPWSTR)nihongoURL;
1497 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1498 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1499 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
1500 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
1501 /* The first invalid character is at index 7 */
1502 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
1503 "Expected invalid char at index 7, got %d\n",
1504 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
1505 /* Now with the URL missing a scheme */
1506 U(entry).pwszURL = (LPWSTR)dnsName;
1507 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1508 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1509 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1512 /* This succeeds, but it shouldn't, so don't worry about conforming */
1515 /* Now with a DNS name */
1516 entry.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
1517 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1518 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1519 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1522 ok(size == sizeof(encodedDnsName), "Wrong size %d\n", size);
1523 ok(!memcmp(buf, encodedDnsName, size), "Unexpected value\n");
1526 /* Test with an IP address */
1527 entry.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
1528 U(entry).IPAddress.cbData = sizeof(localhost);
1529 U(entry).IPAddress.pbData = (LPBYTE)localhost;
1530 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1531 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1534 ok(size == sizeof(encodedIPAddr), "Wrong size %d\n", size);
1535 ok(!memcmp(buf, encodedIPAddr, size), "Unexpected value\n");
1539 entry.dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID;
1540 U(entry).pszRegisteredID = oid;
1541 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1542 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1545 ok(size == sizeof(encodedOidName), "Wrong size %d\n", size);
1546 ok(!memcmp(buf, encodedOidName, size), "Unexpected value\n");
1549 /* Test with directory name */
1550 entry.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
1551 U(entry).DirectoryName.cbData = sizeof(encodedCommonName);
1552 U(entry).DirectoryName.pbData = (LPBYTE)encodedCommonName;
1553 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1554 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1557 ok(size == sizeof(encodedDirectoryName), "Wrong size %d\n", size);
1558 ok(!memcmp(buf, encodedDirectoryName, size), "Unexpected value\n");
1563 static void test_decodeAltName(DWORD dwEncoding)
1565 static const BYTE unimplementedType[] = { 0x30, 0x06, 0x85, 0x04, 0x7f,
1567 static const BYTE bogusType[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00,
1569 static const BYTE dns_embedded_null[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f,
1570 0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 };
1571 static const BYTE dns_embedded_bell[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f,
1572 0x6f,0x2e,0x63,0x6f,0x6d,0x07,0x62,0x61,0x64,0x64,0x69,0x65 };
1573 static const BYTE url_embedded_null[] = { 0x30,0x10,0x86,0x0e,0x66,0x6f,
1574 0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 };
1578 CERT_ALT_NAME_INFO *info;
1580 /* Test some bogus ones first */
1581 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1582 unimplementedType, sizeof(unimplementedType), CRYPT_DECODE_ALLOC_FLAG,
1583 NULL, &buf, &bufSize);
1584 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
1585 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1586 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
1588 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1589 bogusType, sizeof(bogusType), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
1591 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
1592 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1593 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
1595 /* Now expected cases */
1596 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptySequence,
1597 emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1598 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1601 info = (CERT_ALT_NAME_INFO *)buf;
1603 ok(info->cAltEntry == 0, "Expected 0 entries, got %d\n",
1607 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptyURL,
1608 emptyURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1609 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1612 info = (CERT_ALT_NAME_INFO *)buf;
1614 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1616 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1617 "Expected CERT_ALT_NAME_URL, got %d\n",
1618 info->rgAltEntry[0].dwAltNameChoice);
1619 ok(U(info->rgAltEntry[0]).pwszURL == NULL || !*U(info->rgAltEntry[0]).pwszURL,
1620 "Expected empty URL\n");
1623 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1624 emptyURLExtraBytes, sizeof(emptyURLExtraBytes), 0, NULL, NULL, &bufSize);
1625 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1626 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedURL,
1627 encodedURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1628 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1631 info = (CERT_ALT_NAME_INFO *)buf;
1633 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1635 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1636 "Expected CERT_ALT_NAME_URL, got %d\n",
1637 info->rgAltEntry[0].dwAltNameChoice);
1638 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszURL, url), "Unexpected URL\n");
1641 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedDnsName,
1642 encodedDnsName[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1643 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1646 info = (CERT_ALT_NAME_INFO *)buf;
1648 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1650 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1651 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1652 info->rgAltEntry[0].dwAltNameChoice);
1653 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszDNSName, dnsName),
1654 "Unexpected DNS name\n");
1657 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedIPAddr,
1658 encodedIPAddr[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1659 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1662 info = (CERT_ALT_NAME_INFO *)buf;
1664 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1666 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS,
1667 "Expected CERT_ALT_NAME_IP_ADDRESS, got %d\n",
1668 info->rgAltEntry[0].dwAltNameChoice);
1669 ok(U(info->rgAltEntry[0]).IPAddress.cbData == sizeof(localhost),
1670 "Unexpected IP address length %d\n",
1671 U(info->rgAltEntry[0]).IPAddress.cbData);
1672 ok(!memcmp(U(info->rgAltEntry[0]).IPAddress.pbData, localhost,
1673 sizeof(localhost)), "Unexpected IP address value\n");
1676 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedOidName,
1677 sizeof(encodedOidName), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1678 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1681 info = (CERT_ALT_NAME_INFO *)buf;
1683 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1685 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_REGISTERED_ID,
1686 "Expected CERT_ALT_NAME_REGISTERED_ID, got %d\n",
1687 info->rgAltEntry[0].dwAltNameChoice);
1688 ok(!strcmp(U(info->rgAltEntry[0]).pszRegisteredID, "1.2.3"),
1689 "Expected OID 1.2.3, got %s\n", U(info->rgAltEntry[0]).pszRegisteredID);
1692 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1693 encodedDirectoryName, sizeof(encodedDirectoryName),
1694 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1695 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1698 info = (CERT_ALT_NAME_INFO *)buf;
1700 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1702 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME,
1703 "Expected CERT_ALT_NAME_DIRECTORY_NAME, got %d\n",
1704 info->rgAltEntry[0].dwAltNameChoice);
1705 ok(U(info->rgAltEntry[0]).DirectoryName.cbData ==
1706 sizeof(encodedCommonName), "Unexpected directory name length %d\n",
1707 U(info->rgAltEntry[0]).DirectoryName.cbData);
1708 ok(!memcmp(U(info->rgAltEntry[0]).DirectoryName.pbData,
1709 encodedCommonName, sizeof(encodedCommonName)),
1710 "Unexpected directory name value\n");
1713 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1714 dns_embedded_null, sizeof(dns_embedded_null), CRYPT_DECODE_ALLOC_FLAG,
1715 NULL, &buf, &bufSize);
1716 /* Fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned about the
1717 * particular failure, just that it doesn't decode.
1718 * It succeeds on (broken) Windows versions that haven't addressed
1719 * embedded NULLs in alternate names.
1721 ok(!ret || broken(ret), "expected failure\n");
1722 /* An embedded bell character is allowed, however. */
1723 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1724 dns_embedded_bell, sizeof(dns_embedded_bell), CRYPT_DECODE_ALLOC_FLAG,
1725 NULL, &buf, &bufSize);
1726 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1729 info = (CERT_ALT_NAME_INFO *)buf;
1731 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1733 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1734 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1735 info->rgAltEntry[0].dwAltNameChoice);
1738 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1739 url_embedded_null, sizeof(dns_embedded_null), CRYPT_DECODE_ALLOC_FLAG,
1740 NULL, &buf, &bufSize);
1741 /* Again, fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned
1742 * about the particular failure, just that it doesn't decode.
1743 * It succeeds on (broken) Windows versions that haven't addressed
1744 * embedded NULLs in alternate names.
1746 ok(!ret || broken(ret), "expected failure\n");
1749 struct UnicodeExpectedError
1757 static const WCHAR oneW[] = { '1',0 };
1758 static const WCHAR aW[] = { 'a',0 };
1759 static const WCHAR quoteW[] = { '"', 0 };
1761 static struct UnicodeExpectedError unicodeErrors[] = {
1762 { CERT_RDN_ANY_TYPE, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1763 { CERT_RDN_ENCODED_BLOB, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1764 { CERT_RDN_OCTET_STRING, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1765 { CERT_RDN_NUMERIC_STRING, aW, 0, CRYPT_E_INVALID_NUMERIC_STRING },
1766 { CERT_RDN_PRINTABLE_STRING, quoteW, 0, CRYPT_E_INVALID_PRINTABLE_STRING },
1767 { CERT_RDN_IA5_STRING, nihongoURL, 7, CRYPT_E_INVALID_IA5_STRING },
1770 struct UnicodeExpectedResult
1774 CRYPT_DATA_BLOB encoded;
1777 static BYTE oneNumeric[] = { 0x12, 0x01, 0x31 };
1778 static BYTE onePrintable[] = { 0x13, 0x01, 0x31 };
1779 static BYTE oneTeletex[] = { 0x14, 0x01, 0x31 };
1780 static BYTE oneVideotex[] = { 0x15, 0x01, 0x31 };
1781 static BYTE oneIA5[] = { 0x16, 0x01, 0x31 };
1782 static BYTE oneGraphic[] = { 0x19, 0x01, 0x31 };
1783 static BYTE oneVisible[] = { 0x1a, 0x01, 0x31 };
1784 static BYTE oneUniversal[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 };
1785 static BYTE oneGeneral[] = { 0x1b, 0x01, 0x31 };
1786 static BYTE oneBMP[] = { 0x1e, 0x02, 0x00, 0x31 };
1787 static BYTE oneUTF8[] = { 0x0c, 0x01, 0x31 };
1788 static BYTE nihongoT61[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,
1790 static BYTE nihongoGeneral[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1792 static BYTE nihongoBMP[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,
1793 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
1794 static BYTE nihongoUTF8[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1795 0xe2,0x89,0xaf,0xe5,0x9d,0x9b };
1797 static struct UnicodeExpectedResult unicodeResults[] = {
1798 { CERT_RDN_NUMERIC_STRING, oneW, { sizeof(oneNumeric), oneNumeric } },
1799 { CERT_RDN_PRINTABLE_STRING, oneW, { sizeof(onePrintable), onePrintable } },
1800 { CERT_RDN_TELETEX_STRING, oneW, { sizeof(oneTeletex), oneTeletex } },
1801 { CERT_RDN_VIDEOTEX_STRING, oneW, { sizeof(oneVideotex), oneVideotex } },
1802 { CERT_RDN_IA5_STRING, oneW, { sizeof(oneIA5), oneIA5 } },
1803 { CERT_RDN_GRAPHIC_STRING, oneW, { sizeof(oneGraphic), oneGraphic } },
1804 { CERT_RDN_VISIBLE_STRING, oneW, { sizeof(oneVisible), oneVisible } },
1805 { CERT_RDN_UNIVERSAL_STRING, oneW, { sizeof(oneUniversal), oneUniversal } },
1806 { CERT_RDN_GENERAL_STRING, oneW, { sizeof(oneGeneral), oneGeneral } },
1807 { CERT_RDN_BMP_STRING, oneW, { sizeof(oneBMP), oneBMP } },
1808 { CERT_RDN_UTF8_STRING, oneW, { sizeof(oneUTF8), oneUTF8 } },
1809 { CERT_RDN_BMP_STRING, nihongoURL, { sizeof(nihongoBMP), nihongoBMP } },
1810 { CERT_RDN_UTF8_STRING, nihongoURL, { sizeof(nihongoUTF8), nihongoUTF8 } },
1813 static struct UnicodeExpectedResult unicodeWeirdness[] = {
1814 { CERT_RDN_TELETEX_STRING, nihongoURL, { sizeof(nihongoT61), nihongoT61 } },
1815 { CERT_RDN_GENERAL_STRING, nihongoURL, { sizeof(nihongoGeneral), nihongoGeneral } },
1818 static void test_encodeUnicodeNameValue(DWORD dwEncoding)
1823 CERT_NAME_VALUE value;
1827 /* Crashes on win9x */
1828 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, NULL,
1829 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1830 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1831 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1833 /* Have to have a string of some sort */
1834 value.dwValueType = 0; /* aka CERT_RDN_ANY_TYPE */
1835 value.Value.pbData = NULL;
1836 value.Value.cbData = 0;
1837 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1838 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1839 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1840 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1841 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1842 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1843 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1844 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1845 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1846 value.dwValueType = CERT_RDN_ANY_TYPE;
1847 value.Value.pbData = (LPBYTE)oneW;
1848 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1849 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1850 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1851 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1852 value.Value.cbData = sizeof(oneW);
1853 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1854 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1855 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1856 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1857 /* An encoded string with specified length isn't good enough either */
1858 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1859 value.Value.pbData = oneUniversal;
1860 value.Value.cbData = sizeof(oneUniversal);
1861 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1862 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1863 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1864 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1865 /* More failure checking */
1866 value.Value.cbData = 0;
1867 for (i = 0; i < sizeof(unicodeErrors) / sizeof(unicodeErrors[0]); i++)
1869 value.Value.pbData = (LPBYTE)unicodeErrors[i].str;
1870 value.dwValueType = unicodeErrors[i].valueType;
1871 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1872 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1873 ok(!ret && GetLastError() == unicodeErrors[i].error,
1874 "Value type %d: expected %08x, got %08x\n", value.dwValueType,
1875 unicodeErrors[i].error, GetLastError());
1876 ok(size == unicodeErrors[i].errorIndex,
1877 "Expected error index %d, got %d\n", unicodeErrors[i].errorIndex,
1880 /* cbData can be zero if the string is NULL-terminated */
1881 value.Value.cbData = 0;
1882 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1884 value.Value.pbData = (LPBYTE)unicodeResults[i].str;
1885 value.dwValueType = unicodeResults[i].valueType;
1886 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1887 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1888 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
1889 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1892 ok(size == unicodeResults[i].encoded.cbData,
1893 "Value type %d: expected size %d, got %d\n",
1894 value.dwValueType, unicodeResults[i].encoded.cbData, size);
1895 ok(!memcmp(unicodeResults[i].encoded.pbData, buf, size),
1896 "Value type %d: unexpected value\n", value.dwValueType);
1900 /* These "encode," but they do so by truncating each unicode character
1901 * rather than properly encoding it. Kept separate from the proper results,
1902 * because the encoded forms won't decode to their original strings.
1904 for (i = 0; i < sizeof(unicodeWeirdness) / sizeof(unicodeWeirdness[0]); i++)
1906 value.Value.pbData = (LPBYTE)unicodeWeirdness[i].str;
1907 value.dwValueType = unicodeWeirdness[i].valueType;
1908 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1909 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1910 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1913 ok(size == unicodeWeirdness[i].encoded.cbData,
1914 "Value type %d: expected size %d, got %d\n",
1915 value.dwValueType, unicodeWeirdness[i].encoded.cbData, size);
1916 ok(!memcmp(unicodeWeirdness[i].encoded.pbData, buf, size),
1917 "Value type %d: unexpected value\n", value.dwValueType);
1923 static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
1925 if (n <= 0) return 0;
1926 while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
1927 return *str1 - *str2;
1930 static void test_decodeUnicodeNameValue(DWORD dwEncoding)
1934 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1940 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE,
1941 unicodeResults[i].encoded.pbData, unicodeResults[i].encoded.cbData,
1942 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
1943 ok(ret || broken(GetLastError() == CRYPT_E_NOT_CHAR_STRING /* Win9x */),
1944 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1947 PCERT_NAME_VALUE value = (PCERT_NAME_VALUE)buf;
1949 ok(value->dwValueType == unicodeResults[i].valueType,
1950 "Expected value type %d, got %d\n", unicodeResults[i].valueType,
1951 value->dwValueType);
1952 ok(!strncmpW((LPWSTR)value->Value.pbData, unicodeResults[i].str,
1953 value->Value.cbData / sizeof(WCHAR)),
1954 "Unexpected decoded value for index %d (value type %d)\n", i,
1955 unicodeResults[i].valueType);
1961 struct encodedOctets
1964 const BYTE *encoded;
1967 static const unsigned char bin46[] = { 'h','i',0 };
1968 static const unsigned char bin47[] = { 0x04,0x02,'h','i',0 };
1969 static const unsigned char bin48[] = {
1970 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1971 static const unsigned char bin49[] = {
1972 0x04,0x0f,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1973 static const unsigned char bin50[] = { 0 };
1974 static const unsigned char bin51[] = { 0x04,0x00,0 };
1976 static const struct encodedOctets octets[] = {
1982 static void test_encodeOctets(DWORD dwEncoding)
1984 CRYPT_DATA_BLOB blob;
1987 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1993 blob.cbData = strlen((const char*)octets[i].val);
1994 blob.pbData = (BYTE*)octets[i].val;
1995 ret = pCryptEncodeObjectEx(dwEncoding, X509_OCTET_STRING, &blob,
1996 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1997 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
2001 "Got unexpected type %d for octet string (expected 4)\n", buf[0]);
2002 ok(buf[1] == octets[i].encoded[1], "Got length %d, expected %d\n",
2003 buf[1], octets[i].encoded[1]);
2004 ok(!memcmp(buf + 1, octets[i].encoded + 1,
2005 octets[i].encoded[1] + 1), "Got unexpected value\n");
2011 static void test_decodeOctets(DWORD dwEncoding)
2015 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
2021 ret = pCryptDecodeObjectEx(dwEncoding, X509_OCTET_STRING,
2022 octets[i].encoded, octets[i].encoded[1] + 2,
2023 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2024 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2025 ok(bufSize >= sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1],
2026 "Expected size >= %d, got %d\n",
2027 (int)sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1], bufSize);
2028 ok(buf != NULL, "Expected allocated buffer\n");
2031 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)buf;
2034 ok(!memcmp(blob->pbData, octets[i].val, blob->cbData),
2035 "Unexpected value\n");
2041 static const BYTE bytesToEncode[] = { 0xff, 0xff };
2046 const BYTE *encoded;
2048 const BYTE *decoded;
2051 static const unsigned char bin52[] = { 0x03,0x03,0x00,0xff,0xff };
2052 static const unsigned char bin53[] = { 0xff,0xff };
2053 static const unsigned char bin54[] = { 0x03,0x03,0x01,0xff,0xfe };
2054 static const unsigned char bin55[] = { 0xff,0xfe };
2055 static const unsigned char bin56[] = { 0x03,0x02,0x01,0xfe };
2056 static const unsigned char bin57[] = { 0xfe };
2057 static const unsigned char bin58[] = { 0x03,0x01,0x00 };
2059 static const struct encodedBits bits[] = {
2060 /* normal test cases */
2061 { 0, bin52, 2, bin53 },
2062 { 1, bin54, 2, bin55 },
2063 /* strange test case, showing cUnusedBits >= 8 is allowed */
2064 { 9, bin56, 1, bin57 },
2067 static void test_encodeBits(DWORD dwEncoding)
2071 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
2073 CRYPT_BIT_BLOB blob;
2078 blob.cbData = sizeof(bytesToEncode);
2079 blob.pbData = (BYTE *)bytesToEncode;
2080 blob.cUnusedBits = bits[i].cUnusedBits;
2081 ret = pCryptEncodeObjectEx(dwEncoding, X509_BITS, &blob,
2082 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2083 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2086 ok(bufSize == bits[i].encoded[1] + 2,
2087 "%d: Got unexpected size %d, expected %d\n", i, bufSize,
2088 bits[i].encoded[1] + 2);
2089 ok(!memcmp(buf, bits[i].encoded, bits[i].encoded[1] + 2),
2090 "%d: Unexpected value\n", i);
2096 static void test_decodeBits(DWORD dwEncoding)
2098 static const BYTE ber[] = "\x03\x02\x01\xff";
2099 static const BYTE berDecoded = 0xfe;
2106 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
2108 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, bits[i].encoded,
2109 bits[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
2111 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2114 CRYPT_BIT_BLOB *blob;
2116 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + bits[i].cbDecoded,
2117 "Got unexpected size %d\n", bufSize);
2118 blob = (CRYPT_BIT_BLOB *)buf;
2119 ok(blob->cbData == bits[i].cbDecoded,
2120 "Got unexpected length %d, expected %d\n", blob->cbData,
2122 if (blob->cbData && bits[i].cbDecoded)
2123 ok(!memcmp(blob->pbData, bits[i].decoded, bits[i].cbDecoded),
2124 "Unexpected value\n");
2128 /* special case: check that something that's valid in BER but not in DER
2129 * decodes successfully
2131 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, ber, ber[1] + 2,
2132 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2133 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2136 CRYPT_BIT_BLOB *blob;
2138 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + sizeof(berDecoded),
2139 "Got unexpected size %d\n", bufSize);
2140 blob = (CRYPT_BIT_BLOB *)buf;
2141 ok(blob->cbData == sizeof(berDecoded),
2142 "Got unexpected length %d\n", blob->cbData);
2144 ok(*blob->pbData == berDecoded, "Unexpected value\n");
2151 CERT_BASIC_CONSTRAINTS2_INFO info;
2152 const BYTE *encoded;
2155 static const unsigned char bin59[] = { 0x30,0x00 };
2156 static const unsigned char bin60[] = { 0x30,0x03,0x01,0x01,0xff };
2157 static const unsigned char bin61[] = { 0x30,0x03,0x02,0x01,0x00 };
2158 static const unsigned char bin62[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2159 static const struct Constraints2 constraints2[] = {
2160 /* empty constraints */
2161 { { FALSE, FALSE, 0}, bin59 },
2163 { { TRUE, FALSE, 0}, bin60 },
2164 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well,
2165 * but that's not the case
2167 { { FALSE, TRUE, 0}, bin61 },
2168 /* can be a CA and has path length constraints set */
2169 { { TRUE, TRUE, 1}, bin62 },
2172 static const BYTE emptyConstraint[] = { 0x30, 0x03, 0x03, 0x01, 0x00 };
2173 static const BYTE encodedDomainName[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11,
2174 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
2175 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
2176 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2177 static const BYTE constraintWithDomainName[] = { 0x30, 0x32, 0x03, 0x01, 0x00,
2178 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
2179 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30,
2180 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
2181 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2183 static void test_encodeBasicConstraints(DWORD dwEncoding)
2185 DWORD i, bufSize = 0;
2186 CERT_BASIC_CONSTRAINTS_INFO info = { { 0 } };
2187 CERT_NAME_BLOB nameBlob = { sizeof(encodedDomainName),
2188 (LPBYTE)encodedDomainName };
2192 /* First test with the simpler info2 */
2193 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2195 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2196 &constraints2[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf,
2198 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2201 ok(bufSize == constraints2[i].encoded[1] + 2,
2202 "Expected %d bytes, got %d\n", constraints2[i].encoded[1] + 2,
2204 ok(!memcmp(buf, constraints2[i].encoded,
2205 constraints2[i].encoded[1] + 2), "Unexpected value\n");
2209 /* Now test with more complex basic constraints */
2210 info.SubjectType.cbData = 0;
2211 info.fPathLenConstraint = FALSE;
2212 info.cSubtreesConstraint = 0;
2213 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2214 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2215 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2216 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2219 ok(bufSize == sizeof(emptyConstraint), "Wrong size %d\n", bufSize);
2220 ok(!memcmp(buf, emptyConstraint, sizeof(emptyConstraint)),
2221 "Unexpected value\n");
2224 /* None of the certs I examined had any subtree constraint, but I test one
2225 * anyway just in case.
2227 info.cSubtreesConstraint = 1;
2228 info.rgSubtreesConstraint = &nameBlob;
2229 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2230 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2231 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2232 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2235 ok(bufSize == sizeof(constraintWithDomainName), "Wrong size %d\n", bufSize);
2236 ok(!memcmp(buf, constraintWithDomainName,
2237 sizeof(constraintWithDomainName)), "Unexpected value\n");
2240 /* FIXME: test encoding with subject type. */
2243 static const unsigned char bin63[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 };
2245 static void test_decodeBasicConstraints(DWORD dwEncoding)
2247 static const BYTE inverted[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01,
2249 static const struct Constraints2 badBool = { { TRUE, TRUE, 1 }, bin63 };
2255 /* First test with simpler info2 */
2256 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2258 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2259 constraints2[i].encoded, constraints2[i].encoded[1] + 2,
2260 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2261 ok(ret, "CryptDecodeObjectEx failed for item %d: %08x\n", i,
2265 CERT_BASIC_CONSTRAINTS2_INFO *info =
2266 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2268 ok(!memcmp(info, &constraints2[i].info, sizeof(*info)),
2269 "Unexpected value for item %d\n", i);
2273 /* Check with the order of encoded elements inverted */
2275 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2276 inverted, inverted[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
2278 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2279 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2280 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2282 ok(!buf, "Expected buf to be set to NULL\n");
2283 /* Check with a non-DER bool */
2284 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2285 badBool.encoded, badBool.encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2287 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2290 CERT_BASIC_CONSTRAINTS2_INFO *info =
2291 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2293 ok(!memcmp(info, &badBool.info, sizeof(*info)), "Unexpected value\n");
2296 /* Check with a non-basic constraints value */
2297 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2298 encodedCommonName, encodedCommonName[1] + 2,
2299 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2300 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2301 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2302 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2304 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */
2305 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2306 emptyConstraint, sizeof(emptyConstraint), CRYPT_DECODE_ALLOC_FLAG, NULL,
2308 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2311 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2313 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2314 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2315 ok(info->cSubtreesConstraint == 0, "Expected no subtree constraints\n");
2318 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2319 constraintWithDomainName, sizeof(constraintWithDomainName),
2320 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2321 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2324 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2326 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2327 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2328 ok(info->cSubtreesConstraint == 1, "Expected a subtree constraint\n");
2329 if (info->cSubtreesConstraint && info->rgSubtreesConstraint)
2331 ok(info->rgSubtreesConstraint[0].cbData ==
2332 sizeof(encodedDomainName), "Wrong size %d\n",
2333 info->rgSubtreesConstraint[0].cbData);
2334 ok(!memcmp(info->rgSubtreesConstraint[0].pbData, encodedDomainName,
2335 sizeof(encodedDomainName)), "Unexpected value\n");
2341 /* These are terrible public keys of course, I'm just testing encoding */
2342 static const BYTE modulus1[] = { 0,0,0,1,1,1,1,1 };
2343 static const BYTE modulus2[] = { 1,1,1,1,1,0,0,0 };
2344 static const BYTE modulus3[] = { 0x80,1,1,1,1,0,0,0 };
2345 static const BYTE modulus4[] = { 1,1,1,1,1,0,0,0x80 };
2346 static const BYTE mod1_encoded[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 };
2347 static const BYTE mod2_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2348 static const BYTE mod3_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 };
2349 static const BYTE mod4_encoded[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2351 struct EncodedRSAPubKey
2353 const BYTE *modulus;
2355 const BYTE *encoded;
2356 size_t decodedModulusLen;
2359 struct EncodedRSAPubKey rsaPubKeys[] = {
2360 { modulus1, sizeof(modulus1), mod1_encoded, sizeof(modulus1) },
2361 { modulus2, sizeof(modulus2), mod2_encoded, 5 },
2362 { modulus3, sizeof(modulus3), mod3_encoded, 5 },
2363 { modulus4, sizeof(modulus4), mod4_encoded, 8 },
2366 static void test_encodeRsaPublicKey(DWORD dwEncoding)
2368 BYTE toEncode[sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + sizeof(modulus1)];
2369 BLOBHEADER *hdr = (BLOBHEADER *)toEncode;
2370 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(toEncode + sizeof(BLOBHEADER));
2373 DWORD bufSize = 0, i;
2375 /* Try with a bogus blob type */
2377 hdr->bVersion = CUR_BLOB_VERSION;
2379 hdr->aiKeyAlg = CALG_RSA_KEYX;
2380 rsaPubKey->magic = 0x31415352;
2381 rsaPubKey->bitlen = sizeof(modulus1) * 8;
2382 rsaPubKey->pubexp = 65537;
2383 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), modulus1,
2386 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2387 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2388 ok(!ret && GetLastError() == E_INVALIDARG,
2389 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2390 /* Now with a bogus reserved field */
2391 hdr->bType = PUBLICKEYBLOB;
2393 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2394 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2397 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2398 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2399 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2402 /* Now with a bogus blob version */
2405 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2406 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2409 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2410 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2411 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2414 /* And with a bogus alg ID */
2415 hdr->bVersion = CUR_BLOB_VERSION;
2416 hdr->aiKeyAlg = CALG_DES;
2417 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2418 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2421 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2422 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2423 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2426 /* Check a couple of RSA-related OIDs */
2427 hdr->aiKeyAlg = CALG_RSA_KEYX;
2428 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_RSA,
2429 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2430 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2431 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2432 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2433 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2434 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2435 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2436 /* Finally, all valid */
2437 hdr->aiKeyAlg = CALG_RSA_KEYX;
2438 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2440 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2441 rsaPubKeys[i].modulus, rsaPubKeys[i].modulusLen);
2442 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2443 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2444 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2447 ok(bufSize == rsaPubKeys[i].encoded[1] + 2,
2448 "Expected size %d, got %d\n", rsaPubKeys[i].encoded[1] + 2,
2450 ok(!memcmp(buf, rsaPubKeys[i].encoded, bufSize),
2451 "Unexpected value\n");
2457 static void test_decodeRsaPublicKey(DWORD dwEncoding)
2464 /* Try with a bad length */
2465 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2466 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1],
2467 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2468 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
2469 GetLastError() == OSS_MORE_INPUT /* Win9x/NT4 */),
2470 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n",
2472 /* Try with a couple of RSA-related OIDs */
2473 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_RSA,
2474 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2475 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2476 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2477 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2478 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2479 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2480 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2481 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2482 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2483 /* Now try success cases */
2484 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2487 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2488 rsaPubKeys[i].encoded, rsaPubKeys[i].encoded[1] + 2,
2489 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2490 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2493 BLOBHEADER *hdr = (BLOBHEADER *)buf;
2494 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER));
2496 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2497 rsaPubKeys[i].decodedModulusLen,
2498 "Wrong size %d\n", bufSize);
2499 ok(hdr->bType == PUBLICKEYBLOB,
2500 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB,
2502 ok(hdr->bVersion == CUR_BLOB_VERSION,
2503 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
2504 CUR_BLOB_VERSION, hdr->bVersion);
2505 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n",
2507 ok(hdr->aiKeyAlg == CALG_RSA_KEYX,
2508 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg);
2509 ok(rsaPubKey->magic == 0x31415352,
2510 "Expected magic RSA1, got %08x\n", rsaPubKey->magic);
2511 ok(rsaPubKey->bitlen == rsaPubKeys[i].decodedModulusLen * 8,
2512 "Wrong bit len %d\n", rsaPubKey->bitlen);
2513 ok(rsaPubKey->pubexp == 65537, "Expected pubexp 65537, got %d\n",
2515 ok(!memcmp(buf + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2516 rsaPubKeys[i].modulus, rsaPubKeys[i].decodedModulusLen),
2517 "Unexpected modulus\n");
2523 static const BYTE intSequence[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01,
2524 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02,
2525 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2527 static const BYTE mixedSequence[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
2528 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f,
2529 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02,
2530 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2532 static void test_encodeSequenceOfAny(DWORD dwEncoding)
2534 CRYPT_DER_BLOB blobs[sizeof(ints) / sizeof(ints[0])];
2535 CRYPT_SEQUENCE_OF_ANY seq;
2541 /* Encode a homogeneous sequence */
2542 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
2544 blobs[i].cbData = ints[i].encoded[1] + 2;
2545 blobs[i].pbData = (BYTE *)ints[i].encoded;
2547 seq.cValue = sizeof(ints) / sizeof(ints[0]);
2548 seq.rgValue = blobs;
2550 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2551 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2552 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2555 ok(bufSize == sizeof(intSequence), "Wrong size %d\n", bufSize);
2556 ok(!memcmp(buf, intSequence, intSequence[1] + 2), "Unexpected value\n");
2559 /* Change the type of the first element in the sequence, and give it
2562 blobs[0].cbData = times[0].encodedTime[1] + 2;
2563 blobs[0].pbData = (BYTE *)times[0].encodedTime;
2564 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2565 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2566 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2569 ok(bufSize == sizeof(mixedSequence), "Wrong size %d\n", bufSize);
2570 ok(!memcmp(buf, mixedSequence, mixedSequence[1] + 2),
2571 "Unexpected value\n");
2576 static void test_decodeSequenceOfAny(DWORD dwEncoding)
2582 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, intSequence,
2583 intSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2584 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2587 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2590 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2591 "Wrong elements %d\n", seq->cValue);
2592 for (i = 0; i < min(seq->cValue, sizeof(ints) / sizeof(ints[0])); i++)
2594 ok(seq->rgValue[i].cbData == ints[i].encoded[1] + 2,
2595 "Expected %d bytes, got %d\n", ints[i].encoded[1] + 2,
2596 seq->rgValue[i].cbData);
2597 ok(!memcmp(seq->rgValue[i].pbData, ints[i].encoded,
2598 ints[i].encoded[1] + 2), "Unexpected value\n");
2602 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, mixedSequence,
2603 mixedSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
2605 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2608 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2610 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2611 "Wrong elements %d\n", seq->cValue);
2612 /* Just check the first element since it's all that changed */
2613 ok(seq->rgValue[0].cbData == times[0].encodedTime[1] + 2,
2614 "Expected %d bytes, got %d\n", times[0].encodedTime[1] + 2,
2615 seq->rgValue[0].cbData);
2616 ok(!memcmp(seq->rgValue[0].pbData, times[0].encodedTime,
2617 times[0].encodedTime[1] + 2), "Unexpected value\n");
2622 struct encodedExtensions
2624 CERT_EXTENSIONS exts;
2625 const BYTE *encoded;
2628 static BYTE crit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2629 static BYTE noncrit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2630 static CHAR oid_basic_constraints2[] = szOID_BASIC_CONSTRAINTS2;
2631 static CERT_EXTENSION criticalExt =
2632 { oid_basic_constraints2, TRUE, { 8, crit_ext_data } };
2633 static CERT_EXTENSION nonCriticalExt =
2634 { oid_basic_constraints2, FALSE, { 8, noncrit_ext_data } };
2635 static CHAR oid_short[] = "1.1";
2636 static CERT_EXTENSION extWithShortOid =
2637 { oid_short, FALSE, { 0, NULL } };
2639 static const BYTE ext0[] = { 0x30,0x00 };
2640 static const BYTE ext1[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2641 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2642 static const BYTE ext2[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2643 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2644 static const BYTE ext3[] = { 0x30,0x07,0x30,0x05,0x06,0x01,0x29,0x04,0x00 };
2646 static const struct encodedExtensions exts[] = {
2647 { { 0, NULL }, ext0 },
2648 { { 1, &criticalExt }, ext1 },
2649 { { 1, &nonCriticalExt }, ext2 },
2650 { { 1, &extWithShortOid }, ext3 }
2653 static void test_encodeExtensions(DWORD dwEncoding)
2657 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2663 ret = pCryptEncodeObjectEx(dwEncoding, X509_EXTENSIONS, &exts[i].exts,
2664 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2665 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2668 ok(bufSize == exts[i].encoded[1] + 2,
2669 "Expected %d bytes, got %d\n", exts[i].encoded[1] + 2, bufSize);
2670 ok(!memcmp(buf, exts[i].encoded, exts[i].encoded[1] + 2),
2671 "Unexpected value\n");
2677 static void test_decodeExtensions(DWORD dwEncoding)
2681 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2687 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS,
2688 exts[i].encoded, exts[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2689 NULL, &buf, &bufSize);
2690 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2693 CERT_EXTENSIONS *ext = (CERT_EXTENSIONS *)buf;
2696 ok(ext->cExtension == exts[i].exts.cExtension,
2697 "Expected %d extensions, see %d\n", exts[i].exts.cExtension,
2699 for (j = 0; j < min(ext->cExtension, exts[i].exts.cExtension); j++)
2701 ok(!strcmp(ext->rgExtension[j].pszObjId,
2702 exts[i].exts.rgExtension[j].pszObjId),
2703 "Expected OID %s, got %s\n",
2704 exts[i].exts.rgExtension[j].pszObjId,
2705 ext->rgExtension[j].pszObjId);
2706 ok(!memcmp(ext->rgExtension[j].Value.pbData,
2707 exts[i].exts.rgExtension[j].Value.pbData,
2708 exts[i].exts.rgExtension[j].Value.cbData),
2709 "Unexpected value\n");
2716 /* MS encodes public key info with a NULL if the algorithm identifier's
2717 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2718 * it encodes them by omitting the algorithm parameters. It accepts either
2719 * form for decoding.
2721 struct encodedPublicKey
2723 CERT_PUBLIC_KEY_INFO info;
2724 const BYTE *encoded;
2725 const BYTE *encodedNoNull;
2726 CERT_PUBLIC_KEY_INFO decoded;
2729 static const BYTE aKey[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2731 static const BYTE params[] = { 0x02, 0x01, 0x01 };
2733 static const unsigned char bin64[] = {
2734 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2735 static const unsigned char bin65[] = {
2736 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2737 static const unsigned char bin66[] = {
2738 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2739 static const unsigned char bin67[] = {
2740 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2741 static const unsigned char bin68[] = {
2742 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01,
2743 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2744 static const unsigned char bin69[] = {
2745 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2746 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2747 static const unsigned char bin70[] = {
2748 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2749 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2751 static const unsigned char bin71[] = {
2752 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2753 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2755 static unsigned char bin72[] = { 0x05,0x00};
2757 static CHAR oid_bogus[] = "1.2.3",
2758 oid_rsa[] = szOID_RSA;
2760 static const struct encodedPublicKey pubKeys[] = {
2761 /* with a bogus OID */
2762 { { { oid_bogus, { 0, NULL } }, { 0, NULL, 0 } },
2764 { { oid_bogus, { 2, bin72 } }, { 0, NULL, 0 } } },
2765 /* some normal keys */
2766 { { { oid_rsa, { 0, NULL } }, { 0, NULL, 0} },
2768 { { oid_rsa, { 2, bin72 } }, { 0, NULL, 0 } } },
2769 { { { oid_rsa, { 0, NULL } }, { sizeof(aKey), (BYTE *)aKey, 0} },
2771 { { oid_rsa, { 2, bin72 } }, { sizeof(aKey), (BYTE *)aKey, 0} } },
2772 /* with add'l parameters--note they must be DER-encoded */
2773 { { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2774 (BYTE *)aKey, 0 } },
2776 { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2777 (BYTE *)aKey, 0 } } },
2780 static void test_encodePublicKeyInfo(DWORD dwEncoding)
2784 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2790 ret = pCryptEncodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2791 &pubKeys[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf,
2793 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2794 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2797 ok(bufSize == pubKeys[i].encoded[1] + 2,
2798 "Expected %d bytes, got %d\n", pubKeys[i].encoded[1] + 2, bufSize);
2799 if (bufSize == pubKeys[i].encoded[1] + 2)
2800 ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2),
2801 "Unexpected value\n");
2807 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO *expected,
2808 const CERT_PUBLIC_KEY_INFO *got)
2810 ok(!strcmp(expected->Algorithm.pszObjId, got->Algorithm.pszObjId),
2811 "Expected OID %s, got %s\n", expected->Algorithm.pszObjId,
2812 got->Algorithm.pszObjId);
2813 ok(expected->Algorithm.Parameters.cbData ==
2814 got->Algorithm.Parameters.cbData,
2815 "Expected parameters of %d bytes, got %d\n",
2816 expected->Algorithm.Parameters.cbData, got->Algorithm.Parameters.cbData);
2817 if (expected->Algorithm.Parameters.cbData)
2818 ok(!memcmp(expected->Algorithm.Parameters.pbData,
2819 got->Algorithm.Parameters.pbData, got->Algorithm.Parameters.cbData),
2820 "Unexpected algorithm parameters\n");
2821 ok(expected->PublicKey.cbData == got->PublicKey.cbData,
2822 "Expected public key of %d bytes, got %d\n",
2823 expected->PublicKey.cbData, got->PublicKey.cbData);
2824 if (expected->PublicKey.cbData)
2825 ok(!memcmp(expected->PublicKey.pbData, got->PublicKey.pbData,
2826 got->PublicKey.cbData), "Unexpected public key value\n");
2829 static void test_decodePublicKeyInfo(DWORD dwEncoding)
2831 static const BYTE bogusPubKeyInfo[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
2832 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
2833 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
2834 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2840 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2842 /* The NULL form decodes to the decoded member */
2843 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2844 pubKeys[i].encoded, pubKeys[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2845 NULL, &buf, &bufSize);
2846 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2849 comparePublicKeyInfo(&pubKeys[i].decoded,
2850 (CERT_PUBLIC_KEY_INFO *)buf);
2853 /* The non-NULL form decodes to the original */
2854 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2855 pubKeys[i].encodedNoNull, pubKeys[i].encodedNoNull[1] + 2,
2856 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2857 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2860 comparePublicKeyInfo(&pubKeys[i].info, (CERT_PUBLIC_KEY_INFO *)buf);
2864 /* Test with bogus (not valid DER) parameters */
2865 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2866 bogusPubKeyInfo, bogusPubKeyInfo[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2867 NULL, &buf, &bufSize);
2868 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2869 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2870 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2874 static const BYTE v1Cert[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
2875 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2876 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
2877 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
2878 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2879 static const BYTE v2Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02,
2880 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2881 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2882 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2883 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2884 static const BYTE v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2885 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2886 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2887 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2888 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2889 static const BYTE v4Cert[] = {
2890 0x30,0x38,0xa0,0x03,0x02,0x01,0x03,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,
2891 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
2892 0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
2893 0x30,0x30,0x30,0x5a,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00 };
2894 static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
2895 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2896 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2897 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2898 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2899 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2900 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2901 static const BYTE v1CertWithSerial[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
2902 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2903 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2904 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2905 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2906 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2907 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2908 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2909 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
2910 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
2911 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
2912 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
2913 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
2914 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
2915 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
2916 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
2917 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2918 static const BYTE v1CertWithPubKey[] = {
2919 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2920 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2921 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2922 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2923 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2924 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2925 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2926 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2927 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
2928 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
2930 static const BYTE v1CertWithPubKeyNoNull[] = {
2931 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2932 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2933 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2934 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2935 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2936 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2937 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2938 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2939 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
2940 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2941 static const BYTE v1CertWithSubjectKeyId[] = {
2942 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2943 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2944 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2945 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2946 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2947 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2948 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
2949 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2950 0x4c,0x61,0x6e,0x67,0x00 };
2951 static const BYTE v1CertWithIssuerUniqueId[] = {
2952 0x30,0x38,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
2953 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
2954 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
2955 0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x81,0x02,0x00,0x01 };
2956 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueId[] = {
2957 0x30,0x81,0x99,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2958 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2959 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2960 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2961 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2962 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2963 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2964 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2965 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,
2966 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
2967 0x01,0x01,0xff,0x02,0x01,0x01 };
2968 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull[] = {
2969 0x30,0x81,0x97,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2970 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2971 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2972 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2973 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2974 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2975 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2976 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2977 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
2978 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
2979 0xff,0x02,0x01,0x01 };
2981 static const BYTE serialNum[] = { 0x01 };
2983 static void test_encodeCertToBeSigned(DWORD dwEncoding)
2988 CERT_INFO info = { 0 };
2989 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2990 static char oid_subject_key_identifier[] = szOID_SUBJECT_KEY_IDENTIFIER;
2995 /* Test with NULL pvStructInfo (crashes on win9x) */
2996 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL,
2997 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
2998 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2999 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3001 /* Test with a V1 cert */
3002 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3003 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3004 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3005 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3008 ok(size == v1Cert[1] + 2, "Expected size %d, got %d\n",
3009 v1Cert[1] + 2, size);
3010 ok(!memcmp(buf, v1Cert, size), "Got unexpected value\n");
3014 info.dwVersion = CERT_V2;
3015 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3016 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3017 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3018 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3021 ok(size == sizeof(v2Cert), "Wrong size %d\n", size);
3022 ok(!memcmp(buf, v2Cert, size), "Got unexpected value\n");
3026 info.dwVersion = CERT_V3;
3027 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3028 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3029 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3030 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3033 ok(size == sizeof(v3Cert), "Wrong size %d\n", size);
3034 ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n");
3038 info.dwVersion = 3; /* Not a typo, CERT_V3 is 2 */
3039 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3040 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3043 ok(size == sizeof(v4Cert), "Wrong size %d\n", size);
3044 ok(!memcmp(buf, v4Cert, size), "Unexpected value\n");
3047 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
3048 * API doesn't prevent it)
3050 info.dwVersion = CERT_V1;
3051 info.cExtension = 1;
3052 info.rgExtension = &criticalExt;
3053 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3054 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3055 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3056 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3059 ok(size == sizeof(v1CertWithConstraints), "Wrong size %d\n", size);
3060 ok(!memcmp(buf, v1CertWithConstraints, size), "Got unexpected value\n");
3063 /* test v1 cert with a serial number */
3064 info.SerialNumber.cbData = sizeof(serialNum);
3065 info.SerialNumber.pbData = (BYTE *)serialNum;
3066 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3067 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3070 ok(size == sizeof(v1CertWithSerial), "Wrong size %d\n", size);
3071 ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n");
3074 /* Test v1 cert with an issuer name, serial number, and issuer unique id */
3075 info.dwVersion = CERT_V1;
3076 info.cExtension = 0;
3077 info.IssuerUniqueId.cbData = sizeof(serialNum);
3078 info.IssuerUniqueId.pbData = (BYTE *)serialNum;
3079 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3080 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3081 ok(ret || broken(GetLastError() == OSS_BAD_PTR /* Win98 */),
3082 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3085 ok(size == sizeof(v1CertWithIssuerUniqueId), "Wrong size %d\n", size);
3086 ok(!memcmp(buf, v1CertWithIssuerUniqueId, size),
3087 "Got unexpected value\n");
3090 /* Test v1 cert with an issuer name, a subject name, and a serial number */
3091 info.IssuerUniqueId.cbData = 0;
3092 info.IssuerUniqueId.pbData = NULL;
3093 info.cExtension = 1;
3094 info.rgExtension = &criticalExt;
3095 info.Issuer.cbData = sizeof(encodedCommonName);
3096 info.Issuer.pbData = (BYTE *)encodedCommonName;
3097 info.Subject.cbData = sizeof(encodedCommonName);
3098 info.Subject.pbData = (BYTE *)encodedCommonName;
3099 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3100 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3103 ok(size == sizeof(bigCert), "Wrong size %d\n", size);
3104 ok(!memcmp(buf, bigCert, size), "Got unexpected value\n");
3107 /* Add a public key */
3108 info.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3109 info.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
3110 info.SubjectPublicKeyInfo.PublicKey.pbData = (LPBYTE)aKey;
3111 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3112 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3115 ok(size == sizeof(v1CertWithPubKey) ||
3116 size == sizeof(v1CertWithPubKeyNoNull), "Wrong size %d\n", size);
3117 if (size == sizeof(v1CertWithPubKey))
3118 ok(!memcmp(buf, v1CertWithPubKey, size), "Got unexpected value\n");
3119 else if (size == sizeof(v1CertWithPubKeyNoNull))
3120 ok(!memcmp(buf, v1CertWithPubKeyNoNull, size),
3121 "Got unexpected value\n");
3124 /* Again add an issuer unique id */
3125 info.IssuerUniqueId.cbData = sizeof(serialNum);
3126 info.IssuerUniqueId.pbData = (BYTE *)serialNum;
3127 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3128 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3129 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3132 ok(size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId) ||
3133 size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull),
3134 "Wrong size %d\n", size);
3135 if (size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId))
3136 ok(!memcmp(buf, v1CertWithSubjectIssuerSerialAndIssuerUniqueId,
3137 size), "unexpected value\n");
3139 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull))
3141 v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull, size),
3142 "unexpected value\n");
3145 /* Remove the public key, and add a subject key identifier extension */
3146 info.IssuerUniqueId.cbData = 0;
3147 info.IssuerUniqueId.pbData = NULL;
3148 info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
3149 info.SubjectPublicKeyInfo.PublicKey.cbData = 0;
3150 info.SubjectPublicKeyInfo.PublicKey.pbData = NULL;
3151 ext.pszObjId = oid_subject_key_identifier;
3152 ext.fCritical = FALSE;
3153 ext.Value.cbData = sizeof(octetCommonNameValue);
3154 ext.Value.pbData = octetCommonNameValue;
3155 info.cExtension = 1;
3156 info.rgExtension = &ext;
3157 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3158 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3161 ok(size == sizeof(v1CertWithSubjectKeyId), "Wrong size %d\n", size);
3162 ok(!memcmp(buf, v1CertWithSubjectKeyId, size), "Unexpected value\n");
3167 static void test_decodeCertToBeSigned(DWORD dwEncoding)
3169 static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert, v4Cert,
3170 v1CertWithConstraints, v1CertWithSerial, v1CertWithIssuerUniqueId };
3175 /* Test with NULL pbEncoded */
3176 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 0,
3177 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3178 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
3179 GetLastError() == OSS_BAD_ARG /* Win9x */),
3180 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
3183 /* Crashes on win9x */
3184 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 1,
3185 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3186 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3187 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3189 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT or
3190 * CRYPT_E_ASN1_BADTAG, because at a minimum a cert must have a non-zero
3191 * serial number, an issuer, a subject, and a public key.
3193 for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++)
3195 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3196 corruptCerts[i], corruptCerts[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3198 ok(!ret, "Expected failure\n");
3200 /* The following succeeds, even though v1 certs are not allowed to have
3203 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3204 v1CertWithSubjectKeyId, sizeof(v1CertWithSubjectKeyId),
3205 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3206 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3209 CERT_INFO *info = (CERT_INFO *)buf;
3211 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3212 ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %d\n",
3214 ok(info->cExtension == 1, "expected 1 extension, got %d\n",
3218 /* The following also succeeds, even though V1 certs are not allowed to
3219 * have issuer unique ids.
3221 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3222 v1CertWithSubjectIssuerSerialAndIssuerUniqueId,
3223 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId),
3224 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3225 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3228 CERT_INFO *info = (CERT_INFO *)buf;
3230 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3231 ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %d\n",
3233 ok(info->IssuerUniqueId.cbData == sizeof(serialNum),
3234 "unexpected issuer unique id size %d\n", info->IssuerUniqueId.cbData);
3235 ok(!memcmp(info->IssuerUniqueId.pbData, serialNum, sizeof(serialNum)),
3236 "unexpected issuer unique id value\n");
3239 /* Now check with serial number, subject and issuer specified */
3240 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert,
3241 sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3242 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3245 CERT_INFO *info = (CERT_INFO *)buf;
3247 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3248 ok(info->SerialNumber.cbData == 1,
3249 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3250 ok(*info->SerialNumber.pbData == *serialNum,
3251 "Expected serial number %d, got %d\n", *serialNum,
3252 *info->SerialNumber.pbData);
3253 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3254 "Wrong size %d\n", info->Issuer.cbData);
3255 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3256 "Unexpected issuer\n");
3257 ok(info->Subject.cbData == sizeof(encodedCommonName),
3258 "Wrong size %d\n", info->Subject.cbData);
3259 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3260 info->Subject.cbData), "Unexpected subject\n");
3263 /* Check again with pub key specified */
3264 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3265 v1CertWithPubKey, sizeof(v1CertWithPubKey), CRYPT_DECODE_ALLOC_FLAG, NULL,
3267 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3270 CERT_INFO *info = (CERT_INFO *)buf;
3272 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3273 ok(info->SerialNumber.cbData == 1,
3274 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3275 ok(*info->SerialNumber.pbData == *serialNum,
3276 "Expected serial number %d, got %d\n", *serialNum,
3277 *info->SerialNumber.pbData);
3278 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3279 "Wrong size %d\n", info->Issuer.cbData);
3280 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3281 "Unexpected issuer\n");
3282 ok(info->Subject.cbData == sizeof(encodedCommonName),
3283 "Wrong size %d\n", info->Subject.cbData);
3284 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3285 info->Subject.cbData), "Unexpected subject\n");
3286 ok(!strcmp(info->SubjectPublicKeyInfo.Algorithm.pszObjId,
3287 szOID_RSA_RSA), "Expected szOID_RSA_RSA, got %s\n",
3288 info->SubjectPublicKeyInfo.Algorithm.pszObjId);
3289 ok(info->SubjectPublicKeyInfo.PublicKey.cbData == sizeof(aKey),
3290 "Wrong size %d\n", info->SubjectPublicKeyInfo.PublicKey.cbData);
3291 ok(!memcmp(info->SubjectPublicKeyInfo.PublicKey.pbData, aKey,
3292 sizeof(aKey)), "Unexpected public key\n");
3297 static const BYTE hash[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
3300 static const BYTE signedBigCert[] = {
3301 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
3302 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
3303 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
3304 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3305 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
3306 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
3307 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
3308 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
3309 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
3310 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3311 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
3312 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
3314 static void test_encodeCert(DWORD dwEncoding)
3316 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
3317 * also that bigCert is a NULL-terminated string, so don't count its
3318 * last byte (otherwise the signed cert won't decode.)
3320 CERT_SIGNED_CONTENT_INFO info = { { sizeof(bigCert), (BYTE *)bigCert },
3321 { NULL, { 0, NULL } }, { sizeof(hash), (BYTE *)hash, 0 } };
3326 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT, &info,
3327 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
3328 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3331 ok(bufSize == sizeof(signedBigCert), "Wrong size %d\n", bufSize);
3332 ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n");
3337 static void test_decodeCert(DWORD dwEncoding)
3343 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert,
3344 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3345 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3348 CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf;
3350 ok(info->ToBeSigned.cbData == sizeof(bigCert),
3351 "Wrong cert size %d\n", info->ToBeSigned.cbData);
3352 ok(!memcmp(info->ToBeSigned.pbData, bigCert, info->ToBeSigned.cbData),
3353 "Unexpected cert\n");
3354 ok(info->Signature.cbData == sizeof(hash),
3355 "Wrong signature size %d\n", info->Signature.cbData);
3356 ok(!memcmp(info->Signature.pbData, hash, info->Signature.cbData),
3357 "Unexpected signature\n");
3360 /* A signed cert decodes as a CERT_INFO too */
3361 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCert,
3362 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3363 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3366 CERT_INFO *info = (CERT_INFO *)buf;
3368 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3369 ok(info->SerialNumber.cbData == 1,
3370 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3371 ok(*info->SerialNumber.pbData == *serialNum,
3372 "Expected serial number %d, got %d\n", *serialNum,
3373 *info->SerialNumber.pbData);
3374 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3375 "Wrong size %d\n", info->Issuer.cbData);
3376 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3377 "Unexpected issuer\n");
3378 ok(info->Subject.cbData == sizeof(encodedCommonName),
3379 "Wrong size %d\n", info->Subject.cbData);
3380 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3381 info->Subject.cbData), "Unexpected subject\n");
3386 static const BYTE emptyDistPoint[] = { 0x30, 0x02, 0x30, 0x00 };
3387 static const BYTE distPointWithUrl[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3388 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3389 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3390 static const BYTE distPointWithReason[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3392 static const BYTE distPointWithIssuer[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3393 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3394 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3395 static const BYTE distPointWithUrlAndIssuer[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3396 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3397 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3398 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3399 0x2e, 0x6f, 0x72, 0x67 };
3400 static const BYTE crlReason = CRL_REASON_KEY_COMPROMISE |
3401 CRL_REASON_AFFILIATION_CHANGED;
3403 static void test_encodeCRLDistPoints(DWORD dwEncoding)
3405 CRL_DIST_POINTS_INFO info = { 0 };
3406 CRL_DIST_POINT point = { { 0 } };
3407 CERT_ALT_NAME_ENTRY entry = { 0 };
3412 /* Test with an empty info */
3413 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3414 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3415 ok(!ret && GetLastError() == E_INVALIDARG,
3416 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3417 /* Test with one empty dist point */
3418 info.cDistPoint = 1;
3419 info.rgDistPoint = &point;
3420 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3421 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3422 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3425 ok(size == sizeof(emptyDistPoint), "Wrong size %d\n", size);
3426 ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n");
3429 /* A dist point with an invalid name */
3430 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3431 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3432 U(entry).pwszURL = (LPWSTR)nihongoURL;
3433 U(point.DistPointName).FullName.cAltEntry = 1;
3434 U(point.DistPointName).FullName.rgAltEntry = &entry;
3435 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3436 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3437 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
3438 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
3439 /* The first invalid character is at index 7 */
3440 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
3441 "Expected invalid char at index 7, got %d\n",
3442 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
3443 /* A dist point with (just) a valid name */
3444 U(entry).pwszURL = (LPWSTR)url;
3445 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3446 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3447 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3450 ok(size == sizeof(distPointWithUrl), "Wrong size %d\n", size);
3451 ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n");
3454 /* A dist point with (just) reason flags */
3455 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3456 point.ReasonFlags.cbData = sizeof(crlReason);
3457 point.ReasonFlags.pbData = (LPBYTE)&crlReason;
3458 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3459 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3460 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3463 ok(size == sizeof(distPointWithReason), "Wrong size %d\n", size);
3464 ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n");
3467 /* A dist point with just an issuer */
3468 point.ReasonFlags.cbData = 0;
3469 point.CRLIssuer.cAltEntry = 1;
3470 point.CRLIssuer.rgAltEntry = &entry;
3471 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3472 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3473 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3476 ok(size == sizeof(distPointWithIssuer), "Wrong size %d\n", size);
3477 ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n");
3480 /* A dist point with both a name and an issuer */
3481 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3482 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3483 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3484 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3487 ok(size == sizeof(distPointWithUrlAndIssuer),
3488 "Wrong size %d\n", size);
3489 ok(!memcmp(buf, distPointWithUrlAndIssuer, size), "Unexpected value\n");
3494 static void test_decodeCRLDistPoints(DWORD dwEncoding)
3499 PCRL_DIST_POINTS_INFO info;
3500 PCRL_DIST_POINT point;
3501 PCERT_ALT_NAME_ENTRY entry;
3503 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3504 emptyDistPoint, emptyDistPoint[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3506 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3509 info = (PCRL_DIST_POINTS_INFO)buf;
3510 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3511 "Wrong size %d\n", size);
3512 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3514 point = info->rgDistPoint;
3515 ok(point->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_NO_NAME,
3516 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3517 point->DistPointName.dwDistPointNameChoice);
3518 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3519 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3522 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3523 distPointWithUrl, distPointWithUrl[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3525 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3528 info = (PCRL_DIST_POINTS_INFO)buf;
3529 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3530 "Wrong size %d\n", size);
3531 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3533 point = info->rgDistPoint;
3534 ok(point->DistPointName.dwDistPointNameChoice ==
3535 CRL_DIST_POINT_FULL_NAME,
3536 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3537 point->DistPointName.dwDistPointNameChoice);
3538 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3539 "Expected 1 name entry, got %d\n",
3540 U(point->DistPointName).FullName.cAltEntry);
3541 entry = U(point->DistPointName).FullName.rgAltEntry;
3542 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3543 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3544 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3545 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3546 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3549 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3550 distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
3552 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3555 info = (PCRL_DIST_POINTS_INFO)buf;
3556 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3557 "Wrong size %d\n", size);
3558 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3560 point = info->rgDistPoint;
3561 ok(point->DistPointName.dwDistPointNameChoice ==
3562 CRL_DIST_POINT_NO_NAME,
3563 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3564 point->DistPointName.dwDistPointNameChoice);
3565 ok(point->ReasonFlags.cbData == sizeof(crlReason),
3566 "Expected reason length\n");
3567 ok(!memcmp(point->ReasonFlags.pbData, &crlReason, sizeof(crlReason)),
3568 "Unexpected reason\n");
3569 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3572 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3573 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2,
3574 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3575 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3578 info = (PCRL_DIST_POINTS_INFO)buf;
3579 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3580 "Wrong size %d\n", size);
3581 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3583 point = info->rgDistPoint;
3584 ok(point->DistPointName.dwDistPointNameChoice ==
3585 CRL_DIST_POINT_FULL_NAME,
3586 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3587 point->DistPointName.dwDistPointNameChoice);
3588 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3589 "Expected 1 name entry, got %d\n",
3590 U(point->DistPointName).FullName.cAltEntry);
3591 entry = U(point->DistPointName).FullName.rgAltEntry;
3592 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3593 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3594 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3595 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3596 ok(point->CRLIssuer.cAltEntry == 1,
3597 "Expected 1 issuer entry, got %d\n", point->CRLIssuer.cAltEntry);
3598 entry = point->CRLIssuer.rgAltEntry;
3599 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3600 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3601 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3606 static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3607 static const BYTE emptyNameIDP[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3608 static const BYTE urlIDP[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3609 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3612 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding)
3617 CRL_ISSUING_DIST_POINT point = { { 0 } };
3618 CERT_ALT_NAME_ENTRY entry;
3620 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, NULL,
3621 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3622 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3624 skip("no X509_ISSUING_DIST_POINT encode support\n");
3627 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3628 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3629 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3630 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3631 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3634 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
3635 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
3638 /* nonsensical flags */
3639 point.fOnlyContainsUserCerts = TRUE;
3640 point.fOnlyContainsCACerts = TRUE;
3641 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3642 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3643 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3646 ok(size == sizeof(badFlagsIDP), "Unexpected size %d\n", size);
3647 ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n");
3650 /* unimplemented name type */
3651 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3652 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_ISSUER_RDN_NAME;
3653 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3654 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3655 ok(!ret && GetLastError() == E_INVALIDARG,
3656 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3658 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3659 U(point.DistPointName).FullName.cAltEntry = 0;
3660 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3661 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3662 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3665 ok(size == sizeof(emptyNameIDP), "Unexpected size %d\n", size);
3666 ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n");
3669 /* name with URL entry */
3670 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3671 U(entry).pwszURL = (LPWSTR)url;
3672 U(point.DistPointName).FullName.cAltEntry = 1;
3673 U(point.DistPointName).FullName.rgAltEntry = &entry;
3674 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3675 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3676 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3679 ok(size == sizeof(urlIDP), "Unexpected size %d\n", size);
3680 ok(!memcmp(buf, urlIDP, size), "Unexpected value\n");
3685 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY *expected,
3686 const CERT_ALT_NAME_ENTRY *got)
3688 ok(expected->dwAltNameChoice == got->dwAltNameChoice,
3689 "Expected name choice %d, got %d\n", expected->dwAltNameChoice,
3690 got->dwAltNameChoice);
3691 if (expected->dwAltNameChoice == got->dwAltNameChoice)
3693 switch (got->dwAltNameChoice)
3695 case CERT_ALT_NAME_RFC822_NAME:
3696 case CERT_ALT_NAME_DNS_NAME:
3697 case CERT_ALT_NAME_EDI_PARTY_NAME:
3698 case CERT_ALT_NAME_URL:
3699 case CERT_ALT_NAME_REGISTERED_ID:
3700 ok((!U(*expected).pwszURL && !U(*got).pwszURL) ||
3701 (!U(*expected).pwszURL && !lstrlenW(U(*got).pwszURL)) ||
3702 (!U(*got).pwszURL && !lstrlenW(U(*expected).pwszURL)) ||
3703 !lstrcmpW(U(*expected).pwszURL, U(*got).pwszURL),
3704 "Unexpected name\n");
3706 case CERT_ALT_NAME_X400_ADDRESS:
3707 case CERT_ALT_NAME_DIRECTORY_NAME:
3708 case CERT_ALT_NAME_IP_ADDRESS:
3709 ok(U(*got).IPAddress.cbData == U(*expected).IPAddress.cbData,
3710 "Unexpected IP address length %d\n", U(*got).IPAddress.cbData);
3711 ok(!memcmp(U(*got).IPAddress.pbData, U(*got).IPAddress.pbData,
3712 U(*got).IPAddress.cbData), "Unexpected value\n");
3718 static void compareAltNameInfo(const CERT_ALT_NAME_INFO *expected,
3719 const CERT_ALT_NAME_INFO *got)
3723 ok(expected->cAltEntry == got->cAltEntry, "Expected %d entries, got %d\n",
3724 expected->cAltEntry, got->cAltEntry);
3725 for (i = 0; i < min(expected->cAltEntry, got->cAltEntry); i++)
3726 compareAltNameEntry(&expected->rgAltEntry[i], &got->rgAltEntry[i]);
3729 static void compareDistPointName(const CRL_DIST_POINT_NAME *expected,
3730 const CRL_DIST_POINT_NAME *got)
3732 ok(got->dwDistPointNameChoice == expected->dwDistPointNameChoice,
3733 "Unexpected name choice %d\n", got->dwDistPointNameChoice);
3734 if (got->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME)
3735 compareAltNameInfo(&(U(*expected).FullName), &(U(*got).FullName));
3738 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT *expected,
3739 const CRL_ISSUING_DIST_POINT *got)
3741 compareDistPointName(&expected->DistPointName, &got->DistPointName);
3742 ok(got->fOnlyContainsUserCerts == expected->fOnlyContainsUserCerts,
3743 "Unexpected fOnlyContainsUserCerts\n");
3744 ok(got->fOnlyContainsCACerts == expected->fOnlyContainsCACerts,
3745 "Unexpected fOnlyContainsCACerts\n");
3746 ok(got->OnlySomeReasonFlags.cbData == expected->OnlySomeReasonFlags.cbData,
3747 "Unexpected reason flags\n");
3748 ok(got->fIndirectCRL == expected->fIndirectCRL,
3749 "Unexpected fIndirectCRL\n");
3752 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding)
3757 CRL_ISSUING_DIST_POINT point = { { 0 } };
3759 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3760 emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3762 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3764 skip("no X509_ISSUING_DIST_POINT decode support\n");
3767 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3770 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3773 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3774 badFlagsIDP, badFlagsIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3776 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3779 point.fOnlyContainsUserCerts = point.fOnlyContainsCACerts = TRUE;
3780 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3783 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3784 emptyNameIDP, emptyNameIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3786 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3789 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3790 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3791 U(point.DistPointName).FullName.cAltEntry = 0;
3792 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3795 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3796 urlIDP, urlIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3797 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3800 CERT_ALT_NAME_ENTRY entry;
3802 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3803 U(entry).pwszURL = (LPWSTR)url;
3804 U(point.DistPointName).FullName.cAltEntry = 1;
3805 U(point.DistPointName).FullName.rgAltEntry = &entry;
3806 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3811 static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3812 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3814 static const BYTE v2CRL[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3815 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3816 0x30, 0x30, 0x30, 0x30, 0x5a };
3817 static const BYTE v1CRLWithIssuer[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3818 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3819 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3820 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3822 static const BYTE v1CRLWithIssuerAndEmptyEntry[] = { 0x30, 0x43, 0x30, 0x02,
3823 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3824 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3825 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3826 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3827 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3828 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3829 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3830 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3831 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3832 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3833 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3834 static const BYTE v1CRLWithEntryExt[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3835 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3836 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3837 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3838 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3839 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3840 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3841 static const BYTE v1CRLWithExt[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3842 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3843 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3844 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
3845 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3846 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
3847 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3848 static const BYTE v2CRLWithExt[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
3849 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
3850 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
3851 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
3852 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
3853 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
3854 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3856 static void test_encodeCRLToBeSigned(DWORD dwEncoding)
3861 CRL_INFO info = { 0 };
3862 CRL_ENTRY entry = { { 0 }, { 0 }, 0, 0 };
3864 /* Test with a V1 CRL */
3865 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3866 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3867 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3868 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3871 ok(size == sizeof(v1CRL), "Wrong size %d\n", size);
3872 ok(!memcmp(buf, v1CRL, size), "Got unexpected value\n");
3876 info.dwVersion = CRL_V2;
3877 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3878 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3879 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3880 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3883 ok(size == v2CRL[1] + 2, "Expected size %d, got %d\n",
3884 v2CRL[1] + 2, size);
3885 ok(!memcmp(buf, v2CRL, size), "Got unexpected value\n");
3888 /* v1 CRL with a name */
3889 info.dwVersion = CRL_V1;
3890 info.Issuer.cbData = sizeof(encodedCommonName);
3891 info.Issuer.pbData = (BYTE *)encodedCommonName;
3892 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3893 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3894 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3897 ok(size == sizeof(v1CRLWithIssuer), "Wrong size %d\n", size);
3898 ok(!memcmp(buf, v1CRLWithIssuer, size), "Got unexpected value\n");
3903 /* v1 CRL with a name and a NULL entry pointer (crashes on win9x) */
3905 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3906 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3907 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3908 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3910 /* now set an empty entry */
3912 info.rgCRLEntry = &entry;
3913 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3914 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3917 ok(size == sizeof(v1CRLWithIssuerAndEmptyEntry),
3918 "Wrong size %d\n", size);
3919 ok(!memcmp(buf, v1CRLWithIssuerAndEmptyEntry, size),
3920 "Got unexpected value\n");
3923 /* an entry with a serial number */
3924 entry.SerialNumber.cbData = sizeof(serialNum);
3925 entry.SerialNumber.pbData = (BYTE *)serialNum;
3926 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3927 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3930 ok(size == sizeof(v1CRLWithIssuerAndEntry),
3931 "Wrong size %d\n", size);
3932 ok(!memcmp(buf, v1CRLWithIssuerAndEntry, size),
3933 "Got unexpected value\n");
3936 /* an entry with an extension */
3937 entry.cExtension = 1;
3938 entry.rgExtension = &criticalExt;
3939 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3940 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3941 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3944 ok(size == sizeof(v1CRLWithEntryExt), "Wrong size %d\n", size);
3945 ok(!memcmp(buf, v1CRLWithEntryExt, size), "Got unexpected value\n");
3948 /* a CRL with an extension */
3949 entry.cExtension = 0;
3950 info.cExtension = 1;
3951 info.rgExtension = &criticalExt;
3952 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3953 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3954 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3957 ok(size == sizeof(v1CRLWithExt), "Wrong size %d\n", size);
3958 ok(!memcmp(buf, v1CRLWithExt, size), "Got unexpected value\n");
3961 /* a v2 CRL with an extension, this time non-critical */
3962 info.dwVersion = CRL_V2;
3963 info.rgExtension = &nonCriticalExt;
3964 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3965 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3966 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3969 ok(size == sizeof(v2CRLWithExt), "Wrong size %d\n", size);
3970 ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n");
3975 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
3976 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
3977 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
3978 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
3979 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
3980 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
3981 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
3982 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
3983 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
3984 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
3985 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
3986 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
3987 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
3988 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
3989 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
3990 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
3991 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
3992 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
3993 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
3994 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
3995 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
3996 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
3997 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
3998 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
3999 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
4000 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
4001 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
4002 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
4003 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
4004 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
4005 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
4006 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
4007 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
4008 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
4010 static const BYTE verisignCRLWithLotsOfEntries[] = {
4011 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
4012 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
4013 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
4014 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
4015 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
4016 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
4017 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
4018 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
4019 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
4020 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
4021 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
4022 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
4023 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
4024 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
4025 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
4026 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
4027 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
4028 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
4029 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
4030 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
4031 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
4032 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
4033 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
4034 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
4035 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
4036 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
4037 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
4038 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
4039 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
4040 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
4041 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
4042 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
4043 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
4044 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
4045 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
4046 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
4047 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
4048 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
4049 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
4050 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
4051 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
4052 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
4053 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
4054 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
4055 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
4056 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
4057 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
4058 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
4059 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
4060 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
4061 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
4062 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
4063 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
4064 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
4065 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
4066 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
4067 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
4068 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
4069 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
4070 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
4071 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
4072 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
4073 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
4074 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
4075 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
4076 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
4077 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
4078 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
4079 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
4080 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
4081 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
4082 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
4083 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
4084 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
4085 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
4086 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
4087 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
4088 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
4089 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
4090 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
4091 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
4092 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
4093 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
4094 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
4095 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
4096 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
4097 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
4098 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
4099 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
4100 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
4101 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
4102 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
4103 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
4104 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
4105 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
4106 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
4107 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
4108 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
4109 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
4110 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
4111 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
4112 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
4113 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
4114 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
4115 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
4116 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
4117 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
4118 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
4119 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
4120 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
4121 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
4122 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
4123 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
4124 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
4125 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
4126 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
4127 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
4128 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
4129 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
4130 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
4131 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
4132 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
4133 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
4134 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
4135 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
4136 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
4137 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
4138 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
4139 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
4140 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
4141 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
4142 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
4143 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
4144 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
4145 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
4146 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
4147 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
4148 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
4149 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
4150 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
4151 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
4152 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
4153 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
4154 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
4155 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
4156 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
4157 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
4158 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
4159 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
4160 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
4161 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
4162 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
4163 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
4164 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
4165 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
4166 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
4167 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
4168 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
4169 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
4170 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
4171 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
4172 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
4173 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
4174 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
4175 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
4176 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
4177 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
4178 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
4179 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
4180 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
4181 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
4182 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
4183 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
4184 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
4185 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
4186 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
4187 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
4188 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
4189 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
4190 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
4191 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
4192 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
4193 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
4194 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
4195 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
4196 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
4197 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
4198 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
4199 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
4200 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
4201 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
4202 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
4203 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
4204 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
4205 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
4206 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
4207 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
4208 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
4209 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
4210 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
4211 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
4212 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
4213 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
4214 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
4215 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
4216 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
4217 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
4218 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
4219 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
4220 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
4221 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
4222 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
4223 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
4224 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
4225 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
4226 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
4227 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
4228 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
4229 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
4230 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
4231 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
4232 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
4233 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
4234 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
4235 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
4236 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
4237 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
4238 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
4239 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
4240 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
4241 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
4242 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
4243 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
4244 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
4245 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
4246 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
4247 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
4248 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
4249 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
4250 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
4251 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
4252 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
4253 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
4254 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
4255 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
4256 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
4257 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
4258 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
4259 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
4260 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
4261 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
4262 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
4263 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
4264 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
4265 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
4266 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
4267 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
4268 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
4269 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
4270 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
4271 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
4272 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
4273 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
4274 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
4275 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
4276 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
4277 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
4278 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
4279 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
4280 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
4281 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
4282 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
4283 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
4284 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
4285 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
4286 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
4287 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
4288 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
4289 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
4290 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
4291 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
4292 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
4293 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
4294 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
4295 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
4296 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
4297 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
4298 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
4299 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
4300 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
4301 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
4302 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
4303 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
4304 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
4305 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
4306 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
4307 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
4308 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
4309 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
4310 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
4311 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
4312 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
4313 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
4314 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4315 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4316 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4317 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4318 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4319 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4320 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4321 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4322 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4323 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4324 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4325 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4326 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4327 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4328 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4329 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4330 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4331 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4332 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4333 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4334 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4335 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4336 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4337 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4338 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4339 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4340 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4341 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4342 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4343 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4344 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4345 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4346 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4347 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4348 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4349 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4350 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4351 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4352 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4353 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4354 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4355 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4356 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4357 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4358 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4359 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4360 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4361 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4362 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4363 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4364 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4365 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4366 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4367 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4368 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4369 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4370 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4371 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4372 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4373 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4374 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4375 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4376 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4377 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4378 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4379 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4380 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4381 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4382 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4383 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4384 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4385 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4386 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4387 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4388 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4389 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4390 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4391 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4392 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4393 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4394 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4395 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4396 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4397 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4398 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4399 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4400 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4401 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4402 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4403 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4404 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4405 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4406 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4407 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4408 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4409 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4410 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4411 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4412 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4413 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4414 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4415 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4416 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4417 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4418 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4419 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4420 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4421 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4422 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4423 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4424 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4425 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4426 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4427 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4428 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4429 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4430 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4431 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4432 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4433 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4434 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4435 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4436 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4437 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4438 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4439 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4440 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4441 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4442 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4443 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4444 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4445 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4446 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4447 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4448 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4449 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4450 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4451 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4452 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4453 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4454 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4455 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4456 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4457 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4458 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4459 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4460 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4461 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4462 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4463 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4464 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4465 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4466 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4467 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4468 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4469 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4470 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4471 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4472 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4473 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4474 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4475 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4476 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4477 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4478 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4479 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4480 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4481 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4482 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4483 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4484 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4485 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4486 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4487 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4488 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4489 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4490 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4491 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4492 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4493 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4494 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4495 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4496 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4497 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4498 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4499 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4500 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4501 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4502 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4503 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4504 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4505 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4506 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4507 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4508 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4509 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4510 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4511 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4512 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4513 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4514 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4515 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4516 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4517 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4518 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4520 static void test_decodeCRLToBeSigned(DWORD dwEncoding)
4522 static const BYTE *corruptCRLs[] = { v1CRL, v2CRL };
4527 for (i = 0; i < sizeof(corruptCRLs) / sizeof(corruptCRLs[0]); i++)
4529 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4530 corruptCRLs[i], corruptCRLs[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4532 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4533 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4534 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4537 /* at a minimum, a CRL must contain an issuer: */
4538 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4539 v1CRLWithIssuer, v1CRLWithIssuer[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4541 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4544 CRL_INFO *info = (CRL_INFO *)buf;
4546 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4547 ok(info->cCRLEntry == 0, "Expected 0 CRL entries, got %d\n",
4549 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4550 "Wrong issuer size %d\n", info->Issuer.cbData);
4551 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4552 "Unexpected issuer\n");
4555 /* check decoding with an empty CRL entry */
4556 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4557 v1CRLWithIssuerAndEmptyEntry, v1CRLWithIssuerAndEmptyEntry[1] + 2,
4558 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4559 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4560 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4561 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4563 /* with a real CRL entry */
4564 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4565 v1CRLWithIssuerAndEntry, v1CRLWithIssuerAndEntry[1] + 2,
4566 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4567 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4570 CRL_INFO *info = (CRL_INFO *)buf;
4573 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4574 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4576 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4577 entry = info->rgCRLEntry;
4578 ok(entry->SerialNumber.cbData == 1,
4579 "Expected serial number size 1, got %d\n",
4580 entry->SerialNumber.cbData);
4581 ok(*entry->SerialNumber.pbData == *serialNum,
4582 "Expected serial number %d, got %d\n", *serialNum,
4583 *entry->SerialNumber.pbData);
4584 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4585 "Wrong issuer size %d\n", info->Issuer.cbData);
4586 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4587 "Unexpected issuer\n");
4590 /* a real CRL from verisign that has extensions */
4591 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4592 verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG,
4594 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4597 CRL_INFO *info = (CRL_INFO *)buf;
4599 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4600 ok(info->cCRLEntry == 3, "Expected 3 CRL entries, got %d\n",
4602 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4603 ok(info->cExtension == 2, "Expected 2 extensions, got %d\n",
4607 /* another real CRL from verisign that has lots of entries */
4608 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4609 verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries),
4610 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4611 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4614 CRL_INFO *info = (CRL_INFO *)buf;
4616 ok(size >= sizeof(CRL_INFO), "Got size %d\n", size);
4617 ok(info->cCRLEntry == 209, "Expected 209 CRL entries, got %d\n",
4619 ok(info->cExtension == 0, "Expected 0 extensions, got %d\n",
4623 /* and finally, with an extension */
4624 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4625 v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4627 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4630 CRL_INFO *info = (CRL_INFO *)buf;
4633 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4634 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4636 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4637 entry = info->rgCRLEntry;
4638 ok(entry->SerialNumber.cbData == 1,
4639 "Expected serial number size 1, got %d\n",
4640 entry->SerialNumber.cbData);
4641 ok(*entry->SerialNumber.pbData == *serialNum,
4642 "Expected serial number %d, got %d\n", *serialNum,
4643 *entry->SerialNumber.pbData);
4644 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4645 "Wrong issuer size %d\n", info->Issuer.cbData);
4646 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4647 "Unexpected issuer\n");
4648 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4652 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4653 v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4655 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4658 CRL_INFO *info = (CRL_INFO *)buf;
4660 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4666 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
4667 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
4668 static const BYTE encodedUsage[] = {
4669 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4670 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4671 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4673 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding)
4678 CERT_ENHKEY_USAGE usage;
4680 /* Test with empty usage */
4681 usage.cUsageIdentifier = 0;
4682 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4683 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4684 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4687 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
4688 ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n");
4691 /* Test with a few usages */
4692 usage.cUsageIdentifier = sizeof(keyUsages) / sizeof(keyUsages[0]);
4693 usage.rgpszUsageIdentifier = (LPSTR *)keyUsages;
4694 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4695 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4696 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4699 ok(size == sizeof(encodedUsage), "Wrong size %d\n", size);
4700 ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n");
4705 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding)
4711 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4712 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4714 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4717 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4719 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4720 "Wrong size %d\n", size);
4721 ok(usage->cUsageIdentifier == 0, "Expected 0 CRL entries, got %d\n",
4722 usage->cUsageIdentifier);
4725 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4726 encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL,
4728 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4731 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4734 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4735 "Wrong size %d\n", size);
4736 ok(usage->cUsageIdentifier == sizeof(keyUsages) / sizeof(keyUsages[0]),
4737 "Wrong CRL entries count %d\n", usage->cUsageIdentifier);
4738 for (i = 0; i < usage->cUsageIdentifier; i++)
4739 ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]),
4740 "Expected OID %s, got %s\n", keyUsages[i],
4741 usage->rgpszUsageIdentifier[i]);
4746 static BYTE keyId[] = { 1,2,3,4 };
4747 static const BYTE authorityKeyIdWithId[] = {
4748 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4749 static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4750 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4751 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4752 static const BYTE authorityKeyIdWithSerial[] = { 0x30,0x03,0x82,0x01,0x01 };
4754 static void test_encodeAuthorityKeyId(DWORD dwEncoding)
4756 CERT_AUTHORITY_KEY_ID_INFO info = { { 0 } };
4761 /* Test with empty id */
4762 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4763 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4764 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4767 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4768 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4771 /* With just a key id */
4772 info.KeyId.cbData = sizeof(keyId);
4773 info.KeyId.pbData = keyId;
4774 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4775 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4776 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4779 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", size);
4780 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4783 /* With just an issuer */
4784 info.KeyId.cbData = 0;
4785 info.CertIssuer.cbData = sizeof(encodedCommonName);
4786 info.CertIssuer.pbData = (BYTE *)encodedCommonName;
4787 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4788 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4789 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4792 ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %d\n",
4794 ok(!memcmp(buf, authorityKeyIdWithIssuer, size), "Unexpected value\n");
4797 /* With just a serial number */
4798 info.CertIssuer.cbData = 0;
4799 info.CertSerialNumber.cbData = sizeof(serialNum);
4800 info.CertSerialNumber.pbData = (BYTE *)serialNum;
4801 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4802 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4803 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4806 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4808 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4813 static void test_decodeAuthorityKeyId(DWORD dwEncoding)
4819 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4820 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4822 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4825 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4827 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4829 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4830 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4831 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4834 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4835 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4836 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4837 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4840 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4842 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4844 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4845 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4846 "Unexpected key id\n");
4847 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4848 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4851 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4852 authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer),
4853 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4854 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4857 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4859 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4861 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4862 ok(info->CertIssuer.cbData == sizeof(encodedCommonName),
4863 "Unexpected issuer len\n");
4864 ok(!memcmp(info->CertIssuer.pbData, encodedCommonName,
4865 sizeof(encodedCommonName)), "Unexpected issuer\n");
4866 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4869 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4870 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4871 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4872 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4875 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4877 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4879 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4880 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4881 ok(info->CertSerialNumber.cbData == sizeof(serialNum),
4882 "Unexpected serial number len\n");
4883 ok(!memcmp(info->CertSerialNumber.pbData, serialNum, sizeof(serialNum)),
4884 "Unexpected serial number\n");
4889 static const BYTE authorityKeyIdWithIssuerUrl[] = { 0x30,0x15,0xa1,0x13,0x86,
4890 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
4893 static void test_encodeAuthorityKeyId2(DWORD dwEncoding)
4895 CERT_AUTHORITY_KEY_ID2_INFO info = { { 0 } };
4896 CERT_ALT_NAME_ENTRY entry = { 0 };
4901 /* Test with empty id */
4902 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4903 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4904 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4907 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4908 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4911 /* With just a key id */
4912 info.KeyId.cbData = sizeof(keyId);
4913 info.KeyId.pbData = keyId;
4914 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4915 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4916 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4919 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n",
4921 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4924 /* With a bogus issuer name */
4925 info.KeyId.cbData = 0;
4926 info.AuthorityCertIssuer.cAltEntry = 1;
4927 info.AuthorityCertIssuer.rgAltEntry = &entry;
4928 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4929 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4930 ok(!ret && GetLastError() == E_INVALIDARG,
4931 "Expected E_INVALIDARG, got %08x\n", GetLastError());
4932 /* With an issuer name */
4933 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
4934 U(entry).pwszURL = (LPWSTR)url;
4935 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4936 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4937 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4940 ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %d\n",
4942 ok(!memcmp(buf, authorityKeyIdWithIssuerUrl, size),
4943 "Unexpected value\n");
4946 /* With just a serial number */
4947 info.AuthorityCertIssuer.cAltEntry = 0;
4948 info.AuthorityCertSerialNumber.cbData = sizeof(serialNum);
4949 info.AuthorityCertSerialNumber.pbData = (BYTE *)serialNum;
4950 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4951 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4952 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4955 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4957 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4962 static void test_decodeAuthorityKeyId2(DWORD dwEncoding)
4968 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4969 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4971 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4974 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4976 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4978 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4979 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4980 "Expected no issuer name entries\n");
4981 ok(info->AuthorityCertSerialNumber.cbData == 0,
4982 "Expected no serial number\n");
4985 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4986 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4987 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4988 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4991 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4993 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4995 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4996 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4997 "Unexpected key id\n");
4998 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4999 "Expected no issuer name entries\n");
5000 ok(info->AuthorityCertSerialNumber.cbData == 0,
5001 "Expected no serial number\n");
5004 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
5005 authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl),
5006 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5007 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5010 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
5012 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
5014 ok(info->KeyId.cbData == 0, "Expected no key id\n");
5015 ok(info->AuthorityCertIssuer.cAltEntry == 1,
5016 "Expected 1 issuer entry, got %d\n",
5017 info->AuthorityCertIssuer.cAltEntry);
5018 ok(info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice ==
5019 CERT_ALT_NAME_URL, "Expected CERT_ALT_NAME_URL, got %d\n",
5020 info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice);
5021 ok(!lstrcmpW(U(info->AuthorityCertIssuer.rgAltEntry[0]).pwszURL,
5022 url), "Unexpected URL\n");
5023 ok(info->AuthorityCertSerialNumber.cbData == 0,
5024 "Expected no serial number\n");
5027 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
5028 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
5029 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5030 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5033 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
5035 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
5037 ok(info->KeyId.cbData == 0, "Expected no key id\n");
5038 ok(info->AuthorityCertIssuer.cAltEntry == 0,
5039 "Expected no issuer name entries\n");
5040 ok(info->AuthorityCertSerialNumber.cbData == sizeof(serialNum),
5041 "Unexpected serial number len\n");
5042 ok(!memcmp(info->AuthorityCertSerialNumber.pbData, serialNum,
5043 sizeof(serialNum)), "Unexpected serial number\n");
5048 static const BYTE authorityInfoAccessWithUrl[] = {
5049 0x30,0x19,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
5050 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5051 static const BYTE authorityInfoAccessWithUrlAndIPAddr[] = {
5052 0x30,0x29,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
5053 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x0e,0x06,
5054 0x02,0x2d,0x06,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5056 static void test_encodeAuthorityInfoAccess(DWORD dwEncoding)
5058 static char oid1[] = "1.2.3";
5059 static char oid2[] = "1.5.6";
5063 CERT_ACCESS_DESCRIPTION accessDescription[2];
5064 CERT_AUTHORITY_INFO_ACCESS aia;
5066 memset(accessDescription, 0, sizeof(accessDescription));
5068 aia.rgAccDescr = NULL;
5069 /* Having no access descriptions is allowed */
5070 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5071 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5072 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5075 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
5076 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
5080 /* It can't have an empty access method */
5082 aia.rgAccDescr = accessDescription;
5083 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5084 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5085 ok(!ret && (GetLastError() == E_INVALIDARG ||
5086 GetLastError() == OSS_LIMITED /* Win9x */),
5087 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
5088 /* It can't have an empty location */
5089 accessDescription[0].pszAccessMethod = oid1;
5090 SetLastError(0xdeadbeef);
5091 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5092 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5093 ok(!ret && GetLastError() == E_INVALIDARG,
5094 "expected E_INVALIDARG, got %08x\n", GetLastError());
5095 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5096 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
5097 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5098 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5099 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5102 ok(size == sizeof(authorityInfoAccessWithUrl), "unexpected size %d\n",
5104 ok(!memcmp(buf, authorityInfoAccessWithUrl, size),
5105 "unexpected value\n");
5109 accessDescription[1].pszAccessMethod = oid2;
5110 accessDescription[1].AccessLocation.dwAltNameChoice =
5111 CERT_ALT_NAME_IP_ADDRESS;
5112 U(accessDescription[1].AccessLocation).IPAddress.cbData =
5113 sizeof(encodedIPAddr);
5114 U(accessDescription[1].AccessLocation).IPAddress.pbData =
5115 (LPBYTE)encodedIPAddr;
5117 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5118 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5119 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5122 ok(size == sizeof(authorityInfoAccessWithUrlAndIPAddr),
5123 "unexpected size %d\n", size);
5124 ok(!memcmp(buf, authorityInfoAccessWithUrlAndIPAddr, size),
5125 "unexpected value\n");
5131 static void compareAuthorityInfoAccess(LPCSTR header,
5132 const CERT_AUTHORITY_INFO_ACCESS *expected,
5133 const CERT_AUTHORITY_INFO_ACCESS *got)
5137 ok(expected->cAccDescr == got->cAccDescr,
5138 "%s: expected %d access descriptions, got %d\n", header,
5139 expected->cAccDescr, got->cAccDescr);
5140 for (i = 0; i < expected->cAccDescr; i++)
5142 ok(!strcmp(expected->rgAccDescr[i].pszAccessMethod,
5143 got->rgAccDescr[i].pszAccessMethod), "%s[%d]: expected %s, got %s\n",
5144 header, i, expected->rgAccDescr[i].pszAccessMethod,
5145 got->rgAccDescr[i].pszAccessMethod);
5146 compareAltNameEntry(&expected->rgAccDescr[i].AccessLocation,
5147 &got->rgAccDescr[i].AccessLocation);
5151 static void test_decodeAuthorityInfoAccess(DWORD dwEncoding)
5153 static char oid1[] = "1.2.3";
5154 static char oid2[] = "1.5.6";
5159 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5160 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
5162 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5165 CERT_AUTHORITY_INFO_ACCESS aia = { 0, NULL };
5167 compareAuthorityInfoAccess("empty AIA", &aia,
5168 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5172 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5173 authorityInfoAccessWithUrl, sizeof(authorityInfoAccessWithUrl),
5174 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5175 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5178 CERT_ACCESS_DESCRIPTION accessDescription;
5179 CERT_AUTHORITY_INFO_ACCESS aia;
5181 accessDescription.pszAccessMethod = oid1;
5182 accessDescription.AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5183 U(accessDescription.AccessLocation).pwszURL = (LPWSTR)url;
5185 aia.rgAccDescr = &accessDescription;
5186 compareAuthorityInfoAccess("AIA with URL", &aia,
5187 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5191 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5192 authorityInfoAccessWithUrlAndIPAddr,
5193 sizeof(authorityInfoAccessWithUrlAndIPAddr), CRYPT_DECODE_ALLOC_FLAG,
5195 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5198 CERT_ACCESS_DESCRIPTION accessDescription[2];
5199 CERT_AUTHORITY_INFO_ACCESS aia;
5201 accessDescription[0].pszAccessMethod = oid1;
5202 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5203 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
5204 accessDescription[1].pszAccessMethod = oid2;
5205 accessDescription[1].AccessLocation.dwAltNameChoice =
5206 CERT_ALT_NAME_IP_ADDRESS;
5207 U(accessDescription[1].AccessLocation).IPAddress.cbData =
5208 sizeof(encodedIPAddr);
5209 U(accessDescription[1].AccessLocation).IPAddress.pbData =
5210 (LPBYTE)encodedIPAddr;
5212 aia.rgAccDescr = accessDescription;
5213 compareAuthorityInfoAccess("AIA with URL and IP addr", &aia,
5214 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5220 static const BYTE emptyCTL[] = {
5221 0x30,0x17,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5222 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5223 static const BYTE emptyCTLWithVersion1[] = {
5224 0x30,0x1a,0x02,0x01,0x01,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5225 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5226 static const BYTE ctlWithUsageIdentifier[] = {
5227 0x30,0x1b,0x30,0x04,0x06,0x02,0x2a,0x03,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
5228 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5229 static const BYTE ctlWithListIdentifier[] = {
5230 0x30,0x1a,0x30,0x00,0x04,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5231 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5232 static const BYTE ctlWithSequenceNumber[] = {
5233 0x30,0x1a,0x30,0x00,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5234 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5235 static const BYTE ctlWithThisUpdate[] = {
5236 0x30,0x15,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5237 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5238 static const BYTE ctlWithThisAndNextUpdate[] = {
5239 0x30,0x24,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5240 0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5241 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5242 static const BYTE ctlWithAlgId[] = {
5243 0x30,0x1b,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5244 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5245 static const BYTE ctlWithBogusEntry[] = {
5246 0x30,0x29,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5247 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x10,0x30,0x0e,0x04,
5248 0x01,0x01,0x31,0x09,0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,0x01 };
5249 static const BYTE ctlWithOneEntry[] = {
5250 0x30,0x2a,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5251 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x11,0x30,0x0f,0x04,
5252 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00 };
5253 static const BYTE ctlWithTwoEntries[] = {
5254 0x30,0x41,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5255 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x28,0x30,0x0f,0x04,
5256 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00,0x30,
5257 0x15,0x04,0x01,0x01,0x31,0x10,0x30,0x0e,0x06,0x02,0x2d,0x06,0x31,0x08,0x30,
5258 0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5260 static void test_encodeCTL(DWORD dwEncoding)
5262 static char oid1[] = "1.2.3";
5263 static char oid2[] = "1.5.6";
5269 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5270 CTL_ENTRY ctlEntry[2];
5271 CRYPT_ATTRIBUTE attr1, attr2;
5272 CRYPT_ATTR_BLOB value1, value2;
5274 memset(&info, 0, sizeof(info));
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(emptyCTL), "unexpected size %d\n", size);
5281 ok(!memcmp(buf, emptyCTL, size), "unexpected value\n");
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(emptyCTLWithVersion1), "unexpected size %d\n", size);
5292 ok(!memcmp(buf, emptyCTLWithVersion1, size), "unexpected value\n");
5297 info.SubjectUsage.cUsageIdentifier = 1;
5298 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5299 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5300 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5301 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5304 ok(size == sizeof(ctlWithUsageIdentifier), "unexpected size %d\n",
5306 ok(!memcmp(buf, ctlWithUsageIdentifier, size), "unexpected value\n");
5310 info.SubjectUsage.cUsageIdentifier = 0;
5311 info.ListIdentifier.cbData = sizeof(serialNum);
5312 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5313 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5314 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5315 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5318 ok(size == sizeof(ctlWithListIdentifier), "unexpected size %d\n", size);
5319 ok(!memcmp(buf, ctlWithListIdentifier, size), "unexpected value\n");
5323 info.ListIdentifier.cbData = 0;
5324 info.SequenceNumber.cbData = sizeof(serialNum);
5325 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5326 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5327 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5328 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5331 ok(size == sizeof(ctlWithSequenceNumber), "unexpected size %d\n",
5333 ok(!memcmp(buf, ctlWithSequenceNumber, size), "unexpected value\n");
5337 info.SequenceNumber.cbData = 0;
5338 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5339 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5340 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5341 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5344 ok(size == sizeof(ctlWithThisUpdate), "unexpected size %d\n", size);
5345 ok(!memcmp(buf, ctlWithThisUpdate, size), "unexpected value\n");
5349 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5350 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5351 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5352 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5355 ok(size == sizeof(ctlWithThisAndNextUpdate), "unexpected size %d\n",
5357 ok(!memcmp(buf, ctlWithThisAndNextUpdate, size), "unexpected value\n");
5361 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5362 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5363 info.SubjectAlgorithm.pszObjId = oid2;
5364 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5365 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5366 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5369 ok(size == sizeof(ctlWithAlgId), "unexpected size %d\n", size);
5370 ok(!memcmp(buf, ctlWithAlgId, size), "unexpected value\n");
5374 /* The value is supposed to be asn.1 encoded, so this'll fail to decode
5375 * (see tests below) but it'll encode fine.
5377 info.SubjectAlgorithm.pszObjId = NULL;
5378 value1.cbData = sizeof(serialNum);
5379 value1.pbData = (LPBYTE)serialNum;
5380 attr1.pszObjId = oid1;
5382 attr1.rgValue = &value1;
5383 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5384 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5385 ctlEntry[0].cAttribute = 1;
5386 ctlEntry[0].rgAttribute = &attr1;
5388 info.rgCTLEntry = ctlEntry;
5389 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5390 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5391 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5394 ok(size == sizeof(ctlWithBogusEntry), "unexpected size %d\n", size);
5395 ok(!memcmp(buf, ctlWithBogusEntry, size), "unexpected value\n");
5399 value1.cbData = sizeof(emptySequence);
5400 value1.pbData = (LPBYTE)emptySequence;
5401 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5402 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5403 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5406 ok(size == sizeof(ctlWithOneEntry), "unexpected size %d\n", size);
5407 ok(!memcmp(buf, ctlWithOneEntry, size), "unexpected value\n");
5411 value2.cbData = sizeof(encodedIPAddr);
5412 value2.pbData = (LPBYTE)encodedIPAddr;
5413 attr2.pszObjId = oid2;
5415 attr2.rgValue = &value2;
5416 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5417 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5418 ctlEntry[1].cAttribute = 1;
5419 ctlEntry[1].rgAttribute = &attr2;
5421 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5422 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5423 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5426 ok(size == sizeof(ctlWithTwoEntries), "unexpected size %d\n", size);
5427 ok(!memcmp(buf, ctlWithTwoEntries, size), "unexpected value\n");
5433 static void compareCTLInfo(LPCSTR header, const CTL_INFO *expected,
5434 const CTL_INFO *got)
5438 ok(expected->dwVersion == got->dwVersion,
5439 "%s: expected version %d, got %d\n", header, expected->dwVersion,
5441 ok(expected->SubjectUsage.cUsageIdentifier ==
5442 got->SubjectUsage.cUsageIdentifier,
5443 "%s: expected %d usage identifiers, got %d\n", header,
5444 expected->SubjectUsage.cUsageIdentifier,
5445 got->SubjectUsage.cUsageIdentifier);
5446 for (i = 0; i < expected->SubjectUsage.cUsageIdentifier; i++)
5447 ok(!strcmp(expected->SubjectUsage.rgpszUsageIdentifier[i],
5448 got->SubjectUsage.rgpszUsageIdentifier[i]),
5449 "%s[%d]: expected %s, got %s\n", header, i,
5450 expected->SubjectUsage.rgpszUsageIdentifier[i],
5451 got->SubjectUsage.rgpszUsageIdentifier[i]);
5452 ok(expected->ListIdentifier.cbData == got->ListIdentifier.cbData,
5453 "%s: expected list identifier of %d bytes, got %d\n", header,
5454 expected->ListIdentifier.cbData, got->ListIdentifier.cbData);
5455 if (expected->ListIdentifier.cbData)
5456 ok(!memcmp(expected->ListIdentifier.pbData, got->ListIdentifier.pbData,
5457 expected->ListIdentifier.cbData),
5458 "%s: unexpected list identifier value\n", header);
5459 ok(expected->SequenceNumber.cbData == got->SequenceNumber.cbData,
5460 "%s: expected sequence number of %d bytes, got %d\n", header,
5461 expected->SequenceNumber.cbData, got->SequenceNumber.cbData);
5462 if (expected->SequenceNumber.cbData)
5463 ok(!memcmp(expected->SequenceNumber.pbData, got->SequenceNumber.pbData,
5464 expected->SequenceNumber.cbData),
5465 "%s: unexpected sequence number value\n", header);
5466 ok(!memcmp(&expected->ThisUpdate, &got->ThisUpdate, sizeof(FILETIME)),
5467 "%s: expected this update = (%d, %d), got (%d, %d)\n", header,
5468 expected->ThisUpdate.dwLowDateTime, expected->ThisUpdate.dwHighDateTime,
5469 got->ThisUpdate.dwLowDateTime, got->ThisUpdate.dwHighDateTime);
5470 ok(!memcmp(&expected->NextUpdate, &got->NextUpdate, sizeof(FILETIME)),
5471 "%s: expected next update = (%d, %d), got (%d, %d)\n", header,
5472 expected->NextUpdate.dwLowDateTime, expected->NextUpdate.dwHighDateTime,
5473 got->NextUpdate.dwLowDateTime, got->NextUpdate.dwHighDateTime);
5474 if (expected->SubjectAlgorithm.pszObjId &&
5475 *expected->SubjectAlgorithm.pszObjId && !got->SubjectAlgorithm.pszObjId)
5476 ok(0, "%s: expected subject algorithm %s, got NULL\n", header,
5477 expected->SubjectAlgorithm.pszObjId);
5478 if (expected->SubjectAlgorithm.pszObjId && got->SubjectAlgorithm.pszObjId)
5479 ok(!strcmp(expected->SubjectAlgorithm.pszObjId,
5480 got->SubjectAlgorithm.pszObjId),
5481 "%s: expected subject algorithm %s, got %s\n", header,
5482 expected->SubjectAlgorithm.pszObjId, got->SubjectAlgorithm.pszObjId);
5483 ok(expected->SubjectAlgorithm.Parameters.cbData ==
5484 got->SubjectAlgorithm.Parameters.cbData,
5485 "%s: expected subject algorithm parameters of %d bytes, got %d\n", header,
5486 expected->SubjectAlgorithm.Parameters.cbData,
5487 got->SubjectAlgorithm.Parameters.cbData);
5488 if (expected->SubjectAlgorithm.Parameters.cbData)
5489 ok(!memcmp(expected->SubjectAlgorithm.Parameters.pbData,
5490 got->SubjectAlgorithm.Parameters.pbData,
5491 expected->SubjectAlgorithm.Parameters.cbData),
5492 "%s: unexpected subject algorithm parameter value\n", header);
5493 ok(expected->cCTLEntry == got->cCTLEntry,
5494 "%s: expected %d CTL entries, got %d\n", header, expected->cCTLEntry,
5496 for (i = 0; i < expected->cCTLEntry; i++)
5498 ok(expected->rgCTLEntry[i].SubjectIdentifier.cbData ==
5499 got->rgCTLEntry[i].SubjectIdentifier.cbData,
5500 "%s[%d]: expected subject identifier of %d bytes, got %d\n",
5501 header, i, expected->rgCTLEntry[i].SubjectIdentifier.cbData,
5502 got->rgCTLEntry[i].SubjectIdentifier.cbData);
5503 if (expected->rgCTLEntry[i].SubjectIdentifier.cbData)
5504 ok(!memcmp(expected->rgCTLEntry[i].SubjectIdentifier.pbData,
5505 got->rgCTLEntry[i].SubjectIdentifier.pbData,
5506 expected->rgCTLEntry[i].SubjectIdentifier.cbData),
5507 "%s[%d]: unexpected subject identifier value\n",
5509 for (j = 0; j < expected->rgCTLEntry[i].cAttribute; j++)
5511 ok(!strcmp(expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5512 got->rgCTLEntry[i].rgAttribute[j].pszObjId),
5513 "%s[%d][%d]: expected attribute OID %s, got %s\n", header, i, j,
5514 expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5515 got->rgCTLEntry[i].rgAttribute[j].pszObjId);
5516 for (k = 0; k < expected->rgCTLEntry[i].rgAttribute[j].cValue; k++)
5518 ok(expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData ==
5519 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5520 "%s[%d][%d][%d]: expected value of %d bytes, got %d\n",
5522 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5523 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData);
5524 if (expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData)
5526 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5527 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5528 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData),
5529 "%s[%d][%d][%d]: unexpected value\n",
5534 ok(expected->cExtension == got->cExtension,
5535 "%s: expected %d extensions, got %d\n", header, expected->cExtension,
5537 for (i = 0; i < expected->cExtension; i++)
5539 ok(!strcmp(expected->rgExtension[i].pszObjId,
5540 got->rgExtension[i].pszObjId), "%s[%d]: expected %s, got %s\n",
5541 header, i, expected->rgExtension[i].pszObjId,
5542 got->rgExtension[i].pszObjId);
5543 ok(expected->rgExtension[i].fCritical == got->rgExtension[i].fCritical,
5544 "%s[%d]: expected fCritical = %d, got %d\n", header, i,
5545 expected->rgExtension[i].fCritical, got->rgExtension[i].fCritical);
5546 ok(expected->rgExtension[i].Value.cbData ==
5547 got->rgExtension[i].Value.cbData,
5548 "%s[%d]: expected extension value to have %d bytes, got %d\n",
5549 header, i, expected->rgExtension[i].Value.cbData,
5550 got->rgExtension[i].Value.cbData);
5551 if (expected->rgExtension[i].Value.cbData)
5552 ok(!memcmp(expected->rgExtension[i].Value.pbData,
5553 got->rgExtension[i].Value.pbData,
5554 expected->rgExtension[i].Value.cbData),
5555 "%s[%d]: unexpected extension value\n", header, i);
5559 static const BYTE signedCTL[] = {
5560 0x30,0x81,0xc7,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
5561 0x81,0xb9,0x30,0x81,0xb6,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
5562 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x28,0x06,0x09,0x2a,0x86,
5563 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x1b,0x04,0x19,0x30,0x17,0x30,0x00,
5564 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5565 0x30,0x5a,0x30,0x02,0x06,0x00,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
5566 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
5567 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
5568 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5569 0x00,0x04,0x40,0xca,0xd8,0x32,0xd1,0xbd,0x97,0x61,0x54,0xd6,0x80,0xcf,0x0d,
5570 0xbd,0xa2,0x42,0xc7,0xca,0x37,0x91,0x7d,0x9d,0xac,0x8c,0xdf,0x05,0x8a,0x39,
5571 0xc6,0x07,0xc1,0x37,0xe6,0xb9,0xd1,0x0d,0x26,0xec,0xa5,0xb0,0x8a,0x51,0x26,
5572 0x2b,0x4f,0x73,0x44,0x86,0x83,0x5e,0x2b,0x6e,0xcc,0xf8,0x1b,0x85,0x53,0xe9,
5573 0x7a,0x80,0x8f,0x6b,0x42,0x19,0x93 };
5574 static const BYTE signedCTLWithCTLInnerContent[] = {
5575 0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
5576 0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
5577 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
5578 0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
5579 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5580 0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
5581 0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
5582 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
5583 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
5584 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
5585 0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
5586 0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
5587 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
5588 0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5589 0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
5590 0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
5591 0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
5592 0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
5593 0x57,0x6c,0x0b,0x47,0xb8 };
5595 static void test_decodeCTL(DWORD dwEncoding)
5597 static char oid1[] = "1.2.3";
5598 static char oid2[] = "1.5.6";
5599 static BYTE nullData[] = { 5,0 };
5605 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5606 CTL_ENTRY ctlEntry[2];
5607 CRYPT_ATTRIBUTE attr1, attr2;
5608 CRYPT_ATTR_BLOB value1, value2;
5610 memset(&info, 0, sizeof(info));
5611 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTL, sizeof(emptyCTL),
5612 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5613 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5616 compareCTLInfo("empty CTL", &info, (CTL_INFO *)buf);
5621 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTLWithVersion1,
5622 sizeof(emptyCTLWithVersion1), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
5624 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5627 compareCTLInfo("v1 CTL", &info, (CTL_INFO *)buf);
5632 info.SubjectUsage.cUsageIdentifier = 1;
5633 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5634 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithUsageIdentifier,
5635 sizeof(ctlWithUsageIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5637 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5640 compareCTLInfo("CTL with usage identifier", &info, (CTL_INFO *)buf);
5644 info.SubjectUsage.cUsageIdentifier = 0;
5645 info.ListIdentifier.cbData = sizeof(serialNum);
5646 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5647 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithListIdentifier,
5648 sizeof(ctlWithListIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5649 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5652 compareCTLInfo("CTL with list identifier", &info, (CTL_INFO *)buf);
5656 info.ListIdentifier.cbData = 0;
5657 info.SequenceNumber.cbData = sizeof(serialNum);
5658 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5659 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithSequenceNumber,
5660 sizeof(ctlWithSequenceNumber), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5661 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5664 compareCTLInfo("CTL with sequence number", &info, (CTL_INFO *)buf);
5668 info.SequenceNumber.cbData = 0;
5669 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5670 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisUpdate,
5671 sizeof(ctlWithThisUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5672 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5675 compareCTLInfo("CTL with this update", &info, (CTL_INFO *)buf);
5679 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5680 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisAndNextUpdate,
5681 sizeof(ctlWithThisAndNextUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5683 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5686 compareCTLInfo("CTL with this and next update", &info, (CTL_INFO *)buf);
5690 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5691 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5692 info.SubjectAlgorithm.pszObjId = oid2;
5693 info.SubjectAlgorithm.Parameters.cbData = sizeof(nullData);
5694 info.SubjectAlgorithm.Parameters.pbData = nullData;
5695 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithAlgId,
5696 sizeof(ctlWithAlgId), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5697 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5700 compareCTLInfo("CTL with algorithm identifier", &info, (CTL_INFO *)buf);
5704 SetLastError(0xdeadbeef);
5705 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithBogusEntry,
5706 sizeof(ctlWithBogusEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5708 (GetLastError() == CRYPT_E_ASN1_EOD ||
5709 GetLastError() == CRYPT_E_ASN1_CORRUPT ||
5710 GetLastError() == OSS_MORE_INPUT), /* Win9x */
5711 "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n",
5713 info.SubjectAlgorithm.Parameters.cbData = 0;
5714 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5715 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5716 info.SubjectAlgorithm.pszObjId = oid2;
5717 info.SubjectAlgorithm.pszObjId = NULL;
5718 value1.cbData = sizeof(emptySequence);
5719 value1.pbData = (LPBYTE)emptySequence;
5720 attr1.pszObjId = oid1;
5722 attr1.rgValue = &value1;
5723 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5724 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5725 ctlEntry[0].cAttribute = 1;
5726 ctlEntry[0].rgAttribute = &attr1;
5728 info.rgCTLEntry = ctlEntry;
5729 SetLastError(0xdeadbeef);
5730 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithOneEntry,
5731 sizeof(ctlWithOneEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5732 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5735 compareCTLInfo("CTL with one entry", &info, (CTL_INFO *)buf);
5739 value2.cbData = sizeof(encodedIPAddr);
5740 value2.pbData = (LPBYTE)encodedIPAddr;
5741 attr2.pszObjId = oid2;
5743 attr2.rgValue = &value2;
5744 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5745 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5746 ctlEntry[1].cAttribute = 1;
5747 ctlEntry[1].rgAttribute = &attr2;
5749 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithTwoEntries,
5750 sizeof(ctlWithTwoEntries), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5751 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5754 compareCTLInfo("CTL with two entries", &info, (CTL_INFO *)buf);
5758 /* A signed CTL isn't decodable, even if the inner content is a CTL */
5759 SetLastError(0xdeadbeef);
5760 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, signedCTL,
5761 sizeof(signedCTL), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5762 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5763 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5764 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5766 SetLastError(0xdeadbeef);
5767 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL,
5768 signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent),
5769 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5770 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5771 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5772 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5776 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
5777 static const BYTE emptyPKCSContentInfoExtraBytes[] = { 0x30,0x04,0x06,0x02,0x2a,
5779 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
5781 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
5782 0x03,0x02,0x01,0x01 };
5783 static BYTE bogusDER[] = { 1 };
5785 static void test_encodePKCSContentInfo(DWORD dwEncoding)
5790 CRYPT_CONTENT_INFO info = { 0 };
5791 char oid1[] = "1.2.3";
5795 /* Crashes on win9x */
5796 SetLastError(0xdeadbeef);
5797 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL,
5798 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5799 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5800 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5802 SetLastError(0xdeadbeef);
5803 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5804 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5805 ok(!ret && (GetLastError() == E_INVALIDARG ||
5806 GetLastError() == OSS_LIMITED /* Win9x */),
5807 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5808 info.pszObjId = oid1;
5809 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5810 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5811 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5814 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size);
5815 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n");
5818 info.Content.pbData = bogusDER;
5819 info.Content.cbData = sizeof(bogusDER);
5820 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5821 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5822 ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError());
5825 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size);
5826 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n");
5829 info.Content.pbData = (BYTE *)ints[0].encoded;
5830 info.Content.cbData = ints[0].encoded[1] + 2;
5831 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5832 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5835 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size);
5836 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n");
5841 static const BYTE indefiniteSignedPKCSContent[] = {
5842 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
5843 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
5844 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
5845 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
5846 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
5847 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
5848 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5849 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5850 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
5851 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5852 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5853 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
5854 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
5855 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
5856 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
5857 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
5858 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
5859 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
5860 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
5861 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5862 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5863 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
5864 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
5865 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
5866 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
5867 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
5868 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
5869 0x00,0x00,0x00,0x00,0x00,0x00 };
5871 static void test_decodePKCSContentInfo(DWORD dwEncoding)
5876 CRYPT_CONTENT_INFO *info;
5878 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5879 emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo),
5880 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5881 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5884 info = (CRYPT_CONTENT_INFO *)buf;
5886 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5888 ok(info->Content.cbData == 0, "Expected no data, got %d\n",
5889 info->Content.cbData);
5892 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5893 emptyPKCSContentInfoExtraBytes, sizeof(emptyPKCSContentInfoExtraBytes),
5894 0, NULL, NULL, &size);
5895 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5896 SetLastError(0xdeadbeef);
5897 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5898 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo),
5899 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5900 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5901 * I doubt an app depends on that.
5903 ok((!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5904 GetLastError() == CRYPT_E_ASN1_CORRUPT)) || broken(ret),
5905 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5907 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5908 intPKCSContentInfo, sizeof(intPKCSContentInfo),
5909 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5910 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5913 info = (CRYPT_CONTENT_INFO *)buf;
5915 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5917 ok(info->Content.cbData == ints[0].encoded[1] + 2,
5918 "Unexpected size %d\n", info->Content.cbData);
5919 ok(!memcmp(info->Content.pbData, ints[0].encoded,
5920 info->Content.cbData), "Unexpected value\n");
5923 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5924 indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent),
5925 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5926 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5929 info = (CRYPT_CONTENT_INFO *)buf;
5931 ok(!strcmp(info->pszObjId, szOID_RSA_signedData),
5932 "Expected %s, got %s\n", szOID_RSA_signedData, info->pszObjId);
5933 ok(info->Content.cbData == 392, "Expected 392, got %d\n",
5934 info->Content.cbData);
5939 static const BYTE emptyPKCSAttr[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
5941 static const BYTE bogusPKCSAttr[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
5943 static const BYTE intPKCSAttr[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
5946 static void test_encodePKCSAttribute(DWORD dwEncoding)
5948 CRYPT_ATTRIBUTE attr = { 0 };
5952 CRYPT_ATTR_BLOB blob;
5953 char oid[] = "1.2.3";
5957 /* Crashes on win9x */
5958 SetLastError(0xdeadbeef);
5959 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, NULL,
5960 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5961 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5962 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5964 SetLastError(0xdeadbeef);
5965 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5966 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5967 ok(!ret && (GetLastError() == E_INVALIDARG ||
5968 GetLastError() == OSS_LIMITED /* Win9x */),
5969 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5970 attr.pszObjId = oid;
5971 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5972 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5973 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5976 ok(size == sizeof(emptyPKCSAttr), "Unexpected size %d\n", size);
5977 ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n");
5980 blob.cbData = sizeof(bogusDER);
5981 blob.pbData = bogusDER;
5983 attr.rgValue = &blob;
5984 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5985 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5986 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5989 ok(size == sizeof(bogusPKCSAttr), "Unexpected size %d\n", size);
5990 ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n");
5993 blob.pbData = (BYTE *)ints[0].encoded;
5994 blob.cbData = ints[0].encoded[1] + 2;
5995 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5996 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5999 ok(size == sizeof(intPKCSAttr), "Unexpected size %d\n", size);
6000 ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n");
6005 static void test_decodePKCSAttribute(DWORD dwEncoding)
6010 CRYPT_ATTRIBUTE *attr;
6012 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
6013 emptyPKCSAttr, sizeof(emptyPKCSAttr),
6014 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6015 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6018 attr = (CRYPT_ATTRIBUTE *)buf;
6020 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
6022 ok(attr->cValue == 0, "Expected no value, got %d\n", attr->cValue);
6025 SetLastError(0xdeadbeef);
6026 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
6027 bogusPKCSAttr, sizeof(bogusPKCSAttr),
6028 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6029 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
6030 * I doubt an app depends on that.
6032 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
6033 GetLastError() == CRYPT_E_ASN1_CORRUPT ||
6034 GetLastError() == OSS_MORE_INPUT /* Win9x */),
6035 "Expected CRYPT_E_ASN1_EOD, CRYPT_E_ASN1_CORRUPT, or OSS_MORE_INPUT, got %x\n",
6037 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
6038 intPKCSAttr, sizeof(intPKCSAttr),
6039 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6040 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6043 attr = (CRYPT_ATTRIBUTE *)buf;
6045 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
6047 ok(attr->cValue == 1, "Expected 1 value, got %d\n", attr->cValue);
6048 ok(attr->rgValue[0].cbData == ints[0].encoded[1] + 2,
6049 "Unexpected size %d\n", attr->rgValue[0].cbData);
6050 ok(!memcmp(attr->rgValue[0].pbData, ints[0].encoded,
6051 attr->rgValue[0].cbData), "Unexpected value\n");
6056 static const BYTE emptyPKCSAttributes[] = { 0x31,0x00 };
6057 static const BYTE singlePKCSAttributes[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
6058 0x2a,0x03,0x31,0x00 };
6059 static const BYTE doublePKCSAttributes[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
6060 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
6062 static void test_encodePKCSAttributes(DWORD dwEncoding)
6064 CRYPT_ATTRIBUTES attributes = { 0 };
6065 CRYPT_ATTRIBUTE attr[2] = { { 0 } };
6066 CRYPT_ATTR_BLOB blob;
6070 char oid1[] = "1.2.3", oid2[] = "1.5.6";
6072 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6073 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6074 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6077 ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %d\n", size);
6078 ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n");
6081 attributes.cAttr = 1;
6082 attributes.rgAttr = attr;
6083 SetLastError(0xdeadbeef);
6084 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6085 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6086 ok(!ret && (GetLastError() == E_INVALIDARG ||
6087 GetLastError() == OSS_LIMITED /* Win9x */),
6088 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6089 attr[0].pszObjId = oid1;
6090 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6091 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6094 ok(size == sizeof(singlePKCSAttributes), "Unexpected size %d\n", size);
6095 ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n");
6098 attr[1].pszObjId = oid2;
6100 attr[1].rgValue = &blob;
6101 blob.pbData = (BYTE *)ints[0].encoded;
6102 blob.cbData = ints[0].encoded[1] + 2;
6103 attributes.cAttr = 2;
6104 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6105 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6106 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6109 ok(size == sizeof(doublePKCSAttributes), "Unexpected size %d\n", size);
6110 ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n");
6115 static void test_decodePKCSAttributes(DWORD dwEncoding)
6120 CRYPT_ATTRIBUTES *attributes;
6122 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6123 emptyPKCSAttributes, sizeof(emptyPKCSAttributes),
6124 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6125 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6128 attributes = (CRYPT_ATTRIBUTES *)buf;
6129 ok(attributes->cAttr == 0, "Expected no attributes, got %d\n",
6133 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6134 singlePKCSAttributes, sizeof(singlePKCSAttributes),
6135 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6136 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6139 attributes = (CRYPT_ATTRIBUTES *)buf;
6140 ok(attributes->cAttr == 1, "Expected 1 attribute, got %d\n",
6142 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
6143 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
6144 ok(attributes->rgAttr[0].cValue == 0,
6145 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
6148 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6149 doublePKCSAttributes, sizeof(doublePKCSAttributes),
6150 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6151 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6154 attributes = (CRYPT_ATTRIBUTES *)buf;
6155 ok(attributes->cAttr == 2, "Expected 2 attributes, got %d\n",
6157 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
6158 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
6159 ok(attributes->rgAttr[0].cValue == 0,
6160 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
6161 ok(!strcmp(attributes->rgAttr[1].pszObjId, "1.5.6"),
6162 "Expected 1.5.6, got %s\n", attributes->rgAttr[1].pszObjId);
6163 ok(attributes->rgAttr[1].cValue == 1,
6164 "Expected 1 attribute, got %d\n", attributes->rgAttr[1].cValue);
6165 ok(attributes->rgAttr[1].rgValue[0].cbData == ints[0].encoded[1] + 2,
6166 "Unexpected size %d\n", attributes->rgAttr[1].rgValue[0].cbData);
6167 ok(!memcmp(attributes->rgAttr[1].rgValue[0].pbData, ints[0].encoded,
6168 attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n");
6173 static const BYTE singleCapability[] = {
6174 0x30,0x06,0x30,0x04,0x06,0x02,0x2d,0x06 };
6175 static const BYTE twoCapabilities[] = {
6176 0x30,0x0c,0x30,0x04,0x06,0x02,0x2d,0x06,0x30,0x04,0x06,0x02,0x2a,0x03 };
6177 static const BYTE singleCapabilitywithNULL[] = {
6178 0x30,0x08,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
6180 static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding)
6182 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6186 CRYPT_SMIME_CAPABILITY capability[2];
6187 CRYPT_SMIME_CAPABILITIES capabilities;
6189 /* An empty capabilities is allowed */
6190 capabilities.cCapability = 0;
6191 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6192 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6193 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6196 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
6197 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
6200 /* A non-empty capabilities with an empty capability (lacking an OID) is
6203 capability[0].pszObjId = NULL;
6204 capability[0].Parameters.cbData = 0;
6205 capabilities.cCapability = 1;
6206 capabilities.rgCapability = capability;
6207 SetLastError(0xdeadbeef);
6208 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6209 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6210 ok(!ret && (GetLastError() == E_INVALIDARG ||
6211 GetLastError() == OSS_LIMITED /* Win9x */),
6212 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6213 capability[0].pszObjId = oid1;
6214 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6215 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6216 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6219 ok(size == sizeof(singleCapability), "unexpected size %d\n", size);
6220 ok(!memcmp(buf, singleCapability, size), "unexpected value\n");
6223 capability[1].pszObjId = oid2;
6224 capability[1].Parameters.cbData = 0;
6225 capabilities.cCapability = 2;
6226 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6227 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6228 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6231 ok(size == sizeof(twoCapabilities), "unexpected size %d\n", size);
6232 ok(!memcmp(buf, twoCapabilities, size), "unexpected value\n");
6237 static void compareSMimeCapabilities(LPCSTR header,
6238 const CRYPT_SMIME_CAPABILITIES *expected, const CRYPT_SMIME_CAPABILITIES *got)
6242 ok(got->cCapability == expected->cCapability,
6243 "%s: expected %d capabilities, got %d\n", header, expected->cCapability,
6245 for (i = 0; i < expected->cCapability; i++)
6247 ok(!strcmp(expected->rgCapability[i].pszObjId,
6248 got->rgCapability[i].pszObjId), "%s[%d]: expected %s, got %s\n",
6249 header, i, expected->rgCapability[i].pszObjId,
6250 got->rgCapability[i].pszObjId);
6251 ok(expected->rgCapability[i].Parameters.cbData ==
6252 got->rgCapability[i].Parameters.cbData,
6253 "%s[%d]: expected %d bytes, got %d\n", header, i,
6254 expected->rgCapability[i].Parameters.cbData,
6255 got->rgCapability[i].Parameters.cbData);
6256 if (expected->rgCapability[i].Parameters.cbData)
6257 ok(!memcmp(expected->rgCapability[i].Parameters.pbData,
6258 got->rgCapability[i].Parameters.pbData,
6259 expected->rgCapability[i].Parameters.cbData),
6260 "%s[%d]: unexpected value\n", header, i);
6264 static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding)
6266 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6269 CRYPT_SMIME_CAPABILITY capability[2];
6270 CRYPT_SMIME_CAPABILITIES capabilities, *ptr;
6272 SetLastError(0xdeadbeef);
6273 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6274 emptySequence, sizeof(emptySequence),
6275 CRYPT_DECODE_ALLOC_FLAG, NULL, &ptr, &size);
6276 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6279 capabilities.cCapability = 0;
6280 compareSMimeCapabilities("empty capabilities", &capabilities, ptr);
6283 SetLastError(0xdeadbeef);
6284 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6285 singleCapability, sizeof(singleCapability), CRYPT_DECODE_ALLOC_FLAG, NULL,
6287 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6290 capability[0].pszObjId = oid1;
6291 capability[0].Parameters.cbData = 0;
6292 capabilities.cCapability = 1;
6293 capabilities.rgCapability = capability;
6294 compareSMimeCapabilities("single capability", &capabilities, ptr);
6297 SetLastError(0xdeadbeef);
6298 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6299 singleCapabilitywithNULL, sizeof(singleCapabilitywithNULL),
6300 CRYPT_DECODE_ALLOC_FLAG, NULL, &ptr, &size);
6301 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6304 BYTE NULLparam[] = {0x05, 0x00};
6305 capability[0].pszObjId = oid1;
6306 capability[0].Parameters.cbData = 2;
6307 capability[0].Parameters.pbData = NULLparam;
6308 capabilities.cCapability = 1;
6309 capabilities.rgCapability = capability;
6310 compareSMimeCapabilities("single capability with NULL", &capabilities,
6314 SetLastError(0xdeadbeef);
6315 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6316 twoCapabilities, sizeof(twoCapabilities), CRYPT_DECODE_ALLOC_FLAG, NULL,
6318 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6321 capability[0].Parameters.cbData = 0;
6322 capability[1].pszObjId = oid2;
6323 capability[1].Parameters.cbData = 0;
6324 capabilities.cCapability = 2;
6325 compareSMimeCapabilities("two capabilities", &capabilities, ptr);
6330 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
6331 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
6333 static const BYTE minimalPKCSSigner[] = {
6334 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6335 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6336 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6337 static const BYTE PKCSSignerWithSerial[] = {
6338 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6339 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6340 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
6342 static const BYTE PKCSSignerWithHashAlgo[] = {
6343 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6344 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6345 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
6347 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = {
6348 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6349 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6350 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6351 0x06,0x05,0x00,0x04,0x00 };
6352 static const BYTE PKCSSignerWithHash[] = {
6353 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6354 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6355 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6356 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
6357 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6358 static const BYTE PKCSSignerWithAuthAttr[] = {
6359 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6360 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6361 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
6362 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
6363 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
6364 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
6365 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6367 static void test_encodePKCSSignerInfo(DWORD dwEncoding)
6369 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6373 CMSG_SIGNER_INFO info = { 0 };
6374 char oid_common_name[] = szOID_COMMON_NAME;
6375 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
6376 (LPBYTE)encodedCommonName };
6377 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
6379 SetLastError(0xdeadbeef);
6380 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6381 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6382 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6384 skip("no PKCS7_SIGNER_INFO encode support\n");
6387 ok(!ret && (GetLastError() == E_INVALIDARG ||
6388 GetLastError() == OSS_LIMITED /* Win9x */),
6389 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6390 /* To be encoded, a signer must have an issuer at least, and the encoding
6391 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
6392 * see decoding tests.)
6394 info.Issuer.cbData = sizeof(encodedCommonNameNoNull);
6395 info.Issuer.pbData = encodedCommonNameNoNull;
6396 SetLastError(0xdeadbeef);
6397 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6398 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6399 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6400 ok(!ret && GetLastError() == E_INVALIDARG,
6401 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6404 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6405 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6408 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6409 if (size == sizeof(minimalPKCSSigner))
6410 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6412 ok(0, "Unexpected value\n");
6416 info.SerialNumber.cbData = sizeof(serialNum);
6417 info.SerialNumber.pbData = (BYTE *)serialNum;
6418 SetLastError(0xdeadbeef);
6419 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6420 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6421 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6422 ok(!ret && GetLastError() == E_INVALIDARG,
6423 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6426 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6427 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6430 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6432 if (size == sizeof(PKCSSignerWithSerial))
6433 ok(!memcmp(buf, PKCSSignerWithSerial, size),
6434 "Unexpected value\n");
6436 ok(0, "Unexpected value\n");
6440 info.HashAlgorithm.pszObjId = oid1;
6441 SetLastError(0xdeadbeef);
6442 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6443 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6444 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6445 ok(!ret && GetLastError() == E_INVALIDARG,
6446 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6449 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6450 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6453 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6455 if (size == sizeof(PKCSSignerWithHashAlgo))
6456 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6457 "Unexpected value\n");
6459 ok(0, "Unexpected value\n");
6463 info.HashEncryptionAlgorithm.pszObjId = oid2;
6464 SetLastError(0xdeadbeef);
6465 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6466 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6467 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6468 ok(!ret && GetLastError() == E_INVALIDARG,
6469 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6472 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6475 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6476 "Unexpected size %d\n", size);
6477 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo))
6478 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6479 "Unexpected value\n");
6481 ok(0, "Unexpected value\n");
6485 info.EncryptedHash.cbData = sizeof(hash);
6486 info.EncryptedHash.pbData = (BYTE *)hash;
6487 SetLastError(0xdeadbeef);
6488 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6489 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6490 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6491 ok(!ret && GetLastError() == E_INVALIDARG,
6492 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6495 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6498 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6500 if (size == sizeof(PKCSSignerWithHash))
6501 ok(!memcmp(buf, PKCSSignerWithHash, size),
6502 "Unexpected value\n");
6504 ok(0, "Unexpected value\n");
6508 info.AuthAttrs.cAttr = 1;
6509 info.AuthAttrs.rgAttr = &attr;
6510 SetLastError(0xdeadbeef);
6511 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6512 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6513 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6514 ok(!ret && GetLastError() == E_INVALIDARG,
6515 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6518 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6521 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
6523 if (size == sizeof(PKCSSignerWithAuthAttr))
6524 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
6525 "Unexpected value\n");
6527 ok(0, "Unexpected value\n");
6533 static void test_decodePKCSSignerInfo(DWORD dwEncoding)
6538 CMSG_SIGNER_INFO *info;
6540 /* A PKCS signer can't be decoded without a serial number. */
6541 SetLastError(0xdeadbeef);
6542 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6543 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6544 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6545 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
6546 GetLastError() == OSS_DATA_ERROR /* Win9x */),
6547 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %x\n",
6549 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6550 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6551 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6552 ok(ret || broken(GetLastError() == OSS_DATA_ERROR),
6553 "CryptDecodeObjectEx failed: %x\n", GetLastError());
6556 info = (CMSG_SIGNER_INFO *)buf;
6557 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6559 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6560 "Unexpected size %d\n", info->Issuer.cbData);
6561 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6562 info->Issuer.cbData), "Unexpected value\n");
6563 ok(info->SerialNumber.cbData == sizeof(serialNum),
6564 "Unexpected size %d\n", info->SerialNumber.cbData);
6565 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6566 "Unexpected value\n");
6569 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6570 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6571 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6574 info = (CMSG_SIGNER_INFO *)buf;
6575 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6577 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6578 "Unexpected size %d\n", info->Issuer.cbData);
6579 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6580 info->Issuer.cbData), "Unexpected value\n");
6581 ok(info->SerialNumber.cbData == sizeof(serialNum),
6582 "Unexpected size %d\n", info->SerialNumber.cbData);
6583 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6584 "Unexpected value\n");
6585 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6586 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6589 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6590 PKCSSignerWithHashAndEncryptionAlgo,
6591 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6595 info = (CMSG_SIGNER_INFO *)buf;
6596 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6598 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6599 "Unexpected size %d\n", info->Issuer.cbData);
6600 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6601 info->Issuer.cbData), "Unexpected value\n");
6602 ok(info->SerialNumber.cbData == sizeof(serialNum),
6603 "Unexpected size %d\n", info->SerialNumber.cbData);
6604 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6605 "Unexpected value\n");
6606 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6607 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6608 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6609 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6612 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6613 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6614 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6617 info = (CMSG_SIGNER_INFO *)buf;
6618 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6620 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6621 "Unexpected size %d\n", info->Issuer.cbData);
6622 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6623 info->Issuer.cbData), "Unexpected value\n");
6624 ok(info->SerialNumber.cbData == sizeof(serialNum),
6625 "Unexpected size %d\n", info->SerialNumber.cbData);
6626 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6627 "Unexpected value\n");
6628 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6629 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6630 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6631 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6632 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6633 info->EncryptedHash.cbData);
6634 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6635 "Unexpected value\n");
6638 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6639 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
6640 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6643 info = (CMSG_SIGNER_INFO *)buf;
6644 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n",
6645 info->AuthAttrs.cAttr);
6646 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
6647 "Expected %s, got %s\n", szOID_COMMON_NAME,
6648 info->AuthAttrs.rgAttr[0].pszObjId);
6649 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
6650 info->AuthAttrs.rgAttr[0].cValue);
6651 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
6652 sizeof(encodedCommonName), "Unexpected size %d\n",
6653 info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
6654 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
6655 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
6660 static const BYTE CMSSignerWithKeyId[] = {
6661 0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,
6662 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6664 static void test_encodeCMSSignerInfo(DWORD dwEncoding)
6669 CMSG_CMS_SIGNER_INFO info = { 0 };
6670 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6672 SetLastError(0xdeadbeef);
6673 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6674 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6675 ok(!ret, "Expected failure, got %d\n", ret);
6676 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6678 skip("no CMS_SIGNER_INFO encode support\n");
6681 ok(GetLastError() == E_INVALIDARG,
6682 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6683 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6684 SetLastError(0xdeadbeef);
6685 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6686 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6687 ok(!ret, "Expected failure, got %d\n", ret);
6688 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6690 skip("no CMS_SIGNER_INFO encode support\n");
6693 ok(GetLastError() == E_INVALIDARG,
6694 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6695 /* To be encoded, a signer must have a valid cert ID, where a valid ID may
6696 * be a key id or a issuer serial number with at least the issuer set, and
6697 * the encoding must include PKCS_7_ASN_ENCODING.
6698 * (That isn't enough to be decoded, see decoding tests.)
6700 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6701 sizeof(encodedCommonNameNoNull);
6702 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6703 SetLastError(0xdeadbeef);
6704 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6705 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6706 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6707 ok(!ret && GetLastError() == E_INVALIDARG,
6708 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6711 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6714 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6715 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6719 U(info.SignerId).IssuerSerialNumber.SerialNumber.cbData = sizeof(serialNum);
6720 U(info.SignerId).IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
6721 SetLastError(0xdeadbeef);
6722 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6723 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6724 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6725 ok(!ret && GetLastError() == E_INVALIDARG,
6726 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6729 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6732 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6734 ok(!memcmp(buf, PKCSSignerWithSerial, size), "Unexpected value\n");
6738 info.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
6739 U(info.SignerId).KeyId.cbData = sizeof(serialNum);
6740 U(info.SignerId).KeyId.pbData = (BYTE *)serialNum;
6741 SetLastError(0xdeadbeef);
6742 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6743 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6744 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6745 ok(!ret && GetLastError() == E_INVALIDARG,
6746 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6749 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6752 ok(size == sizeof(CMSSignerWithKeyId), "Unexpected size %d\n",
6754 ok(!memcmp(buf, CMSSignerWithKeyId, size), "Unexpected value\n");
6758 /* While a CERT_ID can have a hash type, that's not allowed in CMS, where
6759 * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed
6760 * (see RFC 3852, section 5.3.)
6762 info.SignerId.dwIdChoice = CERT_ID_SHA1_HASH;
6763 U(info.SignerId).HashId.cbData = sizeof(hash);
6764 U(info.SignerId).HashId.pbData = (BYTE *)hash;
6765 SetLastError(0xdeadbeef);
6766 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6767 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6768 ok(!ret && GetLastError() == E_INVALIDARG,
6769 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6770 /* Now with a hash algo */
6771 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6772 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6773 sizeof(encodedCommonNameNoNull);
6774 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6775 info.HashAlgorithm.pszObjId = oid1;
6776 SetLastError(0xdeadbeef);
6777 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6778 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6779 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6780 ok(!ret && GetLastError() == E_INVALIDARG,
6781 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6784 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6787 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6789 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6790 "Unexpected value\n");
6794 info.HashEncryptionAlgorithm.pszObjId = oid2;
6795 SetLastError(0xdeadbeef);
6796 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6797 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6798 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6799 ok(!ret && GetLastError() == E_INVALIDARG,
6800 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6803 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6806 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6807 "Unexpected size %d\n", size);
6808 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6809 "Unexpected value\n");
6813 info.EncryptedHash.cbData = sizeof(hash);
6814 info.EncryptedHash.pbData = (BYTE *)hash;
6815 SetLastError(0xdeadbeef);
6816 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6817 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6818 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6819 ok(!ret && GetLastError() == E_INVALIDARG,
6820 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6823 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6826 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6828 ok(!memcmp(buf, PKCSSignerWithHash, size), "Unexpected value\n");
6834 static void test_decodeCMSSignerInfo(DWORD dwEncoding)
6839 CMSG_CMS_SIGNER_INFO *info;
6840 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6842 /* A CMS signer can't be decoded without a serial number. */
6843 SetLastError(0xdeadbeef);
6844 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6845 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6846 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6847 ok(!ret, "expected failure\n");
6848 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6850 skip("no CMS_SIGNER_INFO decode support\n");
6853 ok(GetLastError() == CRYPT_E_ASN1_CORRUPT,
6854 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
6855 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6856 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6857 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6858 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6861 info = (CMSG_CMS_SIGNER_INFO *)buf;
6862 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6864 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6865 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6866 info->SignerId.dwIdChoice);
6867 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6868 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6869 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6870 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6871 encodedCommonNameNoNull,
6872 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6873 "Unexpected value\n");
6874 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6875 sizeof(serialNum), "Unexpected size %d\n",
6876 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6877 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6878 serialNum, sizeof(serialNum)), "Unexpected value\n");
6881 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6882 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6883 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6884 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6887 info = (CMSG_CMS_SIGNER_INFO *)buf;
6888 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6890 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6891 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6892 info->SignerId.dwIdChoice);
6893 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6894 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6895 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6896 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6897 encodedCommonNameNoNull,
6898 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6899 "Unexpected value\n");
6900 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6901 sizeof(serialNum), "Unexpected size %d\n",
6902 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6903 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6904 serialNum, sizeof(serialNum)), "Unexpected value\n");
6905 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6906 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6909 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6910 PKCSSignerWithHashAndEncryptionAlgo,
6911 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
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_ISSUER_SERIAL_NUMBER,
6920 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6921 info->SignerId.dwIdChoice);
6922 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6923 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6924 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6925 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6926 encodedCommonNameNoNull,
6927 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6928 "Unexpected value\n");
6929 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6930 sizeof(serialNum), "Unexpected size %d\n",
6931 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6932 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6933 serialNum, sizeof(serialNum)), "Unexpected value\n");
6934 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6935 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6936 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6937 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6940 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6941 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6942 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6943 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6946 info = (CMSG_CMS_SIGNER_INFO *)buf;
6947 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6949 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6950 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6951 info->SignerId.dwIdChoice);
6952 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6953 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6954 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6955 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6956 encodedCommonNameNoNull,
6957 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6958 "Unexpected value\n");
6959 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6960 sizeof(serialNum), "Unexpected size %d\n",
6961 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6962 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6963 serialNum, sizeof(serialNum)), "Unexpected value\n");
6964 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6965 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6966 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6967 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6968 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6969 info->EncryptedHash.cbData);
6970 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6971 "Unexpected value\n");
6974 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6975 CMSSignerWithKeyId, sizeof(CMSSignerWithKeyId),
6976 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6977 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6980 info = (CMSG_CMS_SIGNER_INFO *)buf;
6981 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6983 ok(info->SignerId.dwIdChoice == CERT_ID_KEY_IDENTIFIER,
6984 "Expected CERT_ID_KEY_IDENTIFIER, got %d\n",
6985 info->SignerId.dwIdChoice);
6986 ok(U(info->SignerId).KeyId.cbData == sizeof(serialNum),
6987 "Unexpected size %d\n", U(info->SignerId).KeyId.cbData);
6988 ok(!memcmp(U(info->SignerId).KeyId.pbData, serialNum, sizeof(serialNum)),
6989 "Unexpected value\n");
6994 static BYTE emptyDNSPermittedConstraints[] = {
6995 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
6996 static BYTE emptyDNSExcludedConstraints[] = {
6997 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
6998 static BYTE DNSExcludedConstraints[] = {
6999 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
7000 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7001 static BYTE permittedAndExcludedConstraints[] = {
7002 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7003 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
7004 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7005 static BYTE permittedAndExcludedWithMinConstraints[] = {
7006 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7007 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
7008 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7009 static BYTE permittedAndExcludedWithMinMaxConstraints[] = {
7010 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7011 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
7012 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7014 static void test_encodeNameConstraints(DWORD dwEncoding)
7017 CERT_NAME_CONSTRAINTS_INFO constraints = { 0 };
7018 CERT_GENERAL_SUBTREE permitted = { { 0 } };
7019 CERT_GENERAL_SUBTREE excluded = { { 0 } };
7023 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7024 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7025 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7027 skip("no X509_NAME_CONSTRAINTS encode support\n");
7030 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7033 ok(size == sizeof(emptySequence), "Unexpected size\n");
7034 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
7037 constraints.cPermittedSubtree = 1;
7038 constraints.rgPermittedSubtree = &permitted;
7039 SetLastError(0xdeadbeef);
7040 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7041 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7042 ok(!ret && GetLastError() == E_INVALIDARG,
7043 "Expected E_INVALIDARG, got %08x\n", GetLastError());
7044 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
7045 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7046 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7047 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7050 ok(size == sizeof(emptyDNSPermittedConstraints), "Unexpected size\n");
7051 ok(!memcmp(buf, emptyDNSPermittedConstraints, size),
7052 "Unexpected value\n");
7055 constraints.cPermittedSubtree = 0;
7056 constraints.cExcludedSubtree = 1;
7057 constraints.rgExcludedSubtree = &excluded;
7058 excluded.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
7059 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7060 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7061 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7064 ok(size == sizeof(emptyDNSExcludedConstraints), "Unexpected size\n");
7065 ok(!memcmp(buf, emptyDNSExcludedConstraints, size),
7066 "Unexpected value\n");
7069 U(excluded.Base).pwszURL = (LPWSTR)url;
7070 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7071 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7072 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7075 ok(size == sizeof(DNSExcludedConstraints), "Unexpected size\n");
7076 ok(!memcmp(buf, DNSExcludedConstraints, size),
7077 "Unexpected value\n");
7080 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
7081 U(permitted.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7082 U(permitted.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7083 constraints.cPermittedSubtree = 1;
7084 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7085 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7086 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7089 ok(size == sizeof(permittedAndExcludedConstraints),
7090 "Unexpected size\n");
7091 ok(!memcmp(buf, permittedAndExcludedConstraints, size),
7092 "Unexpected value\n");
7095 permitted.dwMinimum = 5;
7096 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7097 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7098 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7101 ok(size == sizeof(permittedAndExcludedWithMinConstraints),
7102 "Unexpected size\n");
7103 ok(!memcmp(buf, permittedAndExcludedWithMinConstraints, size),
7104 "Unexpected value\n");
7107 permitted.fMaximum = TRUE;
7108 permitted.dwMaximum = 3;
7109 SetLastError(0xdeadbeef);
7110 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7111 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7112 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7115 ok(size == sizeof(permittedAndExcludedWithMinMaxConstraints),
7116 "Unexpected size\n");
7117 ok(!memcmp(buf, permittedAndExcludedWithMinMaxConstraints, size),
7118 "Unexpected value\n");
7123 struct EncodedNameConstraints
7125 CRYPT_DATA_BLOB encoded;
7126 CERT_NAME_CONSTRAINTS_INFO constraints;
7129 static CERT_GENERAL_SUBTREE emptyDNSSubtree = {
7130 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
7131 static CERT_GENERAL_SUBTREE DNSSubtree = {
7132 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
7133 static CERT_GENERAL_SUBTREE IPAddressSubtree = {
7134 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 0 };
7135 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree = {
7136 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, 0 };
7137 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree = {
7138 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, TRUE, 3 };
7140 struct EncodedNameConstraints encodedNameConstraints[] = {
7141 { { sizeof(emptySequence), (LPBYTE)emptySequence }, { 0 } },
7142 { { sizeof(emptyDNSPermittedConstraints), emptyDNSPermittedConstraints },
7143 { 1, &emptyDNSSubtree, 0, NULL } },
7144 { { sizeof(emptyDNSExcludedConstraints), emptyDNSExcludedConstraints },
7145 { 0, NULL, 1, &emptyDNSSubtree } },
7146 { { sizeof(DNSExcludedConstraints), DNSExcludedConstraints },
7147 { 0, NULL, 1, &DNSSubtree } },
7148 { { sizeof(permittedAndExcludedConstraints), permittedAndExcludedConstraints },
7149 { 1, &IPAddressSubtree, 1, &DNSSubtree } },
7150 { { sizeof(permittedAndExcludedWithMinConstraints),
7151 permittedAndExcludedWithMinConstraints },
7152 { 1, &IPAddressWithMinSubtree, 1, &DNSSubtree } },
7153 { { sizeof(permittedAndExcludedWithMinMaxConstraints),
7154 permittedAndExcludedWithMinMaxConstraints },
7155 { 1, &IPAddressWithMinMaxSubtree, 1, &DNSSubtree } },
7158 static void test_decodeNameConstraints(DWORD dwEncoding)
7162 CERT_NAME_CONSTRAINTS_INFO *constraints;
7164 U(DNSSubtree.Base).pwszURL = (LPWSTR)url;
7165 U(IPAddressSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7166 U(IPAddressSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7167 U(IPAddressWithMinSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7168 U(IPAddressWithMinSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7169 U(IPAddressWithMinMaxSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7170 U(IPAddressWithMinMaxSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7172 i < sizeof(encodedNameConstraints) / sizeof(encodedNameConstraints[0]);
7177 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS,
7178 encodedNameConstraints[i].encoded.pbData,
7179 encodedNameConstraints[i].encoded.cbData,
7180 CRYPT_DECODE_ALLOC_FLAG, NULL, &constraints, &size);
7181 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7183 skip("no X509_NAME_CONSTRAINTS decode support\n");
7186 ok(ret, "%d: CryptDecodeObjectEx failed: %08x\n", i, GetLastError());
7191 if (constraints->cPermittedSubtree !=
7192 encodedNameConstraints[i].constraints.cPermittedSubtree)
7193 fprintf(stderr, "%d: expected %d permitted, got %d\n", i,
7194 encodedNameConstraints[i].constraints.cPermittedSubtree,
7195 constraints->cPermittedSubtree);
7196 if (constraints->cPermittedSubtree ==
7197 encodedNameConstraints[i].constraints.cPermittedSubtree)
7199 for (j = 0; j < constraints->cPermittedSubtree; j++)
7201 compareAltNameEntry(&constraints->rgPermittedSubtree[j].Base,
7202 &encodedNameConstraints[i].constraints.rgPermittedSubtree[j].Base);
7205 if (constraints->cExcludedSubtree !=
7206 encodedNameConstraints[i].constraints.cExcludedSubtree)
7207 fprintf(stderr, "%d: expected %d excluded, got %d\n", i,
7208 encodedNameConstraints[i].constraints.cExcludedSubtree,
7209 constraints->cExcludedSubtree);
7210 if (constraints->cExcludedSubtree ==
7211 encodedNameConstraints[i].constraints.cExcludedSubtree)
7213 for (j = 0; j < constraints->cExcludedSubtree; j++)
7215 compareAltNameEntry(&constraints->rgExcludedSubtree[j].Base,
7216 &encodedNameConstraints[i].constraints.rgExcludedSubtree[j].Base);
7219 LocalFree(constraints);
7224 static WCHAR noticeText[] = { 'T','h','i','s',' ','i','s',' ','a',' ',
7225 'n','o','t','i','c','e',0 };
7226 static const BYTE noticeWithDisplayText[] = {
7227 0x30,0x22,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,0x00,
7228 0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,0x74,
7229 0x00,0x69,0x00,0x63,0x00,0x65
7231 static char org[] = "Wine";
7232 static int noticeNumbers[] = { 2,3 };
7233 static BYTE noticeWithReference[] = {
7234 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7235 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7236 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7237 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7240 static void test_encodePolicyQualifierUserNotice(DWORD dwEncoding)
7245 CERT_POLICY_QUALIFIER_USER_NOTICE notice;
7246 CERT_POLICY_QUALIFIER_NOTICE_REFERENCE reference;
7248 memset(¬ice, 0, sizeof(notice));
7249 ret = pCryptEncodeObjectEx(dwEncoding,
7250 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, ¬ice, CRYPT_ENCODE_ALLOC_FLAG,
7252 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7254 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE encode support\n");
7257 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7260 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size);
7261 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
7264 notice.pszDisplayText = noticeText;
7265 ret = pCryptEncodeObjectEx(dwEncoding,
7266 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, ¬ice, CRYPT_ENCODE_ALLOC_FLAG,
7268 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7271 ok(sizeof(noticeWithDisplayText) == size, "unexpected size %d\n", size);
7272 ok(!memcmp(buf, noticeWithDisplayText, size), "unexpected value\n");
7275 reference.pszOrganization = org;
7276 reference.cNoticeNumbers = 2;
7277 reference.rgNoticeNumbers = noticeNumbers;
7278 notice.pNoticeReference = &reference;
7279 ret = pCryptEncodeObjectEx(dwEncoding,
7280 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, ¬ice, CRYPT_ENCODE_ALLOC_FLAG,
7282 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7285 ok(sizeof(noticeWithReference) == size, "unexpected size %d\n", size);
7286 ok(!memcmp(buf, noticeWithReference, size), "unexpected value\n");
7291 static void test_decodePolicyQualifierUserNotice(DWORD dwEncoding)
7294 CERT_POLICY_QUALIFIER_USER_NOTICE *notice;
7297 ret = pCryptDecodeObjectEx(dwEncoding,
7298 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7299 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7301 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7303 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE decode support\n");
7306 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7309 ok(notice->pszDisplayText == NULL, "unexpected display text\n");
7310 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7313 ret = pCryptDecodeObjectEx(dwEncoding,
7314 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7315 noticeWithDisplayText, sizeof(noticeWithDisplayText),
7316 CRYPT_DECODE_ALLOC_FLAG, NULL, ¬ice, &size);
7317 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7320 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7321 "unexpected display text\n");
7322 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7325 ret = pCryptDecodeObjectEx(dwEncoding,
7326 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7327 noticeWithReference, sizeof(noticeWithReference),
7328 CRYPT_DECODE_ALLOC_FLAG, NULL, ¬ice, &size);
7329 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7332 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7333 "unexpected display text\n");
7334 ok(notice->pNoticeReference != NULL, "expected a notice reference\n");
7335 if (notice->pNoticeReference)
7337 ok(!strcmp(notice->pNoticeReference->pszOrganization, org),
7338 "unexpected organization %s\n",
7339 notice->pNoticeReference->pszOrganization);
7340 ok(notice->pNoticeReference->cNoticeNumbers == 2,
7341 "expected 2 notice numbers, got %d\n",
7342 notice->pNoticeReference->cNoticeNumbers);
7343 ok(notice->pNoticeReference->rgNoticeNumbers[0] == noticeNumbers[0],
7344 "unexpected notice number %d\n",
7345 notice->pNoticeReference->rgNoticeNumbers[0]);
7346 ok(notice->pNoticeReference->rgNoticeNumbers[1] == noticeNumbers[1],
7347 "unexpected notice number %d\n",
7348 notice->pNoticeReference->rgNoticeNumbers[1]);
7354 static char oid_any_policy[] = "2.5.29.32.0";
7355 static const BYTE policiesWithAnyPolicy[] = {
7356 0x30,0x08,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00
7358 static char oid1[] = "1.2.3";
7359 static char oid_user_notice[] = "1.3.6.1.5.5.7.2.2";
7360 static const BYTE twoPolicies[] = {
7361 0x30,0x50,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00,0x30,0x46,0x06,0x02,0x2a,
7362 0x03,0x30,0x40,0x30,0x3e,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x02,
7363 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7364 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7365 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7366 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7369 static void test_encodeCertPolicies(DWORD dwEncoding)
7372 CERT_POLICIES_INFO info;
7373 CERT_POLICY_INFO policy[2];
7374 CERT_POLICY_QUALIFIER_INFO qualifier;
7378 memset(&info, 0, sizeof(info));
7379 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7380 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7381 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7384 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size);
7385 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
7388 memset(policy, 0, sizeof(policy));
7389 info.cPolicyInfo = 1;
7390 info.rgPolicyInfo = policy;
7391 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7392 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7393 ok(!ret && (GetLastError() == E_INVALIDARG ||
7394 GetLastError() == OSS_LIMITED /* Win9x/NT4 */),
7395 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
7396 policy[0].pszPolicyIdentifier = oid_any_policy;
7397 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7398 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7399 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7402 ok(sizeof(policiesWithAnyPolicy) == size, "unexpected size %d\n", size);
7403 ok(!memcmp(buf, policiesWithAnyPolicy, size), "unexpected value\n");
7406 policy[1].pszPolicyIdentifier = oid1;
7407 memset(&qualifier, 0, sizeof(qualifier));
7408 qualifier.pszPolicyQualifierId = oid_user_notice;
7409 qualifier.Qualifier.cbData = sizeof(noticeWithReference);
7410 qualifier.Qualifier.pbData = noticeWithReference;
7411 policy[1].cPolicyQualifier = 1;
7412 policy[1].rgPolicyQualifier = &qualifier;
7413 info.cPolicyInfo = 2;
7414 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7415 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7416 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7419 ok(sizeof(twoPolicies) == size, "unexpected size %d\n", size);
7420 ok(!memcmp(buf, twoPolicies, size), "unexpected value\n");
7425 static void test_decodeCertPolicies(DWORD dwEncoding)
7428 CERT_POLICIES_INFO *info;
7431 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7432 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7434 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7437 ok(info->cPolicyInfo == 0, "unexpected policy info %d\n",
7441 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7442 policiesWithAnyPolicy, sizeof(policiesWithAnyPolicy),
7443 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7444 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7447 ok(info->cPolicyInfo == 1, "unexpected policy info %d\n",
7449 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy),
7450 "unexpected policy id %s\n",
7451 info->rgPolicyInfo[0].pszPolicyIdentifier);
7452 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0,
7453 "unexpected policy qualifier count %d\n",
7454 info->rgPolicyInfo[0].cPolicyQualifier);
7457 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7458 twoPolicies, sizeof(twoPolicies),
7459 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7460 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7463 ok(info->cPolicyInfo == 2, "unexpected policy info %d\n",
7465 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy),
7466 "unexpected policy id %s\n",
7467 info->rgPolicyInfo[0].pszPolicyIdentifier);
7468 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0,
7469 "unexpected policy qualifier count %d\n",
7470 info->rgPolicyInfo[0].cPolicyQualifier);
7471 ok(!strcmp(info->rgPolicyInfo[1].pszPolicyIdentifier, oid1),
7472 "unexpected policy id %s\n",
7473 info->rgPolicyInfo[1].pszPolicyIdentifier);
7474 ok(info->rgPolicyInfo[1].cPolicyQualifier == 1,
7475 "unexpected policy qualifier count %d\n",
7476 info->rgPolicyInfo[1].cPolicyQualifier);
7478 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId,
7479 oid_user_notice), "unexpected policy qualifier id %s\n",
7480 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId);
7481 ok(info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData ==
7482 sizeof(noticeWithReference), "unexpected qualifier size %d\n",
7483 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData);
7485 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.pbData,
7486 noticeWithReference, sizeof(noticeWithReference)),
7487 "unexpected qualifier value\n");
7492 static const BYTE policyMappingWithOneMapping[] = {
7493 0x30,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04 };
7494 static const BYTE policyMappingWithTwoMappings[] = {
7495 0x30,0x14,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04,0x30,0x08,0x06,
7496 0x02,0x2b,0x04,0x06,0x02,0x55,0x06 };
7497 static const LPCSTR mappingOids[] = { X509_POLICY_MAPPINGS,
7498 szOID_POLICY_MAPPINGS, szOID_LEGACY_POLICY_MAPPINGS };
7500 static void test_encodeCertPolicyMappings(DWORD dwEncoding)
7502 static char oid2[] = "2.3.4";
7503 static char oid3[] = "1.3.4";
7504 static char oid4[] = "2.5.6";
7506 CERT_POLICY_MAPPINGS_INFO info = { 0 };
7507 CERT_POLICY_MAPPING mapping[2];
7511 /* Each of the mapping OIDs is equivalent, so check with all of them */
7512 for (i = 0; i < sizeof(mappingOids) / sizeof(mappingOids[0]); i++)
7514 memset(&info, 0, sizeof(info));
7515 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7516 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7517 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
7518 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7519 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7521 win_skip("no policy mappings support\n");
7526 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
7527 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
7528 "unexpected value\n");
7531 mapping[0].pszIssuerDomainPolicy = NULL;
7532 mapping[0].pszSubjectDomainPolicy = NULL;
7533 info.cPolicyMapping = 1;
7534 info.rgPolicyMapping = mapping;
7535 SetLastError(0xdeadbeef);
7536 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7537 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7538 ok(!ret && GetLastError() == E_INVALIDARG,
7539 "expected E_INVALIDARG, got %08x\n", GetLastError());
7540 mapping[0].pszIssuerDomainPolicy = oid1;
7541 mapping[0].pszSubjectDomainPolicy = oid2;
7542 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7543 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7544 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7547 ok(size == sizeof(policyMappingWithOneMapping),
7548 "unexpected size %d\n", size);
7549 ok(!memcmp(buf, policyMappingWithOneMapping, size),
7550 "unexpected value\n");
7553 mapping[1].pszIssuerDomainPolicy = oid3;
7554 mapping[1].pszSubjectDomainPolicy = oid4;
7555 info.cPolicyMapping = 2;
7556 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7557 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7558 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7561 ok(size == sizeof(policyMappingWithTwoMappings),
7562 "unexpected size %d\n", size);
7563 ok(!memcmp(buf, policyMappingWithTwoMappings, size),
7564 "unexpected value\n");
7570 static void test_decodeCertPolicyMappings(DWORD dwEncoding)
7573 CERT_POLICY_MAPPINGS_INFO *info;
7576 /* Each of the mapping OIDs is equivalent, so check with all of them */
7577 for (i = 0; i < sizeof(mappingOids) / sizeof(mappingOids[0]); i++)
7579 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7580 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7582 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
7583 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7584 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7586 win_skip("no policy mappings support\n");
7591 ok(info->cPolicyMapping == 0,
7592 "expected 0 policy mappings, got %d\n", info->cPolicyMapping);
7595 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7596 policyMappingWithOneMapping, sizeof(policyMappingWithOneMapping),
7597 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7598 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7601 ok(info->cPolicyMapping == 1,
7602 "expected 1 policy mappings, got %d\n", info->cPolicyMapping);
7603 ok(!strcmp(info->rgPolicyMapping[0].pszIssuerDomainPolicy, "1.2.3"),
7604 "unexpected issuer policy %s\n",
7605 info->rgPolicyMapping[0].pszIssuerDomainPolicy);
7606 ok(!strcmp(info->rgPolicyMapping[0].pszSubjectDomainPolicy,
7607 "2.3.4"), "unexpected subject policy %s\n",
7608 info->rgPolicyMapping[0].pszSubjectDomainPolicy);
7611 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7612 policyMappingWithTwoMappings, sizeof(policyMappingWithTwoMappings),
7613 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7614 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7617 ok(info->cPolicyMapping == 2,
7618 "expected 2 policy mappings, got %d\n", info->cPolicyMapping);
7619 ok(!strcmp(info->rgPolicyMapping[0].pszIssuerDomainPolicy, "1.2.3"),
7620 "unexpected issuer policy %s\n",
7621 info->rgPolicyMapping[0].pszIssuerDomainPolicy);
7622 ok(!strcmp(info->rgPolicyMapping[0].pszSubjectDomainPolicy,
7623 "2.3.4"), "unexpected subject policy %s\n",
7624 info->rgPolicyMapping[0].pszSubjectDomainPolicy);
7625 ok(!strcmp(info->rgPolicyMapping[1].pszIssuerDomainPolicy, "1.3.4"),
7626 "unexpected issuer policy %s\n",
7627 info->rgPolicyMapping[1].pszIssuerDomainPolicy);
7628 ok(!strcmp(info->rgPolicyMapping[1].pszSubjectDomainPolicy,
7629 "2.5.6"), "unexpected subject policy %s\n",
7630 info->rgPolicyMapping[1].pszSubjectDomainPolicy);
7636 static const BYTE policyConstraintsWithRequireExplicit[] = {
7637 0x30,0x03,0x80,0x01,0x00 };
7638 static const BYTE policyConstraintsWithInhibitMapping[] = {
7639 0x30,0x03,0x81,0x01,0x01 };
7640 static const BYTE policyConstraintsWithBoth[] = {
7641 0x30,0x06,0x80,0x01,0x01,0x81,0x01,0x01 };
7643 static void test_encodeCertPolicyConstraints(DWORD dwEncoding)
7645 CERT_POLICY_CONSTRAINTS_INFO info = { 0 };
7650 /* Even though RFC 5280 explicitly states CAs must not issue empty
7651 * policy constraints (section 4.2.1.11), the API doesn't prevent it.
7653 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7654 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7655 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
7656 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7657 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7659 win_skip("no policy constraints support\n");
7664 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
7665 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
7666 "unexpected value\n");
7669 /* If fRequireExplicitPolicy is set but dwRequireExplicitPolicySkipCerts
7670 * is not, then a skip of 0 is encoded.
7672 info.fRequireExplicitPolicy = TRUE;
7673 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7674 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7675 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7678 ok(size == sizeof(policyConstraintsWithRequireExplicit),
7679 "unexpected size %d\n", size);
7680 ok(!memcmp(buf, policyConstraintsWithRequireExplicit,
7681 sizeof(policyConstraintsWithRequireExplicit)), "unexpected value\n");
7684 /* With inhibit policy mapping */
7685 info.fRequireExplicitPolicy = FALSE;
7686 info.dwRequireExplicitPolicySkipCerts = 0;
7687 info.fInhibitPolicyMapping = TRUE;
7688 info.dwInhibitPolicyMappingSkipCerts = 1;
7689 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7690 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7691 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7694 ok(size == sizeof(policyConstraintsWithInhibitMapping),
7695 "unexpected size %d\n", size);
7696 ok(!memcmp(buf, policyConstraintsWithInhibitMapping,
7697 sizeof(policyConstraintsWithInhibitMapping)), "unexpected value\n");
7701 info.fRequireExplicitPolicy = TRUE;
7702 info.dwRequireExplicitPolicySkipCerts = 1;
7703 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7704 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7705 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7708 ok(size == sizeof(policyConstraintsWithBoth), "unexpected size %d\n",
7710 ok(!memcmp(buf, policyConstraintsWithBoth,
7711 sizeof(policyConstraintsWithBoth)), "unexpected value\n");
7716 static void test_decodeCertPolicyConstraints(DWORD dwEncoding)
7718 CERT_POLICY_CONSTRAINTS_INFO *info;
7722 /* Again, even though CAs must not issue such constraints, they can be
7725 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7726 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7728 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
7729 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7730 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7732 win_skip("no policy mappings support\n");
7737 ok(!info->fRequireExplicitPolicy,
7738 "expected require explicit = FALSE\n");
7739 ok(!info->fInhibitPolicyMapping,
7740 "expected implicit mapping = FALSE\n");
7743 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7744 policyConstraintsWithRequireExplicit,
7745 sizeof(policyConstraintsWithRequireExplicit), CRYPT_DECODE_ALLOC_FLAG,
7746 NULL, &info, &size);
7747 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7750 ok(info->fRequireExplicitPolicy,
7751 "expected require explicit = TRUE\n");
7752 ok(info->dwRequireExplicitPolicySkipCerts == 0, "expected 0, got %d\n",
7753 info->dwRequireExplicitPolicySkipCerts);
7754 ok(!info->fInhibitPolicyMapping,
7755 "expected implicit mapping = FALSE\n");
7758 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7759 policyConstraintsWithInhibitMapping,
7760 sizeof(policyConstraintsWithInhibitMapping), CRYPT_DECODE_ALLOC_FLAG,
7761 NULL, &info, &size);
7762 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7765 ok(!info->fRequireExplicitPolicy,
7766 "expected require explicit = FALSE\n");
7767 ok(info->fInhibitPolicyMapping,
7768 "expected implicit mapping = TRUE\n");
7769 ok(info->dwInhibitPolicyMappingSkipCerts == 1, "expected 1, got %d\n",
7770 info->dwInhibitPolicyMappingSkipCerts);
7773 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7774 policyConstraintsWithBoth, sizeof(policyConstraintsWithBoth),
7775 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7776 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7779 ok(info->fRequireExplicitPolicy,
7780 "expected require explicit = TRUE\n");
7781 ok(info->dwRequireExplicitPolicySkipCerts == 1, "expected 1, got %d\n",
7782 info->dwRequireExplicitPolicySkipCerts);
7783 ok(info->fInhibitPolicyMapping,
7784 "expected implicit mapping = TRUE\n");
7785 ok(info->dwInhibitPolicyMappingSkipCerts == 1, "expected 1, got %d\n",
7786 info->dwInhibitPolicyMappingSkipCerts);
7791 /* Free *pInfo with HeapFree */
7792 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
7799 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
7801 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size);
7802 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7803 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7804 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL,
7806 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7807 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7808 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL,
7810 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7811 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7812 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7813 0, NULL, NULL, &size);
7814 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7815 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7816 /* Test with no key */
7817 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7818 0, NULL, NULL, &size);
7819 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n",
7821 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
7822 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
7825 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
7826 NULL, 0, NULL, NULL, &size);
7827 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
7828 *pInfo = HeapAlloc(GetProcessHeap(), 0, size);
7831 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
7832 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size);
7833 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n",
7837 /* By default (we passed NULL as the OID) the OID is
7840 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA),
7841 "Expected %s, got %s\n", szOID_RSA_RSA,
7842 (*pInfo)->Algorithm.pszObjId);
7846 CryptDestroyKey(key);
7849 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
7850 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
7851 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
7852 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7853 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7854 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7855 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
7856 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
7857 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7858 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7859 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7860 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
7861 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
7862 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
7863 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
7864 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
7865 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
7866 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
7867 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
7868 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
7869 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
7870 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
7871 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
7872 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
7873 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
7875 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info)
7879 PCCERT_CONTEXT context;
7884 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
7885 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
7886 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
7887 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7890 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key);
7891 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7892 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7893 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key);
7894 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7895 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7896 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL,
7898 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7899 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7901 /* Export key with standard algorithm (CALG_RSA_KEYX) */
7902 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7904 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7906 dwSize = sizeof(ai);
7907 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7908 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7911 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7912 ok(ai == CALG_RSA_KEYX, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai);
7915 CryptDestroyKey(key);
7917 /* Repeat with forced algorithm */
7918 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, CALG_RSA_SIGN, 0, NULL,
7920 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7922 dwSize = sizeof(ai);
7923 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7924 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7927 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7928 ok(ai == CALG_RSA_SIGN, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai);
7931 CryptDestroyKey(key);
7933 /* Test importing a public key from a certificate context */
7934 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert,
7935 sizeof(expiredCert));
7936 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
7940 ok(!strcmp(szOID_RSA_RSA,
7941 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId),
7942 "Expected %s, got %s\n", szOID_RSA_RSA,
7943 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
7944 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING,
7945 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
7946 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7947 CryptDestroyKey(key);
7948 CertFreeCertificateContext(context);
7952 static const char cspName[] = "WineCryptTemp";
7954 static void testPortPublicKeyInfo(void)
7958 PCERT_PUBLIC_KEY_INFO info = NULL;
7960 /* Just in case a previous run failed, delete this thing */
7961 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7962 CRYPT_DELETEKEYSET);
7963 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7965 ok(ret,"CryptAcquireContextA failed");
7967 testExportPublicKey(csp, &info);
7968 testImportPublicKey(csp, info);
7970 HeapFree(GetProcessHeap(), 0, info);
7971 CryptReleaseContext(csp, 0);
7972 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7973 CRYPT_DELETEKEYSET);
7974 ok(ret,"CryptAcquireContextA failed");
7979 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
7980 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING };
7984 hCrypt32 = GetModuleHandleA("crypt32.dll");
7985 pCryptDecodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptDecodeObjectEx");
7986 pCryptEncodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptEncodeObjectEx");
7987 if (!pCryptDecodeObjectEx || !pCryptEncodeObjectEx)
7989 win_skip("CryptDecodeObjectEx() is not available\n");
7993 for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++)
7995 test_encodeInt(encodings[i]);
7996 test_decodeInt(encodings[i]);
7997 test_encodeEnumerated(encodings[i]);
7998 test_decodeEnumerated(encodings[i]);
7999 test_encodeFiletime(encodings[i]);
8000 test_decodeFiletime(encodings[i]);
8001 test_encodeName(encodings[i]);
8002 test_decodeName(encodings[i]);
8003 test_encodeUnicodeName(encodings[i]);
8004 test_decodeUnicodeName(encodings[i]);
8005 test_encodeNameValue(encodings[i]);
8006 test_decodeNameValue(encodings[i]);
8007 test_encodeUnicodeNameValue(encodings[i]);
8008 test_decodeUnicodeNameValue(encodings[i]);
8009 test_encodeAltName(encodings[i]);
8010 test_decodeAltName(encodings[i]);
8011 test_encodeOctets(encodings[i]);
8012 test_decodeOctets(encodings[i]);
8013 test_encodeBits(encodings[i]);
8014 test_decodeBits(encodings[i]);
8015 test_encodeBasicConstraints(encodings[i]);
8016 test_decodeBasicConstraints(encodings[i]);
8017 test_encodeRsaPublicKey(encodings[i]);
8018 test_decodeRsaPublicKey(encodings[i]);
8019 test_encodeSequenceOfAny(encodings[i]);
8020 test_decodeSequenceOfAny(encodings[i]);
8021 test_encodeExtensions(encodings[i]);
8022 test_decodeExtensions(encodings[i]);
8023 test_encodePublicKeyInfo(encodings[i]);
8024 test_decodePublicKeyInfo(encodings[i]);
8025 test_encodeCertToBeSigned(encodings[i]);
8026 test_decodeCertToBeSigned(encodings[i]);
8027 test_encodeCert(encodings[i]);
8028 test_decodeCert(encodings[i]);
8029 test_encodeCRLDistPoints(encodings[i]);
8030 test_decodeCRLDistPoints(encodings[i]);
8031 test_encodeCRLIssuingDistPoint(encodings[i]);
8032 test_decodeCRLIssuingDistPoint(encodings[i]);
8033 test_encodeCRLToBeSigned(encodings[i]);
8034 test_decodeCRLToBeSigned(encodings[i]);
8035 test_encodeEnhancedKeyUsage(encodings[i]);
8036 test_decodeEnhancedKeyUsage(encodings[i]);
8037 test_encodeAuthorityKeyId(encodings[i]);
8038 test_decodeAuthorityKeyId(encodings[i]);
8039 test_encodeAuthorityKeyId2(encodings[i]);
8040 test_decodeAuthorityKeyId2(encodings[i]);
8041 test_encodeAuthorityInfoAccess(encodings[i]);
8042 test_decodeAuthorityInfoAccess(encodings[i]);
8043 test_encodeCTL(encodings[i]);
8044 test_decodeCTL(encodings[i]);
8045 test_encodePKCSContentInfo(encodings[i]);
8046 test_decodePKCSContentInfo(encodings[i]);
8047 test_encodePKCSAttribute(encodings[i]);
8048 test_decodePKCSAttribute(encodings[i]);
8049 test_encodePKCSAttributes(encodings[i]);
8050 test_decodePKCSAttributes(encodings[i]);
8051 test_encodePKCSSMimeCapabilities(encodings[i]);
8052 test_decodePKCSSMimeCapabilities(encodings[i]);
8053 test_encodePKCSSignerInfo(encodings[i]);
8054 test_decodePKCSSignerInfo(encodings[i]);
8055 test_encodeCMSSignerInfo(encodings[i]);
8056 test_decodeCMSSignerInfo(encodings[i]);
8057 test_encodeNameConstraints(encodings[i]);
8058 test_decodeNameConstraints(encodings[i]);
8059 test_encodePolicyQualifierUserNotice(encodings[i]);
8060 test_decodePolicyQualifierUserNotice(encodings[i]);
8061 test_encodeCertPolicies(encodings[i]);
8062 test_decodeCertPolicies(encodings[i]);
8063 test_encodeCertPolicyMappings(encodings[i]);
8064 test_decodeCertPolicyMappings(encodings[i]);
8065 test_encodeCertPolicyConstraints(encodings[i]);
8066 test_decodeCertPolicyConstraints(encodings[i]);
8068 testPortPublicKeyInfo();