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 ok(ret, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
1391 embeddedNullNameValue.value.dwValueType, GetLastError());
1394 CERT_NAME_VALUE rdnEncodedValue = { CERT_RDN_ENCODED_BLOB,
1395 { sizeof(ia5EmbeddedNull), ia5EmbeddedNull } };
1396 CERT_NAME_VALUE embeddedNullValue = { CERT_RDN_IA5_STRING,
1397 { sizeof(embedded_null) - 1, (BYTE *)embedded_null } };
1398 const CERT_NAME_VALUE *got = (const CERT_NAME_VALUE *)buf,
1401 /* Some Windows versions decode name values with embedded NULLs,
1402 * others leave them encoded, even with the same version of crypt32.
1405 ok(got->dwValueType == CERT_RDN_ENCODED_BLOB ||
1406 got->dwValueType == CERT_RDN_IA5_STRING,
1407 "Expected CERT_RDN_ENCODED_BLOB or CERT_RDN_IA5_STRING, got %d\n",
1409 if (got->dwValueType == CERT_RDN_ENCODED_BLOB)
1410 expected = &rdnEncodedValue;
1411 else if (got->dwValueType == CERT_RDN_IA5_STRING)
1412 expected = &embeddedNullValue;
1415 ok(got->Value.cbData == expected->Value.cbData,
1416 "String type %d: unexpected data size, got %d, expected %d\n",
1417 got->dwValueType, got->Value.cbData, expected->Value.cbData);
1418 if (got->Value.cbData && got->Value.pbData)
1419 ok(!memcmp(got->Value.pbData, expected->Value.pbData,
1420 min(got->Value.cbData, expected->Value.cbData)),
1421 "String type %d: unexpected value\n", expected->dwValueType);
1427 static const BYTE emptyURL[] = { 0x30, 0x02, 0x86, 0x00 };
1428 static const BYTE emptyURLExtraBytes[] = { 0x30, 0x02, 0x86, 0x00, 0, 0, 0 };
1429 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e',
1430 'h','q','.','o','r','g',0 };
1431 static const BYTE encodedURL[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74,
1432 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e,
1434 static const WCHAR nihongoURL[] = { 'h','t','t','p',':','/','/',0x226f,
1436 static const WCHAR dnsName[] = { 'w','i','n','e','h','q','.','o','r','g',0 };
1437 static const BYTE encodedDnsName[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69,
1438 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
1439 static const BYTE localhost[] = { 127, 0, 0, 1 };
1440 static const BYTE encodedIPAddr[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00,
1442 static const unsigned char encodedCommonName[] = {
1443 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0};
1444 static const BYTE encodedOidName[] = { 0x30,0x04,0x88,0x02,0x2a,0x03 };
1445 static const BYTE encodedDirectoryName[] = {
1446 0x30,0x19,0xa4,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1447 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1449 static void test_encodeAltName(DWORD dwEncoding)
1451 CERT_ALT_NAME_INFO info = { 0 };
1452 CERT_ALT_NAME_ENTRY entry = { 0 };
1456 char oid[] = "1.2.3";
1458 /* Test with empty info */
1459 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1460 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1463 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
1464 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
1467 /* Test with an empty entry */
1469 info.rgAltEntry = &entry;
1470 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1471 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1472 ok(!ret && GetLastError() == E_INVALIDARG,
1473 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1474 /* Test with an empty pointer */
1475 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
1476 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1477 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1480 ok(size == sizeof(emptyURL), "Wrong size %d\n", size);
1481 ok(!memcmp(buf, emptyURL, size), "Unexpected value\n");
1484 /* Test with a real URL */
1485 U(entry).pwszURL = (LPWSTR)url;
1486 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1487 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1490 ok(size == sizeof(encodedURL), "Wrong size %d\n", size);
1491 ok(!memcmp(buf, encodedURL, size), "Unexpected value\n");
1494 /* Now with the URL containing an invalid IA5 char */
1495 U(entry).pwszURL = (LPWSTR)nihongoURL;
1496 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1497 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1498 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
1499 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
1500 /* The first invalid character is at index 7 */
1501 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
1502 "Expected invalid char at index 7, got %d\n",
1503 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
1504 /* Now with the URL missing a scheme */
1505 U(entry).pwszURL = (LPWSTR)dnsName;
1506 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1507 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1508 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1511 /* This succeeds, but it shouldn't, so don't worry about conforming */
1514 /* Now with a DNS name */
1515 entry.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
1516 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1517 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1518 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1521 ok(size == sizeof(encodedDnsName), "Wrong size %d\n", size);
1522 ok(!memcmp(buf, encodedDnsName, size), "Unexpected value\n");
1525 /* Test with an IP address */
1526 entry.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
1527 U(entry).IPAddress.cbData = sizeof(localhost);
1528 U(entry).IPAddress.pbData = (LPBYTE)localhost;
1529 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1530 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1533 ok(size == sizeof(encodedIPAddr), "Wrong size %d\n", size);
1534 ok(!memcmp(buf, encodedIPAddr, size), "Unexpected value\n");
1538 entry.dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID;
1539 U(entry).pszRegisteredID = oid;
1540 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1541 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1544 ok(size == sizeof(encodedOidName), "Wrong size %d\n", size);
1545 ok(!memcmp(buf, encodedOidName, size), "Unexpected value\n");
1548 /* Test with directory name */
1549 entry.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
1550 U(entry).DirectoryName.cbData = sizeof(encodedCommonName);
1551 U(entry).DirectoryName.pbData = (LPBYTE)encodedCommonName;
1552 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1553 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1556 ok(size == sizeof(encodedDirectoryName), "Wrong size %d\n", size);
1557 ok(!memcmp(buf, encodedDirectoryName, size), "Unexpected value\n");
1562 static void test_decodeAltName(DWORD dwEncoding)
1564 static const BYTE unimplementedType[] = { 0x30, 0x06, 0x85, 0x04, 0x7f,
1566 static const BYTE bogusType[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00,
1568 static const BYTE dns_embedded_null[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f,
1569 0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 };
1570 static const BYTE dns_embedded_bell[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f,
1571 0x6f,0x2e,0x63,0x6f,0x6d,0x07,0x62,0x61,0x64,0x64,0x69,0x65 };
1572 static const BYTE url_embedded_null[] = { 0x30,0x10,0x86,0x0e,0x66,0x6f,
1573 0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 };
1577 CERT_ALT_NAME_INFO *info;
1579 /* Test some bogus ones first */
1580 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1581 unimplementedType, sizeof(unimplementedType), CRYPT_DECODE_ALLOC_FLAG,
1582 NULL, &buf, &bufSize);
1583 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
1584 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1585 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
1587 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1588 bogusType, sizeof(bogusType), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
1590 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
1591 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1592 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
1594 /* Now expected cases */
1595 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptySequence,
1596 emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1597 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1600 info = (CERT_ALT_NAME_INFO *)buf;
1602 ok(info->cAltEntry == 0, "Expected 0 entries, got %d\n",
1606 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptyURL,
1607 emptyURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1608 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1611 info = (CERT_ALT_NAME_INFO *)buf;
1613 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1615 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1616 "Expected CERT_ALT_NAME_URL, got %d\n",
1617 info->rgAltEntry[0].dwAltNameChoice);
1618 ok(U(info->rgAltEntry[0]).pwszURL == NULL || !*U(info->rgAltEntry[0]).pwszURL,
1619 "Expected empty URL\n");
1622 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1623 emptyURLExtraBytes, sizeof(emptyURLExtraBytes), 0, NULL, NULL, &bufSize);
1624 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1625 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedURL,
1626 encodedURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1627 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1630 info = (CERT_ALT_NAME_INFO *)buf;
1632 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1634 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1635 "Expected CERT_ALT_NAME_URL, got %d\n",
1636 info->rgAltEntry[0].dwAltNameChoice);
1637 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszURL, url), "Unexpected URL\n");
1640 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedDnsName,
1641 encodedDnsName[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1642 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1645 info = (CERT_ALT_NAME_INFO *)buf;
1647 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1649 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1650 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1651 info->rgAltEntry[0].dwAltNameChoice);
1652 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszDNSName, dnsName),
1653 "Unexpected DNS name\n");
1656 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedIPAddr,
1657 encodedIPAddr[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1658 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1661 info = (CERT_ALT_NAME_INFO *)buf;
1663 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1665 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS,
1666 "Expected CERT_ALT_NAME_IP_ADDRESS, got %d\n",
1667 info->rgAltEntry[0].dwAltNameChoice);
1668 ok(U(info->rgAltEntry[0]).IPAddress.cbData == sizeof(localhost),
1669 "Unexpected IP address length %d\n",
1670 U(info->rgAltEntry[0]).IPAddress.cbData);
1671 ok(!memcmp(U(info->rgAltEntry[0]).IPAddress.pbData, localhost,
1672 sizeof(localhost)), "Unexpected IP address value\n");
1675 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedOidName,
1676 sizeof(encodedOidName), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1677 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1680 info = (CERT_ALT_NAME_INFO *)buf;
1682 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1684 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_REGISTERED_ID,
1685 "Expected CERT_ALT_NAME_REGISTERED_ID, got %d\n",
1686 info->rgAltEntry[0].dwAltNameChoice);
1687 ok(!strcmp(U(info->rgAltEntry[0]).pszRegisteredID, "1.2.3"),
1688 "Expected OID 1.2.3, got %s\n", U(info->rgAltEntry[0]).pszRegisteredID);
1691 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1692 encodedDirectoryName, sizeof(encodedDirectoryName),
1693 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1694 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1697 info = (CERT_ALT_NAME_INFO *)buf;
1699 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1701 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME,
1702 "Expected CERT_ALT_NAME_DIRECTORY_NAME, got %d\n",
1703 info->rgAltEntry[0].dwAltNameChoice);
1704 ok(U(info->rgAltEntry[0]).DirectoryName.cbData ==
1705 sizeof(encodedCommonName), "Unexpected directory name length %d\n",
1706 U(info->rgAltEntry[0]).DirectoryName.cbData);
1707 ok(!memcmp(U(info->rgAltEntry[0]).DirectoryName.pbData,
1708 encodedCommonName, sizeof(encodedCommonName)),
1709 "Unexpected directory name value\n");
1712 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1713 dns_embedded_null, sizeof(dns_embedded_null), CRYPT_DECODE_ALLOC_FLAG,
1714 NULL, &buf, &bufSize);
1715 /* Fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned about the
1716 * particular failure, just that it doesn't decode.
1717 * It succeeds on (broken) Windows versions that haven't addressed
1718 * embedded NULLs in alternate names.
1720 ok(!ret || broken(ret), "expected failure\n");
1721 /* An embedded bell character is allowed, however. */
1722 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1723 dns_embedded_bell, sizeof(dns_embedded_bell), CRYPT_DECODE_ALLOC_FLAG,
1724 NULL, &buf, &bufSize);
1725 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1728 info = (CERT_ALT_NAME_INFO *)buf;
1730 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1732 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1733 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1734 info->rgAltEntry[0].dwAltNameChoice);
1737 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1738 url_embedded_null, sizeof(dns_embedded_null), CRYPT_DECODE_ALLOC_FLAG,
1739 NULL, &buf, &bufSize);
1740 /* Again, fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned
1741 * about the particular failure, just that it doesn't decode.
1742 * It succeeds on (broken) Windows versions that haven't addressed
1743 * embedded NULLs in alternate names.
1745 ok(!ret || broken(ret), "expected failure\n");
1748 struct UnicodeExpectedError
1756 static const WCHAR oneW[] = { '1',0 };
1757 static const WCHAR aW[] = { 'a',0 };
1758 static const WCHAR quoteW[] = { '"', 0 };
1760 static struct UnicodeExpectedError unicodeErrors[] = {
1761 { CERT_RDN_ANY_TYPE, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1762 { CERT_RDN_ENCODED_BLOB, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1763 { CERT_RDN_OCTET_STRING, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1764 { CERT_RDN_NUMERIC_STRING, aW, 0, CRYPT_E_INVALID_NUMERIC_STRING },
1765 { CERT_RDN_PRINTABLE_STRING, quoteW, 0, CRYPT_E_INVALID_PRINTABLE_STRING },
1766 { CERT_RDN_IA5_STRING, nihongoURL, 7, CRYPT_E_INVALID_IA5_STRING },
1769 struct UnicodeExpectedResult
1773 CRYPT_DATA_BLOB encoded;
1776 static BYTE oneNumeric[] = { 0x12, 0x01, 0x31 };
1777 static BYTE onePrintable[] = { 0x13, 0x01, 0x31 };
1778 static BYTE oneTeletex[] = { 0x14, 0x01, 0x31 };
1779 static BYTE oneVideotex[] = { 0x15, 0x01, 0x31 };
1780 static BYTE oneIA5[] = { 0x16, 0x01, 0x31 };
1781 static BYTE oneGraphic[] = { 0x19, 0x01, 0x31 };
1782 static BYTE oneVisible[] = { 0x1a, 0x01, 0x31 };
1783 static BYTE oneUniversal[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 };
1784 static BYTE oneGeneral[] = { 0x1b, 0x01, 0x31 };
1785 static BYTE oneBMP[] = { 0x1e, 0x02, 0x00, 0x31 };
1786 static BYTE oneUTF8[] = { 0x0c, 0x01, 0x31 };
1787 static BYTE nihongoT61[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,
1789 static BYTE nihongoGeneral[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1791 static BYTE nihongoBMP[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,
1792 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
1793 static BYTE nihongoUTF8[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1794 0xe2,0x89,0xaf,0xe5,0x9d,0x9b };
1796 static struct UnicodeExpectedResult unicodeResults[] = {
1797 { CERT_RDN_NUMERIC_STRING, oneW, { sizeof(oneNumeric), oneNumeric } },
1798 { CERT_RDN_PRINTABLE_STRING, oneW, { sizeof(onePrintable), onePrintable } },
1799 { CERT_RDN_TELETEX_STRING, oneW, { sizeof(oneTeletex), oneTeletex } },
1800 { CERT_RDN_VIDEOTEX_STRING, oneW, { sizeof(oneVideotex), oneVideotex } },
1801 { CERT_RDN_IA5_STRING, oneW, { sizeof(oneIA5), oneIA5 } },
1802 { CERT_RDN_GRAPHIC_STRING, oneW, { sizeof(oneGraphic), oneGraphic } },
1803 { CERT_RDN_VISIBLE_STRING, oneW, { sizeof(oneVisible), oneVisible } },
1804 { CERT_RDN_UNIVERSAL_STRING, oneW, { sizeof(oneUniversal), oneUniversal } },
1805 { CERT_RDN_GENERAL_STRING, oneW, { sizeof(oneGeneral), oneGeneral } },
1806 { CERT_RDN_BMP_STRING, oneW, { sizeof(oneBMP), oneBMP } },
1807 { CERT_RDN_UTF8_STRING, oneW, { sizeof(oneUTF8), oneUTF8 } },
1808 { CERT_RDN_BMP_STRING, nihongoURL, { sizeof(nihongoBMP), nihongoBMP } },
1809 { CERT_RDN_UTF8_STRING, nihongoURL, { sizeof(nihongoUTF8), nihongoUTF8 } },
1812 static struct UnicodeExpectedResult unicodeWeirdness[] = {
1813 { CERT_RDN_TELETEX_STRING, nihongoURL, { sizeof(nihongoT61), nihongoT61 } },
1814 { CERT_RDN_GENERAL_STRING, nihongoURL, { sizeof(nihongoGeneral), nihongoGeneral } },
1817 static void test_encodeUnicodeNameValue(DWORD dwEncoding)
1822 CERT_NAME_VALUE value;
1826 /* Crashes on win9x */
1827 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, NULL,
1828 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1829 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1830 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1832 /* Have to have a string of some sort */
1833 value.dwValueType = 0; /* aka CERT_RDN_ANY_TYPE */
1834 value.Value.pbData = NULL;
1835 value.Value.cbData = 0;
1836 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1837 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1838 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1839 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1840 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1841 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1842 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1843 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1844 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1845 value.dwValueType = CERT_RDN_ANY_TYPE;
1846 value.Value.pbData = (LPBYTE)oneW;
1847 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1848 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1849 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1850 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1851 value.Value.cbData = sizeof(oneW);
1852 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1853 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1854 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1855 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1856 /* An encoded string with specified length isn't good enough either */
1857 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1858 value.Value.pbData = oneUniversal;
1859 value.Value.cbData = sizeof(oneUniversal);
1860 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1861 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1862 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1863 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1864 /* More failure checking */
1865 value.Value.cbData = 0;
1866 for (i = 0; i < sizeof(unicodeErrors) / sizeof(unicodeErrors[0]); i++)
1868 value.Value.pbData = (LPBYTE)unicodeErrors[i].str;
1869 value.dwValueType = unicodeErrors[i].valueType;
1870 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1871 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1872 ok(!ret && GetLastError() == unicodeErrors[i].error,
1873 "Value type %d: expected %08x, got %08x\n", value.dwValueType,
1874 unicodeErrors[i].error, GetLastError());
1875 ok(size == unicodeErrors[i].errorIndex,
1876 "Expected error index %d, got %d\n", unicodeErrors[i].errorIndex,
1879 /* cbData can be zero if the string is NULL-terminated */
1880 value.Value.cbData = 0;
1881 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1883 value.Value.pbData = (LPBYTE)unicodeResults[i].str;
1884 value.dwValueType = unicodeResults[i].valueType;
1885 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1886 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1887 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
1888 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1891 ok(size == unicodeResults[i].encoded.cbData,
1892 "Value type %d: expected size %d, got %d\n",
1893 value.dwValueType, unicodeResults[i].encoded.cbData, size);
1894 ok(!memcmp(unicodeResults[i].encoded.pbData, buf, size),
1895 "Value type %d: unexpected value\n", value.dwValueType);
1899 /* These "encode," but they do so by truncating each unicode character
1900 * rather than properly encoding it. Kept separate from the proper results,
1901 * because the encoded forms won't decode to their original strings.
1903 for (i = 0; i < sizeof(unicodeWeirdness) / sizeof(unicodeWeirdness[0]); i++)
1905 value.Value.pbData = (LPBYTE)unicodeWeirdness[i].str;
1906 value.dwValueType = unicodeWeirdness[i].valueType;
1907 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1908 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1909 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1912 ok(size == unicodeWeirdness[i].encoded.cbData,
1913 "Value type %d: expected size %d, got %d\n",
1914 value.dwValueType, unicodeWeirdness[i].encoded.cbData, size);
1915 ok(!memcmp(unicodeWeirdness[i].encoded.pbData, buf, size),
1916 "Value type %d: unexpected value\n", value.dwValueType);
1922 static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
1924 if (n <= 0) return 0;
1925 while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
1926 return *str1 - *str2;
1929 static void test_decodeUnicodeNameValue(DWORD dwEncoding)
1933 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1939 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE,
1940 unicodeResults[i].encoded.pbData, unicodeResults[i].encoded.cbData,
1941 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
1942 ok(ret || broken(GetLastError() == CRYPT_E_NOT_CHAR_STRING /* Win9x */),
1943 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1946 PCERT_NAME_VALUE value = (PCERT_NAME_VALUE)buf;
1948 ok(value->dwValueType == unicodeResults[i].valueType,
1949 "Expected value type %d, got %d\n", unicodeResults[i].valueType,
1950 value->dwValueType);
1951 ok(!strncmpW((LPWSTR)value->Value.pbData, unicodeResults[i].str,
1952 value->Value.cbData / sizeof(WCHAR)),
1953 "Unexpected decoded value for index %d (value type %d)\n", i,
1954 unicodeResults[i].valueType);
1960 struct encodedOctets
1963 const BYTE *encoded;
1966 static const unsigned char bin46[] = { 'h','i',0 };
1967 static const unsigned char bin47[] = { 0x04,0x02,'h','i',0 };
1968 static const unsigned char bin48[] = {
1969 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1970 static const unsigned char bin49[] = {
1971 0x04,0x0f,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1972 static const unsigned char bin50[] = { 0 };
1973 static const unsigned char bin51[] = { 0x04,0x00,0 };
1975 static const struct encodedOctets octets[] = {
1981 static void test_encodeOctets(DWORD dwEncoding)
1983 CRYPT_DATA_BLOB blob;
1986 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1992 blob.cbData = strlen((const char*)octets[i].val);
1993 blob.pbData = (BYTE*)octets[i].val;
1994 ret = pCryptEncodeObjectEx(dwEncoding, X509_OCTET_STRING, &blob,
1995 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1996 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
2000 "Got unexpected type %d for octet string (expected 4)\n", buf[0]);
2001 ok(buf[1] == octets[i].encoded[1], "Got length %d, expected %d\n",
2002 buf[1], octets[i].encoded[1]);
2003 ok(!memcmp(buf + 1, octets[i].encoded + 1,
2004 octets[i].encoded[1] + 1), "Got unexpected value\n");
2010 static void test_decodeOctets(DWORD dwEncoding)
2014 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
2020 ret = pCryptDecodeObjectEx(dwEncoding, X509_OCTET_STRING,
2021 octets[i].encoded, octets[i].encoded[1] + 2,
2022 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2023 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2024 ok(bufSize >= sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1],
2025 "Expected size >= %d, got %d\n",
2026 (int)sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1], bufSize);
2027 ok(buf != NULL, "Expected allocated buffer\n");
2030 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)buf;
2033 ok(!memcmp(blob->pbData, octets[i].val, blob->cbData),
2034 "Unexpected value\n");
2040 static const BYTE bytesToEncode[] = { 0xff, 0xff };
2045 const BYTE *encoded;
2047 const BYTE *decoded;
2050 static const unsigned char bin52[] = { 0x03,0x03,0x00,0xff,0xff };
2051 static const unsigned char bin53[] = { 0xff,0xff };
2052 static const unsigned char bin54[] = { 0x03,0x03,0x01,0xff,0xfe };
2053 static const unsigned char bin55[] = { 0xff,0xfe };
2054 static const unsigned char bin56[] = { 0x03,0x02,0x01,0xfe };
2055 static const unsigned char bin57[] = { 0xfe };
2056 static const unsigned char bin58[] = { 0x03,0x01,0x00 };
2058 static const struct encodedBits bits[] = {
2059 /* normal test cases */
2060 { 0, bin52, 2, bin53 },
2061 { 1, bin54, 2, bin55 },
2062 /* strange test case, showing cUnusedBits >= 8 is allowed */
2063 { 9, bin56, 1, bin57 },
2066 static void test_encodeBits(DWORD dwEncoding)
2070 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
2072 CRYPT_BIT_BLOB blob;
2077 blob.cbData = sizeof(bytesToEncode);
2078 blob.pbData = (BYTE *)bytesToEncode;
2079 blob.cUnusedBits = bits[i].cUnusedBits;
2080 ret = pCryptEncodeObjectEx(dwEncoding, X509_BITS, &blob,
2081 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2082 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2085 ok(bufSize == bits[i].encoded[1] + 2,
2086 "%d: Got unexpected size %d, expected %d\n", i, bufSize,
2087 bits[i].encoded[1] + 2);
2088 ok(!memcmp(buf, bits[i].encoded, bits[i].encoded[1] + 2),
2089 "%d: Unexpected value\n", i);
2095 static void test_decodeBits(DWORD dwEncoding)
2097 static const BYTE ber[] = "\x03\x02\x01\xff";
2098 static const BYTE berDecoded = 0xfe;
2105 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
2107 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, bits[i].encoded,
2108 bits[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
2110 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2113 CRYPT_BIT_BLOB *blob;
2115 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + bits[i].cbDecoded,
2116 "Got unexpected size %d\n", bufSize);
2117 blob = (CRYPT_BIT_BLOB *)buf;
2118 ok(blob->cbData == bits[i].cbDecoded,
2119 "Got unexpected length %d, expected %d\n", blob->cbData,
2121 if (blob->cbData && bits[i].cbDecoded)
2122 ok(!memcmp(blob->pbData, bits[i].decoded, bits[i].cbDecoded),
2123 "Unexpected value\n");
2127 /* special case: check that something that's valid in BER but not in DER
2128 * decodes successfully
2130 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, ber, ber[1] + 2,
2131 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2132 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2135 CRYPT_BIT_BLOB *blob;
2137 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + sizeof(berDecoded),
2138 "Got unexpected size %d\n", bufSize);
2139 blob = (CRYPT_BIT_BLOB *)buf;
2140 ok(blob->cbData == sizeof(berDecoded),
2141 "Got unexpected length %d\n", blob->cbData);
2143 ok(*blob->pbData == berDecoded, "Unexpected value\n");
2150 CERT_BASIC_CONSTRAINTS2_INFO info;
2151 const BYTE *encoded;
2154 static const unsigned char bin59[] = { 0x30,0x00 };
2155 static const unsigned char bin60[] = { 0x30,0x03,0x01,0x01,0xff };
2156 static const unsigned char bin61[] = { 0x30,0x03,0x02,0x01,0x00 };
2157 static const unsigned char bin62[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2158 static const struct Constraints2 constraints2[] = {
2159 /* empty constraints */
2160 { { FALSE, FALSE, 0}, bin59 },
2162 { { TRUE, FALSE, 0}, bin60 },
2163 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well,
2164 * but that's not the case
2166 { { FALSE, TRUE, 0}, bin61 },
2167 /* can be a CA and has path length constraints set */
2168 { { TRUE, TRUE, 1}, bin62 },
2171 static const BYTE emptyConstraint[] = { 0x30, 0x03, 0x03, 0x01, 0x00 };
2172 static const BYTE encodedDomainName[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11,
2173 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
2174 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
2175 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2176 static const BYTE constraintWithDomainName[] = { 0x30, 0x32, 0x03, 0x01, 0x00,
2177 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
2178 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30,
2179 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
2180 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2182 static void test_encodeBasicConstraints(DWORD dwEncoding)
2184 DWORD i, bufSize = 0;
2185 CERT_BASIC_CONSTRAINTS_INFO info = { { 0 } };
2186 CERT_NAME_BLOB nameBlob = { sizeof(encodedDomainName),
2187 (LPBYTE)encodedDomainName };
2191 /* First test with the simpler info2 */
2192 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2194 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2195 &constraints2[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf,
2197 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2200 ok(bufSize == constraints2[i].encoded[1] + 2,
2201 "Expected %d bytes, got %d\n", constraints2[i].encoded[1] + 2,
2203 ok(!memcmp(buf, constraints2[i].encoded,
2204 constraints2[i].encoded[1] + 2), "Unexpected value\n");
2208 /* Now test with more complex basic constraints */
2209 info.SubjectType.cbData = 0;
2210 info.fPathLenConstraint = FALSE;
2211 info.cSubtreesConstraint = 0;
2212 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2213 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2214 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2215 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2218 ok(bufSize == sizeof(emptyConstraint), "Wrong size %d\n", bufSize);
2219 ok(!memcmp(buf, emptyConstraint, sizeof(emptyConstraint)),
2220 "Unexpected value\n");
2223 /* None of the certs I examined had any subtree constraint, but I test one
2224 * anyway just in case.
2226 info.cSubtreesConstraint = 1;
2227 info.rgSubtreesConstraint = &nameBlob;
2228 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2229 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2230 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2231 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2234 ok(bufSize == sizeof(constraintWithDomainName), "Wrong size %d\n", bufSize);
2235 ok(!memcmp(buf, constraintWithDomainName,
2236 sizeof(constraintWithDomainName)), "Unexpected value\n");
2239 /* FIXME: test encoding with subject type. */
2242 static const unsigned char bin63[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 };
2244 static void test_decodeBasicConstraints(DWORD dwEncoding)
2246 static const BYTE inverted[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01,
2248 static const struct Constraints2 badBool = { { TRUE, TRUE, 1 }, bin63 };
2254 /* First test with simpler info2 */
2255 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2257 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2258 constraints2[i].encoded, constraints2[i].encoded[1] + 2,
2259 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2260 ok(ret, "CryptDecodeObjectEx failed for item %d: %08x\n", i,
2264 CERT_BASIC_CONSTRAINTS2_INFO *info =
2265 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2267 ok(!memcmp(info, &constraints2[i].info, sizeof(*info)),
2268 "Unexpected value for item %d\n", i);
2272 /* Check with the order of encoded elements inverted */
2274 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2275 inverted, inverted[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
2277 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2278 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2279 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2281 ok(!buf, "Expected buf to be set to NULL\n");
2282 /* Check with a non-DER bool */
2283 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2284 badBool.encoded, badBool.encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2286 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2289 CERT_BASIC_CONSTRAINTS2_INFO *info =
2290 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2292 ok(!memcmp(info, &badBool.info, sizeof(*info)), "Unexpected value\n");
2295 /* Check with a non-basic constraints value */
2296 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2297 encodedCommonName, encodedCommonName[1] + 2,
2298 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2299 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2300 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2301 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2303 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */
2304 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2305 emptyConstraint, sizeof(emptyConstraint), CRYPT_DECODE_ALLOC_FLAG, NULL,
2307 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2310 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2312 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2313 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2314 ok(info->cSubtreesConstraint == 0, "Expected no subtree constraints\n");
2317 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2318 constraintWithDomainName, sizeof(constraintWithDomainName),
2319 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2320 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2323 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2325 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2326 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2327 ok(info->cSubtreesConstraint == 1, "Expected a subtree constraint\n");
2328 if (info->cSubtreesConstraint && info->rgSubtreesConstraint)
2330 ok(info->rgSubtreesConstraint[0].cbData ==
2331 sizeof(encodedDomainName), "Wrong size %d\n",
2332 info->rgSubtreesConstraint[0].cbData);
2333 ok(!memcmp(info->rgSubtreesConstraint[0].pbData, encodedDomainName,
2334 sizeof(encodedDomainName)), "Unexpected value\n");
2340 /* These are terrible public keys of course, I'm just testing encoding */
2341 static const BYTE modulus1[] = { 0,0,0,1,1,1,1,1 };
2342 static const BYTE modulus2[] = { 1,1,1,1,1,0,0,0 };
2343 static const BYTE modulus3[] = { 0x80,1,1,1,1,0,0,0 };
2344 static const BYTE modulus4[] = { 1,1,1,1,1,0,0,0x80 };
2345 static const BYTE mod1_encoded[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 };
2346 static const BYTE mod2_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2347 static const BYTE mod3_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 };
2348 static const BYTE mod4_encoded[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2350 struct EncodedRSAPubKey
2352 const BYTE *modulus;
2354 const BYTE *encoded;
2355 size_t decodedModulusLen;
2358 struct EncodedRSAPubKey rsaPubKeys[] = {
2359 { modulus1, sizeof(modulus1), mod1_encoded, sizeof(modulus1) },
2360 { modulus2, sizeof(modulus2), mod2_encoded, 5 },
2361 { modulus3, sizeof(modulus3), mod3_encoded, 5 },
2362 { modulus4, sizeof(modulus4), mod4_encoded, 8 },
2365 static void test_encodeRsaPublicKey(DWORD dwEncoding)
2367 BYTE toEncode[sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + sizeof(modulus1)];
2368 BLOBHEADER *hdr = (BLOBHEADER *)toEncode;
2369 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(toEncode + sizeof(BLOBHEADER));
2372 DWORD bufSize = 0, i;
2374 /* Try with a bogus blob type */
2376 hdr->bVersion = CUR_BLOB_VERSION;
2378 hdr->aiKeyAlg = CALG_RSA_KEYX;
2379 rsaPubKey->magic = 0x31415352;
2380 rsaPubKey->bitlen = sizeof(modulus1) * 8;
2381 rsaPubKey->pubexp = 65537;
2382 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), modulus1,
2385 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2386 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2387 ok(!ret && GetLastError() == E_INVALIDARG,
2388 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2389 /* Now with a bogus reserved field */
2390 hdr->bType = PUBLICKEYBLOB;
2392 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2393 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2396 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2397 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2398 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2401 /* Now with a bogus blob version */
2404 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2405 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2408 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2409 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2410 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2413 /* And with a bogus alg ID */
2414 hdr->bVersion = CUR_BLOB_VERSION;
2415 hdr->aiKeyAlg = CALG_DES;
2416 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2417 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2420 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2421 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2422 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2425 /* Check a couple of RSA-related OIDs */
2426 hdr->aiKeyAlg = CALG_RSA_KEYX;
2427 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_RSA,
2428 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2429 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2430 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2431 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2432 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2433 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2434 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2435 /* Finally, all valid */
2436 hdr->aiKeyAlg = CALG_RSA_KEYX;
2437 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2439 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2440 rsaPubKeys[i].modulus, rsaPubKeys[i].modulusLen);
2441 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2442 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2443 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2446 ok(bufSize == rsaPubKeys[i].encoded[1] + 2,
2447 "Expected size %d, got %d\n", rsaPubKeys[i].encoded[1] + 2,
2449 ok(!memcmp(buf, rsaPubKeys[i].encoded, bufSize),
2450 "Unexpected value\n");
2456 static void test_decodeRsaPublicKey(DWORD dwEncoding)
2463 /* Try with a bad length */
2464 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2465 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1],
2466 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2467 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
2468 GetLastError() == OSS_MORE_INPUT /* Win9x/NT4 */),
2469 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n",
2471 /* Try with a couple of RSA-related OIDs */
2472 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_RSA,
2473 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2474 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2475 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2476 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2477 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2478 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2479 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2480 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2481 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2482 /* Now try success cases */
2483 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2486 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2487 rsaPubKeys[i].encoded, rsaPubKeys[i].encoded[1] + 2,
2488 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2489 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2492 BLOBHEADER *hdr = (BLOBHEADER *)buf;
2493 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER));
2495 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2496 rsaPubKeys[i].decodedModulusLen,
2497 "Wrong size %d\n", bufSize);
2498 ok(hdr->bType == PUBLICKEYBLOB,
2499 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB,
2501 ok(hdr->bVersion == CUR_BLOB_VERSION,
2502 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
2503 CUR_BLOB_VERSION, hdr->bVersion);
2504 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n",
2506 ok(hdr->aiKeyAlg == CALG_RSA_KEYX,
2507 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg);
2508 ok(rsaPubKey->magic == 0x31415352,
2509 "Expected magic RSA1, got %08x\n", rsaPubKey->magic);
2510 ok(rsaPubKey->bitlen == rsaPubKeys[i].decodedModulusLen * 8,
2511 "Wrong bit len %d\n", rsaPubKey->bitlen);
2512 ok(rsaPubKey->pubexp == 65537, "Expected pubexp 65537, got %d\n",
2514 ok(!memcmp(buf + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2515 rsaPubKeys[i].modulus, rsaPubKeys[i].decodedModulusLen),
2516 "Unexpected modulus\n");
2522 static const BYTE intSequence[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01,
2523 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02,
2524 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2526 static const BYTE mixedSequence[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
2527 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f,
2528 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02,
2529 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2531 static void test_encodeSequenceOfAny(DWORD dwEncoding)
2533 CRYPT_DER_BLOB blobs[sizeof(ints) / sizeof(ints[0])];
2534 CRYPT_SEQUENCE_OF_ANY seq;
2540 /* Encode a homogeneous sequence */
2541 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
2543 blobs[i].cbData = ints[i].encoded[1] + 2;
2544 blobs[i].pbData = (BYTE *)ints[i].encoded;
2546 seq.cValue = sizeof(ints) / sizeof(ints[0]);
2547 seq.rgValue = blobs;
2549 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2550 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2551 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2554 ok(bufSize == sizeof(intSequence), "Wrong size %d\n", bufSize);
2555 ok(!memcmp(buf, intSequence, intSequence[1] + 2), "Unexpected value\n");
2558 /* Change the type of the first element in the sequence, and give it
2561 blobs[0].cbData = times[0].encodedTime[1] + 2;
2562 blobs[0].pbData = (BYTE *)times[0].encodedTime;
2563 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2564 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2565 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2568 ok(bufSize == sizeof(mixedSequence), "Wrong size %d\n", bufSize);
2569 ok(!memcmp(buf, mixedSequence, mixedSequence[1] + 2),
2570 "Unexpected value\n");
2575 static void test_decodeSequenceOfAny(DWORD dwEncoding)
2581 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, intSequence,
2582 intSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2583 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2586 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2589 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2590 "Wrong elements %d\n", seq->cValue);
2591 for (i = 0; i < min(seq->cValue, sizeof(ints) / sizeof(ints[0])); i++)
2593 ok(seq->rgValue[i].cbData == ints[i].encoded[1] + 2,
2594 "Expected %d bytes, got %d\n", ints[i].encoded[1] + 2,
2595 seq->rgValue[i].cbData);
2596 ok(!memcmp(seq->rgValue[i].pbData, ints[i].encoded,
2597 ints[i].encoded[1] + 2), "Unexpected value\n");
2601 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, mixedSequence,
2602 mixedSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
2604 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2607 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2609 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2610 "Wrong elements %d\n", seq->cValue);
2611 /* Just check the first element since it's all that changed */
2612 ok(seq->rgValue[0].cbData == times[0].encodedTime[1] + 2,
2613 "Expected %d bytes, got %d\n", times[0].encodedTime[1] + 2,
2614 seq->rgValue[0].cbData);
2615 ok(!memcmp(seq->rgValue[0].pbData, times[0].encodedTime,
2616 times[0].encodedTime[1] + 2), "Unexpected value\n");
2621 struct encodedExtensions
2623 CERT_EXTENSIONS exts;
2624 const BYTE *encoded;
2627 static BYTE crit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2628 static BYTE noncrit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2629 static CHAR oid_basic_constraints2[] = szOID_BASIC_CONSTRAINTS2;
2630 static CERT_EXTENSION criticalExt =
2631 { oid_basic_constraints2, TRUE, { 8, crit_ext_data } };
2632 static CERT_EXTENSION nonCriticalExt =
2633 { oid_basic_constraints2, FALSE, { 8, noncrit_ext_data } };
2634 static CHAR oid_short[] = "1.1";
2635 static CERT_EXTENSION extWithShortOid =
2636 { oid_short, FALSE, { 0, NULL } };
2638 static const BYTE ext0[] = { 0x30,0x00 };
2639 static const BYTE ext1[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2640 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2641 static const BYTE ext2[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2642 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2643 static const BYTE ext3[] = { 0x30,0x07,0x30,0x05,0x06,0x01,0x29,0x04,0x00 };
2645 static const struct encodedExtensions exts[] = {
2646 { { 0, NULL }, ext0 },
2647 { { 1, &criticalExt }, ext1 },
2648 { { 1, &nonCriticalExt }, ext2 },
2649 { { 1, &extWithShortOid }, ext3 }
2652 static void test_encodeExtensions(DWORD dwEncoding)
2656 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2662 ret = pCryptEncodeObjectEx(dwEncoding, X509_EXTENSIONS, &exts[i].exts,
2663 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2664 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2667 ok(bufSize == exts[i].encoded[1] + 2,
2668 "Expected %d bytes, got %d\n", exts[i].encoded[1] + 2, bufSize);
2669 ok(!memcmp(buf, exts[i].encoded, exts[i].encoded[1] + 2),
2670 "Unexpected value\n");
2676 static void test_decodeExtensions(DWORD dwEncoding)
2680 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2686 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS,
2687 exts[i].encoded, exts[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2688 NULL, &buf, &bufSize);
2689 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2692 CERT_EXTENSIONS *ext = (CERT_EXTENSIONS *)buf;
2695 ok(ext->cExtension == exts[i].exts.cExtension,
2696 "Expected %d extensions, see %d\n", exts[i].exts.cExtension,
2698 for (j = 0; j < min(ext->cExtension, exts[i].exts.cExtension); j++)
2700 ok(!strcmp(ext->rgExtension[j].pszObjId,
2701 exts[i].exts.rgExtension[j].pszObjId),
2702 "Expected OID %s, got %s\n",
2703 exts[i].exts.rgExtension[j].pszObjId,
2704 ext->rgExtension[j].pszObjId);
2705 ok(!memcmp(ext->rgExtension[j].Value.pbData,
2706 exts[i].exts.rgExtension[j].Value.pbData,
2707 exts[i].exts.rgExtension[j].Value.cbData),
2708 "Unexpected value\n");
2715 /* MS encodes public key info with a NULL if the algorithm identifier's
2716 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2717 * it encodes them by omitting the algorithm parameters. It accepts either
2718 * form for decoding.
2720 struct encodedPublicKey
2722 CERT_PUBLIC_KEY_INFO info;
2723 const BYTE *encoded;
2724 const BYTE *encodedNoNull;
2725 CERT_PUBLIC_KEY_INFO decoded;
2728 static const BYTE aKey[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2730 static const BYTE params[] = { 0x02, 0x01, 0x01 };
2732 static const unsigned char bin64[] = {
2733 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2734 static const unsigned char bin65[] = {
2735 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2736 static const unsigned char bin66[] = {
2737 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2738 static const unsigned char bin67[] = {
2739 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2740 static const unsigned char bin68[] = {
2741 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01,
2742 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2743 static const unsigned char bin69[] = {
2744 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2745 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2746 static const unsigned char bin70[] = {
2747 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2748 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2750 static const unsigned char bin71[] = {
2751 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2752 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2754 static unsigned char bin72[] = { 0x05,0x00};
2756 static CHAR oid_bogus[] = "1.2.3",
2757 oid_rsa[] = szOID_RSA;
2759 static const struct encodedPublicKey pubKeys[] = {
2760 /* with a bogus OID */
2761 { { { oid_bogus, { 0, NULL } }, { 0, NULL, 0 } },
2763 { { oid_bogus, { 2, bin72 } }, { 0, NULL, 0 } } },
2764 /* some normal keys */
2765 { { { oid_rsa, { 0, NULL } }, { 0, NULL, 0} },
2767 { { oid_rsa, { 2, bin72 } }, { 0, NULL, 0 } } },
2768 { { { oid_rsa, { 0, NULL } }, { sizeof(aKey), (BYTE *)aKey, 0} },
2770 { { oid_rsa, { 2, bin72 } }, { sizeof(aKey), (BYTE *)aKey, 0} } },
2771 /* with add'l parameters--note they must be DER-encoded */
2772 { { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2773 (BYTE *)aKey, 0 } },
2775 { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2776 (BYTE *)aKey, 0 } } },
2779 static void test_encodePublicKeyInfo(DWORD dwEncoding)
2783 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2789 ret = pCryptEncodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2790 &pubKeys[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf,
2792 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2793 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2796 ok(bufSize == pubKeys[i].encoded[1] + 2,
2797 "Expected %d bytes, got %d\n", pubKeys[i].encoded[1] + 2, bufSize);
2798 if (bufSize == pubKeys[i].encoded[1] + 2)
2799 ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2),
2800 "Unexpected value\n");
2806 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO *expected,
2807 const CERT_PUBLIC_KEY_INFO *got)
2809 ok(!strcmp(expected->Algorithm.pszObjId, got->Algorithm.pszObjId),
2810 "Expected OID %s, got %s\n", expected->Algorithm.pszObjId,
2811 got->Algorithm.pszObjId);
2812 ok(expected->Algorithm.Parameters.cbData ==
2813 got->Algorithm.Parameters.cbData,
2814 "Expected parameters of %d bytes, got %d\n",
2815 expected->Algorithm.Parameters.cbData, got->Algorithm.Parameters.cbData);
2816 if (expected->Algorithm.Parameters.cbData)
2817 ok(!memcmp(expected->Algorithm.Parameters.pbData,
2818 got->Algorithm.Parameters.pbData, got->Algorithm.Parameters.cbData),
2819 "Unexpected algorithm parameters\n");
2820 ok(expected->PublicKey.cbData == got->PublicKey.cbData,
2821 "Expected public key of %d bytes, got %d\n",
2822 expected->PublicKey.cbData, got->PublicKey.cbData);
2823 if (expected->PublicKey.cbData)
2824 ok(!memcmp(expected->PublicKey.pbData, got->PublicKey.pbData,
2825 got->PublicKey.cbData), "Unexpected public key value\n");
2828 static void test_decodePublicKeyInfo(DWORD dwEncoding)
2830 static const BYTE bogusPubKeyInfo[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
2831 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
2832 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
2833 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2839 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2841 /* The NULL form decodes to the decoded member */
2842 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2843 pubKeys[i].encoded, pubKeys[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2844 NULL, &buf, &bufSize);
2845 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2848 comparePublicKeyInfo(&pubKeys[i].decoded,
2849 (CERT_PUBLIC_KEY_INFO *)buf);
2852 /* The non-NULL form decodes to the original */
2853 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2854 pubKeys[i].encodedNoNull, pubKeys[i].encodedNoNull[1] + 2,
2855 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2856 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2859 comparePublicKeyInfo(&pubKeys[i].info, (CERT_PUBLIC_KEY_INFO *)buf);
2863 /* Test with bogus (not valid DER) parameters */
2864 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2865 bogusPubKeyInfo, bogusPubKeyInfo[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2866 NULL, &buf, &bufSize);
2867 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2868 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2869 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2873 static const BYTE v1Cert[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
2874 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2875 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
2876 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
2877 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2878 static const BYTE v2Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02,
2879 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2880 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2881 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2882 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2883 static const BYTE v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2884 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2885 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2886 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2887 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2888 static const BYTE v4Cert[] = {
2889 0x30,0x38,0xa0,0x03,0x02,0x01,0x03,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,
2890 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
2891 0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
2892 0x30,0x30,0x30,0x5a,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00 };
2893 static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
2894 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2895 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2896 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2897 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2898 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2899 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2900 static const BYTE v1CertWithSerial[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
2901 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2902 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2903 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2904 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2905 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2906 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2907 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2908 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
2909 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
2910 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
2911 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
2912 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
2913 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
2914 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
2915 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
2916 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2917 static const BYTE v1CertWithPubKey[] = {
2918 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2919 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2920 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2921 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2922 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2923 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2924 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2925 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2926 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
2927 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
2929 static const BYTE v1CertWithPubKeyNoNull[] = {
2930 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2931 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2932 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2933 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2934 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2935 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2936 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2937 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2938 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
2939 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2940 static const BYTE v1CertWithSubjectKeyId[] = {
2941 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2942 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2943 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2944 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2945 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2946 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2947 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
2948 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2949 0x4c,0x61,0x6e,0x67,0x00 };
2950 static const BYTE v1CertWithIssuerUniqueId[] = {
2951 0x30,0x38,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
2952 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
2953 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
2954 0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x81,0x02,0x00,0x01 };
2955 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueId[] = {
2956 0x30,0x81,0x99,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2957 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2958 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2959 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2960 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2961 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2962 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2963 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2964 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,
2965 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
2966 0x01,0x01,0xff,0x02,0x01,0x01 };
2967 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull[] = {
2968 0x30,0x81,0x97,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2969 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2970 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2971 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2972 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2973 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2974 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2975 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2976 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
2977 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
2978 0xff,0x02,0x01,0x01 };
2980 static const BYTE serialNum[] = { 0x01 };
2982 static void test_encodeCertToBeSigned(DWORD dwEncoding)
2987 CERT_INFO info = { 0 };
2988 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2989 static char oid_subject_key_identifier[] = szOID_SUBJECT_KEY_IDENTIFIER;
2994 /* Test with NULL pvStructInfo (crashes on win9x) */
2995 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL,
2996 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
2997 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2998 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3000 /* Test with a V1 cert */
3001 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3002 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3003 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3004 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3007 ok(size == v1Cert[1] + 2, "Expected size %d, got %d\n",
3008 v1Cert[1] + 2, size);
3009 ok(!memcmp(buf, v1Cert, size), "Got unexpected value\n");
3013 info.dwVersion = CERT_V2;
3014 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3015 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3016 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3017 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3020 ok(size == sizeof(v2Cert), "Wrong size %d\n", size);
3021 ok(!memcmp(buf, v2Cert, size), "Got unexpected value\n");
3025 info.dwVersion = CERT_V3;
3026 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3027 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3028 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3029 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3032 ok(size == sizeof(v3Cert), "Wrong size %d\n", size);
3033 ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n");
3037 info.dwVersion = 3; /* Not a typo, CERT_V3 is 2 */
3038 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3039 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3042 ok(size == sizeof(v4Cert), "Wrong size %d\n", size);
3043 ok(!memcmp(buf, v4Cert, size), "Unexpected value\n");
3046 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
3047 * API doesn't prevent it)
3049 info.dwVersion = CERT_V1;
3050 info.cExtension = 1;
3051 info.rgExtension = &criticalExt;
3052 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3053 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3054 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3055 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3058 ok(size == sizeof(v1CertWithConstraints), "Wrong size %d\n", size);
3059 ok(!memcmp(buf, v1CertWithConstraints, size), "Got unexpected value\n");
3062 /* test v1 cert with a serial number */
3063 info.SerialNumber.cbData = sizeof(serialNum);
3064 info.SerialNumber.pbData = (BYTE *)serialNum;
3065 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3066 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3069 ok(size == sizeof(v1CertWithSerial), "Wrong size %d\n", size);
3070 ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n");
3073 /* Test v1 cert with an issuer name, serial number, and issuer unique id */
3074 info.dwVersion = CERT_V1;
3075 info.cExtension = 0;
3076 info.IssuerUniqueId.cbData = sizeof(serialNum);
3077 info.IssuerUniqueId.pbData = (BYTE *)serialNum;
3078 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3079 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3080 ok(ret || broken(GetLastError() == OSS_BAD_PTR /* Win98 */),
3081 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3084 ok(size == sizeof(v1CertWithIssuerUniqueId), "Wrong size %d\n", size);
3085 ok(!memcmp(buf, v1CertWithIssuerUniqueId, size),
3086 "Got unexpected value\n");
3089 /* Test v1 cert with an issuer name, a subject name, and a serial number */
3090 info.IssuerUniqueId.cbData = 0;
3091 info.IssuerUniqueId.pbData = NULL;
3092 info.cExtension = 1;
3093 info.rgExtension = &criticalExt;
3094 info.Issuer.cbData = sizeof(encodedCommonName);
3095 info.Issuer.pbData = (BYTE *)encodedCommonName;
3096 info.Subject.cbData = sizeof(encodedCommonName);
3097 info.Subject.pbData = (BYTE *)encodedCommonName;
3098 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3099 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3102 ok(size == sizeof(bigCert), "Wrong size %d\n", size);
3103 ok(!memcmp(buf, bigCert, size), "Got unexpected value\n");
3106 /* Add a public key */
3107 info.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3108 info.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
3109 info.SubjectPublicKeyInfo.PublicKey.pbData = (LPBYTE)aKey;
3110 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3111 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3114 ok(size == sizeof(v1CertWithPubKey) ||
3115 size == sizeof(v1CertWithPubKeyNoNull), "Wrong size %d\n", size);
3116 if (size == sizeof(v1CertWithPubKey))
3117 ok(!memcmp(buf, v1CertWithPubKey, size), "Got unexpected value\n");
3118 else if (size == sizeof(v1CertWithPubKeyNoNull))
3119 ok(!memcmp(buf, v1CertWithPubKeyNoNull, size),
3120 "Got unexpected value\n");
3123 /* Again add an issuer unique id */
3124 info.IssuerUniqueId.cbData = sizeof(serialNum);
3125 info.IssuerUniqueId.pbData = (BYTE *)serialNum;
3126 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3127 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3128 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3131 ok(size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId) ||
3132 size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull),
3133 "Wrong size %d\n", size);
3134 if (size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId))
3135 ok(!memcmp(buf, v1CertWithSubjectIssuerSerialAndIssuerUniqueId,
3136 size), "unexpected value\n");
3138 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull))
3140 v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull, size),
3141 "unexpected value\n");
3144 /* Remove the public key, and add a subject key identifier extension */
3145 info.IssuerUniqueId.cbData = 0;
3146 info.IssuerUniqueId.pbData = NULL;
3147 info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
3148 info.SubjectPublicKeyInfo.PublicKey.cbData = 0;
3149 info.SubjectPublicKeyInfo.PublicKey.pbData = NULL;
3150 ext.pszObjId = oid_subject_key_identifier;
3151 ext.fCritical = FALSE;
3152 ext.Value.cbData = sizeof(octetCommonNameValue);
3153 ext.Value.pbData = octetCommonNameValue;
3154 info.cExtension = 1;
3155 info.rgExtension = &ext;
3156 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3157 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3160 ok(size == sizeof(v1CertWithSubjectKeyId), "Wrong size %d\n", size);
3161 ok(!memcmp(buf, v1CertWithSubjectKeyId, size), "Unexpected value\n");
3166 static void test_decodeCertToBeSigned(DWORD dwEncoding)
3168 static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert, v4Cert,
3169 v1CertWithConstraints, v1CertWithSerial, v1CertWithIssuerUniqueId };
3174 /* Test with NULL pbEncoded */
3175 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 0,
3176 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3177 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
3178 GetLastError() == OSS_BAD_ARG /* Win9x */),
3179 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
3182 /* Crashes on win9x */
3183 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 1,
3184 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3185 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3186 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3188 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT or
3189 * CRYPT_E_ASN1_BADTAG, because at a minimum a cert must have a non-zero
3190 * serial number, an issuer, a subject, and a public key.
3192 for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++)
3194 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3195 corruptCerts[i], corruptCerts[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3197 ok(!ret, "Expected failure\n");
3199 /* The following succeeds, even though v1 certs are not allowed to have
3202 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3203 v1CertWithSubjectKeyId, sizeof(v1CertWithSubjectKeyId),
3204 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3205 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3208 CERT_INFO *info = (CERT_INFO *)buf;
3210 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3211 ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %d\n",
3213 ok(info->cExtension == 1, "expected 1 extension, got %d\n",
3217 /* The following also succeeds, even though V1 certs are not allowed to
3218 * have issuer unique ids.
3220 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3221 v1CertWithSubjectIssuerSerialAndIssuerUniqueId,
3222 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId),
3223 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3224 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3227 CERT_INFO *info = (CERT_INFO *)buf;
3229 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3230 ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %d\n",
3232 ok(info->IssuerUniqueId.cbData == sizeof(serialNum),
3233 "unexpected issuer unique id size %d\n", info->IssuerUniqueId.cbData);
3234 ok(!memcmp(info->IssuerUniqueId.pbData, serialNum, sizeof(serialNum)),
3235 "unexpected issuer unique id value\n");
3238 /* Now check with serial number, subject and issuer specified */
3239 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert,
3240 sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3241 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3244 CERT_INFO *info = (CERT_INFO *)buf;
3246 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3247 ok(info->SerialNumber.cbData == 1,
3248 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3249 ok(*info->SerialNumber.pbData == *serialNum,
3250 "Expected serial number %d, got %d\n", *serialNum,
3251 *info->SerialNumber.pbData);
3252 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3253 "Wrong size %d\n", info->Issuer.cbData);
3254 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3255 "Unexpected issuer\n");
3256 ok(info->Subject.cbData == sizeof(encodedCommonName),
3257 "Wrong size %d\n", info->Subject.cbData);
3258 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3259 info->Subject.cbData), "Unexpected subject\n");
3262 /* Check again with pub key specified */
3263 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3264 v1CertWithPubKey, sizeof(v1CertWithPubKey), CRYPT_DECODE_ALLOC_FLAG, NULL,
3266 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3269 CERT_INFO *info = (CERT_INFO *)buf;
3271 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3272 ok(info->SerialNumber.cbData == 1,
3273 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3274 ok(*info->SerialNumber.pbData == *serialNum,
3275 "Expected serial number %d, got %d\n", *serialNum,
3276 *info->SerialNumber.pbData);
3277 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3278 "Wrong size %d\n", info->Issuer.cbData);
3279 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3280 "Unexpected issuer\n");
3281 ok(info->Subject.cbData == sizeof(encodedCommonName),
3282 "Wrong size %d\n", info->Subject.cbData);
3283 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3284 info->Subject.cbData), "Unexpected subject\n");
3285 ok(!strcmp(info->SubjectPublicKeyInfo.Algorithm.pszObjId,
3286 szOID_RSA_RSA), "Expected szOID_RSA_RSA, got %s\n",
3287 info->SubjectPublicKeyInfo.Algorithm.pszObjId);
3288 ok(info->SubjectPublicKeyInfo.PublicKey.cbData == sizeof(aKey),
3289 "Wrong size %d\n", info->SubjectPublicKeyInfo.PublicKey.cbData);
3290 ok(!memcmp(info->SubjectPublicKeyInfo.PublicKey.pbData, aKey,
3291 sizeof(aKey)), "Unexpected public key\n");
3296 static const BYTE hash[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
3299 static const BYTE signedBigCert[] = {
3300 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
3301 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
3302 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
3303 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3304 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
3305 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
3306 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
3307 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
3308 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
3309 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3310 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
3311 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
3313 static void test_encodeCert(DWORD dwEncoding)
3315 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
3316 * also that bigCert is a NULL-terminated string, so don't count its
3317 * last byte (otherwise the signed cert won't decode.)
3319 CERT_SIGNED_CONTENT_INFO info = { { sizeof(bigCert), (BYTE *)bigCert },
3320 { NULL, { 0, NULL } }, { sizeof(hash), (BYTE *)hash, 0 } };
3325 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT, &info,
3326 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
3327 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3330 ok(bufSize == sizeof(signedBigCert), "Wrong size %d\n", bufSize);
3331 ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n");
3336 static void test_decodeCert(DWORD dwEncoding)
3342 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert,
3343 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3344 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3347 CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf;
3349 ok(info->ToBeSigned.cbData == sizeof(bigCert),
3350 "Wrong cert size %d\n", info->ToBeSigned.cbData);
3351 ok(!memcmp(info->ToBeSigned.pbData, bigCert, info->ToBeSigned.cbData),
3352 "Unexpected cert\n");
3353 ok(info->Signature.cbData == sizeof(hash),
3354 "Wrong signature size %d\n", info->Signature.cbData);
3355 ok(!memcmp(info->Signature.pbData, hash, info->Signature.cbData),
3356 "Unexpected signature\n");
3359 /* A signed cert decodes as a CERT_INFO too */
3360 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCert,
3361 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3362 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3365 CERT_INFO *info = (CERT_INFO *)buf;
3367 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3368 ok(info->SerialNumber.cbData == 1,
3369 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3370 ok(*info->SerialNumber.pbData == *serialNum,
3371 "Expected serial number %d, got %d\n", *serialNum,
3372 *info->SerialNumber.pbData);
3373 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3374 "Wrong size %d\n", info->Issuer.cbData);
3375 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3376 "Unexpected issuer\n");
3377 ok(info->Subject.cbData == sizeof(encodedCommonName),
3378 "Wrong size %d\n", info->Subject.cbData);
3379 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3380 info->Subject.cbData), "Unexpected subject\n");
3385 static const BYTE emptyDistPoint[] = { 0x30, 0x02, 0x30, 0x00 };
3386 static const BYTE distPointWithUrl[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3387 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3388 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3389 static const BYTE distPointWithReason[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3391 static const BYTE distPointWithIssuer[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3392 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3393 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3394 static const BYTE distPointWithUrlAndIssuer[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3395 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3396 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3397 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3398 0x2e, 0x6f, 0x72, 0x67 };
3399 static const BYTE crlReason = CRL_REASON_KEY_COMPROMISE |
3400 CRL_REASON_AFFILIATION_CHANGED;
3402 static void test_encodeCRLDistPoints(DWORD dwEncoding)
3404 CRL_DIST_POINTS_INFO info = { 0 };
3405 CRL_DIST_POINT point = { { 0 } };
3406 CERT_ALT_NAME_ENTRY entry = { 0 };
3411 /* Test with an empty info */
3412 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3413 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3414 ok(!ret && GetLastError() == E_INVALIDARG,
3415 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3416 /* Test with one empty dist point */
3417 info.cDistPoint = 1;
3418 info.rgDistPoint = &point;
3419 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3420 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3421 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3424 ok(size == sizeof(emptyDistPoint), "Wrong size %d\n", size);
3425 ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n");
3428 /* A dist point with an invalid name */
3429 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3430 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3431 U(entry).pwszURL = (LPWSTR)nihongoURL;
3432 U(point.DistPointName).FullName.cAltEntry = 1;
3433 U(point.DistPointName).FullName.rgAltEntry = &entry;
3434 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3435 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3436 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
3437 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
3438 /* The first invalid character is at index 7 */
3439 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
3440 "Expected invalid char at index 7, got %d\n",
3441 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
3442 /* A dist point with (just) a valid name */
3443 U(entry).pwszURL = (LPWSTR)url;
3444 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3445 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3446 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3449 ok(size == sizeof(distPointWithUrl), "Wrong size %d\n", size);
3450 ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n");
3453 /* A dist point with (just) reason flags */
3454 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3455 point.ReasonFlags.cbData = sizeof(crlReason);
3456 point.ReasonFlags.pbData = (LPBYTE)&crlReason;
3457 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3458 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3459 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3462 ok(size == sizeof(distPointWithReason), "Wrong size %d\n", size);
3463 ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n");
3466 /* A dist point with just an issuer */
3467 point.ReasonFlags.cbData = 0;
3468 point.CRLIssuer.cAltEntry = 1;
3469 point.CRLIssuer.rgAltEntry = &entry;
3470 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3471 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3472 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3475 ok(size == sizeof(distPointWithIssuer), "Wrong size %d\n", size);
3476 ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n");
3479 /* A dist point with both a name and an issuer */
3480 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3481 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3482 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3483 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3486 ok(size == sizeof(distPointWithUrlAndIssuer),
3487 "Wrong size %d\n", size);
3488 ok(!memcmp(buf, distPointWithUrlAndIssuer, size), "Unexpected value\n");
3493 static void test_decodeCRLDistPoints(DWORD dwEncoding)
3498 PCRL_DIST_POINTS_INFO info;
3499 PCRL_DIST_POINT point;
3500 PCERT_ALT_NAME_ENTRY entry;
3502 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3503 emptyDistPoint, emptyDistPoint[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3505 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3508 info = (PCRL_DIST_POINTS_INFO)buf;
3509 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3510 "Wrong size %d\n", size);
3511 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3513 point = info->rgDistPoint;
3514 ok(point->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_NO_NAME,
3515 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3516 point->DistPointName.dwDistPointNameChoice);
3517 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3518 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3521 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3522 distPointWithUrl, distPointWithUrl[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3524 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3527 info = (PCRL_DIST_POINTS_INFO)buf;
3528 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3529 "Wrong size %d\n", size);
3530 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3532 point = info->rgDistPoint;
3533 ok(point->DistPointName.dwDistPointNameChoice ==
3534 CRL_DIST_POINT_FULL_NAME,
3535 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3536 point->DistPointName.dwDistPointNameChoice);
3537 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3538 "Expected 1 name entry, got %d\n",
3539 U(point->DistPointName).FullName.cAltEntry);
3540 entry = U(point->DistPointName).FullName.rgAltEntry;
3541 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3542 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3543 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3544 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3545 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3548 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3549 distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
3551 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3554 info = (PCRL_DIST_POINTS_INFO)buf;
3555 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3556 "Wrong size %d\n", size);
3557 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3559 point = info->rgDistPoint;
3560 ok(point->DistPointName.dwDistPointNameChoice ==
3561 CRL_DIST_POINT_NO_NAME,
3562 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3563 point->DistPointName.dwDistPointNameChoice);
3564 ok(point->ReasonFlags.cbData == sizeof(crlReason),
3565 "Expected reason length\n");
3566 ok(!memcmp(point->ReasonFlags.pbData, &crlReason, sizeof(crlReason)),
3567 "Unexpected reason\n");
3568 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3571 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3572 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2,
3573 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3574 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3577 info = (PCRL_DIST_POINTS_INFO)buf;
3578 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3579 "Wrong size %d\n", size);
3580 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3582 point = info->rgDistPoint;
3583 ok(point->DistPointName.dwDistPointNameChoice ==
3584 CRL_DIST_POINT_FULL_NAME,
3585 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3586 point->DistPointName.dwDistPointNameChoice);
3587 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3588 "Expected 1 name entry, got %d\n",
3589 U(point->DistPointName).FullName.cAltEntry);
3590 entry = U(point->DistPointName).FullName.rgAltEntry;
3591 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3592 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3593 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3594 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3595 ok(point->CRLIssuer.cAltEntry == 1,
3596 "Expected 1 issuer entry, got %d\n", point->CRLIssuer.cAltEntry);
3597 entry = point->CRLIssuer.rgAltEntry;
3598 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3599 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3600 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3605 static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3606 static const BYTE emptyNameIDP[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3607 static const BYTE urlIDP[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3608 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3611 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding)
3616 CRL_ISSUING_DIST_POINT point = { { 0 } };
3617 CERT_ALT_NAME_ENTRY entry;
3619 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, NULL,
3620 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3621 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3623 skip("no X509_ISSUING_DIST_POINT encode support\n");
3626 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3627 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3628 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3629 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3630 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3633 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
3634 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
3637 /* nonsensical flags */
3638 point.fOnlyContainsUserCerts = TRUE;
3639 point.fOnlyContainsCACerts = TRUE;
3640 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3641 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3642 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3645 ok(size == sizeof(badFlagsIDP), "Unexpected size %d\n", size);
3646 ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n");
3649 /* unimplemented name type */
3650 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3651 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_ISSUER_RDN_NAME;
3652 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3653 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3654 ok(!ret && GetLastError() == E_INVALIDARG,
3655 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3657 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3658 U(point.DistPointName).FullName.cAltEntry = 0;
3659 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3660 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3661 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3664 ok(size == sizeof(emptyNameIDP), "Unexpected size %d\n", size);
3665 ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n");
3668 /* name with URL entry */
3669 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3670 U(entry).pwszURL = (LPWSTR)url;
3671 U(point.DistPointName).FullName.cAltEntry = 1;
3672 U(point.DistPointName).FullName.rgAltEntry = &entry;
3673 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3674 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3675 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3678 ok(size == sizeof(urlIDP), "Unexpected size %d\n", size);
3679 ok(!memcmp(buf, urlIDP, size), "Unexpected value\n");
3684 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY *expected,
3685 const CERT_ALT_NAME_ENTRY *got)
3687 ok(expected->dwAltNameChoice == got->dwAltNameChoice,
3688 "Expected name choice %d, got %d\n", expected->dwAltNameChoice,
3689 got->dwAltNameChoice);
3690 if (expected->dwAltNameChoice == got->dwAltNameChoice)
3692 switch (got->dwAltNameChoice)
3694 case CERT_ALT_NAME_RFC822_NAME:
3695 case CERT_ALT_NAME_DNS_NAME:
3696 case CERT_ALT_NAME_EDI_PARTY_NAME:
3697 case CERT_ALT_NAME_URL:
3698 case CERT_ALT_NAME_REGISTERED_ID:
3699 ok((!U(*expected).pwszURL && !U(*got).pwszURL) ||
3700 (!U(*expected).pwszURL && !lstrlenW(U(*got).pwszURL)) ||
3701 (!U(*got).pwszURL && !lstrlenW(U(*expected).pwszURL)) ||
3702 !lstrcmpW(U(*expected).pwszURL, U(*got).pwszURL),
3703 "Unexpected name\n");
3705 case CERT_ALT_NAME_X400_ADDRESS:
3706 case CERT_ALT_NAME_DIRECTORY_NAME:
3707 case CERT_ALT_NAME_IP_ADDRESS:
3708 ok(U(*got).IPAddress.cbData == U(*expected).IPAddress.cbData,
3709 "Unexpected IP address length %d\n", U(*got).IPAddress.cbData);
3710 ok(!memcmp(U(*got).IPAddress.pbData, U(*got).IPAddress.pbData,
3711 U(*got).IPAddress.cbData), "Unexpected value\n");
3717 static void compareAltNameInfo(const CERT_ALT_NAME_INFO *expected,
3718 const CERT_ALT_NAME_INFO *got)
3722 ok(expected->cAltEntry == got->cAltEntry, "Expected %d entries, got %d\n",
3723 expected->cAltEntry, got->cAltEntry);
3724 for (i = 0; i < min(expected->cAltEntry, got->cAltEntry); i++)
3725 compareAltNameEntry(&expected->rgAltEntry[i], &got->rgAltEntry[i]);
3728 static void compareDistPointName(const CRL_DIST_POINT_NAME *expected,
3729 const CRL_DIST_POINT_NAME *got)
3731 ok(got->dwDistPointNameChoice == expected->dwDistPointNameChoice,
3732 "Unexpected name choice %d\n", got->dwDistPointNameChoice);
3733 if (got->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME)
3734 compareAltNameInfo(&(U(*expected).FullName), &(U(*got).FullName));
3737 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT *expected,
3738 const CRL_ISSUING_DIST_POINT *got)
3740 compareDistPointName(&expected->DistPointName, &got->DistPointName);
3741 ok(got->fOnlyContainsUserCerts == expected->fOnlyContainsUserCerts,
3742 "Unexpected fOnlyContainsUserCerts\n");
3743 ok(got->fOnlyContainsCACerts == expected->fOnlyContainsCACerts,
3744 "Unexpected fOnlyContainsCACerts\n");
3745 ok(got->OnlySomeReasonFlags.cbData == expected->OnlySomeReasonFlags.cbData,
3746 "Unexpected reason flags\n");
3747 ok(got->fIndirectCRL == expected->fIndirectCRL,
3748 "Unexpected fIndirectCRL\n");
3751 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding)
3756 CRL_ISSUING_DIST_POINT point = { { 0 } };
3758 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3759 emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3761 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3763 skip("no X509_ISSUING_DIST_POINT decode support\n");
3766 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3769 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3772 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3773 badFlagsIDP, badFlagsIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3775 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3778 point.fOnlyContainsUserCerts = point.fOnlyContainsCACerts = TRUE;
3779 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3782 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3783 emptyNameIDP, emptyNameIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3785 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3788 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3789 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3790 U(point.DistPointName).FullName.cAltEntry = 0;
3791 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3794 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3795 urlIDP, urlIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3796 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3799 CERT_ALT_NAME_ENTRY entry;
3801 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3802 U(entry).pwszURL = (LPWSTR)url;
3803 U(point.DistPointName).FullName.cAltEntry = 1;
3804 U(point.DistPointName).FullName.rgAltEntry = &entry;
3805 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3810 static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3811 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3813 static const BYTE v2CRL[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3814 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3815 0x30, 0x30, 0x30, 0x30, 0x5a };
3816 static const BYTE v1CRLWithIssuer[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3817 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3818 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3819 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3821 static const BYTE v1CRLWithIssuerAndEmptyEntry[] = { 0x30, 0x43, 0x30, 0x02,
3822 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3823 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3824 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3825 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3826 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3827 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3828 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3829 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3830 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3831 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3832 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3833 static const BYTE v1CRLWithEntryExt[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3834 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3835 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3836 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3837 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3838 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3839 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3840 static const BYTE v1CRLWithExt[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3841 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3842 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3843 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
3844 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3845 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
3846 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3847 static const BYTE v2CRLWithExt[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
3848 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
3849 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
3850 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
3851 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
3852 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
3853 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3855 static void test_encodeCRLToBeSigned(DWORD dwEncoding)
3860 CRL_INFO info = { 0 };
3861 CRL_ENTRY entry = { { 0 }, { 0 }, 0, 0 };
3863 /* Test with a V1 CRL */
3864 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3865 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3866 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3867 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3870 ok(size == sizeof(v1CRL), "Wrong size %d\n", size);
3871 ok(!memcmp(buf, v1CRL, size), "Got unexpected value\n");
3875 info.dwVersion = CRL_V2;
3876 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3877 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3878 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3879 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3882 ok(size == v2CRL[1] + 2, "Expected size %d, got %d\n",
3883 v2CRL[1] + 2, size);
3884 ok(!memcmp(buf, v2CRL, size), "Got unexpected value\n");
3887 /* v1 CRL with a name */
3888 info.dwVersion = CRL_V1;
3889 info.Issuer.cbData = sizeof(encodedCommonName);
3890 info.Issuer.pbData = (BYTE *)encodedCommonName;
3891 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3892 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3893 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3896 ok(size == sizeof(v1CRLWithIssuer), "Wrong size %d\n", size);
3897 ok(!memcmp(buf, v1CRLWithIssuer, size), "Got unexpected value\n");
3902 /* v1 CRL with a name and a NULL entry pointer (crashes on win9x) */
3904 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3905 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3906 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3907 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3909 /* now set an empty entry */
3911 info.rgCRLEntry = &entry;
3912 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3913 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3916 ok(size == sizeof(v1CRLWithIssuerAndEmptyEntry),
3917 "Wrong size %d\n", size);
3918 ok(!memcmp(buf, v1CRLWithIssuerAndEmptyEntry, size),
3919 "Got unexpected value\n");
3922 /* an entry with a serial number */
3923 entry.SerialNumber.cbData = sizeof(serialNum);
3924 entry.SerialNumber.pbData = (BYTE *)serialNum;
3925 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3926 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3929 ok(size == sizeof(v1CRLWithIssuerAndEntry),
3930 "Wrong size %d\n", size);
3931 ok(!memcmp(buf, v1CRLWithIssuerAndEntry, size),
3932 "Got unexpected value\n");
3935 /* an entry with an extension */
3936 entry.cExtension = 1;
3937 entry.rgExtension = &criticalExt;
3938 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3939 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3940 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3943 ok(size == sizeof(v1CRLWithEntryExt), "Wrong size %d\n", size);
3944 ok(!memcmp(buf, v1CRLWithEntryExt, size), "Got unexpected value\n");
3947 /* a CRL with an extension */
3948 entry.cExtension = 0;
3949 info.cExtension = 1;
3950 info.rgExtension = &criticalExt;
3951 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3952 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3953 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3956 ok(size == sizeof(v1CRLWithExt), "Wrong size %d\n", size);
3957 ok(!memcmp(buf, v1CRLWithExt, size), "Got unexpected value\n");
3960 /* a v2 CRL with an extension, this time non-critical */
3961 info.dwVersion = CRL_V2;
3962 info.rgExtension = &nonCriticalExt;
3963 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3964 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3965 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3968 ok(size == sizeof(v2CRLWithExt), "Wrong size %d\n", size);
3969 ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n");
3974 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
3975 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
3976 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
3977 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
3978 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
3979 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
3980 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
3981 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
3982 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
3983 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
3984 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
3985 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
3986 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
3987 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
3988 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
3989 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
3990 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
3991 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
3992 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
3993 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
3994 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
3995 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
3996 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
3997 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
3998 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
3999 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
4000 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
4001 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
4002 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
4003 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
4004 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
4005 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
4006 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
4007 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
4009 static const BYTE verisignCRLWithLotsOfEntries[] = {
4010 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
4011 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
4012 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
4013 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
4014 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
4015 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
4016 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
4017 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
4018 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
4019 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
4020 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
4021 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
4022 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
4023 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
4024 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
4025 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
4026 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
4027 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
4028 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
4029 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
4030 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
4031 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
4032 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
4033 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
4034 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
4035 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
4036 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
4037 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
4038 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
4039 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
4040 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
4041 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
4042 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
4043 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
4044 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
4045 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
4046 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
4047 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
4048 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
4049 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
4050 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
4051 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
4052 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
4053 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
4054 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
4055 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
4056 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
4057 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
4058 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
4059 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
4060 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
4061 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
4062 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
4063 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
4064 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
4065 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
4066 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
4067 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
4068 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
4069 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
4070 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
4071 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
4072 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
4073 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
4074 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
4075 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
4076 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
4077 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
4078 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
4079 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
4080 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
4081 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
4082 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
4083 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
4084 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
4085 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
4086 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
4087 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
4088 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
4089 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
4090 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
4091 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
4092 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
4093 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
4094 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
4095 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
4096 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
4097 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
4098 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
4099 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
4100 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
4101 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
4102 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
4103 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
4104 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
4105 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
4106 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
4107 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
4108 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
4109 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
4110 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
4111 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
4112 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
4113 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
4114 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
4115 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
4116 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
4117 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
4118 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
4119 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
4120 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
4121 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
4122 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
4123 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
4124 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
4125 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
4126 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
4127 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
4128 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
4129 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
4130 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
4131 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
4132 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
4133 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
4134 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
4135 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
4136 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
4137 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
4138 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
4139 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
4140 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
4141 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
4142 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
4143 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
4144 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
4145 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
4146 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
4147 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
4148 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
4149 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
4150 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
4151 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
4152 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
4153 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
4154 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
4155 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
4156 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
4157 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
4158 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
4159 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
4160 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
4161 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
4162 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
4163 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
4164 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
4165 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
4166 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
4167 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
4168 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
4169 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
4170 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
4171 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
4172 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
4173 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
4174 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
4175 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
4176 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
4177 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
4178 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
4179 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
4180 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
4181 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
4182 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
4183 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
4184 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
4185 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
4186 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
4187 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
4188 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
4189 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
4190 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
4191 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
4192 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
4193 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
4194 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
4195 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
4196 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
4197 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
4198 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
4199 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
4200 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
4201 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
4202 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
4203 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
4204 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
4205 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
4206 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
4207 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
4208 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
4209 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
4210 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
4211 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
4212 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
4213 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
4214 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
4215 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
4216 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
4217 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
4218 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
4219 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
4220 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
4221 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
4222 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
4223 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
4224 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
4225 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
4226 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
4227 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
4228 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
4229 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
4230 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
4231 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
4232 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
4233 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
4234 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
4235 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
4236 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
4237 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
4238 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
4239 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
4240 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
4241 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
4242 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
4243 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
4244 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
4245 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
4246 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
4247 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
4248 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
4249 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
4250 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
4251 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
4252 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
4253 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
4254 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
4255 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
4256 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
4257 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
4258 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
4259 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
4260 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
4261 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
4262 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
4263 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
4264 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
4265 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
4266 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
4267 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
4268 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
4269 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
4270 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
4271 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
4272 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
4273 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
4274 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
4275 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
4276 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
4277 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
4278 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
4279 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
4280 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
4281 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
4282 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
4283 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
4284 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
4285 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
4286 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
4287 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
4288 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
4289 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
4290 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
4291 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
4292 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
4293 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
4294 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
4295 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
4296 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
4297 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
4298 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
4299 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
4300 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
4301 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
4302 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
4303 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
4304 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
4305 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
4306 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
4307 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
4308 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
4309 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
4310 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
4311 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
4312 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
4313 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4314 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4315 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4316 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4317 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4318 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4319 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4320 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4321 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4322 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4323 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4324 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4325 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4326 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4327 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4328 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4329 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4330 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4331 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4332 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4333 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4334 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4335 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4336 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4337 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4338 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4339 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4340 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4341 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4342 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4343 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4344 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4345 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4346 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4347 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4348 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4349 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4350 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4351 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4352 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4353 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4354 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4355 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4356 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4357 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4358 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4359 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4360 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4361 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4362 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4363 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4364 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4365 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4366 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4367 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4368 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4369 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4370 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4371 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4372 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4373 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4374 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4375 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4376 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4377 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4378 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4379 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4380 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4381 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4382 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4383 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4384 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4385 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4386 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4387 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4388 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4389 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4390 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4391 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4392 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4393 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4394 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4395 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4396 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4397 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4398 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4399 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4400 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4401 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4402 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4403 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4404 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4405 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4406 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4407 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4408 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4409 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4410 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4411 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4412 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4413 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4414 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4415 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4416 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4417 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4418 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4419 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4420 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4421 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4422 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4423 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4424 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4425 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4426 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4427 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4428 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4429 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4430 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4431 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4432 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4433 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4434 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4435 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4436 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4437 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4438 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4439 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4440 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4441 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4442 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4443 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4444 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4445 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4446 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4447 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4448 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4449 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4450 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4451 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4452 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4453 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4454 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4455 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4456 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4457 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4458 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4459 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4460 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4461 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4462 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4463 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4464 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4465 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4466 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4467 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4468 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4469 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4470 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4471 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4472 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4473 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4474 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4475 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4476 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4477 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4478 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4479 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4480 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4481 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4482 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4483 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4484 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4485 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4486 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4487 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4488 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4489 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4490 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4491 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4492 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4493 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4494 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4495 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4496 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4497 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4498 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4499 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4500 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4501 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4502 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4503 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4504 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4505 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4506 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4507 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4508 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4509 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4510 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4511 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4512 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4513 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4514 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4515 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4516 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4517 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4519 static void test_decodeCRLToBeSigned(DWORD dwEncoding)
4521 static const BYTE *corruptCRLs[] = { v1CRL, v2CRL };
4526 for (i = 0; i < sizeof(corruptCRLs) / sizeof(corruptCRLs[0]); i++)
4528 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4529 corruptCRLs[i], corruptCRLs[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4531 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4532 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4533 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4536 /* at a minimum, a CRL must contain an issuer: */
4537 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4538 v1CRLWithIssuer, v1CRLWithIssuer[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4540 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4543 CRL_INFO *info = (CRL_INFO *)buf;
4545 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4546 ok(info->cCRLEntry == 0, "Expected 0 CRL entries, got %d\n",
4548 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4549 "Wrong issuer size %d\n", info->Issuer.cbData);
4550 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4551 "Unexpected issuer\n");
4554 /* check decoding with an empty CRL entry */
4555 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4556 v1CRLWithIssuerAndEmptyEntry, v1CRLWithIssuerAndEmptyEntry[1] + 2,
4557 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4558 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4559 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4560 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4562 /* with a real CRL entry */
4563 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4564 v1CRLWithIssuerAndEntry, v1CRLWithIssuerAndEntry[1] + 2,
4565 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4566 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4569 CRL_INFO *info = (CRL_INFO *)buf;
4572 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4573 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4575 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4576 entry = info->rgCRLEntry;
4577 ok(entry->SerialNumber.cbData == 1,
4578 "Expected serial number size 1, got %d\n",
4579 entry->SerialNumber.cbData);
4580 ok(*entry->SerialNumber.pbData == *serialNum,
4581 "Expected serial number %d, got %d\n", *serialNum,
4582 *entry->SerialNumber.pbData);
4583 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4584 "Wrong issuer size %d\n", info->Issuer.cbData);
4585 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4586 "Unexpected issuer\n");
4589 /* a real CRL from verisign that has extensions */
4590 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4591 verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG,
4593 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4596 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 entry = info->rgCRLEntry;
4604 ok(info->cExtension == 2, "Expected 2 extensions, got %d\n",
4608 /* another real CRL from verisign that has lots of entries */
4609 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4610 verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries),
4611 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4612 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4615 CRL_INFO *info = (CRL_INFO *)buf;
4617 ok(size >= sizeof(CRL_INFO), "Got size %d\n", size);
4618 ok(info->cCRLEntry == 209, "Expected 209 CRL entries, got %d\n",
4620 ok(info->cExtension == 0, "Expected 0 extensions, got %d\n",
4624 /* and finally, with an extension */
4625 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4626 v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4628 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4631 CRL_INFO *info = (CRL_INFO *)buf;
4634 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4635 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4637 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4638 entry = info->rgCRLEntry;
4639 ok(entry->SerialNumber.cbData == 1,
4640 "Expected serial number size 1, got %d\n",
4641 entry->SerialNumber.cbData);
4642 ok(*entry->SerialNumber.pbData == *serialNum,
4643 "Expected serial number %d, got %d\n", *serialNum,
4644 *entry->SerialNumber.pbData);
4645 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4646 "Wrong issuer size %d\n", info->Issuer.cbData);
4647 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4648 "Unexpected issuer\n");
4649 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4653 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4654 v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4656 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4659 CRL_INFO *info = (CRL_INFO *)buf;
4661 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4667 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
4668 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
4669 static const BYTE encodedUsage[] = {
4670 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4671 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4672 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4674 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding)
4679 CERT_ENHKEY_USAGE usage;
4681 /* Test with empty usage */
4682 usage.cUsageIdentifier = 0;
4683 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4684 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4685 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4688 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
4689 ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n");
4692 /* Test with a few usages */
4693 usage.cUsageIdentifier = sizeof(keyUsages) / sizeof(keyUsages[0]);
4694 usage.rgpszUsageIdentifier = (LPSTR *)keyUsages;
4695 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4696 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4697 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4700 ok(size == sizeof(encodedUsage), "Wrong size %d\n", size);
4701 ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n");
4706 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding)
4712 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4713 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4715 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4718 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4720 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4721 "Wrong size %d\n", size);
4722 ok(usage->cUsageIdentifier == 0, "Expected 0 CRL entries, got %d\n",
4723 usage->cUsageIdentifier);
4726 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4727 encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL,
4729 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4732 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4735 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4736 "Wrong size %d\n", size);
4737 ok(usage->cUsageIdentifier == sizeof(keyUsages) / sizeof(keyUsages[0]),
4738 "Wrong CRL entries count %d\n", usage->cUsageIdentifier);
4739 for (i = 0; i < usage->cUsageIdentifier; i++)
4740 ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]),
4741 "Expected OID %s, got %s\n", keyUsages[i],
4742 usage->rgpszUsageIdentifier[i]);
4747 static BYTE keyId[] = { 1,2,3,4 };
4748 static const BYTE authorityKeyIdWithId[] = {
4749 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4750 static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4751 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4752 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4753 static const BYTE authorityKeyIdWithSerial[] = { 0x30,0x03,0x82,0x01,0x01 };
4755 static void test_encodeAuthorityKeyId(DWORD dwEncoding)
4757 CERT_AUTHORITY_KEY_ID_INFO info = { { 0 } };
4762 /* Test with empty id */
4763 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4764 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4765 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4768 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4769 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4772 /* With just a key id */
4773 info.KeyId.cbData = sizeof(keyId);
4774 info.KeyId.pbData = keyId;
4775 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4776 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4777 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4780 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", size);
4781 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4784 /* With just an issuer */
4785 info.KeyId.cbData = 0;
4786 info.CertIssuer.cbData = sizeof(encodedCommonName);
4787 info.CertIssuer.pbData = (BYTE *)encodedCommonName;
4788 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4789 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4790 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4793 ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %d\n",
4795 ok(!memcmp(buf, authorityKeyIdWithIssuer, size), "Unexpected value\n");
4798 /* With just a serial number */
4799 info.CertIssuer.cbData = 0;
4800 info.CertSerialNumber.cbData = sizeof(serialNum);
4801 info.CertSerialNumber.pbData = (BYTE *)serialNum;
4802 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4803 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4804 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4807 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4809 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4814 static void test_decodeAuthorityKeyId(DWORD dwEncoding)
4820 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4821 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4823 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4826 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4828 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4830 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4831 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4832 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4835 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4836 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4837 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4838 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4841 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4843 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4845 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4846 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4847 "Unexpected key id\n");
4848 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4849 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4852 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4853 authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer),
4854 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4855 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4858 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4860 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4862 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4863 ok(info->CertIssuer.cbData == sizeof(encodedCommonName),
4864 "Unexpected issuer len\n");
4865 ok(!memcmp(info->CertIssuer.pbData, encodedCommonName,
4866 sizeof(encodedCommonName)), "Unexpected issuer\n");
4867 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4870 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4871 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4872 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4873 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4876 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4878 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4880 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4881 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4882 ok(info->CertSerialNumber.cbData == sizeof(serialNum),
4883 "Unexpected serial number len\n");
4884 ok(!memcmp(info->CertSerialNumber.pbData, serialNum, sizeof(serialNum)),
4885 "Unexpected serial number\n");
4890 static const BYTE authorityKeyIdWithIssuerUrl[] = { 0x30,0x15,0xa1,0x13,0x86,
4891 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
4894 static void test_encodeAuthorityKeyId2(DWORD dwEncoding)
4896 CERT_AUTHORITY_KEY_ID2_INFO info = { { 0 } };
4897 CERT_ALT_NAME_ENTRY entry = { 0 };
4902 /* Test with empty id */
4903 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4904 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4905 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4908 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4909 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4912 /* With just a key id */
4913 info.KeyId.cbData = sizeof(keyId);
4914 info.KeyId.pbData = keyId;
4915 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4916 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4917 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4920 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n",
4922 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4925 /* With a bogus issuer name */
4926 info.KeyId.cbData = 0;
4927 info.AuthorityCertIssuer.cAltEntry = 1;
4928 info.AuthorityCertIssuer.rgAltEntry = &entry;
4929 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4930 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4931 ok(!ret && GetLastError() == E_INVALIDARG,
4932 "Expected E_INVALIDARG, got %08x\n", GetLastError());
4933 /* With an issuer name */
4934 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
4935 U(entry).pwszURL = (LPWSTR)url;
4936 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4937 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4938 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4941 ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %d\n",
4943 ok(!memcmp(buf, authorityKeyIdWithIssuerUrl, size),
4944 "Unexpected value\n");
4947 /* With just a serial number */
4948 info.AuthorityCertIssuer.cAltEntry = 0;
4949 info.AuthorityCertSerialNumber.cbData = sizeof(serialNum);
4950 info.AuthorityCertSerialNumber.pbData = (BYTE *)serialNum;
4951 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4952 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4953 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4956 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4958 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4963 static void test_decodeAuthorityKeyId2(DWORD dwEncoding)
4969 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4970 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4972 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4975 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4977 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4979 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4980 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4981 "Expected no issuer name entries\n");
4982 ok(info->AuthorityCertSerialNumber.cbData == 0,
4983 "Expected no serial number\n");
4986 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4987 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4988 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4989 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4992 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4994 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4996 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4997 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4998 "Unexpected key id\n");
4999 ok(info->AuthorityCertIssuer.cAltEntry == 0,
5000 "Expected no issuer name entries\n");
5001 ok(info->AuthorityCertSerialNumber.cbData == 0,
5002 "Expected no serial number\n");
5005 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
5006 authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl),
5007 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5008 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5011 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
5013 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
5015 ok(info->KeyId.cbData == 0, "Expected no key id\n");
5016 ok(info->AuthorityCertIssuer.cAltEntry == 1,
5017 "Expected 1 issuer entry, got %d\n",
5018 info->AuthorityCertIssuer.cAltEntry);
5019 ok(info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice ==
5020 CERT_ALT_NAME_URL, "Expected CERT_ALT_NAME_URL, got %d\n",
5021 info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice);
5022 ok(!lstrcmpW(U(info->AuthorityCertIssuer.rgAltEntry[0]).pwszURL,
5023 url), "Unexpected URL\n");
5024 ok(info->AuthorityCertSerialNumber.cbData == 0,
5025 "Expected no serial number\n");
5028 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
5029 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
5030 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5031 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5034 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
5036 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
5038 ok(info->KeyId.cbData == 0, "Expected no key id\n");
5039 ok(info->AuthorityCertIssuer.cAltEntry == 0,
5040 "Expected no issuer name entries\n");
5041 ok(info->AuthorityCertSerialNumber.cbData == sizeof(serialNum),
5042 "Unexpected serial number len\n");
5043 ok(!memcmp(info->AuthorityCertSerialNumber.pbData, serialNum,
5044 sizeof(serialNum)), "Unexpected serial number\n");
5049 static const BYTE authorityInfoAccessWithUrl[] = {
5050 0x30,0x19,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
5051 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5052 static const BYTE authorityInfoAccessWithUrlAndIPAddr[] = {
5053 0x30,0x29,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
5054 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x0e,0x06,
5055 0x02,0x2d,0x06,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5057 static void test_encodeAuthorityInfoAccess(DWORD dwEncoding)
5059 static char oid1[] = "1.2.3";
5060 static char oid2[] = "1.5.6";
5064 CERT_ACCESS_DESCRIPTION accessDescription[2];
5065 CERT_AUTHORITY_INFO_ACCESS aia;
5067 memset(accessDescription, 0, sizeof(accessDescription));
5069 aia.rgAccDescr = NULL;
5070 /* Having no access descriptions is allowed */
5071 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5072 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5073 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5076 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
5077 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
5081 /* It can't have an empty access method */
5083 aia.rgAccDescr = accessDescription;
5084 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5085 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5086 ok(!ret && (GetLastError() == E_INVALIDARG ||
5087 GetLastError() == OSS_LIMITED /* Win9x */),
5088 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
5089 /* It can't have an empty location */
5090 accessDescription[0].pszAccessMethod = oid1;
5091 SetLastError(0xdeadbeef);
5092 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5093 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5094 ok(!ret && GetLastError() == E_INVALIDARG,
5095 "expected E_INVALIDARG, got %08x\n", GetLastError());
5096 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5097 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
5098 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5099 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5100 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5103 ok(size == sizeof(authorityInfoAccessWithUrl), "unexpected size %d\n",
5105 ok(!memcmp(buf, authorityInfoAccessWithUrl, size),
5106 "unexpected value\n");
5110 accessDescription[1].pszAccessMethod = oid2;
5111 accessDescription[1].AccessLocation.dwAltNameChoice =
5112 CERT_ALT_NAME_IP_ADDRESS;
5113 U(accessDescription[1].AccessLocation).IPAddress.cbData =
5114 sizeof(encodedIPAddr);
5115 U(accessDescription[1].AccessLocation).IPAddress.pbData =
5116 (LPBYTE)encodedIPAddr;
5118 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5119 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5120 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5123 ok(size == sizeof(authorityInfoAccessWithUrlAndIPAddr),
5124 "unexpected size %d\n", size);
5125 ok(!memcmp(buf, authorityInfoAccessWithUrlAndIPAddr, size),
5126 "unexpected value\n");
5132 static void compareAuthorityInfoAccess(LPCSTR header,
5133 const CERT_AUTHORITY_INFO_ACCESS *expected,
5134 const CERT_AUTHORITY_INFO_ACCESS *got)
5138 ok(expected->cAccDescr == got->cAccDescr,
5139 "%s: expected %d access descriptions, got %d\n", header,
5140 expected->cAccDescr, got->cAccDescr);
5141 for (i = 0; i < expected->cAccDescr; i++)
5143 ok(!strcmp(expected->rgAccDescr[i].pszAccessMethod,
5144 got->rgAccDescr[i].pszAccessMethod), "%s[%d]: expected %s, got %s\n",
5145 header, i, expected->rgAccDescr[i].pszAccessMethod,
5146 got->rgAccDescr[i].pszAccessMethod);
5147 compareAltNameEntry(&expected->rgAccDescr[i].AccessLocation,
5148 &got->rgAccDescr[i].AccessLocation);
5152 static void test_decodeAuthorityInfoAccess(DWORD dwEncoding)
5154 static char oid1[] = "1.2.3";
5155 static char oid2[] = "1.5.6";
5160 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5161 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
5163 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5166 CERT_AUTHORITY_INFO_ACCESS aia = { 0, NULL };
5168 compareAuthorityInfoAccess("empty AIA", &aia,
5169 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5173 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5174 authorityInfoAccessWithUrl, sizeof(authorityInfoAccessWithUrl),
5175 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5176 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5179 CERT_ACCESS_DESCRIPTION accessDescription;
5180 CERT_AUTHORITY_INFO_ACCESS aia;
5182 accessDescription.pszAccessMethod = oid1;
5183 accessDescription.AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5184 U(accessDescription.AccessLocation).pwszURL = (LPWSTR)url;
5186 aia.rgAccDescr = &accessDescription;
5187 compareAuthorityInfoAccess("AIA with URL", &aia,
5188 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5192 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5193 authorityInfoAccessWithUrlAndIPAddr,
5194 sizeof(authorityInfoAccessWithUrlAndIPAddr), CRYPT_DECODE_ALLOC_FLAG,
5196 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5199 CERT_ACCESS_DESCRIPTION accessDescription[2];
5200 CERT_AUTHORITY_INFO_ACCESS aia;
5202 accessDescription[0].pszAccessMethod = oid1;
5203 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5204 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
5205 accessDescription[1].pszAccessMethod = oid2;
5206 accessDescription[1].AccessLocation.dwAltNameChoice =
5207 CERT_ALT_NAME_IP_ADDRESS;
5208 U(accessDescription[1].AccessLocation).IPAddress.cbData =
5209 sizeof(encodedIPAddr);
5210 U(accessDescription[1].AccessLocation).IPAddress.pbData =
5211 (LPBYTE)encodedIPAddr;
5213 aia.rgAccDescr = accessDescription;
5214 compareAuthorityInfoAccess("AIA with URL and IP addr", &aia,
5215 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5221 static const BYTE emptyCTL[] = {
5222 0x30,0x17,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5223 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5224 static const BYTE emptyCTLWithVersion1[] = {
5225 0x30,0x1a,0x02,0x01,0x01,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5226 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5227 static const BYTE ctlWithUsageIdentifier[] = {
5228 0x30,0x1b,0x30,0x04,0x06,0x02,0x2a,0x03,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
5229 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5230 static const BYTE ctlWithListIdentifier[] = {
5231 0x30,0x1a,0x30,0x00,0x04,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5232 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5233 static const BYTE ctlWithSequenceNumber[] = {
5234 0x30,0x1a,0x30,0x00,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5235 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5236 static const BYTE ctlWithThisUpdate[] = {
5237 0x30,0x15,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5238 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5239 static const BYTE ctlWithThisAndNextUpdate[] = {
5240 0x30,0x24,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5241 0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5242 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5243 static const BYTE ctlWithAlgId[] = {
5244 0x30,0x1b,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5245 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5246 static const BYTE ctlWithBogusEntry[] = {
5247 0x30,0x29,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5248 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x10,0x30,0x0e,0x04,
5249 0x01,0x01,0x31,0x09,0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,0x01 };
5250 static const BYTE ctlWithOneEntry[] = {
5251 0x30,0x2a,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5252 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x11,0x30,0x0f,0x04,
5253 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00 };
5254 static const BYTE ctlWithTwoEntries[] = {
5255 0x30,0x41,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5256 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x28,0x30,0x0f,0x04,
5257 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00,0x30,
5258 0x15,0x04,0x01,0x01,0x31,0x10,0x30,0x0e,0x06,0x02,0x2d,0x06,0x31,0x08,0x30,
5259 0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5261 static void test_encodeCTL(DWORD dwEncoding)
5263 static char oid1[] = "1.2.3";
5264 static char oid2[] = "1.5.6";
5270 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5271 CTL_ENTRY ctlEntry[2];
5272 CRYPT_ATTRIBUTE attr1, attr2;
5273 CRYPT_ATTR_BLOB value1, value2;
5275 memset(&info, 0, sizeof(info));
5276 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5277 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5278 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5281 ok(size == sizeof(emptyCTL), "unexpected size %d\n", size);
5282 ok(!memcmp(buf, emptyCTL, size), "unexpected value\n");
5287 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5288 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5289 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5292 ok(size == sizeof(emptyCTLWithVersion1), "unexpected size %d\n", size);
5293 ok(!memcmp(buf, emptyCTLWithVersion1, size), "unexpected value\n");
5298 info.SubjectUsage.cUsageIdentifier = 1;
5299 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5300 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5301 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5302 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5305 ok(size == sizeof(ctlWithUsageIdentifier), "unexpected size %d\n",
5307 ok(!memcmp(buf, ctlWithUsageIdentifier, size), "unexpected value\n");
5311 info.SubjectUsage.cUsageIdentifier = 0;
5312 info.ListIdentifier.cbData = sizeof(serialNum);
5313 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5314 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5315 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5316 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5319 ok(size == sizeof(ctlWithListIdentifier), "unexpected size %d\n", size);
5320 ok(!memcmp(buf, ctlWithListIdentifier, size), "unexpected value\n");
5324 info.ListIdentifier.cbData = 0;
5325 info.SequenceNumber.cbData = sizeof(serialNum);
5326 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5327 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5328 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5329 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5332 ok(size == sizeof(ctlWithSequenceNumber), "unexpected size %d\n",
5334 ok(!memcmp(buf, ctlWithSequenceNumber, size), "unexpected value\n");
5338 info.SequenceNumber.cbData = 0;
5339 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5340 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5341 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5342 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5345 ok(size == sizeof(ctlWithThisUpdate), "unexpected size %d\n", size);
5346 ok(!memcmp(buf, ctlWithThisUpdate, size), "unexpected value\n");
5350 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5351 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5352 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5353 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5356 ok(size == sizeof(ctlWithThisAndNextUpdate), "unexpected size %d\n",
5358 ok(!memcmp(buf, ctlWithThisAndNextUpdate, size), "unexpected value\n");
5362 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5363 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5364 info.SubjectAlgorithm.pszObjId = oid2;
5365 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5366 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5367 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5370 ok(size == sizeof(ctlWithAlgId), "unexpected size %d\n", size);
5371 ok(!memcmp(buf, ctlWithAlgId, size), "unexpected value\n");
5375 /* The value is supposed to be asn.1 encoded, so this'll fail to decode
5376 * (see tests below) but it'll encode fine.
5378 info.SubjectAlgorithm.pszObjId = NULL;
5379 value1.cbData = sizeof(serialNum);
5380 value1.pbData = (LPBYTE)serialNum;
5381 attr1.pszObjId = oid1;
5383 attr1.rgValue = &value1;
5384 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5385 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5386 ctlEntry[0].cAttribute = 1;
5387 ctlEntry[0].rgAttribute = &attr1;
5389 info.rgCTLEntry = ctlEntry;
5390 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5391 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5392 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5395 ok(size == sizeof(ctlWithBogusEntry), "unexpected size %d\n", size);
5396 ok(!memcmp(buf, ctlWithBogusEntry, size), "unexpected value\n");
5400 value1.cbData = sizeof(emptySequence);
5401 value1.pbData = (LPBYTE)emptySequence;
5402 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5403 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5404 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5407 ok(size == sizeof(ctlWithOneEntry), "unexpected size %d\n", size);
5408 ok(!memcmp(buf, ctlWithOneEntry, size), "unexpected value\n");
5412 value2.cbData = sizeof(encodedIPAddr);
5413 value2.pbData = (LPBYTE)encodedIPAddr;
5414 attr2.pszObjId = oid2;
5416 attr2.rgValue = &value2;
5417 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5418 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5419 ctlEntry[1].cAttribute = 1;
5420 ctlEntry[1].rgAttribute = &attr2;
5422 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5423 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5424 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5427 ok(size == sizeof(ctlWithTwoEntries), "unexpected size %d\n", size);
5428 ok(!memcmp(buf, ctlWithTwoEntries, size), "unexpected value\n");
5434 static void compareCTLInfo(LPCSTR header, const CTL_INFO *expected,
5435 const CTL_INFO *got)
5439 ok(expected->dwVersion == got->dwVersion,
5440 "%s: expected version %d, got %d\n", header, expected->dwVersion,
5442 ok(expected->SubjectUsage.cUsageIdentifier ==
5443 got->SubjectUsage.cUsageIdentifier,
5444 "%s: expected %d usage identifiers, got %d\n", header,
5445 expected->SubjectUsage.cUsageIdentifier,
5446 got->SubjectUsage.cUsageIdentifier);
5447 for (i = 0; i < expected->SubjectUsage.cUsageIdentifier; i++)
5448 ok(!strcmp(expected->SubjectUsage.rgpszUsageIdentifier[i],
5449 got->SubjectUsage.rgpszUsageIdentifier[i]),
5450 "%s[%d]: expected %s, got %s\n", header, i,
5451 expected->SubjectUsage.rgpszUsageIdentifier[i],
5452 got->SubjectUsage.rgpszUsageIdentifier[i]);
5453 ok(expected->ListIdentifier.cbData == got->ListIdentifier.cbData,
5454 "%s: expected list identifier of %d bytes, got %d\n", header,
5455 expected->ListIdentifier.cbData, got->ListIdentifier.cbData);
5456 if (expected->ListIdentifier.cbData)
5457 ok(!memcmp(expected->ListIdentifier.pbData, got->ListIdentifier.pbData,
5458 expected->ListIdentifier.cbData),
5459 "%s: unexpected list identifier value\n", header);
5460 ok(expected->SequenceNumber.cbData == got->SequenceNumber.cbData,
5461 "%s: expected sequence number of %d bytes, got %d\n", header,
5462 expected->SequenceNumber.cbData, got->SequenceNumber.cbData);
5463 if (expected->SequenceNumber.cbData)
5464 ok(!memcmp(expected->SequenceNumber.pbData, got->SequenceNumber.pbData,
5465 expected->SequenceNumber.cbData),
5466 "%s: unexpected sequence number value\n", header);
5467 ok(!memcmp(&expected->ThisUpdate, &got->ThisUpdate, sizeof(FILETIME)),
5468 "%s: expected this update = (%d, %d), got (%d, %d)\n", header,
5469 expected->ThisUpdate.dwLowDateTime, expected->ThisUpdate.dwHighDateTime,
5470 got->ThisUpdate.dwLowDateTime, got->ThisUpdate.dwHighDateTime);
5471 ok(!memcmp(&expected->NextUpdate, &got->NextUpdate, sizeof(FILETIME)),
5472 "%s: expected next update = (%d, %d), got (%d, %d)\n", header,
5473 expected->NextUpdate.dwLowDateTime, expected->NextUpdate.dwHighDateTime,
5474 got->NextUpdate.dwLowDateTime, got->NextUpdate.dwHighDateTime);
5475 if (expected->SubjectAlgorithm.pszObjId &&
5476 *expected->SubjectAlgorithm.pszObjId && !got->SubjectAlgorithm.pszObjId)
5477 ok(0, "%s: expected subject algorithm %s, got NULL\n", header,
5478 expected->SubjectAlgorithm.pszObjId);
5479 if (expected->SubjectAlgorithm.pszObjId && got->SubjectAlgorithm.pszObjId)
5480 ok(!strcmp(expected->SubjectAlgorithm.pszObjId,
5481 got->SubjectAlgorithm.pszObjId),
5482 "%s: expected subject algorithm %s, got %s\n", header,
5483 expected->SubjectAlgorithm.pszObjId, got->SubjectAlgorithm.pszObjId);
5484 ok(expected->SubjectAlgorithm.Parameters.cbData ==
5485 got->SubjectAlgorithm.Parameters.cbData,
5486 "%s: expected subject algorithm parameters of %d bytes, got %d\n", header,
5487 expected->SubjectAlgorithm.Parameters.cbData,
5488 got->SubjectAlgorithm.Parameters.cbData);
5489 if (expected->SubjectAlgorithm.Parameters.cbData)
5490 ok(!memcmp(expected->SubjectAlgorithm.Parameters.pbData,
5491 got->SubjectAlgorithm.Parameters.pbData,
5492 expected->SubjectAlgorithm.Parameters.cbData),
5493 "%s: unexpected subject algorithm parameter value\n", header);
5494 ok(expected->cCTLEntry == got->cCTLEntry,
5495 "%s: expected %d CTL entries, got %d\n", header, expected->cCTLEntry,
5497 for (i = 0; i < expected->cCTLEntry; i++)
5499 ok(expected->rgCTLEntry[i].SubjectIdentifier.cbData ==
5500 got->rgCTLEntry[i].SubjectIdentifier.cbData,
5501 "%s[%d]: expected subject identifier of %d bytes, got %d\n",
5502 header, i, expected->rgCTLEntry[i].SubjectIdentifier.cbData,
5503 got->rgCTLEntry[i].SubjectIdentifier.cbData);
5504 if (expected->rgCTLEntry[i].SubjectIdentifier.cbData)
5505 ok(!memcmp(expected->rgCTLEntry[i].SubjectIdentifier.pbData,
5506 got->rgCTLEntry[i].SubjectIdentifier.pbData,
5507 expected->rgCTLEntry[i].SubjectIdentifier.cbData),
5508 "%s[%d]: unexpected subject identifier value\n",
5510 for (j = 0; j < expected->rgCTLEntry[i].cAttribute; j++)
5512 ok(!strcmp(expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5513 got->rgCTLEntry[i].rgAttribute[j].pszObjId),
5514 "%s[%d][%d]: expected attribute OID %s, got %s\n", header, i, j,
5515 expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5516 got->rgCTLEntry[i].rgAttribute[j].pszObjId);
5517 for (k = 0; k < expected->rgCTLEntry[i].rgAttribute[j].cValue; k++)
5519 ok(expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData ==
5520 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5521 "%s[%d][%d][%d]: expected value of %d bytes, got %d\n",
5523 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5524 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData);
5525 if (expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData)
5527 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5528 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5529 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData),
5530 "%s[%d][%d][%d]: unexpected value\n",
5535 ok(expected->cExtension == got->cExtension,
5536 "%s: expected %d extensions, got %d\n", header, expected->cExtension,
5538 for (i = 0; i < expected->cExtension; i++)
5540 ok(!strcmp(expected->rgExtension[i].pszObjId,
5541 got->rgExtension[i].pszObjId), "%s[%d]: expected %s, got %s\n",
5542 header, i, expected->rgExtension[i].pszObjId,
5543 got->rgExtension[i].pszObjId);
5544 ok(expected->rgExtension[i].fCritical == got->rgExtension[i].fCritical,
5545 "%s[%d]: expected fCritical = %d, got %d\n", header, i,
5546 expected->rgExtension[i].fCritical, got->rgExtension[i].fCritical);
5547 ok(expected->rgExtension[i].Value.cbData ==
5548 got->rgExtension[i].Value.cbData,
5549 "%s[%d]: expected extension value to have %d bytes, got %d\n",
5550 header, i, expected->rgExtension[i].Value.cbData,
5551 got->rgExtension[i].Value.cbData);
5552 if (expected->rgExtension[i].Value.cbData)
5553 ok(!memcmp(expected->rgExtension[i].Value.pbData,
5554 got->rgExtension[i].Value.pbData,
5555 expected->rgExtension[i].Value.cbData),
5556 "%s[%d]: unexpected extension value\n", header, i);
5560 static const BYTE signedCTL[] = {
5561 0x30,0x81,0xc7,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
5562 0x81,0xb9,0x30,0x81,0xb6,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
5563 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x28,0x06,0x09,0x2a,0x86,
5564 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x1b,0x04,0x19,0x30,0x17,0x30,0x00,
5565 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5566 0x30,0x5a,0x30,0x02,0x06,0x00,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
5567 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
5568 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
5569 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5570 0x00,0x04,0x40,0xca,0xd8,0x32,0xd1,0xbd,0x97,0x61,0x54,0xd6,0x80,0xcf,0x0d,
5571 0xbd,0xa2,0x42,0xc7,0xca,0x37,0x91,0x7d,0x9d,0xac,0x8c,0xdf,0x05,0x8a,0x39,
5572 0xc6,0x07,0xc1,0x37,0xe6,0xb9,0xd1,0x0d,0x26,0xec,0xa5,0xb0,0x8a,0x51,0x26,
5573 0x2b,0x4f,0x73,0x44,0x86,0x83,0x5e,0x2b,0x6e,0xcc,0xf8,0x1b,0x85,0x53,0xe9,
5574 0x7a,0x80,0x8f,0x6b,0x42,0x19,0x93 };
5575 static const BYTE signedCTLWithCTLInnerContent[] = {
5576 0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
5577 0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
5578 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
5579 0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
5580 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5581 0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
5582 0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
5583 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
5584 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
5585 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
5586 0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
5587 0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
5588 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
5589 0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5590 0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
5591 0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
5592 0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
5593 0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
5594 0x57,0x6c,0x0b,0x47,0xb8 };
5596 static void test_decodeCTL(DWORD dwEncoding)
5598 static char oid1[] = "1.2.3";
5599 static char oid2[] = "1.5.6";
5600 static BYTE nullData[] = { 5,0 };
5606 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5607 CTL_ENTRY ctlEntry[2];
5608 CRYPT_ATTRIBUTE attr1, attr2;
5609 CRYPT_ATTR_BLOB value1, value2;
5611 memset(&info, 0, sizeof(info));
5612 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTL, sizeof(emptyCTL),
5613 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5614 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5617 compareCTLInfo("empty CTL", &info, (CTL_INFO *)buf);
5622 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTLWithVersion1,
5623 sizeof(emptyCTLWithVersion1), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
5625 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5628 compareCTLInfo("v1 CTL", &info, (CTL_INFO *)buf);
5633 info.SubjectUsage.cUsageIdentifier = 1;
5634 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5635 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithUsageIdentifier,
5636 sizeof(ctlWithUsageIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5638 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5641 compareCTLInfo("CTL with usage identifier", &info, (CTL_INFO *)buf);
5645 info.SubjectUsage.cUsageIdentifier = 0;
5646 info.ListIdentifier.cbData = sizeof(serialNum);
5647 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5648 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithListIdentifier,
5649 sizeof(ctlWithListIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5650 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5653 compareCTLInfo("CTL with list identifier", &info, (CTL_INFO *)buf);
5657 info.ListIdentifier.cbData = 0;
5658 info.SequenceNumber.cbData = sizeof(serialNum);
5659 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5660 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithSequenceNumber,
5661 sizeof(ctlWithSequenceNumber), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5662 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5665 compareCTLInfo("CTL with sequence number", &info, (CTL_INFO *)buf);
5669 info.SequenceNumber.cbData = 0;
5670 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5671 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisUpdate,
5672 sizeof(ctlWithThisUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5673 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5676 compareCTLInfo("CTL with this update", &info, (CTL_INFO *)buf);
5680 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5681 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisAndNextUpdate,
5682 sizeof(ctlWithThisAndNextUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5684 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5687 compareCTLInfo("CTL with this and next update", &info, (CTL_INFO *)buf);
5691 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5692 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5693 info.SubjectAlgorithm.pszObjId = oid2;
5694 info.SubjectAlgorithm.Parameters.cbData = sizeof(nullData);
5695 info.SubjectAlgorithm.Parameters.pbData = nullData;
5696 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithAlgId,
5697 sizeof(ctlWithAlgId), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5698 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5701 compareCTLInfo("CTL with algorithm identifier", &info, (CTL_INFO *)buf);
5705 SetLastError(0xdeadbeef);
5706 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithBogusEntry,
5707 sizeof(ctlWithBogusEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5709 (GetLastError() == CRYPT_E_ASN1_EOD ||
5710 GetLastError() == CRYPT_E_ASN1_CORRUPT ||
5711 GetLastError() == OSS_MORE_INPUT), /* Win9x */
5712 "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n",
5714 info.SubjectAlgorithm.Parameters.cbData = 0;
5715 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5716 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5717 info.SubjectAlgorithm.pszObjId = oid2;
5718 info.SubjectAlgorithm.pszObjId = NULL;
5719 value1.cbData = sizeof(emptySequence);
5720 value1.pbData = (LPBYTE)emptySequence;
5721 attr1.pszObjId = oid1;
5723 attr1.rgValue = &value1;
5724 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5725 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5726 ctlEntry[0].cAttribute = 1;
5727 ctlEntry[0].rgAttribute = &attr1;
5729 info.rgCTLEntry = ctlEntry;
5730 SetLastError(0xdeadbeef);
5731 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithOneEntry,
5732 sizeof(ctlWithOneEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5733 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5736 compareCTLInfo("CTL with one entry", &info, (CTL_INFO *)buf);
5740 value2.cbData = sizeof(encodedIPAddr);
5741 value2.pbData = (LPBYTE)encodedIPAddr;
5742 attr2.pszObjId = oid2;
5744 attr2.rgValue = &value2;
5745 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5746 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5747 ctlEntry[1].cAttribute = 1;
5748 ctlEntry[1].rgAttribute = &attr2;
5750 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithTwoEntries,
5751 sizeof(ctlWithTwoEntries), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5752 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5755 compareCTLInfo("CTL with two entries", &info, (CTL_INFO *)buf);
5759 /* A signed CTL isn't decodable, even if the inner content is a CTL */
5760 SetLastError(0xdeadbeef);
5761 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, signedCTL,
5762 sizeof(signedCTL), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5763 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5764 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5765 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5767 SetLastError(0xdeadbeef);
5768 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL,
5769 signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent),
5770 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5771 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5772 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5773 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5777 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
5778 static const BYTE emptyPKCSContentInfoExtraBytes[] = { 0x30,0x04,0x06,0x02,0x2a,
5780 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
5782 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
5783 0x03,0x02,0x01,0x01 };
5784 static BYTE bogusDER[] = { 1 };
5786 static void test_encodePKCSContentInfo(DWORD dwEncoding)
5791 CRYPT_CONTENT_INFO info = { 0 };
5792 char oid1[] = "1.2.3";
5796 /* Crashes on win9x */
5797 SetLastError(0xdeadbeef);
5798 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL,
5799 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5800 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5801 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5803 SetLastError(0xdeadbeef);
5804 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5805 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5806 ok(!ret && (GetLastError() == E_INVALIDARG ||
5807 GetLastError() == OSS_LIMITED /* Win9x */),
5808 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5809 info.pszObjId = oid1;
5810 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5811 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5812 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5815 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size);
5816 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n");
5819 info.Content.pbData = bogusDER;
5820 info.Content.cbData = sizeof(bogusDER);
5821 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5822 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5823 ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError());
5826 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size);
5827 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n");
5830 info.Content.pbData = (BYTE *)ints[0].encoded;
5831 info.Content.cbData = ints[0].encoded[1] + 2;
5832 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5833 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5836 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size);
5837 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n");
5842 static const BYTE indefiniteSignedPKCSContent[] = {
5843 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
5844 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
5845 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
5846 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
5847 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
5848 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
5849 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5850 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5851 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
5852 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5853 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5854 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
5855 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
5856 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
5857 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
5858 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
5859 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
5860 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
5861 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
5862 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5863 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5864 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
5865 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
5866 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
5867 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
5868 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
5869 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
5870 0x00,0x00,0x00,0x00,0x00,0x00 };
5872 static void test_decodePKCSContentInfo(DWORD dwEncoding)
5877 CRYPT_CONTENT_INFO *info;
5879 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5880 emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo),
5881 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5882 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5885 info = (CRYPT_CONTENT_INFO *)buf;
5887 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5889 ok(info->Content.cbData == 0, "Expected no data, got %d\n",
5890 info->Content.cbData);
5893 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5894 emptyPKCSContentInfoExtraBytes, sizeof(emptyPKCSContentInfoExtraBytes),
5895 0, NULL, NULL, &size);
5896 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5897 SetLastError(0xdeadbeef);
5898 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5899 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo),
5900 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5901 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5902 * I doubt an app depends on that.
5904 ok((!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5905 GetLastError() == CRYPT_E_ASN1_CORRUPT)) || broken(ret),
5906 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5908 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5909 intPKCSContentInfo, sizeof(intPKCSContentInfo),
5910 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5911 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5914 info = (CRYPT_CONTENT_INFO *)buf;
5916 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5918 ok(info->Content.cbData == ints[0].encoded[1] + 2,
5919 "Unexpected size %d\n", info->Content.cbData);
5920 ok(!memcmp(info->Content.pbData, ints[0].encoded,
5921 info->Content.cbData), "Unexpected value\n");
5924 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5925 indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent),
5926 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5927 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5930 info = (CRYPT_CONTENT_INFO *)buf;
5932 ok(!strcmp(info->pszObjId, szOID_RSA_signedData),
5933 "Expected %s, got %s\n", szOID_RSA_signedData, info->pszObjId);
5934 ok(info->Content.cbData == 392, "Expected 392, got %d\n",
5935 info->Content.cbData);
5940 static const BYTE emptyPKCSAttr[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
5942 static const BYTE bogusPKCSAttr[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
5944 static const BYTE intPKCSAttr[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
5947 static void test_encodePKCSAttribute(DWORD dwEncoding)
5949 CRYPT_ATTRIBUTE attr = { 0 };
5953 CRYPT_ATTR_BLOB blob;
5954 char oid[] = "1.2.3";
5958 /* Crashes on win9x */
5959 SetLastError(0xdeadbeef);
5960 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, NULL,
5961 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5962 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5963 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5965 SetLastError(0xdeadbeef);
5966 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5967 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5968 ok(!ret && (GetLastError() == E_INVALIDARG ||
5969 GetLastError() == OSS_LIMITED /* Win9x */),
5970 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5971 attr.pszObjId = oid;
5972 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5973 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5974 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5977 ok(size == sizeof(emptyPKCSAttr), "Unexpected size %d\n", size);
5978 ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n");
5981 blob.cbData = sizeof(bogusDER);
5982 blob.pbData = bogusDER;
5984 attr.rgValue = &blob;
5985 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5986 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5987 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5990 ok(size == sizeof(bogusPKCSAttr), "Unexpected size %d\n", size);
5991 ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n");
5994 blob.pbData = (BYTE *)ints[0].encoded;
5995 blob.cbData = ints[0].encoded[1] + 2;
5996 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5997 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6000 ok(size == sizeof(intPKCSAttr), "Unexpected size %d\n", size);
6001 ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n");
6006 static void test_decodePKCSAttribute(DWORD dwEncoding)
6011 CRYPT_ATTRIBUTE *attr;
6013 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
6014 emptyPKCSAttr, sizeof(emptyPKCSAttr),
6015 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6016 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6019 attr = (CRYPT_ATTRIBUTE *)buf;
6021 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
6023 ok(attr->cValue == 0, "Expected no value, got %d\n", attr->cValue);
6026 SetLastError(0xdeadbeef);
6027 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
6028 bogusPKCSAttr, sizeof(bogusPKCSAttr),
6029 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6030 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
6031 * I doubt an app depends on that.
6033 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
6034 GetLastError() == CRYPT_E_ASN1_CORRUPT ||
6035 GetLastError() == OSS_MORE_INPUT /* Win9x */),
6036 "Expected CRYPT_E_ASN1_EOD, CRYPT_E_ASN1_CORRUPT, or OSS_MORE_INPUT, got %x\n",
6038 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
6039 intPKCSAttr, sizeof(intPKCSAttr),
6040 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6041 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6044 attr = (CRYPT_ATTRIBUTE *)buf;
6046 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
6048 ok(attr->cValue == 1, "Expected 1 value, got %d\n", attr->cValue);
6049 ok(attr->rgValue[0].cbData == ints[0].encoded[1] + 2,
6050 "Unexpected size %d\n", attr->rgValue[0].cbData);
6051 ok(!memcmp(attr->rgValue[0].pbData, ints[0].encoded,
6052 attr->rgValue[0].cbData), "Unexpected value\n");
6057 static const BYTE emptyPKCSAttributes[] = { 0x31,0x00 };
6058 static const BYTE singlePKCSAttributes[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
6059 0x2a,0x03,0x31,0x00 };
6060 static const BYTE doublePKCSAttributes[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
6061 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
6063 static void test_encodePKCSAttributes(DWORD dwEncoding)
6065 CRYPT_ATTRIBUTES attributes = { 0 };
6066 CRYPT_ATTRIBUTE attr[2] = { { 0 } };
6067 CRYPT_ATTR_BLOB blob;
6071 char oid1[] = "1.2.3", oid2[] = "1.5.6";
6073 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6074 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6075 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6078 ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %d\n", size);
6079 ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n");
6082 attributes.cAttr = 1;
6083 attributes.rgAttr = attr;
6084 SetLastError(0xdeadbeef);
6085 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6086 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6087 ok(!ret && (GetLastError() == E_INVALIDARG ||
6088 GetLastError() == OSS_LIMITED /* Win9x */),
6089 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6090 attr[0].pszObjId = oid1;
6091 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6092 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6095 ok(size == sizeof(singlePKCSAttributes), "Unexpected size %d\n", size);
6096 ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n");
6099 attr[1].pszObjId = oid2;
6101 attr[1].rgValue = &blob;
6102 blob.pbData = (BYTE *)ints[0].encoded;
6103 blob.cbData = ints[0].encoded[1] + 2;
6104 attributes.cAttr = 2;
6105 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6106 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6107 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6110 ok(size == sizeof(doublePKCSAttributes), "Unexpected size %d\n", size);
6111 ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n");
6116 static void test_decodePKCSAttributes(DWORD dwEncoding)
6121 CRYPT_ATTRIBUTES *attributes;
6123 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6124 emptyPKCSAttributes, sizeof(emptyPKCSAttributes),
6125 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6126 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6129 attributes = (CRYPT_ATTRIBUTES *)buf;
6130 ok(attributes->cAttr == 0, "Expected no attributes, got %d\n",
6134 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6135 singlePKCSAttributes, sizeof(singlePKCSAttributes),
6136 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6137 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6140 attributes = (CRYPT_ATTRIBUTES *)buf;
6141 ok(attributes->cAttr == 1, "Expected 1 attribute, got %d\n",
6143 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
6144 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
6145 ok(attributes->rgAttr[0].cValue == 0,
6146 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
6149 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6150 doublePKCSAttributes, sizeof(doublePKCSAttributes),
6151 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6152 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6155 attributes = (CRYPT_ATTRIBUTES *)buf;
6156 ok(attributes->cAttr == 2, "Expected 2 attributes, got %d\n",
6158 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
6159 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
6160 ok(attributes->rgAttr[0].cValue == 0,
6161 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
6162 ok(!strcmp(attributes->rgAttr[1].pszObjId, "1.5.6"),
6163 "Expected 1.5.6, got %s\n", attributes->rgAttr[1].pszObjId);
6164 ok(attributes->rgAttr[1].cValue == 1,
6165 "Expected 1 attribute, got %d\n", attributes->rgAttr[1].cValue);
6166 ok(attributes->rgAttr[1].rgValue[0].cbData == ints[0].encoded[1] + 2,
6167 "Unexpected size %d\n", attributes->rgAttr[1].rgValue[0].cbData);
6168 ok(!memcmp(attributes->rgAttr[1].rgValue[0].pbData, ints[0].encoded,
6169 attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n");
6174 static const BYTE singleCapability[] = {
6175 0x30,0x06,0x30,0x04,0x06,0x02,0x2d,0x06 };
6176 static const BYTE twoCapabilities[] = {
6177 0x30,0x0c,0x30,0x04,0x06,0x02,0x2d,0x06,0x30,0x04,0x06,0x02,0x2a,0x03 };
6178 static const BYTE singleCapabilitywithNULL[] = {
6179 0x30,0x08,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
6181 static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding)
6183 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6187 CRYPT_SMIME_CAPABILITY capability[2];
6188 CRYPT_SMIME_CAPABILITIES capabilities;
6190 /* An empty capabilities is allowed */
6191 capabilities.cCapability = 0;
6192 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6193 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6194 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6197 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
6198 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
6201 /* A non-empty capabilities with an empty capability (lacking an OID) is
6204 capability[0].pszObjId = NULL;
6205 capability[0].Parameters.cbData = 0;
6206 capabilities.cCapability = 1;
6207 capabilities.rgCapability = capability;
6208 SetLastError(0xdeadbeef);
6209 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6210 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6211 ok(!ret && (GetLastError() == E_INVALIDARG ||
6212 GetLastError() == OSS_LIMITED /* Win9x */),
6213 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6214 capability[0].pszObjId = oid1;
6215 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6216 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6217 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6220 ok(size == sizeof(singleCapability), "unexpected size %d\n", size);
6221 ok(!memcmp(buf, singleCapability, size), "unexpected value\n");
6224 capability[1].pszObjId = oid2;
6225 capability[1].Parameters.cbData = 0;
6226 capabilities.cCapability = 2;
6227 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6228 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6229 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6232 ok(size == sizeof(twoCapabilities), "unexpected size %d\n", size);
6233 ok(!memcmp(buf, twoCapabilities, size), "unexpected value\n");
6238 static void compareSMimeCapabilities(LPCSTR header,
6239 const CRYPT_SMIME_CAPABILITIES *expected, const CRYPT_SMIME_CAPABILITIES *got)
6243 ok(got->cCapability == expected->cCapability,
6244 "%s: expected %d capabilities, got %d\n", header, expected->cCapability,
6246 for (i = 0; i < expected->cCapability; i++)
6248 ok(!strcmp(expected->rgCapability[i].pszObjId,
6249 got->rgCapability[i].pszObjId), "%s[%d]: expected %s, got %s\n",
6250 header, i, expected->rgCapability[i].pszObjId,
6251 got->rgCapability[i].pszObjId);
6252 ok(expected->rgCapability[i].Parameters.cbData ==
6253 got->rgCapability[i].Parameters.cbData,
6254 "%s[%d]: expected %d bytes, got %d\n", header, i,
6255 expected->rgCapability[i].Parameters.cbData,
6256 got->rgCapability[i].Parameters.cbData);
6257 if (expected->rgCapability[i].Parameters.cbData)
6258 ok(!memcmp(expected->rgCapability[i].Parameters.pbData,
6259 got->rgCapability[i].Parameters.pbData,
6260 expected->rgCapability[i].Parameters.cbData),
6261 "%s[%d]: unexpected value\n", header, i);
6265 static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding)
6267 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6270 CRYPT_SMIME_CAPABILITY capability[2];
6271 CRYPT_SMIME_CAPABILITIES capabilities, *ptr;
6273 SetLastError(0xdeadbeef);
6274 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6275 emptySequence, sizeof(emptySequence),
6276 CRYPT_DECODE_ALLOC_FLAG, NULL, &ptr, &size);
6277 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6280 capabilities.cCapability = 0;
6281 compareSMimeCapabilities("empty capabilities", &capabilities, ptr);
6284 SetLastError(0xdeadbeef);
6285 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6286 singleCapability, sizeof(singleCapability), CRYPT_DECODE_ALLOC_FLAG, NULL,
6288 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6291 capability[0].pszObjId = oid1;
6292 capability[0].Parameters.cbData = 0;
6293 capabilities.cCapability = 1;
6294 capabilities.rgCapability = capability;
6295 compareSMimeCapabilities("single capability", &capabilities, ptr);
6298 SetLastError(0xdeadbeef);
6299 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6300 singleCapabilitywithNULL, sizeof(singleCapabilitywithNULL),
6301 CRYPT_DECODE_ALLOC_FLAG, NULL, &ptr, &size);
6302 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6305 BYTE NULLparam[] = {0x05, 0x00};
6306 capability[0].pszObjId = oid1;
6307 capability[0].Parameters.cbData = 2;
6308 capability[0].Parameters.pbData = NULLparam;
6309 capabilities.cCapability = 1;
6310 capabilities.rgCapability = capability;
6311 compareSMimeCapabilities("single capability with NULL", &capabilities,
6315 SetLastError(0xdeadbeef);
6316 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6317 twoCapabilities, sizeof(twoCapabilities), CRYPT_DECODE_ALLOC_FLAG, NULL,
6319 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6322 capability[0].Parameters.cbData = 0;
6323 capability[1].pszObjId = oid2;
6324 capability[1].Parameters.cbData = 0;
6325 capabilities.cCapability = 2;
6326 compareSMimeCapabilities("two capabilities", &capabilities, ptr);
6331 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
6332 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
6334 static const BYTE minimalPKCSSigner[] = {
6335 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6336 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6337 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6338 static const BYTE PKCSSignerWithSerial[] = {
6339 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6340 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6341 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
6343 static const BYTE PKCSSignerWithHashAlgo[] = {
6344 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6345 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6346 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
6348 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = {
6349 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6350 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6351 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6352 0x06,0x05,0x00,0x04,0x00 };
6353 static const BYTE PKCSSignerWithHash[] = {
6354 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6355 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6356 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6357 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
6358 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6359 static const BYTE PKCSSignerWithAuthAttr[] = {
6360 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6361 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6362 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
6363 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
6364 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
6365 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
6366 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6368 static void test_encodePKCSSignerInfo(DWORD dwEncoding)
6370 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6374 CMSG_SIGNER_INFO info = { 0 };
6375 char oid_common_name[] = szOID_COMMON_NAME;
6376 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
6377 (LPBYTE)encodedCommonName };
6378 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
6380 SetLastError(0xdeadbeef);
6381 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6382 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6383 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6385 skip("no PKCS7_SIGNER_INFO encode support\n");
6388 ok(!ret && (GetLastError() == E_INVALIDARG ||
6389 GetLastError() == OSS_LIMITED /* Win9x */),
6390 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6391 /* To be encoded, a signer must have an issuer at least, and the encoding
6392 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
6393 * see decoding tests.)
6395 info.Issuer.cbData = sizeof(encodedCommonNameNoNull);
6396 info.Issuer.pbData = encodedCommonNameNoNull;
6397 SetLastError(0xdeadbeef);
6398 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6399 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6400 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6401 ok(!ret && GetLastError() == E_INVALIDARG,
6402 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6405 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6406 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6409 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6410 if (size == sizeof(minimalPKCSSigner))
6411 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6413 ok(0, "Unexpected value\n");
6417 info.SerialNumber.cbData = sizeof(serialNum);
6418 info.SerialNumber.pbData = (BYTE *)serialNum;
6419 SetLastError(0xdeadbeef);
6420 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6421 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6422 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6423 ok(!ret && GetLastError() == E_INVALIDARG,
6424 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6427 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6428 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6431 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6433 if (size == sizeof(PKCSSignerWithSerial))
6434 ok(!memcmp(buf, PKCSSignerWithSerial, size),
6435 "Unexpected value\n");
6437 ok(0, "Unexpected value\n");
6441 info.HashAlgorithm.pszObjId = oid1;
6442 SetLastError(0xdeadbeef);
6443 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6444 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6445 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6446 ok(!ret && GetLastError() == E_INVALIDARG,
6447 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6450 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6451 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6454 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6456 if (size == sizeof(PKCSSignerWithHashAlgo))
6457 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6458 "Unexpected value\n");
6460 ok(0, "Unexpected value\n");
6464 info.HashEncryptionAlgorithm.pszObjId = oid2;
6465 SetLastError(0xdeadbeef);
6466 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6467 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6468 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6469 ok(!ret && GetLastError() == E_INVALIDARG,
6470 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6473 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6476 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6477 "Unexpected size %d\n", size);
6478 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo))
6479 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6480 "Unexpected value\n");
6482 ok(0, "Unexpected value\n");
6486 info.EncryptedHash.cbData = sizeof(hash);
6487 info.EncryptedHash.pbData = (BYTE *)hash;
6488 SetLastError(0xdeadbeef);
6489 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6490 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6491 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6492 ok(!ret && GetLastError() == E_INVALIDARG,
6493 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6496 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6499 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6501 if (size == sizeof(PKCSSignerWithHash))
6502 ok(!memcmp(buf, PKCSSignerWithHash, size),
6503 "Unexpected value\n");
6505 ok(0, "Unexpected value\n");
6509 info.AuthAttrs.cAttr = 1;
6510 info.AuthAttrs.rgAttr = &attr;
6511 SetLastError(0xdeadbeef);
6512 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6513 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6514 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6515 ok(!ret && GetLastError() == E_INVALIDARG,
6516 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6519 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6522 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
6524 if (size == sizeof(PKCSSignerWithAuthAttr))
6525 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
6526 "Unexpected value\n");
6528 ok(0, "Unexpected value\n");
6534 static void test_decodePKCSSignerInfo(DWORD dwEncoding)
6539 CMSG_SIGNER_INFO *info;
6541 /* A PKCS signer can't be decoded without a serial number. */
6542 SetLastError(0xdeadbeef);
6543 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6544 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6545 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6546 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
6547 GetLastError() == OSS_DATA_ERROR /* Win9x */),
6548 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %x\n",
6550 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6551 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6552 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6553 ok(ret || broken(GetLastError() == OSS_DATA_ERROR),
6554 "CryptDecodeObjectEx failed: %x\n", GetLastError());
6557 info = (CMSG_SIGNER_INFO *)buf;
6558 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6560 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6561 "Unexpected size %d\n", info->Issuer.cbData);
6562 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6563 info->Issuer.cbData), "Unexpected value\n");
6564 ok(info->SerialNumber.cbData == sizeof(serialNum),
6565 "Unexpected size %d\n", info->SerialNumber.cbData);
6566 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6567 "Unexpected value\n");
6570 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6571 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6572 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6575 info = (CMSG_SIGNER_INFO *)buf;
6576 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6578 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6579 "Unexpected size %d\n", info->Issuer.cbData);
6580 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6581 info->Issuer.cbData), "Unexpected value\n");
6582 ok(info->SerialNumber.cbData == sizeof(serialNum),
6583 "Unexpected size %d\n", info->SerialNumber.cbData);
6584 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6585 "Unexpected value\n");
6586 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6587 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6590 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6591 PKCSSignerWithHashAndEncryptionAlgo,
6592 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6596 info = (CMSG_SIGNER_INFO *)buf;
6597 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6599 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6600 "Unexpected size %d\n", info->Issuer.cbData);
6601 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6602 info->Issuer.cbData), "Unexpected value\n");
6603 ok(info->SerialNumber.cbData == sizeof(serialNum),
6604 "Unexpected size %d\n", info->SerialNumber.cbData);
6605 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6606 "Unexpected value\n");
6607 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6608 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6609 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6610 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6613 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6614 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6615 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6618 info = (CMSG_SIGNER_INFO *)buf;
6619 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6621 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6622 "Unexpected size %d\n", info->Issuer.cbData);
6623 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6624 info->Issuer.cbData), "Unexpected value\n");
6625 ok(info->SerialNumber.cbData == sizeof(serialNum),
6626 "Unexpected size %d\n", info->SerialNumber.cbData);
6627 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6628 "Unexpected value\n");
6629 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6630 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6631 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6632 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6633 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6634 info->EncryptedHash.cbData);
6635 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6636 "Unexpected value\n");
6639 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6640 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
6641 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6644 info = (CMSG_SIGNER_INFO *)buf;
6645 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n",
6646 info->AuthAttrs.cAttr);
6647 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
6648 "Expected %s, got %s\n", szOID_COMMON_NAME,
6649 info->AuthAttrs.rgAttr[0].pszObjId);
6650 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
6651 info->AuthAttrs.rgAttr[0].cValue);
6652 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
6653 sizeof(encodedCommonName), "Unexpected size %d\n",
6654 info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
6655 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
6656 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
6661 static const BYTE CMSSignerWithKeyId[] = {
6662 0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,
6663 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6665 static void test_encodeCMSSignerInfo(DWORD dwEncoding)
6670 CMSG_CMS_SIGNER_INFO info = { 0 };
6671 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6673 SetLastError(0xdeadbeef);
6674 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6675 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6676 ok(!ret, "Expected failure, got %d\n", ret);
6677 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6679 skip("no CMS_SIGNER_INFO encode support\n");
6682 ok(GetLastError() == E_INVALIDARG,
6683 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6684 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6685 SetLastError(0xdeadbeef);
6686 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6687 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6688 ok(!ret, "Expected failure, got %d\n", ret);
6689 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6691 skip("no CMS_SIGNER_INFO encode support\n");
6694 ok(GetLastError() == E_INVALIDARG,
6695 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6696 /* To be encoded, a signer must have a valid cert ID, where a valid ID may
6697 * be a key id or a issuer serial number with at least the issuer set, and
6698 * the encoding must include PKCS_7_ASN_ENCODING.
6699 * (That isn't enough to be decoded, see decoding tests.)
6701 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6702 sizeof(encodedCommonNameNoNull);
6703 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6704 SetLastError(0xdeadbeef);
6705 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6706 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6707 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6708 ok(!ret && GetLastError() == E_INVALIDARG,
6709 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6712 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6715 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6716 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6720 U(info.SignerId).IssuerSerialNumber.SerialNumber.cbData = sizeof(serialNum);
6721 U(info.SignerId).IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
6722 SetLastError(0xdeadbeef);
6723 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6724 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6725 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6726 ok(!ret && GetLastError() == E_INVALIDARG,
6727 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6730 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6733 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6735 ok(!memcmp(buf, PKCSSignerWithSerial, size), "Unexpected value\n");
6739 info.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
6740 U(info.SignerId).KeyId.cbData = sizeof(serialNum);
6741 U(info.SignerId).KeyId.pbData = (BYTE *)serialNum;
6742 SetLastError(0xdeadbeef);
6743 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6744 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6745 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6746 ok(!ret && GetLastError() == E_INVALIDARG,
6747 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6750 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6753 ok(size == sizeof(CMSSignerWithKeyId), "Unexpected size %d\n",
6755 ok(!memcmp(buf, CMSSignerWithKeyId, size), "Unexpected value\n");
6759 /* While a CERT_ID can have a hash type, that's not allowed in CMS, where
6760 * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed
6761 * (see RFC 3852, section 5.3.)
6763 info.SignerId.dwIdChoice = CERT_ID_SHA1_HASH;
6764 U(info.SignerId).HashId.cbData = sizeof(hash);
6765 U(info.SignerId).HashId.pbData = (BYTE *)hash;
6766 SetLastError(0xdeadbeef);
6767 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6768 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6769 ok(!ret && GetLastError() == E_INVALIDARG,
6770 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6771 /* Now with a hash algo */
6772 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6773 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6774 sizeof(encodedCommonNameNoNull);
6775 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6776 info.HashAlgorithm.pszObjId = oid1;
6777 SetLastError(0xdeadbeef);
6778 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6779 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6780 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6781 ok(!ret && GetLastError() == E_INVALIDARG,
6782 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6785 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6788 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6790 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6791 "Unexpected value\n");
6795 info.HashEncryptionAlgorithm.pszObjId = oid2;
6796 SetLastError(0xdeadbeef);
6797 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6798 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6799 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6800 ok(!ret && GetLastError() == E_INVALIDARG,
6801 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6804 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6807 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6808 "Unexpected size %d\n", size);
6809 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6810 "Unexpected value\n");
6814 info.EncryptedHash.cbData = sizeof(hash);
6815 info.EncryptedHash.pbData = (BYTE *)hash;
6816 SetLastError(0xdeadbeef);
6817 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6818 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6819 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6820 ok(!ret && GetLastError() == E_INVALIDARG,
6821 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6824 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6827 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6829 ok(!memcmp(buf, PKCSSignerWithHash, size), "Unexpected value\n");
6835 static void test_decodeCMSSignerInfo(DWORD dwEncoding)
6840 CMSG_CMS_SIGNER_INFO *info;
6841 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6843 /* A CMS signer can't be decoded without a serial number. */
6844 SetLastError(0xdeadbeef);
6845 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6846 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6847 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6848 ok(!ret, "expected failure\n");
6849 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6851 skip("no CMS_SIGNER_INFO decode support\n");
6854 ok(GetLastError() == CRYPT_E_ASN1_CORRUPT,
6855 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
6856 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6857 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6858 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6859 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6862 info = (CMSG_CMS_SIGNER_INFO *)buf;
6863 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6865 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6866 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6867 info->SignerId.dwIdChoice);
6868 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6869 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6870 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6871 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6872 encodedCommonNameNoNull,
6873 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6874 "Unexpected value\n");
6875 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6876 sizeof(serialNum), "Unexpected size %d\n",
6877 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6878 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6879 serialNum, sizeof(serialNum)), "Unexpected value\n");
6882 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6883 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6884 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6885 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6888 info = (CMSG_CMS_SIGNER_INFO *)buf;
6889 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6891 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6892 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6893 info->SignerId.dwIdChoice);
6894 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6895 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6896 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6897 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6898 encodedCommonNameNoNull,
6899 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6900 "Unexpected value\n");
6901 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6902 sizeof(serialNum), "Unexpected size %d\n",
6903 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6904 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6905 serialNum, sizeof(serialNum)), "Unexpected value\n");
6906 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6907 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6910 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6911 PKCSSignerWithHashAndEncryptionAlgo,
6912 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6914 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6917 info = (CMSG_CMS_SIGNER_INFO *)buf;
6918 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6920 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6921 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6922 info->SignerId.dwIdChoice);
6923 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6924 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6925 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6926 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6927 encodedCommonNameNoNull,
6928 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6929 "Unexpected value\n");
6930 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6931 sizeof(serialNum), "Unexpected size %d\n",
6932 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6933 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6934 serialNum, sizeof(serialNum)), "Unexpected value\n");
6935 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6936 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6937 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6938 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6941 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6942 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6943 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6944 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6947 info = (CMSG_CMS_SIGNER_INFO *)buf;
6948 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6950 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6951 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6952 info->SignerId.dwIdChoice);
6953 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6954 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6955 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6956 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6957 encodedCommonNameNoNull,
6958 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6959 "Unexpected value\n");
6960 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6961 sizeof(serialNum), "Unexpected size %d\n",
6962 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6963 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6964 serialNum, sizeof(serialNum)), "Unexpected value\n");
6965 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6966 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6967 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6968 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6969 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6970 info->EncryptedHash.cbData);
6971 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6972 "Unexpected value\n");
6975 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6976 CMSSignerWithKeyId, sizeof(CMSSignerWithKeyId),
6977 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6978 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6981 info = (CMSG_CMS_SIGNER_INFO *)buf;
6982 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6984 ok(info->SignerId.dwIdChoice == CERT_ID_KEY_IDENTIFIER,
6985 "Expected CERT_ID_KEY_IDENTIFIER, got %d\n",
6986 info->SignerId.dwIdChoice);
6987 ok(U(info->SignerId).KeyId.cbData == sizeof(serialNum),
6988 "Unexpected size %d\n", U(info->SignerId).KeyId.cbData);
6989 ok(!memcmp(U(info->SignerId).KeyId.pbData, serialNum, sizeof(serialNum)),
6990 "Unexpected value\n");
6995 static BYTE emptyDNSPermittedConstraints[] = {
6996 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
6997 static BYTE emptyDNSExcludedConstraints[] = {
6998 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
6999 static BYTE DNSExcludedConstraints[] = {
7000 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
7001 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7002 static BYTE permittedAndExcludedConstraints[] = {
7003 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7004 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
7005 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7006 static BYTE permittedAndExcludedWithMinConstraints[] = {
7007 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7008 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
7009 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7010 static BYTE permittedAndExcludedWithMinMaxConstraints[] = {
7011 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7012 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
7013 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7015 static void test_encodeNameConstraints(DWORD dwEncoding)
7018 CERT_NAME_CONSTRAINTS_INFO constraints = { 0 };
7019 CERT_GENERAL_SUBTREE permitted = { { 0 } };
7020 CERT_GENERAL_SUBTREE excluded = { { 0 } };
7024 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7025 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7026 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7028 skip("no X509_NAME_CONSTRAINTS encode support\n");
7031 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7034 ok(size == sizeof(emptySequence), "Unexpected size\n");
7035 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
7038 constraints.cPermittedSubtree = 1;
7039 constraints.rgPermittedSubtree = &permitted;
7040 SetLastError(0xdeadbeef);
7041 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7042 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7043 ok(!ret && GetLastError() == E_INVALIDARG,
7044 "Expected E_INVALIDARG, got %08x\n", GetLastError());
7045 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
7046 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7047 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7048 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7051 ok(size == sizeof(emptyDNSPermittedConstraints), "Unexpected size\n");
7052 ok(!memcmp(buf, emptyDNSPermittedConstraints, size),
7053 "Unexpected value\n");
7056 constraints.cPermittedSubtree = 0;
7057 constraints.cExcludedSubtree = 1;
7058 constraints.rgExcludedSubtree = &excluded;
7059 excluded.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
7060 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7061 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7062 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7065 ok(size == sizeof(emptyDNSExcludedConstraints), "Unexpected size\n");
7066 ok(!memcmp(buf, emptyDNSExcludedConstraints, size),
7067 "Unexpected value\n");
7070 U(excluded.Base).pwszURL = (LPWSTR)url;
7071 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7072 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7073 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7076 ok(size == sizeof(DNSExcludedConstraints), "Unexpected size\n");
7077 ok(!memcmp(buf, DNSExcludedConstraints, size),
7078 "Unexpected value\n");
7081 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
7082 U(permitted.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7083 U(permitted.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7084 constraints.cPermittedSubtree = 1;
7085 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7086 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7087 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7090 ok(size == sizeof(permittedAndExcludedConstraints),
7091 "Unexpected size\n");
7092 ok(!memcmp(buf, permittedAndExcludedConstraints, size),
7093 "Unexpected value\n");
7096 permitted.dwMinimum = 5;
7097 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7098 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7099 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7102 ok(size == sizeof(permittedAndExcludedWithMinConstraints),
7103 "Unexpected size\n");
7104 ok(!memcmp(buf, permittedAndExcludedWithMinConstraints, size),
7105 "Unexpected value\n");
7108 permitted.fMaximum = TRUE;
7109 permitted.dwMaximum = 3;
7110 SetLastError(0xdeadbeef);
7111 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7112 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7113 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7116 ok(size == sizeof(permittedAndExcludedWithMinMaxConstraints),
7117 "Unexpected size\n");
7118 ok(!memcmp(buf, permittedAndExcludedWithMinMaxConstraints, size),
7119 "Unexpected value\n");
7124 struct EncodedNameConstraints
7126 CRYPT_DATA_BLOB encoded;
7127 CERT_NAME_CONSTRAINTS_INFO constraints;
7130 static CERT_GENERAL_SUBTREE emptyDNSSubtree = {
7131 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
7132 static CERT_GENERAL_SUBTREE DNSSubtree = {
7133 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
7134 static CERT_GENERAL_SUBTREE IPAddressSubtree = {
7135 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 0 };
7136 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree = {
7137 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, 0 };
7138 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree = {
7139 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, TRUE, 3 };
7141 struct EncodedNameConstraints encodedNameConstraints[] = {
7142 { { sizeof(emptySequence), (LPBYTE)emptySequence }, { 0 } },
7143 { { sizeof(emptyDNSPermittedConstraints), emptyDNSPermittedConstraints },
7144 { 1, &emptyDNSSubtree, 0, NULL } },
7145 { { sizeof(emptyDNSExcludedConstraints), emptyDNSExcludedConstraints },
7146 { 0, NULL, 1, &emptyDNSSubtree } },
7147 { { sizeof(DNSExcludedConstraints), DNSExcludedConstraints },
7148 { 0, NULL, 1, &DNSSubtree } },
7149 { { sizeof(permittedAndExcludedConstraints), permittedAndExcludedConstraints },
7150 { 1, &IPAddressSubtree, 1, &DNSSubtree } },
7151 { { sizeof(permittedAndExcludedWithMinConstraints),
7152 permittedAndExcludedWithMinConstraints },
7153 { 1, &IPAddressWithMinSubtree, 1, &DNSSubtree } },
7154 { { sizeof(permittedAndExcludedWithMinMaxConstraints),
7155 permittedAndExcludedWithMinMaxConstraints },
7156 { 1, &IPAddressWithMinMaxSubtree, 1, &DNSSubtree } },
7159 static void test_decodeNameConstraints(DWORD dwEncoding)
7163 CERT_NAME_CONSTRAINTS_INFO *constraints;
7165 U(DNSSubtree.Base).pwszURL = (LPWSTR)url;
7166 U(IPAddressSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7167 U(IPAddressSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7168 U(IPAddressWithMinSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7169 U(IPAddressWithMinSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7170 U(IPAddressWithMinMaxSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7171 U(IPAddressWithMinMaxSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7173 i < sizeof(encodedNameConstraints) / sizeof(encodedNameConstraints[0]);
7178 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS,
7179 encodedNameConstraints[i].encoded.pbData,
7180 encodedNameConstraints[i].encoded.cbData,
7181 CRYPT_DECODE_ALLOC_FLAG, NULL, &constraints, &size);
7182 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7184 skip("no X509_NAME_CONSTRAINTS decode support\n");
7187 ok(ret, "%d: CryptDecodeObjectEx failed: %08x\n", i, GetLastError());
7192 if (constraints->cPermittedSubtree !=
7193 encodedNameConstraints[i].constraints.cPermittedSubtree)
7194 fprintf(stderr, "%d: expected %d permitted, got %d\n", i,
7195 encodedNameConstraints[i].constraints.cPermittedSubtree,
7196 constraints->cPermittedSubtree);
7197 if (constraints->cPermittedSubtree ==
7198 encodedNameConstraints[i].constraints.cPermittedSubtree)
7200 for (j = 0; j < constraints->cPermittedSubtree; j++)
7202 compareAltNameEntry(&constraints->rgPermittedSubtree[j].Base,
7203 &encodedNameConstraints[i].constraints.rgPermittedSubtree[j].Base);
7206 if (constraints->cExcludedSubtree !=
7207 encodedNameConstraints[i].constraints.cExcludedSubtree)
7208 fprintf(stderr, "%d: expected %d excluded, got %d\n", i,
7209 encodedNameConstraints[i].constraints.cExcludedSubtree,
7210 constraints->cExcludedSubtree);
7211 if (constraints->cExcludedSubtree ==
7212 encodedNameConstraints[i].constraints.cExcludedSubtree)
7214 for (j = 0; j < constraints->cExcludedSubtree; j++)
7216 compareAltNameEntry(&constraints->rgExcludedSubtree[j].Base,
7217 &encodedNameConstraints[i].constraints.rgExcludedSubtree[j].Base);
7220 LocalFree(constraints);
7225 static WCHAR noticeText[] = { 'T','h','i','s',' ','i','s',' ','a',' ',
7226 'n','o','t','i','c','e',0 };
7227 static const BYTE noticeWithDisplayText[] = {
7228 0x30,0x22,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,0x00,
7229 0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,0x74,
7230 0x00,0x69,0x00,0x63,0x00,0x65
7232 static char org[] = "Wine";
7233 static int noticeNumbers[] = { 2,3 };
7234 static BYTE noticeWithReference[] = {
7235 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7236 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7237 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7238 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7241 static void test_encodePolicyQualifierUserNotice(DWORD dwEncoding)
7246 CERT_POLICY_QUALIFIER_USER_NOTICE notice;
7247 CERT_POLICY_QUALIFIER_NOTICE_REFERENCE reference;
7249 memset(¬ice, 0, sizeof(notice));
7250 ret = pCryptEncodeObjectEx(dwEncoding,
7251 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, ¬ice, CRYPT_ENCODE_ALLOC_FLAG,
7253 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7255 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE encode support\n");
7258 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7261 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size);
7262 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
7265 notice.pszDisplayText = noticeText;
7266 ret = pCryptEncodeObjectEx(dwEncoding,
7267 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, ¬ice, CRYPT_ENCODE_ALLOC_FLAG,
7269 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7272 ok(sizeof(noticeWithDisplayText) == size, "unexpected size %d\n", size);
7273 ok(!memcmp(buf, noticeWithDisplayText, size), "unexpected value\n");
7276 reference.pszOrganization = org;
7277 reference.cNoticeNumbers = 2;
7278 reference.rgNoticeNumbers = noticeNumbers;
7279 notice.pNoticeReference = &reference;
7280 ret = pCryptEncodeObjectEx(dwEncoding,
7281 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, ¬ice, CRYPT_ENCODE_ALLOC_FLAG,
7283 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7286 ok(sizeof(noticeWithReference) == size, "unexpected size %d\n", size);
7287 ok(!memcmp(buf, noticeWithReference, size), "unexpected value\n");
7292 static void test_decodePolicyQualifierUserNotice(DWORD dwEncoding)
7295 CERT_POLICY_QUALIFIER_USER_NOTICE *notice;
7298 ret = pCryptDecodeObjectEx(dwEncoding,
7299 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7300 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7302 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7304 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE decode support\n");
7307 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7310 ok(notice->pszDisplayText == NULL, "unexpected display text\n");
7311 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7314 ret = pCryptDecodeObjectEx(dwEncoding,
7315 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7316 noticeWithDisplayText, sizeof(noticeWithDisplayText),
7317 CRYPT_DECODE_ALLOC_FLAG, NULL, ¬ice, &size);
7318 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7321 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7322 "unexpected display text\n");
7323 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7326 ret = pCryptDecodeObjectEx(dwEncoding,
7327 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7328 noticeWithReference, sizeof(noticeWithReference),
7329 CRYPT_DECODE_ALLOC_FLAG, NULL, ¬ice, &size);
7330 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7333 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7334 "unexpected display text\n");
7335 ok(notice->pNoticeReference != NULL, "expected a notice reference\n");
7336 if (notice->pNoticeReference)
7338 ok(!strcmp(notice->pNoticeReference->pszOrganization, org),
7339 "unexpected organization %s\n",
7340 notice->pNoticeReference->pszOrganization);
7341 ok(notice->pNoticeReference->cNoticeNumbers == 2,
7342 "expected 2 notice numbers, got %d\n",
7343 notice->pNoticeReference->cNoticeNumbers);
7344 ok(notice->pNoticeReference->rgNoticeNumbers[0] == noticeNumbers[0],
7345 "unexpected notice number %d\n",
7346 notice->pNoticeReference->rgNoticeNumbers[0]);
7347 ok(notice->pNoticeReference->rgNoticeNumbers[1] == noticeNumbers[1],
7348 "unexpected notice number %d\n",
7349 notice->pNoticeReference->rgNoticeNumbers[1]);
7355 static char oid_any_policy[] = "2.5.29.32.0";
7356 static const BYTE policiesWithAnyPolicy[] = {
7357 0x30,0x08,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00
7359 static char oid1[] = "1.2.3";
7360 static char oid_user_notice[] = "1.3.6.1.5.5.7.2.2";
7361 static const BYTE twoPolicies[] = {
7362 0x30,0x50,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00,0x30,0x46,0x06,0x02,0x2a,
7363 0x03,0x30,0x40,0x30,0x3e,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x02,
7364 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7365 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7366 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7367 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7370 static void test_encodeCertPolicies(DWORD dwEncoding)
7373 CERT_POLICIES_INFO info;
7374 CERT_POLICY_INFO policy[2];
7375 CERT_POLICY_QUALIFIER_INFO qualifier;
7379 memset(&info, 0, sizeof(info));
7380 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7381 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7382 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7385 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size);
7386 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
7389 memset(policy, 0, sizeof(policy));
7390 info.cPolicyInfo = 1;
7391 info.rgPolicyInfo = policy;
7392 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7393 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7394 ok(!ret && (GetLastError() == E_INVALIDARG ||
7395 GetLastError() == OSS_LIMITED /* Win9x/NT4 */),
7396 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
7397 policy[0].pszPolicyIdentifier = oid_any_policy;
7398 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7399 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7400 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7403 ok(sizeof(policiesWithAnyPolicy) == size, "unexpected size %d\n", size);
7404 ok(!memcmp(buf, policiesWithAnyPolicy, size), "unexpected value\n");
7407 policy[1].pszPolicyIdentifier = oid1;
7408 memset(&qualifier, 0, sizeof(qualifier));
7409 qualifier.pszPolicyQualifierId = oid_user_notice;
7410 qualifier.Qualifier.cbData = sizeof(noticeWithReference);
7411 qualifier.Qualifier.pbData = noticeWithReference;
7412 policy[1].cPolicyQualifier = 1;
7413 policy[1].rgPolicyQualifier = &qualifier;
7414 info.cPolicyInfo = 2;
7415 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7416 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7417 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7420 ok(sizeof(twoPolicies) == size, "unexpected size %d\n", size);
7421 ok(!memcmp(buf, twoPolicies, size), "unexpected value\n");
7426 static void test_decodeCertPolicies(DWORD dwEncoding)
7429 CERT_POLICIES_INFO *info;
7432 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7433 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7435 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7438 ok(info->cPolicyInfo == 0, "unexpected policy info %d\n",
7442 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7443 policiesWithAnyPolicy, sizeof(policiesWithAnyPolicy),
7444 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7445 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7448 ok(info->cPolicyInfo == 1, "unexpected policy info %d\n",
7450 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy),
7451 "unexpected policy id %s\n",
7452 info->rgPolicyInfo[0].pszPolicyIdentifier);
7453 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0,
7454 "unexpected policy qualifier count %d\n",
7455 info->rgPolicyInfo[0].cPolicyQualifier);
7458 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7459 twoPolicies, sizeof(twoPolicies),
7460 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7461 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7464 ok(info->cPolicyInfo == 2, "unexpected policy info %d\n",
7466 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy),
7467 "unexpected policy id %s\n",
7468 info->rgPolicyInfo[0].pszPolicyIdentifier);
7469 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0,
7470 "unexpected policy qualifier count %d\n",
7471 info->rgPolicyInfo[0].cPolicyQualifier);
7472 ok(!strcmp(info->rgPolicyInfo[1].pszPolicyIdentifier, oid1),
7473 "unexpected policy id %s\n",
7474 info->rgPolicyInfo[1].pszPolicyIdentifier);
7475 ok(info->rgPolicyInfo[1].cPolicyQualifier == 1,
7476 "unexpected policy qualifier count %d\n",
7477 info->rgPolicyInfo[1].cPolicyQualifier);
7479 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId,
7480 oid_user_notice), "unexpected policy qualifier id %s\n",
7481 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId);
7482 ok(info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData ==
7483 sizeof(noticeWithReference), "unexpected qualifier size %d\n",
7484 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData);
7486 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.pbData,
7487 noticeWithReference, sizeof(noticeWithReference)),
7488 "unexpected qualifier value\n");
7493 static const BYTE policyMappingWithOneMapping[] = {
7494 0x30,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04 };
7495 static const BYTE policyMappingWithTwoMappings[] = {
7496 0x30,0x14,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04,0x30,0x08,0x06,
7497 0x02,0x2b,0x04,0x06,0x02,0x55,0x06 };
7498 static const LPCSTR mappingOids[] = { X509_POLICY_MAPPINGS,
7499 szOID_POLICY_MAPPINGS, szOID_LEGACY_POLICY_MAPPINGS };
7501 static void test_encodeCertPolicyMappings(DWORD dwEncoding)
7503 static char oid2[] = "2.3.4";
7504 static char oid3[] = "1.3.4";
7505 static char oid4[] = "2.5.6";
7507 CERT_POLICY_MAPPINGS_INFO info = { 0 };
7508 CERT_POLICY_MAPPING mapping[2];
7512 /* Each of the mapping OIDs is equivalent, so check with all of them */
7513 for (i = 0; i < sizeof(mappingOids) / sizeof(mappingOids[0]); i++)
7515 memset(&info, 0, sizeof(info));
7516 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7517 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7518 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
7519 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7520 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7522 win_skip("no policy mappings support\n");
7527 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
7528 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
7529 "unexpected value\n");
7532 mapping[0].pszIssuerDomainPolicy = NULL;
7533 mapping[0].pszSubjectDomainPolicy = NULL;
7534 info.cPolicyMapping = 1;
7535 info.rgPolicyMapping = mapping;
7536 SetLastError(0xdeadbeef);
7537 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7538 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7539 ok(!ret && GetLastError() == E_INVALIDARG,
7540 "expected E_INVALIDARG, got %08x\n", GetLastError());
7541 mapping[0].pszIssuerDomainPolicy = oid1;
7542 mapping[0].pszSubjectDomainPolicy = oid2;
7543 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7544 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7545 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7548 ok(size == sizeof(policyMappingWithOneMapping),
7549 "unexpected size %d\n", size);
7550 ok(!memcmp(buf, policyMappingWithOneMapping, size),
7551 "unexpected value\n");
7554 mapping[1].pszIssuerDomainPolicy = oid3;
7555 mapping[1].pszSubjectDomainPolicy = oid4;
7556 info.cPolicyMapping = 2;
7557 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7558 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7559 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7562 ok(size == sizeof(policyMappingWithTwoMappings),
7563 "unexpected size %d\n", size);
7564 ok(!memcmp(buf, policyMappingWithTwoMappings, size),
7565 "unexpected value\n");
7571 static void test_decodeCertPolicyMappings(DWORD dwEncoding)
7574 CERT_POLICY_MAPPINGS_INFO *info;
7577 /* Each of the mapping OIDs is equivalent, so check with all of them */
7578 for (i = 0; i < sizeof(mappingOids) / sizeof(mappingOids[0]); i++)
7580 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7581 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7583 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
7584 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7585 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7587 win_skip("no policy mappings support\n");
7592 ok(info->cPolicyMapping == 0,
7593 "expected 0 policy mappings, got %d\n", info->cPolicyMapping);
7596 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7597 policyMappingWithOneMapping, sizeof(policyMappingWithOneMapping),
7598 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7599 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7602 ok(info->cPolicyMapping == 1,
7603 "expected 1 policy mappings, got %d\n", info->cPolicyMapping);
7604 ok(!strcmp(info->rgPolicyMapping[0].pszIssuerDomainPolicy, "1.2.3"),
7605 "unexpected issuer policy %s\n",
7606 info->rgPolicyMapping[0].pszIssuerDomainPolicy);
7607 ok(!strcmp(info->rgPolicyMapping[0].pszSubjectDomainPolicy,
7608 "2.3.4"), "unexpected subject policy %s\n",
7609 info->rgPolicyMapping[0].pszSubjectDomainPolicy);
7612 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7613 policyMappingWithTwoMappings, sizeof(policyMappingWithTwoMappings),
7614 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7615 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7618 ok(info->cPolicyMapping == 2,
7619 "expected 2 policy mappings, got %d\n", info->cPolicyMapping);
7620 ok(!strcmp(info->rgPolicyMapping[0].pszIssuerDomainPolicy, "1.2.3"),
7621 "unexpected issuer policy %s\n",
7622 info->rgPolicyMapping[0].pszIssuerDomainPolicy);
7623 ok(!strcmp(info->rgPolicyMapping[0].pszSubjectDomainPolicy,
7624 "2.3.4"), "unexpected subject policy %s\n",
7625 info->rgPolicyMapping[0].pszSubjectDomainPolicy);
7626 ok(!strcmp(info->rgPolicyMapping[1].pszIssuerDomainPolicy, "1.3.4"),
7627 "unexpected issuer policy %s\n",
7628 info->rgPolicyMapping[1].pszIssuerDomainPolicy);
7629 ok(!strcmp(info->rgPolicyMapping[1].pszSubjectDomainPolicy,
7630 "2.5.6"), "unexpected subject policy %s\n",
7631 info->rgPolicyMapping[1].pszSubjectDomainPolicy);
7637 static const BYTE policyConstraintsWithRequireExplicit[] = {
7638 0x30,0x03,0x80,0x01,0x00 };
7639 static const BYTE policyConstraintsWithInhibitMapping[] = {
7640 0x30,0x03,0x81,0x01,0x01 };
7641 static const BYTE policyConstraintsWithBoth[] = {
7642 0x30,0x06,0x80,0x01,0x01,0x81,0x01,0x01 };
7644 static void test_encodeCertPolicyConstraints(DWORD dwEncoding)
7646 CERT_POLICY_CONSTRAINTS_INFO info = { 0 };
7651 /* Even though RFC 5280 explicitly states CAs must not issue empty
7652 * policy constraints (section 4.2.1.11), the API doesn't prevent it.
7654 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7655 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7656 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
7657 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7658 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7660 win_skip("no policy constraints support\n");
7665 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
7666 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
7667 "unexpected value\n");
7670 /* If fRequireExplicitPolicy is set but dwRequireExplicitPolicySkipCerts
7671 * is not, then a skip of 0 is encoded.
7673 info.fRequireExplicitPolicy = TRUE;
7674 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7675 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7676 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7679 ok(size == sizeof(policyConstraintsWithRequireExplicit),
7680 "unexpected size %d\n", size);
7681 ok(!memcmp(buf, policyConstraintsWithRequireExplicit,
7682 sizeof(policyConstraintsWithRequireExplicit)), "unexpected value\n");
7685 /* With inhibit policy mapping */
7686 info.fRequireExplicitPolicy = FALSE;
7687 info.dwRequireExplicitPolicySkipCerts = 0;
7688 info.fInhibitPolicyMapping = TRUE;
7689 info.dwInhibitPolicyMappingSkipCerts = 1;
7690 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7691 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7692 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7695 ok(size == sizeof(policyConstraintsWithInhibitMapping),
7696 "unexpected size %d\n", size);
7697 ok(!memcmp(buf, policyConstraintsWithInhibitMapping,
7698 sizeof(policyConstraintsWithInhibitMapping)), "unexpected value\n");
7702 info.fRequireExplicitPolicy = TRUE;
7703 info.dwRequireExplicitPolicySkipCerts = 1;
7704 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7705 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7706 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7709 ok(size == sizeof(policyConstraintsWithBoth), "unexpected size %d\n",
7711 ok(!memcmp(buf, policyConstraintsWithBoth,
7712 sizeof(policyConstraintsWithBoth)), "unexpected value\n");
7717 static void test_decodeCertPolicyConstraints(DWORD dwEncoding)
7719 CERT_POLICY_CONSTRAINTS_INFO *info;
7723 /* Again, even though CAs must not issue such constraints, they can be
7726 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7727 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7729 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
7730 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7731 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7733 win_skip("no policy mappings support\n");
7738 ok(!info->fRequireExplicitPolicy,
7739 "expected require explicit = FALSE\n");
7740 ok(!info->fInhibitPolicyMapping,
7741 "expected implicit mapping = FALSE\n");
7744 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7745 policyConstraintsWithRequireExplicit,
7746 sizeof(policyConstraintsWithRequireExplicit), CRYPT_DECODE_ALLOC_FLAG,
7747 NULL, &info, &size);
7748 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7751 ok(info->fRequireExplicitPolicy,
7752 "expected require explicit = TRUE\n");
7753 ok(info->dwRequireExplicitPolicySkipCerts == 0, "expected 0, got %d\n",
7754 info->dwRequireExplicitPolicySkipCerts);
7755 ok(!info->fInhibitPolicyMapping,
7756 "expected implicit mapping = FALSE\n");
7759 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7760 policyConstraintsWithInhibitMapping,
7761 sizeof(policyConstraintsWithInhibitMapping), CRYPT_DECODE_ALLOC_FLAG,
7762 NULL, &info, &size);
7763 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7766 ok(!info->fRequireExplicitPolicy,
7767 "expected require explicit = FALSE\n");
7768 ok(info->fInhibitPolicyMapping,
7769 "expected implicit mapping = TRUE\n");
7770 ok(info->dwInhibitPolicyMappingSkipCerts == 1, "expected 1, got %d\n",
7771 info->dwInhibitPolicyMappingSkipCerts);
7774 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7775 policyConstraintsWithBoth, sizeof(policyConstraintsWithBoth),
7776 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7777 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7780 ok(info->fRequireExplicitPolicy,
7781 "expected require explicit = TRUE\n");
7782 ok(info->dwRequireExplicitPolicySkipCerts == 1, "expected 1, got %d\n",
7783 info->dwRequireExplicitPolicySkipCerts);
7784 ok(info->fInhibitPolicyMapping,
7785 "expected implicit mapping = TRUE\n");
7786 ok(info->dwInhibitPolicyMappingSkipCerts == 1, "expected 1, got %d\n",
7787 info->dwInhibitPolicyMappingSkipCerts);
7792 /* Free *pInfo with HeapFree */
7793 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
7800 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
7802 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size);
7803 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7804 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7805 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL,
7807 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7808 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7809 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL,
7811 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7812 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7813 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7814 0, NULL, NULL, &size);
7815 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7816 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7817 /* Test with no key */
7818 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7819 0, NULL, NULL, &size);
7820 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n",
7822 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
7823 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
7826 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
7827 NULL, 0, NULL, NULL, &size);
7828 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
7829 *pInfo = HeapAlloc(GetProcessHeap(), 0, size);
7832 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
7833 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size);
7834 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n",
7838 /* By default (we passed NULL as the OID) the OID is
7841 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA),
7842 "Expected %s, got %s\n", szOID_RSA_RSA,
7843 (*pInfo)->Algorithm.pszObjId);
7847 CryptDestroyKey(key);
7850 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
7851 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
7852 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
7853 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7854 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7855 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7856 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
7857 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
7858 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7859 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7860 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7861 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
7862 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
7863 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
7864 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
7865 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
7866 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
7867 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
7868 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
7869 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
7870 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
7871 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
7872 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
7873 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
7874 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
7876 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info)
7880 PCCERT_CONTEXT context;
7885 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
7886 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
7887 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
7888 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7891 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key);
7892 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7893 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7894 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key);
7895 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7896 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7897 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL,
7899 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7900 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7902 /* Export key with standard algorithm (CALG_RSA_KEYX) */
7903 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7905 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7907 dwSize = sizeof(ai);
7908 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7909 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7912 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7913 ok(ai == CALG_RSA_KEYX, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai);
7916 CryptDestroyKey(key);
7918 /* Repeat with forced algorithm */
7919 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, CALG_RSA_SIGN, 0, NULL,
7921 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7923 dwSize = sizeof(ai);
7924 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7925 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7928 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7929 ok(ai == CALG_RSA_SIGN, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai);
7932 CryptDestroyKey(key);
7934 /* Test importing a public key from a certificate context */
7935 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert,
7936 sizeof(expiredCert));
7937 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
7941 ok(!strcmp(szOID_RSA_RSA,
7942 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId),
7943 "Expected %s, got %s\n", szOID_RSA_RSA,
7944 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
7945 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING,
7946 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
7947 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7948 CryptDestroyKey(key);
7949 CertFreeCertificateContext(context);
7953 static const char cspName[] = "WineCryptTemp";
7955 static void testPortPublicKeyInfo(void)
7959 PCERT_PUBLIC_KEY_INFO info = NULL;
7961 /* Just in case a previous run failed, delete this thing */
7962 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7963 CRYPT_DELETEKEYSET);
7964 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
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);
7978 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
7979 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING };
7983 hCrypt32 = GetModuleHandleA("crypt32.dll");
7984 pCryptDecodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptDecodeObjectEx");
7985 pCryptEncodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptEncodeObjectEx");
7986 if (!pCryptDecodeObjectEx || !pCryptEncodeObjectEx)
7988 win_skip("CryptDecodeObjectEx() is not available\n");
7992 for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++)
7994 test_encodeInt(encodings[i]);
7995 test_decodeInt(encodings[i]);
7996 test_encodeEnumerated(encodings[i]);
7997 test_decodeEnumerated(encodings[i]);
7998 test_encodeFiletime(encodings[i]);
7999 test_decodeFiletime(encodings[i]);
8000 test_encodeName(encodings[i]);
8001 test_decodeName(encodings[i]);
8002 test_encodeUnicodeName(encodings[i]);
8003 test_decodeUnicodeName(encodings[i]);
8004 test_encodeNameValue(encodings[i]);
8005 test_decodeNameValue(encodings[i]);
8006 test_encodeUnicodeNameValue(encodings[i]);
8007 test_decodeUnicodeNameValue(encodings[i]);
8008 test_encodeAltName(encodings[i]);
8009 test_decodeAltName(encodings[i]);
8010 test_encodeOctets(encodings[i]);
8011 test_decodeOctets(encodings[i]);
8012 test_encodeBits(encodings[i]);
8013 test_decodeBits(encodings[i]);
8014 test_encodeBasicConstraints(encodings[i]);
8015 test_decodeBasicConstraints(encodings[i]);
8016 test_encodeRsaPublicKey(encodings[i]);
8017 test_decodeRsaPublicKey(encodings[i]);
8018 test_encodeSequenceOfAny(encodings[i]);
8019 test_decodeSequenceOfAny(encodings[i]);
8020 test_encodeExtensions(encodings[i]);
8021 test_decodeExtensions(encodings[i]);
8022 test_encodePublicKeyInfo(encodings[i]);
8023 test_decodePublicKeyInfo(encodings[i]);
8024 test_encodeCertToBeSigned(encodings[i]);
8025 test_decodeCertToBeSigned(encodings[i]);
8026 test_encodeCert(encodings[i]);
8027 test_decodeCert(encodings[i]);
8028 test_encodeCRLDistPoints(encodings[i]);
8029 test_decodeCRLDistPoints(encodings[i]);
8030 test_encodeCRLIssuingDistPoint(encodings[i]);
8031 test_decodeCRLIssuingDistPoint(encodings[i]);
8032 test_encodeCRLToBeSigned(encodings[i]);
8033 test_decodeCRLToBeSigned(encodings[i]);
8034 test_encodeEnhancedKeyUsage(encodings[i]);
8035 test_decodeEnhancedKeyUsage(encodings[i]);
8036 test_encodeAuthorityKeyId(encodings[i]);
8037 test_decodeAuthorityKeyId(encodings[i]);
8038 test_encodeAuthorityKeyId2(encodings[i]);
8039 test_decodeAuthorityKeyId2(encodings[i]);
8040 test_encodeAuthorityInfoAccess(encodings[i]);
8041 test_decodeAuthorityInfoAccess(encodings[i]);
8042 test_encodeCTL(encodings[i]);
8043 test_decodeCTL(encodings[i]);
8044 test_encodePKCSContentInfo(encodings[i]);
8045 test_decodePKCSContentInfo(encodings[i]);
8046 test_encodePKCSAttribute(encodings[i]);
8047 test_decodePKCSAttribute(encodings[i]);
8048 test_encodePKCSAttributes(encodings[i]);
8049 test_decodePKCSAttributes(encodings[i]);
8050 test_encodePKCSSMimeCapabilities(encodings[i]);
8051 test_decodePKCSSMimeCapabilities(encodings[i]);
8052 test_encodePKCSSignerInfo(encodings[i]);
8053 test_decodePKCSSignerInfo(encodings[i]);
8054 test_encodeCMSSignerInfo(encodings[i]);
8055 test_decodeCMSSignerInfo(encodings[i]);
8056 test_encodeNameConstraints(encodings[i]);
8057 test_decodeNameConstraints(encodings[i]);
8058 test_encodePolicyQualifierUserNotice(encodings[i]);
8059 test_decodePolicyQualifierUserNotice(encodings[i]);
8060 test_encodeCertPolicies(encodings[i]);
8061 test_decodeCertPolicies(encodings[i]);
8062 test_encodeCertPolicyMappings(encodings[i]);
8063 test_decodeCertPolicyMappings(encodings[i]);
8064 test_encodeCertPolicyConstraints(encodings[i]);
8065 test_decodeCertPolicyConstraints(encodings[i]);
8067 testPortPublicKeyInfo();