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 value = { CERT_RDN_ENCODED_BLOB,
1395 { sizeof(ia5EmbeddedNull), ia5EmbeddedNull } };
1398 compareNameValues(&value, (const CERT_NAME_VALUE *)buf);
1403 static const BYTE emptyURL[] = { 0x30, 0x02, 0x86, 0x00 };
1404 static const BYTE emptyURLExtraBytes[] = { 0x30, 0x02, 0x86, 0x00, 0, 0, 0 };
1405 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e',
1406 'h','q','.','o','r','g',0 };
1407 static const BYTE encodedURL[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74,
1408 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e,
1410 static const WCHAR nihongoURL[] = { 'h','t','t','p',':','/','/',0x226f,
1412 static const WCHAR dnsName[] = { 'w','i','n','e','h','q','.','o','r','g',0 };
1413 static const BYTE encodedDnsName[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69,
1414 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
1415 static const BYTE localhost[] = { 127, 0, 0, 1 };
1416 static const BYTE encodedIPAddr[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00,
1418 static const unsigned char encodedCommonName[] = {
1419 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0};
1420 static const BYTE encodedOidName[] = { 0x30,0x04,0x88,0x02,0x2a,0x03 };
1421 static const BYTE encodedDirectoryName[] = {
1422 0x30,0x19,0xa4,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1423 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1425 static void test_encodeAltName(DWORD dwEncoding)
1427 CERT_ALT_NAME_INFO info = { 0 };
1428 CERT_ALT_NAME_ENTRY entry = { 0 };
1432 char oid[] = "1.2.3";
1434 /* Test with empty info */
1435 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1436 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1439 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
1440 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
1443 /* Test with an empty entry */
1445 info.rgAltEntry = &entry;
1446 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1447 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1448 ok(!ret && GetLastError() == E_INVALIDARG,
1449 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1450 /* Test with an empty pointer */
1451 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
1452 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1453 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1456 ok(size == sizeof(emptyURL), "Wrong size %d\n", size);
1457 ok(!memcmp(buf, emptyURL, size), "Unexpected value\n");
1460 /* Test with a real URL */
1461 U(entry).pwszURL = (LPWSTR)url;
1462 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1463 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1466 ok(size == sizeof(encodedURL), "Wrong size %d\n", size);
1467 ok(!memcmp(buf, encodedURL, size), "Unexpected value\n");
1470 /* Now with the URL containing an invalid IA5 char */
1471 U(entry).pwszURL = (LPWSTR)nihongoURL;
1472 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1473 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1474 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
1475 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
1476 /* The first invalid character is at index 7 */
1477 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
1478 "Expected invalid char at index 7, got %d\n",
1479 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
1480 /* Now with the URL missing a scheme */
1481 U(entry).pwszURL = (LPWSTR)dnsName;
1482 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1483 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1484 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1487 /* This succeeds, but it shouldn't, so don't worry about conforming */
1490 /* Now with a DNS name */
1491 entry.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
1492 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1493 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1494 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1497 ok(size == sizeof(encodedDnsName), "Wrong size %d\n", size);
1498 ok(!memcmp(buf, encodedDnsName, size), "Unexpected value\n");
1501 /* Test with an IP address */
1502 entry.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
1503 U(entry).IPAddress.cbData = sizeof(localhost);
1504 U(entry).IPAddress.pbData = (LPBYTE)localhost;
1505 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1506 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1509 ok(size == sizeof(encodedIPAddr), "Wrong size %d\n", size);
1510 ok(!memcmp(buf, encodedIPAddr, size), "Unexpected value\n");
1514 entry.dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID;
1515 U(entry).pszRegisteredID = oid;
1516 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1517 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1520 ok(size == sizeof(encodedOidName), "Wrong size %d\n", size);
1521 ok(!memcmp(buf, encodedOidName, size), "Unexpected value\n");
1524 /* Test with directory name */
1525 entry.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
1526 U(entry).DirectoryName.cbData = sizeof(encodedCommonName);
1527 U(entry).DirectoryName.pbData = (LPBYTE)encodedCommonName;
1528 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1529 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1532 ok(size == sizeof(encodedDirectoryName), "Wrong size %d\n", size);
1533 ok(!memcmp(buf, encodedDirectoryName, size), "Unexpected value\n");
1538 static void test_decodeAltName(DWORD dwEncoding)
1540 static const BYTE unimplementedType[] = { 0x30, 0x06, 0x85, 0x04, 0x7f,
1542 static const BYTE bogusType[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00,
1544 static const BYTE dns_embedded_null[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f,
1545 0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 };
1546 static const BYTE dns_embedded_bell[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f,
1547 0x6f,0x2e,0x63,0x6f,0x6d,0x07,0x62,0x61,0x64,0x64,0x69,0x65 };
1548 static const BYTE url_embedded_null[] = { 0x30,0x10,0x86,0x0e,0x66,0x6f,
1549 0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 };
1553 CERT_ALT_NAME_INFO *info;
1555 /* Test some bogus ones first */
1556 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1557 unimplementedType, sizeof(unimplementedType), CRYPT_DECODE_ALLOC_FLAG,
1558 NULL, &buf, &bufSize);
1559 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
1560 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1561 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
1563 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1564 bogusType, sizeof(bogusType), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
1566 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
1567 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1568 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
1570 /* Now expected cases */
1571 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptySequence,
1572 emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1573 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1576 info = (CERT_ALT_NAME_INFO *)buf;
1578 ok(info->cAltEntry == 0, "Expected 0 entries, got %d\n",
1582 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptyURL,
1583 emptyURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1584 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1587 info = (CERT_ALT_NAME_INFO *)buf;
1589 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1591 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1592 "Expected CERT_ALT_NAME_URL, got %d\n",
1593 info->rgAltEntry[0].dwAltNameChoice);
1594 ok(U(info->rgAltEntry[0]).pwszURL == NULL || !*U(info->rgAltEntry[0]).pwszURL,
1595 "Expected empty URL\n");
1598 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1599 emptyURLExtraBytes, sizeof(emptyURLExtraBytes), 0, NULL, NULL, &bufSize);
1600 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1601 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedURL,
1602 encodedURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1603 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1606 info = (CERT_ALT_NAME_INFO *)buf;
1608 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1610 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1611 "Expected CERT_ALT_NAME_URL, got %d\n",
1612 info->rgAltEntry[0].dwAltNameChoice);
1613 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszURL, url), "Unexpected URL\n");
1616 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedDnsName,
1617 encodedDnsName[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1618 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1621 info = (CERT_ALT_NAME_INFO *)buf;
1623 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1625 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1626 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1627 info->rgAltEntry[0].dwAltNameChoice);
1628 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszDNSName, dnsName),
1629 "Unexpected DNS name\n");
1632 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedIPAddr,
1633 encodedIPAddr[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1634 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1637 info = (CERT_ALT_NAME_INFO *)buf;
1639 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1641 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS,
1642 "Expected CERT_ALT_NAME_IP_ADDRESS, got %d\n",
1643 info->rgAltEntry[0].dwAltNameChoice);
1644 ok(U(info->rgAltEntry[0]).IPAddress.cbData == sizeof(localhost),
1645 "Unexpected IP address length %d\n",
1646 U(info->rgAltEntry[0]).IPAddress.cbData);
1647 ok(!memcmp(U(info->rgAltEntry[0]).IPAddress.pbData, localhost,
1648 sizeof(localhost)), "Unexpected IP address value\n");
1651 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedOidName,
1652 sizeof(encodedOidName), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1653 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1656 info = (CERT_ALT_NAME_INFO *)buf;
1658 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1660 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_REGISTERED_ID,
1661 "Expected CERT_ALT_NAME_REGISTERED_ID, got %d\n",
1662 info->rgAltEntry[0].dwAltNameChoice);
1663 ok(!strcmp(U(info->rgAltEntry[0]).pszRegisteredID, "1.2.3"),
1664 "Expected OID 1.2.3, got %s\n", U(info->rgAltEntry[0]).pszRegisteredID);
1667 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1668 encodedDirectoryName, sizeof(encodedDirectoryName),
1669 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1670 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1673 info = (CERT_ALT_NAME_INFO *)buf;
1675 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1677 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME,
1678 "Expected CERT_ALT_NAME_DIRECTORY_NAME, got %d\n",
1679 info->rgAltEntry[0].dwAltNameChoice);
1680 ok(U(info->rgAltEntry[0]).DirectoryName.cbData ==
1681 sizeof(encodedCommonName), "Unexpected directory name length %d\n",
1682 U(info->rgAltEntry[0]).DirectoryName.cbData);
1683 ok(!memcmp(U(info->rgAltEntry[0]).DirectoryName.pbData,
1684 encodedCommonName, sizeof(encodedCommonName)),
1685 "Unexpected directory name value\n");
1688 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1689 dns_embedded_null, sizeof(dns_embedded_null), CRYPT_DECODE_ALLOC_FLAG,
1690 NULL, &buf, &bufSize);
1691 /* Fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned about the
1692 * particular failure, just that it doesn't decode.
1694 ok(!ret, "expected failure\n");
1695 /* An embedded bell character is allowed, however. */
1696 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1697 dns_embedded_bell, sizeof(dns_embedded_bell), CRYPT_DECODE_ALLOC_FLAG,
1698 NULL, &buf, &bufSize);
1699 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1702 info = (CERT_ALT_NAME_INFO *)buf;
1704 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1706 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1707 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1708 info->rgAltEntry[0].dwAltNameChoice);
1711 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1712 url_embedded_null, sizeof(dns_embedded_null), CRYPT_DECODE_ALLOC_FLAG,
1713 NULL, &buf, &bufSize);
1714 /* Again, fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned
1715 * about the particular failure, just that it doesn't decode.
1717 ok(!ret, "expected failure\n");
1720 struct UnicodeExpectedError
1728 static const WCHAR oneW[] = { '1',0 };
1729 static const WCHAR aW[] = { 'a',0 };
1730 static const WCHAR quoteW[] = { '"', 0 };
1732 static struct UnicodeExpectedError unicodeErrors[] = {
1733 { CERT_RDN_ANY_TYPE, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1734 { CERT_RDN_ENCODED_BLOB, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1735 { CERT_RDN_OCTET_STRING, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1736 { CERT_RDN_NUMERIC_STRING, aW, 0, CRYPT_E_INVALID_NUMERIC_STRING },
1737 { CERT_RDN_PRINTABLE_STRING, quoteW, 0, CRYPT_E_INVALID_PRINTABLE_STRING },
1738 { CERT_RDN_IA5_STRING, nihongoURL, 7, CRYPT_E_INVALID_IA5_STRING },
1741 struct UnicodeExpectedResult
1745 CRYPT_DATA_BLOB encoded;
1748 static BYTE oneNumeric[] = { 0x12, 0x01, 0x31 };
1749 static BYTE onePrintable[] = { 0x13, 0x01, 0x31 };
1750 static BYTE oneTeletex[] = { 0x14, 0x01, 0x31 };
1751 static BYTE oneVideotex[] = { 0x15, 0x01, 0x31 };
1752 static BYTE oneIA5[] = { 0x16, 0x01, 0x31 };
1753 static BYTE oneGraphic[] = { 0x19, 0x01, 0x31 };
1754 static BYTE oneVisible[] = { 0x1a, 0x01, 0x31 };
1755 static BYTE oneUniversal[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 };
1756 static BYTE oneGeneral[] = { 0x1b, 0x01, 0x31 };
1757 static BYTE oneBMP[] = { 0x1e, 0x02, 0x00, 0x31 };
1758 static BYTE oneUTF8[] = { 0x0c, 0x01, 0x31 };
1759 static BYTE nihongoT61[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,
1761 static BYTE nihongoGeneral[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1763 static BYTE nihongoBMP[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,
1764 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
1765 static BYTE nihongoUTF8[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1766 0xe2,0x89,0xaf,0xe5,0x9d,0x9b };
1768 static struct UnicodeExpectedResult unicodeResults[] = {
1769 { CERT_RDN_NUMERIC_STRING, oneW, { sizeof(oneNumeric), oneNumeric } },
1770 { CERT_RDN_PRINTABLE_STRING, oneW, { sizeof(onePrintable), onePrintable } },
1771 { CERT_RDN_TELETEX_STRING, oneW, { sizeof(oneTeletex), oneTeletex } },
1772 { CERT_RDN_VIDEOTEX_STRING, oneW, { sizeof(oneVideotex), oneVideotex } },
1773 { CERT_RDN_IA5_STRING, oneW, { sizeof(oneIA5), oneIA5 } },
1774 { CERT_RDN_GRAPHIC_STRING, oneW, { sizeof(oneGraphic), oneGraphic } },
1775 { CERT_RDN_VISIBLE_STRING, oneW, { sizeof(oneVisible), oneVisible } },
1776 { CERT_RDN_UNIVERSAL_STRING, oneW, { sizeof(oneUniversal), oneUniversal } },
1777 { CERT_RDN_GENERAL_STRING, oneW, { sizeof(oneGeneral), oneGeneral } },
1778 { CERT_RDN_BMP_STRING, oneW, { sizeof(oneBMP), oneBMP } },
1779 { CERT_RDN_UTF8_STRING, oneW, { sizeof(oneUTF8), oneUTF8 } },
1780 { CERT_RDN_BMP_STRING, nihongoURL, { sizeof(nihongoBMP), nihongoBMP } },
1781 { CERT_RDN_UTF8_STRING, nihongoURL, { sizeof(nihongoUTF8), nihongoUTF8 } },
1784 static struct UnicodeExpectedResult unicodeWeirdness[] = {
1785 { CERT_RDN_TELETEX_STRING, nihongoURL, { sizeof(nihongoT61), nihongoT61 } },
1786 { CERT_RDN_GENERAL_STRING, nihongoURL, { sizeof(nihongoGeneral), nihongoGeneral } },
1789 static void test_encodeUnicodeNameValue(DWORD dwEncoding)
1794 CERT_NAME_VALUE value;
1798 /* Crashes on win9x */
1799 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, NULL,
1800 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1801 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1802 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1804 /* Have to have a string of some sort */
1805 value.dwValueType = 0; /* aka CERT_RDN_ANY_TYPE */
1806 value.Value.pbData = NULL;
1807 value.Value.cbData = 0;
1808 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1809 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1810 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1811 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1812 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1813 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1814 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1815 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1816 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1817 value.dwValueType = CERT_RDN_ANY_TYPE;
1818 value.Value.pbData = (LPBYTE)oneW;
1819 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1820 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1821 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1822 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1823 value.Value.cbData = sizeof(oneW);
1824 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1825 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1826 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1827 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1828 /* An encoded string with specified length isn't good enough either */
1829 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1830 value.Value.pbData = oneUniversal;
1831 value.Value.cbData = sizeof(oneUniversal);
1832 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1833 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1834 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1835 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1836 /* More failure checking */
1837 value.Value.cbData = 0;
1838 for (i = 0; i < sizeof(unicodeErrors) / sizeof(unicodeErrors[0]); i++)
1840 value.Value.pbData = (LPBYTE)unicodeErrors[i].str;
1841 value.dwValueType = unicodeErrors[i].valueType;
1842 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1843 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1844 ok(!ret && GetLastError() == unicodeErrors[i].error,
1845 "Value type %d: expected %08x, got %08x\n", value.dwValueType,
1846 unicodeErrors[i].error, GetLastError());
1847 ok(size == unicodeErrors[i].errorIndex,
1848 "Expected error index %d, got %d\n", unicodeErrors[i].errorIndex,
1851 /* cbData can be zero if the string is NULL-terminated */
1852 value.Value.cbData = 0;
1853 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1855 value.Value.pbData = (LPBYTE)unicodeResults[i].str;
1856 value.dwValueType = unicodeResults[i].valueType;
1857 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1858 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1859 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
1860 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1863 ok(size == unicodeResults[i].encoded.cbData,
1864 "Value type %d: expected size %d, got %d\n",
1865 value.dwValueType, unicodeResults[i].encoded.cbData, size);
1866 ok(!memcmp(unicodeResults[i].encoded.pbData, buf, size),
1867 "Value type %d: unexpected value\n", value.dwValueType);
1871 /* These "encode," but they do so by truncating each unicode character
1872 * rather than properly encoding it. Kept separate from the proper results,
1873 * because the encoded forms won't decode to their original strings.
1875 for (i = 0; i < sizeof(unicodeWeirdness) / sizeof(unicodeWeirdness[0]); i++)
1877 value.Value.pbData = (LPBYTE)unicodeWeirdness[i].str;
1878 value.dwValueType = unicodeWeirdness[i].valueType;
1879 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1880 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1881 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1884 ok(size == unicodeWeirdness[i].encoded.cbData,
1885 "Value type %d: expected size %d, got %d\n",
1886 value.dwValueType, unicodeWeirdness[i].encoded.cbData, size);
1887 ok(!memcmp(unicodeWeirdness[i].encoded.pbData, buf, size),
1888 "Value type %d: unexpected value\n", value.dwValueType);
1894 static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
1896 if (n <= 0) return 0;
1897 while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
1898 return *str1 - *str2;
1901 static void test_decodeUnicodeNameValue(DWORD dwEncoding)
1905 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1911 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE,
1912 unicodeResults[i].encoded.pbData, unicodeResults[i].encoded.cbData,
1913 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
1914 ok(ret || broken(GetLastError() == CRYPT_E_NOT_CHAR_STRING /* Win9x */),
1915 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1918 PCERT_NAME_VALUE value = (PCERT_NAME_VALUE)buf;
1920 ok(value->dwValueType == unicodeResults[i].valueType,
1921 "Expected value type %d, got %d\n", unicodeResults[i].valueType,
1922 value->dwValueType);
1923 ok(!strncmpW((LPWSTR)value->Value.pbData, unicodeResults[i].str,
1924 value->Value.cbData / sizeof(WCHAR)),
1925 "Unexpected decoded value for index %d (value type %d)\n", i,
1926 unicodeResults[i].valueType);
1932 struct encodedOctets
1935 const BYTE *encoded;
1938 static const unsigned char bin46[] = { 'h','i',0 };
1939 static const unsigned char bin47[] = { 0x04,0x02,'h','i',0 };
1940 static const unsigned char bin48[] = {
1941 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1942 static const unsigned char bin49[] = {
1943 0x04,0x0f,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1944 static const unsigned char bin50[] = { 0 };
1945 static const unsigned char bin51[] = { 0x04,0x00,0 };
1947 static const struct encodedOctets octets[] = {
1953 static void test_encodeOctets(DWORD dwEncoding)
1955 CRYPT_DATA_BLOB blob;
1958 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1964 blob.cbData = strlen((const char*)octets[i].val);
1965 blob.pbData = (BYTE*)octets[i].val;
1966 ret = pCryptEncodeObjectEx(dwEncoding, X509_OCTET_STRING, &blob,
1967 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1968 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
1972 "Got unexpected type %d for octet string (expected 4)\n", buf[0]);
1973 ok(buf[1] == octets[i].encoded[1], "Got length %d, expected %d\n",
1974 buf[1], octets[i].encoded[1]);
1975 ok(!memcmp(buf + 1, octets[i].encoded + 1,
1976 octets[i].encoded[1] + 1), "Got unexpected value\n");
1982 static void test_decodeOctets(DWORD dwEncoding)
1986 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1992 ret = pCryptDecodeObjectEx(dwEncoding, X509_OCTET_STRING,
1993 octets[i].encoded, octets[i].encoded[1] + 2,
1994 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1995 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1996 ok(bufSize >= sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1],
1997 "Expected size >= %d, got %d\n",
1998 (int)sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1], bufSize);
1999 ok(buf != NULL, "Expected allocated buffer\n");
2002 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)buf;
2005 ok(!memcmp(blob->pbData, octets[i].val, blob->cbData),
2006 "Unexpected value\n");
2012 static const BYTE bytesToEncode[] = { 0xff, 0xff };
2017 const BYTE *encoded;
2019 const BYTE *decoded;
2022 static const unsigned char bin52[] = { 0x03,0x03,0x00,0xff,0xff };
2023 static const unsigned char bin53[] = { 0xff,0xff };
2024 static const unsigned char bin54[] = { 0x03,0x03,0x01,0xff,0xfe };
2025 static const unsigned char bin55[] = { 0xff,0xfe };
2026 static const unsigned char bin56[] = { 0x03,0x02,0x01,0xfe };
2027 static const unsigned char bin57[] = { 0xfe };
2028 static const unsigned char bin58[] = { 0x03,0x01,0x00 };
2030 static const struct encodedBits bits[] = {
2031 /* normal test cases */
2032 { 0, bin52, 2, bin53 },
2033 { 1, bin54, 2, bin55 },
2034 /* strange test case, showing cUnusedBits >= 8 is allowed */
2035 { 9, bin56, 1, bin57 },
2038 static void test_encodeBits(DWORD dwEncoding)
2042 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
2044 CRYPT_BIT_BLOB blob;
2049 blob.cbData = sizeof(bytesToEncode);
2050 blob.pbData = (BYTE *)bytesToEncode;
2051 blob.cUnusedBits = bits[i].cUnusedBits;
2052 ret = pCryptEncodeObjectEx(dwEncoding, X509_BITS, &blob,
2053 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2054 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2057 ok(bufSize == bits[i].encoded[1] + 2,
2058 "%d: Got unexpected size %d, expected %d\n", i, bufSize,
2059 bits[i].encoded[1] + 2);
2060 ok(!memcmp(buf, bits[i].encoded, bits[i].encoded[1] + 2),
2061 "%d: Unexpected value\n", i);
2067 static void test_decodeBits(DWORD dwEncoding)
2069 static const BYTE ber[] = "\x03\x02\x01\xff";
2070 static const BYTE berDecoded = 0xfe;
2077 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
2079 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, bits[i].encoded,
2080 bits[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
2082 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2085 CRYPT_BIT_BLOB *blob;
2087 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + bits[i].cbDecoded,
2088 "Got unexpected size %d\n", bufSize);
2089 blob = (CRYPT_BIT_BLOB *)buf;
2090 ok(blob->cbData == bits[i].cbDecoded,
2091 "Got unexpected length %d, expected %d\n", blob->cbData,
2093 if (blob->cbData && bits[i].cbDecoded)
2094 ok(!memcmp(blob->pbData, bits[i].decoded, bits[i].cbDecoded),
2095 "Unexpected value\n");
2099 /* special case: check that something that's valid in BER but not in DER
2100 * decodes successfully
2102 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, ber, ber[1] + 2,
2103 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2104 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2107 CRYPT_BIT_BLOB *blob;
2109 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + sizeof(berDecoded),
2110 "Got unexpected size %d\n", bufSize);
2111 blob = (CRYPT_BIT_BLOB *)buf;
2112 ok(blob->cbData == sizeof(berDecoded),
2113 "Got unexpected length %d\n", blob->cbData);
2115 ok(*blob->pbData == berDecoded, "Unexpected value\n");
2122 CERT_BASIC_CONSTRAINTS2_INFO info;
2123 const BYTE *encoded;
2126 static const unsigned char bin59[] = { 0x30,0x00 };
2127 static const unsigned char bin60[] = { 0x30,0x03,0x01,0x01,0xff };
2128 static const unsigned char bin61[] = { 0x30,0x03,0x02,0x01,0x00 };
2129 static const unsigned char bin62[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2130 static const struct Constraints2 constraints2[] = {
2131 /* empty constraints */
2132 { { FALSE, FALSE, 0}, bin59 },
2134 { { TRUE, FALSE, 0}, bin60 },
2135 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well,
2136 * but that's not the case
2138 { { FALSE, TRUE, 0}, bin61 },
2139 /* can be a CA and has path length constraints set */
2140 { { TRUE, TRUE, 1}, bin62 },
2143 static const BYTE emptyConstraint[] = { 0x30, 0x03, 0x03, 0x01, 0x00 };
2144 static const BYTE encodedDomainName[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11,
2145 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
2146 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
2147 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2148 static const BYTE constraintWithDomainName[] = { 0x30, 0x32, 0x03, 0x01, 0x00,
2149 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
2150 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30,
2151 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
2152 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2154 static void test_encodeBasicConstraints(DWORD dwEncoding)
2156 DWORD i, bufSize = 0;
2157 CERT_BASIC_CONSTRAINTS_INFO info = { { 0 } };
2158 CERT_NAME_BLOB nameBlob = { sizeof(encodedDomainName),
2159 (LPBYTE)encodedDomainName };
2163 /* First test with the simpler info2 */
2164 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2166 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2167 &constraints2[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf,
2169 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2172 ok(bufSize == constraints2[i].encoded[1] + 2,
2173 "Expected %d bytes, got %d\n", constraints2[i].encoded[1] + 2,
2175 ok(!memcmp(buf, constraints2[i].encoded,
2176 constraints2[i].encoded[1] + 2), "Unexpected value\n");
2180 /* Now test with more complex basic constraints */
2181 info.SubjectType.cbData = 0;
2182 info.fPathLenConstraint = FALSE;
2183 info.cSubtreesConstraint = 0;
2184 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2185 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2186 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2187 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2190 ok(bufSize == sizeof(emptyConstraint), "Wrong size %d\n", bufSize);
2191 ok(!memcmp(buf, emptyConstraint, sizeof(emptyConstraint)),
2192 "Unexpected value\n");
2195 /* None of the certs I examined had any subtree constraint, but I test one
2196 * anyway just in case.
2198 info.cSubtreesConstraint = 1;
2199 info.rgSubtreesConstraint = &nameBlob;
2200 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2201 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2202 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2203 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2206 ok(bufSize == sizeof(constraintWithDomainName), "Wrong size %d\n", bufSize);
2207 ok(!memcmp(buf, constraintWithDomainName,
2208 sizeof(constraintWithDomainName)), "Unexpected value\n");
2211 /* FIXME: test encoding with subject type. */
2214 static const unsigned char bin63[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 };
2216 static void test_decodeBasicConstraints(DWORD dwEncoding)
2218 static const BYTE inverted[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01,
2220 static const struct Constraints2 badBool = { { TRUE, TRUE, 1 }, bin63 };
2226 /* First test with simpler info2 */
2227 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2229 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2230 constraints2[i].encoded, constraints2[i].encoded[1] + 2,
2231 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2232 ok(ret, "CryptDecodeObjectEx failed for item %d: %08x\n", i,
2236 CERT_BASIC_CONSTRAINTS2_INFO *info =
2237 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2239 ok(!memcmp(info, &constraints2[i].info, sizeof(*info)),
2240 "Unexpected value for item %d\n", i);
2244 /* Check with the order of encoded elements inverted */
2246 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2247 inverted, inverted[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
2249 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2250 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2251 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2253 ok(!buf, "Expected buf to be set to NULL\n");
2254 /* Check with a non-DER bool */
2255 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2256 badBool.encoded, badBool.encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2258 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2261 CERT_BASIC_CONSTRAINTS2_INFO *info =
2262 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2264 ok(!memcmp(info, &badBool.info, sizeof(*info)), "Unexpected value\n");
2267 /* Check with a non-basic constraints value */
2268 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2269 encodedCommonName, encodedCommonName[1] + 2,
2270 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2271 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2272 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2273 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2275 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */
2276 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2277 emptyConstraint, sizeof(emptyConstraint), CRYPT_DECODE_ALLOC_FLAG, NULL,
2279 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2282 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2284 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2285 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2286 ok(info->cSubtreesConstraint == 0, "Expected no subtree constraints\n");
2289 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2290 constraintWithDomainName, sizeof(constraintWithDomainName),
2291 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2292 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2295 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2297 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2298 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2299 ok(info->cSubtreesConstraint == 1, "Expected a subtree constraint\n");
2300 if (info->cSubtreesConstraint && info->rgSubtreesConstraint)
2302 ok(info->rgSubtreesConstraint[0].cbData ==
2303 sizeof(encodedDomainName), "Wrong size %d\n",
2304 info->rgSubtreesConstraint[0].cbData);
2305 ok(!memcmp(info->rgSubtreesConstraint[0].pbData, encodedDomainName,
2306 sizeof(encodedDomainName)), "Unexpected value\n");
2312 /* These are terrible public keys of course, I'm just testing encoding */
2313 static const BYTE modulus1[] = { 0,0,0,1,1,1,1,1 };
2314 static const BYTE modulus2[] = { 1,1,1,1,1,0,0,0 };
2315 static const BYTE modulus3[] = { 0x80,1,1,1,1,0,0,0 };
2316 static const BYTE modulus4[] = { 1,1,1,1,1,0,0,0x80 };
2317 static const BYTE mod1_encoded[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 };
2318 static const BYTE mod2_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2319 static const BYTE mod3_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 };
2320 static const BYTE mod4_encoded[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2322 struct EncodedRSAPubKey
2324 const BYTE *modulus;
2326 const BYTE *encoded;
2327 size_t decodedModulusLen;
2330 struct EncodedRSAPubKey rsaPubKeys[] = {
2331 { modulus1, sizeof(modulus1), mod1_encoded, sizeof(modulus1) },
2332 { modulus2, sizeof(modulus2), mod2_encoded, 5 },
2333 { modulus3, sizeof(modulus3), mod3_encoded, 5 },
2334 { modulus4, sizeof(modulus4), mod4_encoded, 8 },
2337 static void test_encodeRsaPublicKey(DWORD dwEncoding)
2339 BYTE toEncode[sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + sizeof(modulus1)];
2340 BLOBHEADER *hdr = (BLOBHEADER *)toEncode;
2341 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(toEncode + sizeof(BLOBHEADER));
2344 DWORD bufSize = 0, i;
2346 /* Try with a bogus blob type */
2348 hdr->bVersion = CUR_BLOB_VERSION;
2350 hdr->aiKeyAlg = CALG_RSA_KEYX;
2351 rsaPubKey->magic = 0x31415352;
2352 rsaPubKey->bitlen = sizeof(modulus1) * 8;
2353 rsaPubKey->pubexp = 65537;
2354 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), modulus1,
2357 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2358 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2359 ok(!ret && GetLastError() == E_INVALIDARG,
2360 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2361 /* Now with a bogus reserved field */
2362 hdr->bType = PUBLICKEYBLOB;
2364 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2365 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2368 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2369 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2370 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2373 /* Now with a bogus blob version */
2376 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2377 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2380 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2381 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2382 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2385 /* And with a bogus alg ID */
2386 hdr->bVersion = CUR_BLOB_VERSION;
2387 hdr->aiKeyAlg = CALG_DES;
2388 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2389 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2392 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2393 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2394 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2397 /* Check a couple of RSA-related OIDs */
2398 hdr->aiKeyAlg = CALG_RSA_KEYX;
2399 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_RSA,
2400 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2401 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2402 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2403 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2404 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2405 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2406 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2407 /* Finally, all valid */
2408 hdr->aiKeyAlg = CALG_RSA_KEYX;
2409 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2411 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2412 rsaPubKeys[i].modulus, rsaPubKeys[i].modulusLen);
2413 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2414 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2415 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2418 ok(bufSize == rsaPubKeys[i].encoded[1] + 2,
2419 "Expected size %d, got %d\n", rsaPubKeys[i].encoded[1] + 2,
2421 ok(!memcmp(buf, rsaPubKeys[i].encoded, bufSize),
2422 "Unexpected value\n");
2428 static void test_decodeRsaPublicKey(DWORD dwEncoding)
2435 /* Try with a bad length */
2436 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2437 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1],
2438 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2439 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
2440 GetLastError() == OSS_MORE_INPUT /* Win9x/NT4 */),
2441 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n",
2443 /* Try with a couple of RSA-related OIDs */
2444 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_RSA,
2445 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2446 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2447 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2448 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2449 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2450 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2451 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2452 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2453 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2454 /* Now try success cases */
2455 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2458 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2459 rsaPubKeys[i].encoded, rsaPubKeys[i].encoded[1] + 2,
2460 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2461 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2464 BLOBHEADER *hdr = (BLOBHEADER *)buf;
2465 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER));
2467 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2468 rsaPubKeys[i].decodedModulusLen,
2469 "Wrong size %d\n", bufSize);
2470 ok(hdr->bType == PUBLICKEYBLOB,
2471 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB,
2473 ok(hdr->bVersion == CUR_BLOB_VERSION,
2474 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
2475 CUR_BLOB_VERSION, hdr->bVersion);
2476 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n",
2478 ok(hdr->aiKeyAlg == CALG_RSA_KEYX,
2479 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg);
2480 ok(rsaPubKey->magic == 0x31415352,
2481 "Expected magic RSA1, got %08x\n", rsaPubKey->magic);
2482 ok(rsaPubKey->bitlen == rsaPubKeys[i].decodedModulusLen * 8,
2483 "Wrong bit len %d\n", rsaPubKey->bitlen);
2484 ok(rsaPubKey->pubexp == 65537, "Expected pubexp 65537, got %d\n",
2486 ok(!memcmp(buf + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2487 rsaPubKeys[i].modulus, rsaPubKeys[i].decodedModulusLen),
2488 "Unexpected modulus\n");
2494 static const BYTE intSequence[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01,
2495 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02,
2496 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2498 static const BYTE mixedSequence[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
2499 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f,
2500 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02,
2501 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2503 static void test_encodeSequenceOfAny(DWORD dwEncoding)
2505 CRYPT_DER_BLOB blobs[sizeof(ints) / sizeof(ints[0])];
2506 CRYPT_SEQUENCE_OF_ANY seq;
2512 /* Encode a homogeneous sequence */
2513 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
2515 blobs[i].cbData = ints[i].encoded[1] + 2;
2516 blobs[i].pbData = (BYTE *)ints[i].encoded;
2518 seq.cValue = sizeof(ints) / sizeof(ints[0]);
2519 seq.rgValue = blobs;
2521 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2522 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2523 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2526 ok(bufSize == sizeof(intSequence), "Wrong size %d\n", bufSize);
2527 ok(!memcmp(buf, intSequence, intSequence[1] + 2), "Unexpected value\n");
2530 /* Change the type of the first element in the sequence, and give it
2533 blobs[0].cbData = times[0].encodedTime[1] + 2;
2534 blobs[0].pbData = (BYTE *)times[0].encodedTime;
2535 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2536 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2537 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2540 ok(bufSize == sizeof(mixedSequence), "Wrong size %d\n", bufSize);
2541 ok(!memcmp(buf, mixedSequence, mixedSequence[1] + 2),
2542 "Unexpected value\n");
2547 static void test_decodeSequenceOfAny(DWORD dwEncoding)
2553 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, intSequence,
2554 intSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2555 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2558 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2561 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2562 "Wrong elements %d\n", seq->cValue);
2563 for (i = 0; i < min(seq->cValue, sizeof(ints) / sizeof(ints[0])); i++)
2565 ok(seq->rgValue[i].cbData == ints[i].encoded[1] + 2,
2566 "Expected %d bytes, got %d\n", ints[i].encoded[1] + 2,
2567 seq->rgValue[i].cbData);
2568 ok(!memcmp(seq->rgValue[i].pbData, ints[i].encoded,
2569 ints[i].encoded[1] + 2), "Unexpected value\n");
2573 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, mixedSequence,
2574 mixedSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
2576 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2579 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2581 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2582 "Wrong elements %d\n", seq->cValue);
2583 /* Just check the first element since it's all that changed */
2584 ok(seq->rgValue[0].cbData == times[0].encodedTime[1] + 2,
2585 "Expected %d bytes, got %d\n", times[0].encodedTime[1] + 2,
2586 seq->rgValue[0].cbData);
2587 ok(!memcmp(seq->rgValue[0].pbData, times[0].encodedTime,
2588 times[0].encodedTime[1] + 2), "Unexpected value\n");
2593 struct encodedExtensions
2595 CERT_EXTENSIONS exts;
2596 const BYTE *encoded;
2599 static BYTE crit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2600 static BYTE noncrit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2601 static CHAR oid_basic_constraints2[] = szOID_BASIC_CONSTRAINTS2;
2602 static CERT_EXTENSION criticalExt =
2603 { oid_basic_constraints2, TRUE, { 8, crit_ext_data } };
2604 static CERT_EXTENSION nonCriticalExt =
2605 { oid_basic_constraints2, FALSE, { 8, noncrit_ext_data } };
2606 static CHAR oid_short[] = "1.1";
2607 static CERT_EXTENSION extWithShortOid =
2608 { oid_short, FALSE, { 0, NULL } };
2610 static const BYTE ext0[] = { 0x30,0x00 };
2611 static const BYTE ext1[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2612 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2613 static const BYTE ext2[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2614 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2615 static const BYTE ext3[] = { 0x30,0x07,0x30,0x05,0x06,0x01,0x29,0x04,0x00 };
2617 static const struct encodedExtensions exts[] = {
2618 { { 0, NULL }, ext0 },
2619 { { 1, &criticalExt }, ext1 },
2620 { { 1, &nonCriticalExt }, ext2 },
2621 { { 1, &extWithShortOid }, ext3 }
2624 static void test_encodeExtensions(DWORD dwEncoding)
2628 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2634 ret = pCryptEncodeObjectEx(dwEncoding, X509_EXTENSIONS, &exts[i].exts,
2635 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2636 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2639 ok(bufSize == exts[i].encoded[1] + 2,
2640 "Expected %d bytes, got %d\n", exts[i].encoded[1] + 2, bufSize);
2641 ok(!memcmp(buf, exts[i].encoded, exts[i].encoded[1] + 2),
2642 "Unexpected value\n");
2648 static void test_decodeExtensions(DWORD dwEncoding)
2652 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2658 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS,
2659 exts[i].encoded, exts[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2660 NULL, &buf, &bufSize);
2661 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2664 CERT_EXTENSIONS *ext = (CERT_EXTENSIONS *)buf;
2667 ok(ext->cExtension == exts[i].exts.cExtension,
2668 "Expected %d extensions, see %d\n", exts[i].exts.cExtension,
2670 for (j = 0; j < min(ext->cExtension, exts[i].exts.cExtension); j++)
2672 ok(!strcmp(ext->rgExtension[j].pszObjId,
2673 exts[i].exts.rgExtension[j].pszObjId),
2674 "Expected OID %s, got %s\n",
2675 exts[i].exts.rgExtension[j].pszObjId,
2676 ext->rgExtension[j].pszObjId);
2677 ok(!memcmp(ext->rgExtension[j].Value.pbData,
2678 exts[i].exts.rgExtension[j].Value.pbData,
2679 exts[i].exts.rgExtension[j].Value.cbData),
2680 "Unexpected value\n");
2687 /* MS encodes public key info with a NULL if the algorithm identifier's
2688 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2689 * it encodes them by omitting the algorithm parameters. It accepts either
2690 * form for decoding.
2692 struct encodedPublicKey
2694 CERT_PUBLIC_KEY_INFO info;
2695 const BYTE *encoded;
2696 const BYTE *encodedNoNull;
2697 CERT_PUBLIC_KEY_INFO decoded;
2700 static const BYTE aKey[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2702 static const BYTE params[] = { 0x02, 0x01, 0x01 };
2704 static const unsigned char bin64[] = {
2705 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2706 static const unsigned char bin65[] = {
2707 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2708 static const unsigned char bin66[] = {
2709 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2710 static const unsigned char bin67[] = {
2711 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2712 static const unsigned char bin68[] = {
2713 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01,
2714 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2715 static const unsigned char bin69[] = {
2716 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2717 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2718 static const unsigned char bin70[] = {
2719 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2720 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2722 static const unsigned char bin71[] = {
2723 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2724 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2726 static unsigned char bin72[] = { 0x05,0x00};
2728 static CHAR oid_bogus[] = "1.2.3",
2729 oid_rsa[] = szOID_RSA;
2731 static const struct encodedPublicKey pubKeys[] = {
2732 /* with a bogus OID */
2733 { { { oid_bogus, { 0, NULL } }, { 0, NULL, 0 } },
2735 { { oid_bogus, { 2, bin72 } }, { 0, NULL, 0 } } },
2736 /* some normal keys */
2737 { { { oid_rsa, { 0, NULL } }, { 0, NULL, 0} },
2739 { { oid_rsa, { 2, bin72 } }, { 0, NULL, 0 } } },
2740 { { { oid_rsa, { 0, NULL } }, { sizeof(aKey), (BYTE *)aKey, 0} },
2742 { { oid_rsa, { 2, bin72 } }, { sizeof(aKey), (BYTE *)aKey, 0} } },
2743 /* with add'l parameters--note they must be DER-encoded */
2744 { { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2745 (BYTE *)aKey, 0 } },
2747 { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2748 (BYTE *)aKey, 0 } } },
2751 static void test_encodePublicKeyInfo(DWORD dwEncoding)
2755 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2761 ret = pCryptEncodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2762 &pubKeys[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf,
2764 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2765 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2768 ok(bufSize == pubKeys[i].encoded[1] + 2,
2769 "Expected %d bytes, got %d\n", pubKeys[i].encoded[1] + 2, bufSize);
2770 if (bufSize == pubKeys[i].encoded[1] + 2)
2771 ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2),
2772 "Unexpected value\n");
2778 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO *expected,
2779 const CERT_PUBLIC_KEY_INFO *got)
2781 ok(!strcmp(expected->Algorithm.pszObjId, got->Algorithm.pszObjId),
2782 "Expected OID %s, got %s\n", expected->Algorithm.pszObjId,
2783 got->Algorithm.pszObjId);
2784 ok(expected->Algorithm.Parameters.cbData ==
2785 got->Algorithm.Parameters.cbData,
2786 "Expected parameters of %d bytes, got %d\n",
2787 expected->Algorithm.Parameters.cbData, got->Algorithm.Parameters.cbData);
2788 if (expected->Algorithm.Parameters.cbData)
2789 ok(!memcmp(expected->Algorithm.Parameters.pbData,
2790 got->Algorithm.Parameters.pbData, got->Algorithm.Parameters.cbData),
2791 "Unexpected algorithm parameters\n");
2792 ok(expected->PublicKey.cbData == got->PublicKey.cbData,
2793 "Expected public key of %d bytes, got %d\n",
2794 expected->PublicKey.cbData, got->PublicKey.cbData);
2795 if (expected->PublicKey.cbData)
2796 ok(!memcmp(expected->PublicKey.pbData, got->PublicKey.pbData,
2797 got->PublicKey.cbData), "Unexpected public key value\n");
2800 static void test_decodePublicKeyInfo(DWORD dwEncoding)
2802 static const BYTE bogusPubKeyInfo[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
2803 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
2804 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
2805 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2811 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2813 /* The NULL form decodes to the decoded member */
2814 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2815 pubKeys[i].encoded, pubKeys[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2816 NULL, &buf, &bufSize);
2817 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2820 comparePublicKeyInfo(&pubKeys[i].decoded,
2821 (CERT_PUBLIC_KEY_INFO *)buf);
2824 /* The non-NULL form decodes to the original */
2825 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2826 pubKeys[i].encodedNoNull, pubKeys[i].encodedNoNull[1] + 2,
2827 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2828 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2831 comparePublicKeyInfo(&pubKeys[i].info, (CERT_PUBLIC_KEY_INFO *)buf);
2835 /* Test with bogus (not valid DER) parameters */
2836 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2837 bogusPubKeyInfo, bogusPubKeyInfo[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2838 NULL, &buf, &bufSize);
2839 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2840 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2841 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2845 static const BYTE v1Cert[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
2846 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2847 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
2848 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
2849 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2850 static const BYTE v2Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02,
2851 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2852 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2853 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2854 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2855 static const BYTE v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2856 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2857 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2858 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2859 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2860 static const BYTE v4Cert[] = {
2861 0x30,0x38,0xa0,0x03,0x02,0x01,0x03,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,
2862 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
2863 0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
2864 0x30,0x30,0x30,0x5a,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00 };
2865 static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
2866 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2867 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2868 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2869 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2870 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2871 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2872 static const BYTE v1CertWithSerial[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
2873 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2874 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2875 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2876 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2877 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2878 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2879 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2880 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
2881 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
2882 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
2883 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
2884 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
2885 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
2886 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
2887 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
2888 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2889 static const BYTE v1CertWithPubKey[] = {
2890 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2891 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2892 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2893 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2894 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2895 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2896 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2897 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2898 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
2899 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
2901 static const BYTE v1CertWithPubKeyNoNull[] = {
2902 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2903 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2904 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2905 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2906 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2907 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2908 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2909 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2910 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
2911 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2912 static const BYTE v1CertWithSubjectKeyId[] = {
2913 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2914 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2915 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2916 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2917 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2918 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2919 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
2920 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2921 0x4c,0x61,0x6e,0x67,0x00 };
2922 static const BYTE v1CertWithIssuerUniqueId[] = {
2923 0x30,0x38,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
2924 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
2925 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
2926 0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x81,0x02,0x00,0x01 };
2927 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueId[] = {
2928 0x30,0x81,0x99,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2929 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2930 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2931 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2932 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2933 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2934 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2935 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2936 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,
2937 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
2938 0x01,0x01,0xff,0x02,0x01,0x01 };
2939 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull[] = {
2940 0x30,0x81,0x97,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2941 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2942 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2943 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2944 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2945 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2946 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2947 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2948 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
2949 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
2950 0xff,0x02,0x01,0x01 };
2952 static const BYTE serialNum[] = { 0x01 };
2954 static void test_encodeCertToBeSigned(DWORD dwEncoding)
2959 CERT_INFO info = { 0 };
2960 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2961 static char oid_subject_key_identifier[] = szOID_SUBJECT_KEY_IDENTIFIER;
2966 /* Test with NULL pvStructInfo (crashes on win9x) */
2967 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL,
2968 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
2969 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2970 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2972 /* Test with a V1 cert */
2973 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2974 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
2975 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2976 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2979 ok(size == v1Cert[1] + 2, "Expected size %d, got %d\n",
2980 v1Cert[1] + 2, size);
2981 ok(!memcmp(buf, v1Cert, size), "Got unexpected value\n");
2985 info.dwVersion = CERT_V2;
2986 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2987 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
2988 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2989 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2992 ok(size == sizeof(v2Cert), "Wrong size %d\n", size);
2993 ok(!memcmp(buf, v2Cert, size), "Got unexpected value\n");
2997 info.dwVersion = CERT_V3;
2998 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2999 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3000 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3001 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3004 ok(size == sizeof(v3Cert), "Wrong size %d\n", size);
3005 ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n");
3009 info.dwVersion = 3; /* Not a typo, CERT_V3 is 2 */
3010 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3011 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3014 ok(size == sizeof(v4Cert), "Wrong size %d\n", size);
3015 ok(!memcmp(buf, v4Cert, size), "Unexpected value\n");
3018 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
3019 * API doesn't prevent it)
3021 info.dwVersion = CERT_V1;
3022 info.cExtension = 1;
3023 info.rgExtension = &criticalExt;
3024 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3025 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3026 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3027 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3030 ok(size == sizeof(v1CertWithConstraints), "Wrong size %d\n", size);
3031 ok(!memcmp(buf, v1CertWithConstraints, size), "Got unexpected value\n");
3034 /* test v1 cert with a serial number */
3035 info.SerialNumber.cbData = sizeof(serialNum);
3036 info.SerialNumber.pbData = (BYTE *)serialNum;
3037 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3038 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3041 ok(size == sizeof(v1CertWithSerial), "Wrong size %d\n", size);
3042 ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n");
3045 /* Test v1 cert with an issuer name, serial number, and issuer unique id */
3046 info.dwVersion = CERT_V1;
3047 info.cExtension = 0;
3048 info.IssuerUniqueId.cbData = sizeof(serialNum);
3049 info.IssuerUniqueId.pbData = (BYTE *)serialNum;
3050 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3051 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3052 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3055 ok(size == sizeof(v1CertWithIssuerUniqueId), "Wrong size %d\n", size);
3056 ok(!memcmp(buf, v1CertWithIssuerUniqueId, size),
3057 "Got unexpected value\n");
3060 /* Test v1 cert with an issuer name, a subject name, and a serial number */
3061 info.IssuerUniqueId.cbData = 0;
3062 info.IssuerUniqueId.pbData = NULL;
3063 info.cExtension = 1;
3064 info.rgExtension = &criticalExt;
3065 info.Issuer.cbData = sizeof(encodedCommonName);
3066 info.Issuer.pbData = (BYTE *)encodedCommonName;
3067 info.Subject.cbData = sizeof(encodedCommonName);
3068 info.Subject.pbData = (BYTE *)encodedCommonName;
3069 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3070 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3073 ok(size == sizeof(bigCert), "Wrong size %d\n", size);
3074 ok(!memcmp(buf, bigCert, size), "Got unexpected value\n");
3077 /* Add a public key */
3078 info.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3079 info.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
3080 info.SubjectPublicKeyInfo.PublicKey.pbData = (LPBYTE)aKey;
3081 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3082 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3085 ok(size == sizeof(v1CertWithPubKey) ||
3086 size == sizeof(v1CertWithPubKeyNoNull), "Wrong size %d\n", size);
3087 if (size == sizeof(v1CertWithPubKey))
3088 ok(!memcmp(buf, v1CertWithPubKey, size), "Got unexpected value\n");
3089 else if (size == sizeof(v1CertWithPubKeyNoNull))
3090 ok(!memcmp(buf, v1CertWithPubKeyNoNull, size),
3091 "Got unexpected value\n");
3094 /* Again add an issuer unique id */
3095 info.IssuerUniqueId.cbData = sizeof(serialNum);
3096 info.IssuerUniqueId.pbData = (BYTE *)serialNum;
3097 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3098 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3099 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3102 ok(size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId) ||
3103 size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull),
3104 "Wrong size %d\n", size);
3105 if (size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId))
3106 ok(!memcmp(buf, v1CertWithSubjectIssuerSerialAndIssuerUniqueId,
3107 size), "unexpected value\n");
3109 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull))
3111 v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull, size),
3112 "unexpected value\n");
3115 /* Remove the public key, and add a subject key identifier extension */
3116 info.IssuerUniqueId.cbData = 0;
3117 info.IssuerUniqueId.pbData = NULL;
3118 info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
3119 info.SubjectPublicKeyInfo.PublicKey.cbData = 0;
3120 info.SubjectPublicKeyInfo.PublicKey.pbData = NULL;
3121 ext.pszObjId = oid_subject_key_identifier;
3122 ext.fCritical = FALSE;
3123 ext.Value.cbData = sizeof(octetCommonNameValue);
3124 ext.Value.pbData = octetCommonNameValue;
3125 info.cExtension = 1;
3126 info.rgExtension = &ext;
3127 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3128 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3131 ok(size == sizeof(v1CertWithSubjectKeyId), "Wrong size %d\n", size);
3132 ok(!memcmp(buf, v1CertWithSubjectKeyId, size), "Unexpected value\n");
3137 static void test_decodeCertToBeSigned(DWORD dwEncoding)
3139 static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert, v4Cert,
3140 v1CertWithConstraints, v1CertWithSerial, v1CertWithIssuerUniqueId };
3145 /* Test with NULL pbEncoded */
3146 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 0,
3147 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3148 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
3149 GetLastError() == OSS_BAD_ARG /* Win9x */),
3150 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
3153 /* Crashes on win9x */
3154 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 1,
3155 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3156 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3157 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3159 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT or
3160 * CRYPT_E_ASN1_BADTAG, because at a minimum a cert must have a non-zero
3161 * serial number, an issuer, a subject, and a public key.
3163 for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++)
3165 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3166 corruptCerts[i], corruptCerts[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3168 ok(!ret, "Expected failure\n");
3170 /* The following succeeds, even though v1 certs are not allowed to have
3173 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3174 v1CertWithSubjectKeyId, sizeof(v1CertWithSubjectKeyId),
3175 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3176 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3179 CERT_INFO *info = (CERT_INFO *)buf;
3181 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3182 ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %d\n",
3184 ok(info->cExtension == 1, "expected 1 extension, got %d\n",
3188 /* The following also succeeds, even though V1 certs are not allowed to
3189 * have issuer unique ids.
3191 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3192 v1CertWithSubjectIssuerSerialAndIssuerUniqueId,
3193 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId),
3194 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3195 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3198 CERT_INFO *info = (CERT_INFO *)buf;
3200 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3201 ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %d\n",
3203 ok(info->IssuerUniqueId.cbData == sizeof(serialNum),
3204 "unexpected issuer unique id size %d\n", info->IssuerUniqueId.cbData);
3205 ok(!memcmp(info->IssuerUniqueId.pbData, serialNum, sizeof(serialNum)),
3206 "unexpected issuer unique id value\n");
3209 /* Now check with serial number, subject and issuer specified */
3210 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert,
3211 sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3212 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3215 CERT_INFO *info = (CERT_INFO *)buf;
3217 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3218 ok(info->SerialNumber.cbData == 1,
3219 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3220 ok(*info->SerialNumber.pbData == *serialNum,
3221 "Expected serial number %d, got %d\n", *serialNum,
3222 *info->SerialNumber.pbData);
3223 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3224 "Wrong size %d\n", info->Issuer.cbData);
3225 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3226 "Unexpected issuer\n");
3227 ok(info->Subject.cbData == sizeof(encodedCommonName),
3228 "Wrong size %d\n", info->Subject.cbData);
3229 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3230 info->Subject.cbData), "Unexpected subject\n");
3233 /* Check again with pub key specified */
3234 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3235 v1CertWithPubKey, sizeof(v1CertWithPubKey), CRYPT_DECODE_ALLOC_FLAG, NULL,
3237 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3240 CERT_INFO *info = (CERT_INFO *)buf;
3242 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3243 ok(info->SerialNumber.cbData == 1,
3244 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3245 ok(*info->SerialNumber.pbData == *serialNum,
3246 "Expected serial number %d, got %d\n", *serialNum,
3247 *info->SerialNumber.pbData);
3248 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3249 "Wrong size %d\n", info->Issuer.cbData);
3250 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3251 "Unexpected issuer\n");
3252 ok(info->Subject.cbData == sizeof(encodedCommonName),
3253 "Wrong size %d\n", info->Subject.cbData);
3254 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3255 info->Subject.cbData), "Unexpected subject\n");
3256 ok(!strcmp(info->SubjectPublicKeyInfo.Algorithm.pszObjId,
3257 szOID_RSA_RSA), "Expected szOID_RSA_RSA, got %s\n",
3258 info->SubjectPublicKeyInfo.Algorithm.pszObjId);
3259 ok(info->SubjectPublicKeyInfo.PublicKey.cbData == sizeof(aKey),
3260 "Wrong size %d\n", info->SubjectPublicKeyInfo.PublicKey.cbData);
3261 ok(!memcmp(info->SubjectPublicKeyInfo.PublicKey.pbData, aKey,
3262 sizeof(aKey)), "Unexpected public key\n");
3267 static const BYTE hash[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
3270 static const BYTE signedBigCert[] = {
3271 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
3272 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
3273 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
3274 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3275 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
3276 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
3277 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
3278 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
3279 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
3280 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3281 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
3282 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
3284 static void test_encodeCert(DWORD dwEncoding)
3286 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
3287 * also that bigCert is a NULL-terminated string, so don't count its
3288 * last byte (otherwise the signed cert won't decode.)
3290 CERT_SIGNED_CONTENT_INFO info = { { sizeof(bigCert), (BYTE *)bigCert },
3291 { NULL, { 0, NULL } }, { sizeof(hash), (BYTE *)hash, 0 } };
3296 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT, &info,
3297 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
3298 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3301 ok(bufSize == sizeof(signedBigCert), "Wrong size %d\n", bufSize);
3302 ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n");
3307 static void test_decodeCert(DWORD dwEncoding)
3313 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert,
3314 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3315 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3318 CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf;
3320 ok(info->ToBeSigned.cbData == sizeof(bigCert),
3321 "Wrong cert size %d\n", info->ToBeSigned.cbData);
3322 ok(!memcmp(info->ToBeSigned.pbData, bigCert, info->ToBeSigned.cbData),
3323 "Unexpected cert\n");
3324 ok(info->Signature.cbData == sizeof(hash),
3325 "Wrong signature size %d\n", info->Signature.cbData);
3326 ok(!memcmp(info->Signature.pbData, hash, info->Signature.cbData),
3327 "Unexpected signature\n");
3330 /* A signed cert decodes as a CERT_INFO too */
3331 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCert,
3332 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3333 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3336 CERT_INFO *info = (CERT_INFO *)buf;
3338 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3339 ok(info->SerialNumber.cbData == 1,
3340 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3341 ok(*info->SerialNumber.pbData == *serialNum,
3342 "Expected serial number %d, got %d\n", *serialNum,
3343 *info->SerialNumber.pbData);
3344 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3345 "Wrong size %d\n", info->Issuer.cbData);
3346 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3347 "Unexpected issuer\n");
3348 ok(info->Subject.cbData == sizeof(encodedCommonName),
3349 "Wrong size %d\n", info->Subject.cbData);
3350 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3351 info->Subject.cbData), "Unexpected subject\n");
3356 static const BYTE emptyDistPoint[] = { 0x30, 0x02, 0x30, 0x00 };
3357 static const BYTE distPointWithUrl[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3358 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3359 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3360 static const BYTE distPointWithReason[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3362 static const BYTE distPointWithIssuer[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3363 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3364 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3365 static const BYTE distPointWithUrlAndIssuer[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3366 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3367 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3368 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3369 0x2e, 0x6f, 0x72, 0x67 };
3370 static const BYTE crlReason = CRL_REASON_KEY_COMPROMISE |
3371 CRL_REASON_AFFILIATION_CHANGED;
3373 static void test_encodeCRLDistPoints(DWORD dwEncoding)
3375 CRL_DIST_POINTS_INFO info = { 0 };
3376 CRL_DIST_POINT point = { { 0 } };
3377 CERT_ALT_NAME_ENTRY entry = { 0 };
3382 /* Test with an empty info */
3383 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3384 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3385 ok(!ret && GetLastError() == E_INVALIDARG,
3386 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3387 /* Test with one empty dist point */
3388 info.cDistPoint = 1;
3389 info.rgDistPoint = &point;
3390 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3391 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3392 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3395 ok(size == sizeof(emptyDistPoint), "Wrong size %d\n", size);
3396 ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n");
3399 /* A dist point with an invalid name */
3400 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3401 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3402 U(entry).pwszURL = (LPWSTR)nihongoURL;
3403 U(point.DistPointName).FullName.cAltEntry = 1;
3404 U(point.DistPointName).FullName.rgAltEntry = &entry;
3405 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3406 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3407 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
3408 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
3409 /* The first invalid character is at index 7 */
3410 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
3411 "Expected invalid char at index 7, got %d\n",
3412 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
3413 /* A dist point with (just) a valid name */
3414 U(entry).pwszURL = (LPWSTR)url;
3415 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3416 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3417 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3420 ok(size == sizeof(distPointWithUrl), "Wrong size %d\n", size);
3421 ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n");
3424 /* A dist point with (just) reason flags */
3425 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3426 point.ReasonFlags.cbData = sizeof(crlReason);
3427 point.ReasonFlags.pbData = (LPBYTE)&crlReason;
3428 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3429 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3430 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3433 ok(size == sizeof(distPointWithReason), "Wrong size %d\n", size);
3434 ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n");
3437 /* A dist point with just an issuer */
3438 point.ReasonFlags.cbData = 0;
3439 point.CRLIssuer.cAltEntry = 1;
3440 point.CRLIssuer.rgAltEntry = &entry;
3441 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3442 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3443 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3446 ok(size == sizeof(distPointWithIssuer), "Wrong size %d\n", size);
3447 ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n");
3450 /* A dist point with both a name and an issuer */
3451 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3452 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3453 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3454 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3457 ok(size == sizeof(distPointWithUrlAndIssuer),
3458 "Wrong size %d\n", size);
3459 ok(!memcmp(buf, distPointWithUrlAndIssuer, size), "Unexpected value\n");
3464 static void test_decodeCRLDistPoints(DWORD dwEncoding)
3469 PCRL_DIST_POINTS_INFO info;
3470 PCRL_DIST_POINT point;
3471 PCERT_ALT_NAME_ENTRY entry;
3473 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3474 emptyDistPoint, emptyDistPoint[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3476 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3479 info = (PCRL_DIST_POINTS_INFO)buf;
3480 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3481 "Wrong size %d\n", size);
3482 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3484 point = info->rgDistPoint;
3485 ok(point->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_NO_NAME,
3486 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3487 point->DistPointName.dwDistPointNameChoice);
3488 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3489 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3492 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3493 distPointWithUrl, distPointWithUrl[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3495 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3498 info = (PCRL_DIST_POINTS_INFO)buf;
3499 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3500 "Wrong size %d\n", size);
3501 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3503 point = info->rgDistPoint;
3504 ok(point->DistPointName.dwDistPointNameChoice ==
3505 CRL_DIST_POINT_FULL_NAME,
3506 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3507 point->DistPointName.dwDistPointNameChoice);
3508 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3509 "Expected 1 name entry, got %d\n",
3510 U(point->DistPointName).FullName.cAltEntry);
3511 entry = U(point->DistPointName).FullName.rgAltEntry;
3512 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3513 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3514 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3515 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3516 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3519 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3520 distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
3522 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3525 info = (PCRL_DIST_POINTS_INFO)buf;
3526 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3527 "Wrong size %d\n", size);
3528 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3530 point = info->rgDistPoint;
3531 ok(point->DistPointName.dwDistPointNameChoice ==
3532 CRL_DIST_POINT_NO_NAME,
3533 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3534 point->DistPointName.dwDistPointNameChoice);
3535 ok(point->ReasonFlags.cbData == sizeof(crlReason),
3536 "Expected reason length\n");
3537 ok(!memcmp(point->ReasonFlags.pbData, &crlReason, sizeof(crlReason)),
3538 "Unexpected reason\n");
3539 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3542 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3543 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2,
3544 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3545 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3548 info = (PCRL_DIST_POINTS_INFO)buf;
3549 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3550 "Wrong size %d\n", size);
3551 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3553 point = info->rgDistPoint;
3554 ok(point->DistPointName.dwDistPointNameChoice ==
3555 CRL_DIST_POINT_FULL_NAME,
3556 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3557 point->DistPointName.dwDistPointNameChoice);
3558 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3559 "Expected 1 name entry, got %d\n",
3560 U(point->DistPointName).FullName.cAltEntry);
3561 entry = U(point->DistPointName).FullName.rgAltEntry;
3562 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3563 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3564 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3565 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3566 ok(point->CRLIssuer.cAltEntry == 1,
3567 "Expected 1 issuer entry, got %d\n", point->CRLIssuer.cAltEntry);
3568 entry = point->CRLIssuer.rgAltEntry;
3569 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3570 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3571 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3576 static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3577 static const BYTE emptyNameIDP[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3578 static const BYTE urlIDP[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3579 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3582 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding)
3587 CRL_ISSUING_DIST_POINT point = { { 0 } };
3588 CERT_ALT_NAME_ENTRY entry;
3590 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, NULL,
3591 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3592 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3594 skip("no X509_ISSUING_DIST_POINT encode support\n");
3597 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3598 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3599 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3600 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3601 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3604 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
3605 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
3608 /* nonsensical flags */
3609 point.fOnlyContainsUserCerts = TRUE;
3610 point.fOnlyContainsCACerts = TRUE;
3611 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3612 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3613 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3616 ok(size == sizeof(badFlagsIDP), "Unexpected size %d\n", size);
3617 ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n");
3620 /* unimplemented name type */
3621 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3622 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_ISSUER_RDN_NAME;
3623 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3624 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3625 ok(!ret && GetLastError() == E_INVALIDARG,
3626 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3628 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3629 U(point.DistPointName).FullName.cAltEntry = 0;
3630 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3631 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3632 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3635 ok(size == sizeof(emptyNameIDP), "Unexpected size %d\n", size);
3636 ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n");
3639 /* name with URL entry */
3640 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3641 U(entry).pwszURL = (LPWSTR)url;
3642 U(point.DistPointName).FullName.cAltEntry = 1;
3643 U(point.DistPointName).FullName.rgAltEntry = &entry;
3644 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3645 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3646 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3649 ok(size == sizeof(urlIDP), "Unexpected size %d\n", size);
3650 ok(!memcmp(buf, urlIDP, size), "Unexpected value\n");
3655 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY *expected,
3656 const CERT_ALT_NAME_ENTRY *got)
3658 ok(expected->dwAltNameChoice == got->dwAltNameChoice,
3659 "Expected name choice %d, got %d\n", expected->dwAltNameChoice,
3660 got->dwAltNameChoice);
3661 if (expected->dwAltNameChoice == got->dwAltNameChoice)
3663 switch (got->dwAltNameChoice)
3665 case CERT_ALT_NAME_RFC822_NAME:
3666 case CERT_ALT_NAME_DNS_NAME:
3667 case CERT_ALT_NAME_EDI_PARTY_NAME:
3668 case CERT_ALT_NAME_URL:
3669 case CERT_ALT_NAME_REGISTERED_ID:
3670 ok((!U(*expected).pwszURL && !U(*got).pwszURL) ||
3671 (!U(*expected).pwszURL && !lstrlenW(U(*got).pwszURL)) ||
3672 (!U(*got).pwszURL && !lstrlenW(U(*expected).pwszURL)) ||
3673 !lstrcmpW(U(*expected).pwszURL, U(*got).pwszURL),
3674 "Unexpected name\n");
3676 case CERT_ALT_NAME_X400_ADDRESS:
3677 case CERT_ALT_NAME_DIRECTORY_NAME:
3678 case CERT_ALT_NAME_IP_ADDRESS:
3679 ok(U(*got).IPAddress.cbData == U(*expected).IPAddress.cbData,
3680 "Unexpected IP address length %d\n", U(*got).IPAddress.cbData);
3681 ok(!memcmp(U(*got).IPAddress.pbData, U(*got).IPAddress.pbData,
3682 U(*got).IPAddress.cbData), "Unexpected value\n");
3688 static void compareAltNameInfo(const CERT_ALT_NAME_INFO *expected,
3689 const CERT_ALT_NAME_INFO *got)
3693 ok(expected->cAltEntry == got->cAltEntry, "Expected %d entries, got %d\n",
3694 expected->cAltEntry, got->cAltEntry);
3695 for (i = 0; i < min(expected->cAltEntry, got->cAltEntry); i++)
3696 compareAltNameEntry(&expected->rgAltEntry[i], &got->rgAltEntry[i]);
3699 static void compareDistPointName(const CRL_DIST_POINT_NAME *expected,
3700 const CRL_DIST_POINT_NAME *got)
3702 ok(got->dwDistPointNameChoice == expected->dwDistPointNameChoice,
3703 "Unexpected name choice %d\n", got->dwDistPointNameChoice);
3704 if (got->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME)
3705 compareAltNameInfo(&(U(*expected).FullName), &(U(*got).FullName));
3708 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT *expected,
3709 const CRL_ISSUING_DIST_POINT *got)
3711 compareDistPointName(&expected->DistPointName, &got->DistPointName);
3712 ok(got->fOnlyContainsUserCerts == expected->fOnlyContainsUserCerts,
3713 "Unexpected fOnlyContainsUserCerts\n");
3714 ok(got->fOnlyContainsCACerts == expected->fOnlyContainsCACerts,
3715 "Unexpected fOnlyContainsCACerts\n");
3716 ok(got->OnlySomeReasonFlags.cbData == expected->OnlySomeReasonFlags.cbData,
3717 "Unexpected reason flags\n");
3718 ok(got->fIndirectCRL == expected->fIndirectCRL,
3719 "Unexpected fIndirectCRL\n");
3722 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding)
3727 CRL_ISSUING_DIST_POINT point = { { 0 } };
3729 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3730 emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3732 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3734 skip("no X509_ISSUING_DIST_POINT decode support\n");
3737 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3740 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3743 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3744 badFlagsIDP, badFlagsIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3746 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3749 point.fOnlyContainsUserCerts = point.fOnlyContainsCACerts = TRUE;
3750 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3753 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3754 emptyNameIDP, emptyNameIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3756 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3759 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3760 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3761 U(point.DistPointName).FullName.cAltEntry = 0;
3762 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3765 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3766 urlIDP, urlIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3767 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3770 CERT_ALT_NAME_ENTRY entry;
3772 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3773 U(entry).pwszURL = (LPWSTR)url;
3774 U(point.DistPointName).FullName.cAltEntry = 1;
3775 U(point.DistPointName).FullName.rgAltEntry = &entry;
3776 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3781 static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3782 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3784 static const BYTE v2CRL[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3785 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3786 0x30, 0x30, 0x30, 0x30, 0x5a };
3787 static const BYTE v1CRLWithIssuer[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3788 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3789 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3790 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3792 static const BYTE v1CRLWithIssuerAndEmptyEntry[] = { 0x30, 0x43, 0x30, 0x02,
3793 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3794 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3795 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3796 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3797 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3798 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3799 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3800 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3801 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3802 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3803 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3804 static const BYTE v1CRLWithEntryExt[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3805 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3806 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3807 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3808 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3809 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3810 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3811 static const BYTE v1CRLWithExt[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3812 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3813 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3814 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
3815 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3816 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
3817 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3818 static const BYTE v2CRLWithExt[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
3819 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
3820 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
3821 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
3822 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
3823 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
3824 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3825 static const BYTE v2CRLWithIssuingDistPoint[] = { 0x30,0x5c,0x02,0x01,0x01,
3826 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
3827 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
3828 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
3829 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3830 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
3831 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3833 static void test_encodeCRLToBeSigned(DWORD dwEncoding)
3837 static CHAR oid_issuing_dist_point[] = szOID_ISSUING_DIST_POINT;
3839 CRL_INFO info = { 0 };
3840 CRL_ENTRY entry = { { 0 }, { 0 }, 0, 0 };
3843 /* Test with a V1 CRL */
3844 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3845 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3846 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3847 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3850 ok(size == sizeof(v1CRL), "Wrong size %d\n", size);
3851 ok(!memcmp(buf, v1CRL, size), "Got unexpected value\n");
3855 info.dwVersion = CRL_V2;
3856 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3857 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3858 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3859 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3862 ok(size == v2CRL[1] + 2, "Expected size %d, got %d\n",
3863 v2CRL[1] + 2, size);
3864 ok(!memcmp(buf, v2CRL, size), "Got unexpected value\n");
3867 /* v1 CRL with a name */
3868 info.dwVersion = CRL_V1;
3869 info.Issuer.cbData = sizeof(encodedCommonName);
3870 info.Issuer.pbData = (BYTE *)encodedCommonName;
3871 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3872 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3873 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3876 ok(size == sizeof(v1CRLWithIssuer), "Wrong size %d\n", size);
3877 ok(!memcmp(buf, v1CRLWithIssuer, size), "Got unexpected value\n");
3882 /* v1 CRL with a name and a NULL entry pointer (crashes on win9x) */
3884 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3885 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3886 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3887 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3889 /* now set an empty entry */
3891 info.rgCRLEntry = &entry;
3892 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3893 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3896 ok(size == sizeof(v1CRLWithIssuerAndEmptyEntry),
3897 "Wrong size %d\n", size);
3898 ok(!memcmp(buf, v1CRLWithIssuerAndEmptyEntry, size),
3899 "Got unexpected value\n");
3902 /* an entry with a serial number */
3903 entry.SerialNumber.cbData = sizeof(serialNum);
3904 entry.SerialNumber.pbData = (BYTE *)serialNum;
3905 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3906 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3909 ok(size == sizeof(v1CRLWithIssuerAndEntry),
3910 "Wrong size %d\n", size);
3911 ok(!memcmp(buf, v1CRLWithIssuerAndEntry, size),
3912 "Got unexpected value\n");
3915 /* an entry with an extension */
3916 entry.cExtension = 1;
3917 entry.rgExtension = &criticalExt;
3918 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3919 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3920 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3923 ok(size == sizeof(v1CRLWithEntryExt), "Wrong size %d\n", size);
3924 ok(!memcmp(buf, v1CRLWithEntryExt, size), "Got unexpected value\n");
3927 /* a CRL with an extension */
3928 entry.cExtension = 0;
3929 info.cExtension = 1;
3930 info.rgExtension = &criticalExt;
3931 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3932 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3933 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3936 ok(size == sizeof(v1CRLWithExt), "Wrong size %d\n", size);
3937 ok(!memcmp(buf, v1CRLWithExt, size), "Got unexpected value\n");
3940 /* a v2 CRL with an extension, this time non-critical */
3941 info.dwVersion = CRL_V2;
3942 info.rgExtension = &nonCriticalExt;
3943 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3944 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3945 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3948 ok(size == sizeof(v2CRLWithExt), "Wrong size %d\n", size);
3949 ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n");
3952 /* a v2 CRL with an issuing dist point extension */
3953 ext.pszObjId = oid_issuing_dist_point;
3954 ext.fCritical = TRUE;
3955 ext.Value.cbData = sizeof(urlIDP);
3956 ext.Value.pbData = (LPBYTE)urlIDP;
3957 entry.rgExtension = &ext;
3958 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3959 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3960 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3963 ok(size == sizeof(v2CRLWithIssuingDistPoint), "Wrong size %d\n", size);
3964 ok(!memcmp(buf, v2CRLWithIssuingDistPoint, size), "Unexpected value\n");
3969 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
3970 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
3971 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
3972 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
3973 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
3974 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
3975 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
3976 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
3977 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
3978 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
3979 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
3980 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
3981 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
3982 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
3983 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
3984 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
3985 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
3986 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
3987 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
3988 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
3989 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
3990 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
3991 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
3992 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
3993 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
3994 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
3995 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
3996 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
3997 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
3998 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
3999 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
4000 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
4001 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
4002 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
4004 static const BYTE verisignCRLWithLotsOfEntries[] = {
4005 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
4006 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
4007 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
4008 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
4009 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
4010 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
4011 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
4012 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
4013 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
4014 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
4015 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
4016 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
4017 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
4018 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
4019 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
4020 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
4021 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
4022 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
4023 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
4024 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
4025 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
4026 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
4027 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
4028 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
4029 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
4030 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
4031 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
4032 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
4033 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
4034 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
4035 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
4036 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
4037 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
4038 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
4039 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
4040 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
4041 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
4042 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
4043 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
4044 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
4045 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
4046 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
4047 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
4048 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
4049 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
4050 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
4051 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
4052 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
4053 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
4054 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
4055 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
4056 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
4057 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
4058 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
4059 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
4060 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
4061 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
4062 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
4063 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
4064 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
4065 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
4066 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
4067 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
4068 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
4069 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
4070 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
4071 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
4072 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
4073 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
4074 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
4075 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
4076 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
4077 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
4078 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
4079 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
4080 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
4081 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
4082 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
4083 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
4084 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
4085 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
4086 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
4087 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
4088 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
4089 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
4090 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
4091 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
4092 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
4093 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
4094 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
4095 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
4096 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
4097 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
4098 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
4099 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
4100 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
4101 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
4102 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
4103 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
4104 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
4105 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
4106 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
4107 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
4108 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
4109 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
4110 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
4111 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
4112 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
4113 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
4114 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
4115 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
4116 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
4117 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
4118 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
4119 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
4120 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
4121 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
4122 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
4123 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
4124 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
4125 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
4126 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
4127 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
4128 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
4129 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
4130 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
4131 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
4132 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
4133 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
4134 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
4135 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
4136 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
4137 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
4138 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
4139 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
4140 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
4141 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
4142 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
4143 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
4144 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
4145 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
4146 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
4147 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
4148 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
4149 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
4150 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
4151 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
4152 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
4153 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
4154 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
4155 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
4156 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
4157 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
4158 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
4159 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
4160 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
4161 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
4162 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
4163 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
4164 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
4165 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
4166 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
4167 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
4168 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
4169 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
4170 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
4171 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
4172 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
4173 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
4174 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
4175 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
4176 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
4177 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
4178 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
4179 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
4180 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
4181 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
4182 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
4183 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
4184 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
4185 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
4186 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
4187 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
4188 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
4189 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
4190 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
4191 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
4192 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
4193 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
4194 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
4195 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
4196 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
4197 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
4198 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
4199 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
4200 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
4201 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
4202 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
4203 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
4204 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
4205 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
4206 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
4207 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
4208 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
4209 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
4210 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
4211 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
4212 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
4213 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
4214 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
4215 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
4216 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
4217 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
4218 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
4219 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
4220 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
4221 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
4222 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
4223 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
4224 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
4225 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
4226 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
4227 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
4228 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
4229 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
4230 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
4231 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
4232 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
4233 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
4234 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
4235 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
4236 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
4237 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
4238 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
4239 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
4240 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
4241 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
4242 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
4243 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
4244 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
4245 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
4246 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
4247 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
4248 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
4249 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
4250 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
4251 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
4252 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
4253 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
4254 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
4255 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
4256 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
4257 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
4258 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
4259 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
4260 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
4261 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
4262 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
4263 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
4264 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
4265 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
4266 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
4267 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
4268 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
4269 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
4270 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
4271 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
4272 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
4273 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
4274 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
4275 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
4276 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
4277 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
4278 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
4279 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
4280 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
4281 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
4282 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
4283 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
4284 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
4285 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
4286 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
4287 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
4288 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
4289 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
4290 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
4291 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
4292 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
4293 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
4294 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
4295 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
4296 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
4297 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
4298 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
4299 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
4300 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
4301 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
4302 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
4303 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
4304 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
4305 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
4306 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
4307 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
4308 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4309 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4310 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4311 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4312 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4313 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4314 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4315 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4316 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4317 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4318 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4319 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4320 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4321 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4322 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4323 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4324 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4325 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4326 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4327 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4328 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4329 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4330 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4331 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4332 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4333 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4334 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4335 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4336 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4337 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4338 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4339 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4340 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4341 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4342 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4343 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4344 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4345 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4346 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4347 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4348 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4349 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4350 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4351 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4352 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4353 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4354 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4355 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4356 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4357 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4358 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4359 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4360 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4361 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4362 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4363 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4364 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4365 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4366 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4367 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4368 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4369 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4370 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4371 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4372 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4373 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4374 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4375 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4376 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4377 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4378 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4379 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4380 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4381 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4382 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4383 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4384 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4385 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4386 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4387 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4388 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4389 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4390 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4391 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4392 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4393 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4394 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4395 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4396 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4397 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4398 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4399 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4400 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4401 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4402 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4403 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4404 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4405 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4406 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4407 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4408 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4409 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4410 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4411 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4412 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4413 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4414 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4415 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4416 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4417 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4418 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4419 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4420 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4421 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4422 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4423 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4424 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4425 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4426 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4427 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4428 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4429 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4430 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4431 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4432 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4433 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4434 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4435 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4436 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4437 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4438 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4439 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4440 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4441 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4442 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4443 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4444 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4445 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4446 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4447 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4448 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4449 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4450 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4451 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4452 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4453 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4454 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4455 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4456 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4457 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4458 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4459 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4460 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4461 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4462 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4463 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4464 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4465 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4466 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4467 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4468 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4469 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4470 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4471 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4472 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4473 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4474 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4475 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4476 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4477 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4478 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4479 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4480 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4481 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4482 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4483 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4484 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4485 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4486 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4487 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4488 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4489 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4490 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4491 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4492 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4493 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4494 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4495 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4496 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4497 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4498 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4499 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4500 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4501 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4502 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4503 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4504 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4505 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4506 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4507 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4508 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4509 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4510 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4511 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4512 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4514 static void test_decodeCRLToBeSigned(DWORD dwEncoding)
4516 static const BYTE *corruptCRLs[] = { v1CRL, v2CRL };
4521 for (i = 0; i < sizeof(corruptCRLs) / sizeof(corruptCRLs[0]); i++)
4523 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4524 corruptCRLs[i], corruptCRLs[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4526 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4527 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4528 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4531 /* at a minimum, a CRL must contain an issuer: */
4532 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4533 v1CRLWithIssuer, v1CRLWithIssuer[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4535 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4538 CRL_INFO *info = (CRL_INFO *)buf;
4540 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4541 ok(info->cCRLEntry == 0, "Expected 0 CRL entries, got %d\n",
4543 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4544 "Wrong issuer size %d\n", info->Issuer.cbData);
4545 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4546 "Unexpected issuer\n");
4549 /* check decoding with an empty CRL entry */
4550 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4551 v1CRLWithIssuerAndEmptyEntry, v1CRLWithIssuerAndEmptyEntry[1] + 2,
4552 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4553 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4554 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4555 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4557 /* with a real CRL entry */
4558 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4559 v1CRLWithIssuerAndEntry, v1CRLWithIssuerAndEntry[1] + 2,
4560 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4561 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4564 CRL_INFO *info = (CRL_INFO *)buf;
4567 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4568 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4570 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4571 entry = info->rgCRLEntry;
4572 ok(entry->SerialNumber.cbData == 1,
4573 "Expected serial number size 1, got %d\n",
4574 entry->SerialNumber.cbData);
4575 ok(*entry->SerialNumber.pbData == *serialNum,
4576 "Expected serial number %d, got %d\n", *serialNum,
4577 *entry->SerialNumber.pbData);
4578 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4579 "Wrong issuer size %d\n", info->Issuer.cbData);
4580 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4581 "Unexpected issuer\n");
4584 /* a real CRL from verisign that has extensions */
4585 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4586 verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG,
4588 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4591 CRL_INFO *info = (CRL_INFO *)buf;
4594 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4595 ok(info->cCRLEntry == 3, "Expected 3 CRL entries, got %d\n",
4597 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4598 entry = info->rgCRLEntry;
4599 ok(info->cExtension == 2, "Expected 2 extensions, got %d\n",
4603 /* another real CRL from verisign that has lots of entries */
4604 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4605 verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries),
4606 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4607 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4610 CRL_INFO *info = (CRL_INFO *)buf;
4612 ok(size >= sizeof(CRL_INFO), "Got size %d\n", size);
4613 ok(info->cCRLEntry == 209, "Expected 209 CRL entries, got %d\n",
4615 ok(info->cExtension == 0, "Expected 0 extensions, got %d\n",
4619 /* and finally, with an extension */
4620 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4621 v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4623 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4626 CRL_INFO *info = (CRL_INFO *)buf;
4629 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4630 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4632 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4633 entry = info->rgCRLEntry;
4634 ok(entry->SerialNumber.cbData == 1,
4635 "Expected serial number size 1, got %d\n",
4636 entry->SerialNumber.cbData);
4637 ok(*entry->SerialNumber.pbData == *serialNum,
4638 "Expected serial number %d, got %d\n", *serialNum,
4639 *entry->SerialNumber.pbData);
4640 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4641 "Wrong issuer size %d\n", info->Issuer.cbData);
4642 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4643 "Unexpected issuer\n");
4644 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4648 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4649 v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4651 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4654 CRL_INFO *info = (CRL_INFO *)buf;
4656 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4660 /* And again, with an issuing dist point */
4661 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4662 v2CRLWithIssuingDistPoint, sizeof(v2CRLWithIssuingDistPoint),
4663 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4664 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4667 CRL_INFO *info = (CRL_INFO *)buf;
4669 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4675 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
4676 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
4677 static const BYTE encodedUsage[] = {
4678 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4679 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4680 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4682 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding)
4687 CERT_ENHKEY_USAGE usage;
4689 /* Test with empty usage */
4690 usage.cUsageIdentifier = 0;
4691 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4692 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4693 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4696 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
4697 ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n");
4700 /* Test with a few usages */
4701 usage.cUsageIdentifier = sizeof(keyUsages) / sizeof(keyUsages[0]);
4702 usage.rgpszUsageIdentifier = (LPSTR *)keyUsages;
4703 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4704 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4705 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4708 ok(size == sizeof(encodedUsage), "Wrong size %d\n", size);
4709 ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n");
4714 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding)
4720 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4721 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4723 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4726 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4728 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4729 "Wrong size %d\n", size);
4730 ok(usage->cUsageIdentifier == 0, "Expected 0 CRL entries, got %d\n",
4731 usage->cUsageIdentifier);
4734 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4735 encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL,
4737 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4740 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4743 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4744 "Wrong size %d\n", size);
4745 ok(usage->cUsageIdentifier == sizeof(keyUsages) / sizeof(keyUsages[0]),
4746 "Wrong CRL entries count %d\n", usage->cUsageIdentifier);
4747 for (i = 0; i < usage->cUsageIdentifier; i++)
4748 ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]),
4749 "Expected OID %s, got %s\n", keyUsages[i],
4750 usage->rgpszUsageIdentifier[i]);
4755 static BYTE keyId[] = { 1,2,3,4 };
4756 static const BYTE authorityKeyIdWithId[] = {
4757 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4758 static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4759 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4760 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4761 static const BYTE authorityKeyIdWithSerial[] = { 0x30,0x03,0x82,0x01,0x01 };
4763 static void test_encodeAuthorityKeyId(DWORD dwEncoding)
4765 CERT_AUTHORITY_KEY_ID_INFO info = { { 0 } };
4770 /* Test with empty id */
4771 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4772 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4773 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4776 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4777 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4780 /* With just a key id */
4781 info.KeyId.cbData = sizeof(keyId);
4782 info.KeyId.pbData = keyId;
4783 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4784 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4785 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4788 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", size);
4789 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4792 /* With just an issuer */
4793 info.KeyId.cbData = 0;
4794 info.CertIssuer.cbData = sizeof(encodedCommonName);
4795 info.CertIssuer.pbData = (BYTE *)encodedCommonName;
4796 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4797 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4798 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4801 ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %d\n",
4803 ok(!memcmp(buf, authorityKeyIdWithIssuer, size), "Unexpected value\n");
4806 /* With just a serial number */
4807 info.CertIssuer.cbData = 0;
4808 info.CertSerialNumber.cbData = sizeof(serialNum);
4809 info.CertSerialNumber.pbData = (BYTE *)serialNum;
4810 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4811 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4812 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4815 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4817 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4822 static void test_decodeAuthorityKeyId(DWORD dwEncoding)
4828 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4829 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4831 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4834 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4836 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4838 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4839 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4840 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4843 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4844 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4845 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4846 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4849 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4851 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4853 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4854 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4855 "Unexpected key id\n");
4856 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4857 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4860 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4861 authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer),
4862 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4863 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4866 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4868 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4870 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4871 ok(info->CertIssuer.cbData == sizeof(encodedCommonName),
4872 "Unexpected issuer len\n");
4873 ok(!memcmp(info->CertIssuer.pbData, encodedCommonName,
4874 sizeof(encodedCommonName)), "Unexpected issuer\n");
4875 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4878 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4879 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4880 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4881 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4884 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4886 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4888 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4889 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4890 ok(info->CertSerialNumber.cbData == sizeof(serialNum),
4891 "Unexpected serial number len\n");
4892 ok(!memcmp(info->CertSerialNumber.pbData, serialNum, sizeof(serialNum)),
4893 "Unexpected serial number\n");
4898 static const BYTE authorityKeyIdWithIssuerUrl[] = { 0x30,0x15,0xa1,0x13,0x86,
4899 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
4902 static void test_encodeAuthorityKeyId2(DWORD dwEncoding)
4904 CERT_AUTHORITY_KEY_ID2_INFO info = { { 0 } };
4905 CERT_ALT_NAME_ENTRY entry = { 0 };
4910 /* Test with empty id */
4911 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4912 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4913 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4916 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4917 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4920 /* With just a key id */
4921 info.KeyId.cbData = sizeof(keyId);
4922 info.KeyId.pbData = keyId;
4923 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4924 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4925 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4928 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n",
4930 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4933 /* With a bogus issuer name */
4934 info.KeyId.cbData = 0;
4935 info.AuthorityCertIssuer.cAltEntry = 1;
4936 info.AuthorityCertIssuer.rgAltEntry = &entry;
4937 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4938 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4939 ok(!ret && GetLastError() == E_INVALIDARG,
4940 "Expected E_INVALIDARG, got %08x\n", GetLastError());
4941 /* With an issuer name */
4942 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
4943 U(entry).pwszURL = (LPWSTR)url;
4944 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4945 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4946 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4949 ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %d\n",
4951 ok(!memcmp(buf, authorityKeyIdWithIssuerUrl, size),
4952 "Unexpected value\n");
4955 /* With just a serial number */
4956 info.AuthorityCertIssuer.cAltEntry = 0;
4957 info.AuthorityCertSerialNumber.cbData = sizeof(serialNum);
4958 info.AuthorityCertSerialNumber.pbData = (BYTE *)serialNum;
4959 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4960 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4961 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4964 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4966 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4971 static void test_decodeAuthorityKeyId2(DWORD dwEncoding)
4977 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4978 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4980 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4983 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4985 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4987 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4988 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4989 "Expected no issuer name entries\n");
4990 ok(info->AuthorityCertSerialNumber.cbData == 0,
4991 "Expected no serial number\n");
4994 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4995 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4996 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4997 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5000 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
5002 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
5004 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
5005 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
5006 "Unexpected key id\n");
5007 ok(info->AuthorityCertIssuer.cAltEntry == 0,
5008 "Expected no issuer name entries\n");
5009 ok(info->AuthorityCertSerialNumber.cbData == 0,
5010 "Expected no serial number\n");
5013 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
5014 authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl),
5015 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5016 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5019 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
5021 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
5023 ok(info->KeyId.cbData == 0, "Expected no key id\n");
5024 ok(info->AuthorityCertIssuer.cAltEntry == 1,
5025 "Expected 1 issuer entry, got %d\n",
5026 info->AuthorityCertIssuer.cAltEntry);
5027 ok(info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice ==
5028 CERT_ALT_NAME_URL, "Expected CERT_ALT_NAME_URL, got %d\n",
5029 info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice);
5030 ok(!lstrcmpW(U(info->AuthorityCertIssuer.rgAltEntry[0]).pwszURL,
5031 url), "Unexpected URL\n");
5032 ok(info->AuthorityCertSerialNumber.cbData == 0,
5033 "Expected no serial number\n");
5036 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
5037 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
5038 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5039 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5042 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
5044 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
5046 ok(info->KeyId.cbData == 0, "Expected no key id\n");
5047 ok(info->AuthorityCertIssuer.cAltEntry == 0,
5048 "Expected no issuer name entries\n");
5049 ok(info->AuthorityCertSerialNumber.cbData == sizeof(serialNum),
5050 "Unexpected serial number len\n");
5051 ok(!memcmp(info->AuthorityCertSerialNumber.pbData, serialNum,
5052 sizeof(serialNum)), "Unexpected serial number\n");
5057 static const BYTE authorityInfoAccessWithUrl[] = {
5058 0x30,0x19,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
5059 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5060 static const BYTE authorityInfoAccessWithUrlAndIPAddr[] = {
5061 0x30,0x29,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
5062 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x0e,0x06,
5063 0x02,0x2d,0x06,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5065 static void test_encodeAuthorityInfoAccess(DWORD dwEncoding)
5067 static char oid1[] = "1.2.3";
5068 static char oid2[] = "1.5.6";
5072 CERT_ACCESS_DESCRIPTION accessDescription[2];
5073 CERT_AUTHORITY_INFO_ACCESS aia;
5075 memset(accessDescription, 0, sizeof(accessDescription));
5077 aia.rgAccDescr = NULL;
5078 /* Having no access descriptions is allowed */
5079 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5080 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5081 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5084 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
5085 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
5089 /* It can't have an empty access method */
5091 aia.rgAccDescr = accessDescription;
5092 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5093 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5094 ok(!ret && (GetLastError() == E_INVALIDARG ||
5095 GetLastError() == OSS_LIMITED /* Win9x */),
5096 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
5097 /* It can't have an empty location */
5098 accessDescription[0].pszAccessMethod = oid1;
5099 SetLastError(0xdeadbeef);
5100 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5101 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5102 ok(!ret && GetLastError() == E_INVALIDARG,
5103 "expected E_INVALIDARG, got %08x\n", GetLastError());
5104 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5105 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
5106 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5107 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5108 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5111 ok(size == sizeof(authorityInfoAccessWithUrl), "unexpected size %d\n",
5113 ok(!memcmp(buf, authorityInfoAccessWithUrl, size),
5114 "unexpected value\n");
5118 accessDescription[1].pszAccessMethod = oid2;
5119 accessDescription[1].AccessLocation.dwAltNameChoice =
5120 CERT_ALT_NAME_IP_ADDRESS;
5121 U(accessDescription[1].AccessLocation).IPAddress.cbData =
5122 sizeof(encodedIPAddr);
5123 U(accessDescription[1].AccessLocation).IPAddress.pbData =
5124 (LPBYTE)encodedIPAddr;
5126 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5127 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5128 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5131 ok(size == sizeof(authorityInfoAccessWithUrlAndIPAddr),
5132 "unexpected size %d\n", size);
5133 ok(!memcmp(buf, authorityInfoAccessWithUrlAndIPAddr, size),
5134 "unexpected value\n");
5140 static void compareAuthorityInfoAccess(LPCSTR header,
5141 const CERT_AUTHORITY_INFO_ACCESS *expected,
5142 const CERT_AUTHORITY_INFO_ACCESS *got)
5146 ok(expected->cAccDescr == got->cAccDescr,
5147 "%s: expected %d access descriptions, got %d\n", header,
5148 expected->cAccDescr, got->cAccDescr);
5149 for (i = 0; i < expected->cAccDescr; i++)
5151 ok(!strcmp(expected->rgAccDescr[i].pszAccessMethod,
5152 got->rgAccDescr[i].pszAccessMethod), "%s[%d]: expected %s, got %s\n",
5153 header, i, expected->rgAccDescr[i].pszAccessMethod,
5154 got->rgAccDescr[i].pszAccessMethod);
5155 compareAltNameEntry(&expected->rgAccDescr[i].AccessLocation,
5156 &got->rgAccDescr[i].AccessLocation);
5160 static void test_decodeAuthorityInfoAccess(DWORD dwEncoding)
5162 static char oid1[] = "1.2.3";
5163 static char oid2[] = "1.5.6";
5168 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5169 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
5171 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5174 CERT_AUTHORITY_INFO_ACCESS aia = { 0, NULL };
5176 compareAuthorityInfoAccess("empty AIA", &aia,
5177 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5181 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5182 authorityInfoAccessWithUrl, sizeof(authorityInfoAccessWithUrl),
5183 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5184 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5187 CERT_ACCESS_DESCRIPTION accessDescription;
5188 CERT_AUTHORITY_INFO_ACCESS aia;
5190 accessDescription.pszAccessMethod = oid1;
5191 accessDescription.AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5192 U(accessDescription.AccessLocation).pwszURL = (LPWSTR)url;
5194 aia.rgAccDescr = &accessDescription;
5195 compareAuthorityInfoAccess("AIA with URL", &aia,
5196 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5200 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5201 authorityInfoAccessWithUrlAndIPAddr,
5202 sizeof(authorityInfoAccessWithUrlAndIPAddr), CRYPT_DECODE_ALLOC_FLAG,
5204 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5207 CERT_ACCESS_DESCRIPTION accessDescription[2];
5208 CERT_AUTHORITY_INFO_ACCESS aia;
5210 accessDescription[0].pszAccessMethod = oid1;
5211 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5212 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
5213 accessDescription[1].pszAccessMethod = oid2;
5214 accessDescription[1].AccessLocation.dwAltNameChoice =
5215 CERT_ALT_NAME_IP_ADDRESS;
5216 U(accessDescription[1].AccessLocation).IPAddress.cbData =
5217 sizeof(encodedIPAddr);
5218 U(accessDescription[1].AccessLocation).IPAddress.pbData =
5219 (LPBYTE)encodedIPAddr;
5221 aia.rgAccDescr = accessDescription;
5222 compareAuthorityInfoAccess("AIA with URL and IP addr", &aia,
5223 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5229 static const BYTE emptyCTL[] = {
5230 0x30,0x17,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5231 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5232 static const BYTE emptyCTLWithVersion1[] = {
5233 0x30,0x1a,0x02,0x01,0x01,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5234 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5235 static const BYTE ctlWithUsageIdentifier[] = {
5236 0x30,0x1b,0x30,0x04,0x06,0x02,0x2a,0x03,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
5237 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5238 static const BYTE ctlWithListIdentifier[] = {
5239 0x30,0x1a,0x30,0x00,0x04,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5240 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5241 static const BYTE ctlWithSequenceNumber[] = {
5242 0x30,0x1a,0x30,0x00,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5243 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5244 static const BYTE ctlWithThisUpdate[] = {
5245 0x30,0x15,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5246 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5247 static const BYTE ctlWithThisAndNextUpdate[] = {
5248 0x30,0x24,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5249 0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5250 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5251 static const BYTE ctlWithAlgId[] = {
5252 0x30,0x1b,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5253 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5254 static const BYTE ctlWithBogusEntry[] = {
5255 0x30,0x29,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,0x10,0x30,0x0e,0x04,
5257 0x01,0x01,0x31,0x09,0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,0x01 };
5258 static const BYTE ctlWithOneEntry[] = {
5259 0x30,0x2a,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5260 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x11,0x30,0x0f,0x04,
5261 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00 };
5262 static const BYTE ctlWithTwoEntries[] = {
5263 0x30,0x41,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5264 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x28,0x30,0x0f,0x04,
5265 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00,0x30,
5266 0x15,0x04,0x01,0x01,0x31,0x10,0x30,0x0e,0x06,0x02,0x2d,0x06,0x31,0x08,0x30,
5267 0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5269 static void test_encodeCTL(DWORD dwEncoding)
5271 static char oid1[] = "1.2.3";
5272 static char oid2[] = "1.5.6";
5278 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5279 CTL_ENTRY ctlEntry[2];
5280 CRYPT_ATTRIBUTE attr1, attr2;
5281 CRYPT_ATTR_BLOB value1, value2;
5283 memset(&info, 0, sizeof(info));
5284 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5285 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5286 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5289 ok(size == sizeof(emptyCTL), "unexpected size %d\n", size);
5290 ok(!memcmp(buf, emptyCTL, size), "unexpected value\n");
5295 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5296 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5297 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5300 ok(size == sizeof(emptyCTLWithVersion1), "unexpected size %d\n", size);
5301 ok(!memcmp(buf, emptyCTLWithVersion1, size), "unexpected value\n");
5306 info.SubjectUsage.cUsageIdentifier = 1;
5307 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5308 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5309 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5310 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5313 ok(size == sizeof(ctlWithUsageIdentifier), "unexpected size %d\n",
5315 ok(!memcmp(buf, ctlWithUsageIdentifier, size), "unexpected value\n");
5319 info.SubjectUsage.cUsageIdentifier = 0;
5320 info.ListIdentifier.cbData = sizeof(serialNum);
5321 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5322 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5323 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5324 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5327 ok(size == sizeof(ctlWithListIdentifier), "unexpected size %d\n", size);
5328 ok(!memcmp(buf, ctlWithListIdentifier, size), "unexpected value\n");
5332 info.ListIdentifier.cbData = 0;
5333 info.SequenceNumber.cbData = sizeof(serialNum);
5334 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5335 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5336 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5337 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5340 ok(size == sizeof(ctlWithSequenceNumber), "unexpected size %d\n",
5342 ok(!memcmp(buf, ctlWithSequenceNumber, size), "unexpected value\n");
5346 info.SequenceNumber.cbData = 0;
5347 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5348 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5349 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5350 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5353 ok(size == sizeof(ctlWithThisUpdate), "unexpected size %d\n", size);
5354 ok(!memcmp(buf, ctlWithThisUpdate, size), "unexpected value\n");
5358 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5359 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5360 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5361 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5364 ok(size == sizeof(ctlWithThisAndNextUpdate), "unexpected size %d\n",
5366 ok(!memcmp(buf, ctlWithThisAndNextUpdate, size), "unexpected value\n");
5370 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5371 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5372 info.SubjectAlgorithm.pszObjId = oid2;
5373 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5374 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5375 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5378 ok(size == sizeof(ctlWithAlgId), "unexpected size %d\n", size);
5379 ok(!memcmp(buf, ctlWithAlgId, size), "unexpected value\n");
5383 /* The value is supposed to be asn.1 encoded, so this'll fail to decode
5384 * (see tests below) but it'll encode fine.
5386 info.SubjectAlgorithm.pszObjId = NULL;
5387 value1.cbData = sizeof(serialNum);
5388 value1.pbData = (LPBYTE)serialNum;
5389 attr1.pszObjId = oid1;
5391 attr1.rgValue = &value1;
5392 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5393 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5394 ctlEntry[0].cAttribute = 1;
5395 ctlEntry[0].rgAttribute = &attr1;
5397 info.rgCTLEntry = ctlEntry;
5398 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5399 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5400 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5403 ok(size == sizeof(ctlWithBogusEntry), "unexpected size %d\n", size);
5404 ok(!memcmp(buf, ctlWithBogusEntry, size), "unexpected value\n");
5408 value1.cbData = sizeof(emptySequence);
5409 value1.pbData = (LPBYTE)emptySequence;
5410 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5411 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5412 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5415 ok(size == sizeof(ctlWithOneEntry), "unexpected size %d\n", size);
5416 ok(!memcmp(buf, ctlWithOneEntry, size), "unexpected value\n");
5420 value2.cbData = sizeof(encodedIPAddr);
5421 value2.pbData = (LPBYTE)encodedIPAddr;
5422 attr2.pszObjId = oid2;
5424 attr2.rgValue = &value2;
5425 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5426 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5427 ctlEntry[1].cAttribute = 1;
5428 ctlEntry[1].rgAttribute = &attr2;
5430 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5431 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5432 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5435 ok(size == sizeof(ctlWithTwoEntries), "unexpected size %d\n", size);
5436 ok(!memcmp(buf, ctlWithTwoEntries, size), "unexpected value\n");
5442 static void compareCTLInfo(LPCSTR header, const CTL_INFO *expected,
5443 const CTL_INFO *got)
5447 ok(expected->dwVersion == got->dwVersion,
5448 "%s: expected version %d, got %d\n", header, expected->dwVersion,
5450 ok(expected->SubjectUsage.cUsageIdentifier ==
5451 got->SubjectUsage.cUsageIdentifier,
5452 "%s: expected %d usage identifiers, got %d\n", header,
5453 expected->SubjectUsage.cUsageIdentifier,
5454 got->SubjectUsage.cUsageIdentifier);
5455 for (i = 0; i < expected->SubjectUsage.cUsageIdentifier; i++)
5456 ok(!strcmp(expected->SubjectUsage.rgpszUsageIdentifier[i],
5457 got->SubjectUsage.rgpszUsageIdentifier[i]),
5458 "%s[%d]: expected %s, got %s\n", header, i,
5459 expected->SubjectUsage.rgpszUsageIdentifier[i],
5460 got->SubjectUsage.rgpszUsageIdentifier[i]);
5461 ok(expected->ListIdentifier.cbData == got->ListIdentifier.cbData,
5462 "%s: expected list identifier of %d bytes, got %d\n", header,
5463 expected->ListIdentifier.cbData, got->ListIdentifier.cbData);
5464 if (expected->ListIdentifier.cbData)
5465 ok(!memcmp(expected->ListIdentifier.pbData, got->ListIdentifier.pbData,
5466 expected->ListIdentifier.cbData),
5467 "%s: unexpected list identifier value\n", header);
5468 ok(expected->SequenceNumber.cbData == got->SequenceNumber.cbData,
5469 "%s: expected sequence number of %d bytes, got %d\n", header,
5470 expected->SequenceNumber.cbData, got->SequenceNumber.cbData);
5471 if (expected->SequenceNumber.cbData)
5472 ok(!memcmp(expected->SequenceNumber.pbData, got->SequenceNumber.pbData,
5473 expected->SequenceNumber.cbData),
5474 "%s: unexpected sequence number value\n", header);
5475 ok(!memcmp(&expected->ThisUpdate, &got->ThisUpdate, sizeof(FILETIME)),
5476 "%s: expected this update = (%d, %d), got (%d, %d)\n", header,
5477 expected->ThisUpdate.dwLowDateTime, expected->ThisUpdate.dwHighDateTime,
5478 got->ThisUpdate.dwLowDateTime, got->ThisUpdate.dwHighDateTime);
5479 ok(!memcmp(&expected->NextUpdate, &got->NextUpdate, sizeof(FILETIME)),
5480 "%s: expected next update = (%d, %d), got (%d, %d)\n", header,
5481 expected->NextUpdate.dwLowDateTime, expected->NextUpdate.dwHighDateTime,
5482 got->NextUpdate.dwLowDateTime, got->NextUpdate.dwHighDateTime);
5483 if (expected->SubjectAlgorithm.pszObjId &&
5484 *expected->SubjectAlgorithm.pszObjId && !got->SubjectAlgorithm.pszObjId)
5485 ok(0, "%s: expected subject algorithm %s, got NULL\n", header,
5486 expected->SubjectAlgorithm.pszObjId);
5487 if (expected->SubjectAlgorithm.pszObjId && got->SubjectAlgorithm.pszObjId)
5488 ok(!strcmp(expected->SubjectAlgorithm.pszObjId,
5489 got->SubjectAlgorithm.pszObjId),
5490 "%s: expected subject algorithm %s, got %s\n", header,
5491 expected->SubjectAlgorithm.pszObjId, got->SubjectAlgorithm.pszObjId);
5492 ok(expected->SubjectAlgorithm.Parameters.cbData ==
5493 got->SubjectAlgorithm.Parameters.cbData,
5494 "%s: expected subject algorithm parameters of %d bytes, got %d\n", header,
5495 expected->SubjectAlgorithm.Parameters.cbData,
5496 got->SubjectAlgorithm.Parameters.cbData);
5497 if (expected->SubjectAlgorithm.Parameters.cbData)
5498 ok(!memcmp(expected->SubjectAlgorithm.Parameters.pbData,
5499 got->SubjectAlgorithm.Parameters.pbData,
5500 expected->SubjectAlgorithm.Parameters.cbData),
5501 "%s: unexpected subject algorithm parameter value\n", header);
5502 ok(expected->cCTLEntry == got->cCTLEntry,
5503 "%s: expected %d CTL entries, got %d\n", header, expected->cCTLEntry,
5505 for (i = 0; i < expected->cCTLEntry; i++)
5507 ok(expected->rgCTLEntry[i].SubjectIdentifier.cbData ==
5508 got->rgCTLEntry[i].SubjectIdentifier.cbData,
5509 "%s[%d]: expected subject identifier of %d bytes, got %d\n",
5510 header, i, expected->rgCTLEntry[i].SubjectIdentifier.cbData,
5511 got->rgCTLEntry[i].SubjectIdentifier.cbData);
5512 if (expected->rgCTLEntry[i].SubjectIdentifier.cbData)
5513 ok(!memcmp(expected->rgCTLEntry[i].SubjectIdentifier.pbData,
5514 got->rgCTLEntry[i].SubjectIdentifier.pbData,
5515 expected->rgCTLEntry[i].SubjectIdentifier.cbData),
5516 "%s[%d]: unexpected subject identifier value\n",
5518 for (j = 0; j < expected->rgCTLEntry[i].cAttribute; j++)
5520 ok(!strcmp(expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5521 got->rgCTLEntry[i].rgAttribute[j].pszObjId),
5522 "%s[%d][%d]: expected attribute OID %s, got %s\n", header, i, j,
5523 expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5524 got->rgCTLEntry[i].rgAttribute[j].pszObjId);
5525 for (k = 0; k < expected->rgCTLEntry[i].rgAttribute[j].cValue; k++)
5527 ok(expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData ==
5528 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5529 "%s[%d][%d][%d]: expected value of %d bytes, got %d\n",
5531 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5532 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData);
5533 if (expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData)
5535 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5536 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5537 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData),
5538 "%s[%d][%d][%d]: unexpected value\n",
5543 ok(expected->cExtension == got->cExtension,
5544 "%s: expected %d extensions, got %d\n", header, expected->cExtension,
5546 for (i = 0; i < expected->cExtension; i++)
5548 ok(!strcmp(expected->rgExtension[i].pszObjId,
5549 got->rgExtension[i].pszObjId), "%s[%d]: expected %s, got %s\n",
5550 header, i, expected->rgExtension[i].pszObjId,
5551 got->rgExtension[i].pszObjId);
5552 ok(expected->rgExtension[i].fCritical == got->rgExtension[i].fCritical,
5553 "%s[%d]: expected fCritical = %d, got %d\n", header, i,
5554 expected->rgExtension[i].fCritical, got->rgExtension[i].fCritical);
5555 ok(expected->rgExtension[i].Value.cbData ==
5556 got->rgExtension[i].Value.cbData,
5557 "%s[%d]: expected extension value to have %d bytes, got %d\n",
5558 header, i, expected->rgExtension[i].Value.cbData,
5559 got->rgExtension[i].Value.cbData);
5560 if (expected->rgExtension[i].Value.cbData)
5561 ok(!memcmp(expected->rgExtension[i].Value.pbData,
5562 got->rgExtension[i].Value.pbData,
5563 expected->rgExtension[i].Value.cbData),
5564 "%s[%d]: unexpected extension value\n", header, i);
5568 static const BYTE signedCTL[] = {
5569 0x30,0x81,0xc7,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
5570 0x81,0xb9,0x30,0x81,0xb6,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
5571 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x28,0x06,0x09,0x2a,0x86,
5572 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x1b,0x04,0x19,0x30,0x17,0x30,0x00,
5573 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5574 0x30,0x5a,0x30,0x02,0x06,0x00,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
5575 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
5576 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
5577 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5578 0x00,0x04,0x40,0xca,0xd8,0x32,0xd1,0xbd,0x97,0x61,0x54,0xd6,0x80,0xcf,0x0d,
5579 0xbd,0xa2,0x42,0xc7,0xca,0x37,0x91,0x7d,0x9d,0xac,0x8c,0xdf,0x05,0x8a,0x39,
5580 0xc6,0x07,0xc1,0x37,0xe6,0xb9,0xd1,0x0d,0x26,0xec,0xa5,0xb0,0x8a,0x51,0x26,
5581 0x2b,0x4f,0x73,0x44,0x86,0x83,0x5e,0x2b,0x6e,0xcc,0xf8,0x1b,0x85,0x53,0xe9,
5582 0x7a,0x80,0x8f,0x6b,0x42,0x19,0x93 };
5583 static const BYTE signedCTLWithCTLInnerContent[] = {
5584 0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
5585 0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
5586 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
5587 0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
5588 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5589 0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
5590 0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
5591 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
5592 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
5593 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
5594 0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
5595 0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
5596 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
5597 0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5598 0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
5599 0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
5600 0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
5601 0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
5602 0x57,0x6c,0x0b,0x47,0xb8 };
5604 static void test_decodeCTL(DWORD dwEncoding)
5606 static char oid1[] = "1.2.3";
5607 static char oid2[] = "1.5.6";
5608 static BYTE nullData[] = { 5,0 };
5614 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5615 CTL_ENTRY ctlEntry[2];
5616 CRYPT_ATTRIBUTE attr1, attr2;
5617 CRYPT_ATTR_BLOB value1, value2;
5619 memset(&info, 0, sizeof(info));
5620 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTL, sizeof(emptyCTL),
5621 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5622 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5625 compareCTLInfo("empty CTL", &info, (CTL_INFO *)buf);
5630 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTLWithVersion1,
5631 sizeof(emptyCTLWithVersion1), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
5633 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5636 compareCTLInfo("v1 CTL", &info, (CTL_INFO *)buf);
5641 info.SubjectUsage.cUsageIdentifier = 1;
5642 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5643 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithUsageIdentifier,
5644 sizeof(ctlWithUsageIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5646 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5649 compareCTLInfo("CTL with usage identifier", &info, (CTL_INFO *)buf);
5653 info.SubjectUsage.cUsageIdentifier = 0;
5654 info.ListIdentifier.cbData = sizeof(serialNum);
5655 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5656 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithListIdentifier,
5657 sizeof(ctlWithListIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5658 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5661 compareCTLInfo("CTL with list identifier", &info, (CTL_INFO *)buf);
5665 info.ListIdentifier.cbData = 0;
5666 info.SequenceNumber.cbData = sizeof(serialNum);
5667 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5668 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithSequenceNumber,
5669 sizeof(ctlWithSequenceNumber), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5670 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5673 compareCTLInfo("CTL with sequence number", &info, (CTL_INFO *)buf);
5677 info.SequenceNumber.cbData = 0;
5678 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5679 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisUpdate,
5680 sizeof(ctlWithThisUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5681 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5684 compareCTLInfo("CTL with this update", &info, (CTL_INFO *)buf);
5688 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5689 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisAndNextUpdate,
5690 sizeof(ctlWithThisAndNextUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5692 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5695 compareCTLInfo("CTL with this and next update", &info, (CTL_INFO *)buf);
5699 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5700 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5701 info.SubjectAlgorithm.pszObjId = oid2;
5702 info.SubjectAlgorithm.Parameters.cbData = sizeof(nullData);
5703 info.SubjectAlgorithm.Parameters.pbData = nullData;
5704 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithAlgId,
5705 sizeof(ctlWithAlgId), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5706 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5709 compareCTLInfo("CTL with algorithm identifier", &info, (CTL_INFO *)buf);
5713 SetLastError(0xdeadbeef);
5714 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithBogusEntry,
5715 sizeof(ctlWithBogusEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5717 (GetLastError() == CRYPT_E_ASN1_EOD ||
5718 GetLastError() == CRYPT_E_ASN1_CORRUPT ||
5719 GetLastError() == OSS_MORE_INPUT), /* Win9x */
5720 "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n",
5722 info.SubjectAlgorithm.Parameters.cbData = 0;
5723 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5724 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5725 info.SubjectAlgorithm.pszObjId = oid2;
5726 info.SubjectAlgorithm.pszObjId = NULL;
5727 value1.cbData = sizeof(emptySequence);
5728 value1.pbData = (LPBYTE)emptySequence;
5729 attr1.pszObjId = oid1;
5731 attr1.rgValue = &value1;
5732 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5733 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5734 ctlEntry[0].cAttribute = 1;
5735 ctlEntry[0].rgAttribute = &attr1;
5737 info.rgCTLEntry = ctlEntry;
5738 SetLastError(0xdeadbeef);
5739 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithOneEntry,
5740 sizeof(ctlWithOneEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5741 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5744 compareCTLInfo("CTL with one entry", &info, (CTL_INFO *)buf);
5748 value2.cbData = sizeof(encodedIPAddr);
5749 value2.pbData = (LPBYTE)encodedIPAddr;
5750 attr2.pszObjId = oid2;
5752 attr2.rgValue = &value2;
5753 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5754 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5755 ctlEntry[1].cAttribute = 1;
5756 ctlEntry[1].rgAttribute = &attr2;
5758 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithTwoEntries,
5759 sizeof(ctlWithTwoEntries), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5760 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5763 compareCTLInfo("CTL with two entries", &info, (CTL_INFO *)buf);
5767 /* A signed CTL isn't decodable, even if the inner content is a CTL */
5768 SetLastError(0xdeadbeef);
5769 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, signedCTL,
5770 sizeof(signedCTL), 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",
5775 SetLastError(0xdeadbeef);
5776 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL,
5777 signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent),
5778 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5779 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5780 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5781 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5785 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
5786 static const BYTE emptyPKCSContentInfoExtraBytes[] = { 0x30,0x04,0x06,0x02,0x2a,
5788 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
5790 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
5791 0x03,0x02,0x01,0x01 };
5792 static BYTE bogusDER[] = { 1 };
5794 static void test_encodePKCSContentInfo(DWORD dwEncoding)
5799 CRYPT_CONTENT_INFO info = { 0 };
5800 char oid1[] = "1.2.3";
5804 /* Crashes on win9x */
5805 SetLastError(0xdeadbeef);
5806 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL,
5807 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5808 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5809 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5811 SetLastError(0xdeadbeef);
5812 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5813 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5814 ok(!ret && (GetLastError() == E_INVALIDARG ||
5815 GetLastError() == OSS_LIMITED /* Win9x */),
5816 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5817 info.pszObjId = oid1;
5818 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5819 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5820 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5823 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size);
5824 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n");
5827 info.Content.pbData = bogusDER;
5828 info.Content.cbData = sizeof(bogusDER);
5829 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5830 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5831 ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError());
5834 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size);
5835 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n");
5838 info.Content.pbData = (BYTE *)ints[0].encoded;
5839 info.Content.cbData = ints[0].encoded[1] + 2;
5840 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5841 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5844 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size);
5845 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n");
5850 static const BYTE indefiniteSignedPKCSContent[] = {
5851 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
5852 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
5853 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
5854 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
5855 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
5856 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
5857 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5858 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5859 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
5860 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5861 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5862 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
5863 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
5864 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
5865 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
5866 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
5867 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
5868 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
5869 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
5870 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5871 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5872 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
5873 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
5874 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
5875 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
5876 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
5877 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
5878 0x00,0x00,0x00,0x00,0x00,0x00 };
5880 static void test_decodePKCSContentInfo(DWORD dwEncoding)
5885 CRYPT_CONTENT_INFO *info;
5887 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5888 emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo),
5889 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5890 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5893 info = (CRYPT_CONTENT_INFO *)buf;
5895 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5897 ok(info->Content.cbData == 0, "Expected no data, got %d\n",
5898 info->Content.cbData);
5901 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5902 emptyPKCSContentInfoExtraBytes, sizeof(emptyPKCSContentInfoExtraBytes),
5903 0, NULL, NULL, &size);
5904 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5905 SetLastError(0xdeadbeef);
5906 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5907 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo),
5908 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5909 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5910 * I doubt an app depends on that.
5912 ok((!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5913 GetLastError() == CRYPT_E_ASN1_CORRUPT)) || broken(ret),
5914 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5916 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5917 intPKCSContentInfo, sizeof(intPKCSContentInfo),
5918 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5919 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5922 info = (CRYPT_CONTENT_INFO *)buf;
5924 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5926 ok(info->Content.cbData == ints[0].encoded[1] + 2,
5927 "Unexpected size %d\n", info->Content.cbData);
5928 ok(!memcmp(info->Content.pbData, ints[0].encoded,
5929 info->Content.cbData), "Unexpected value\n");
5932 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5933 indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent),
5934 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5935 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5938 info = (CRYPT_CONTENT_INFO *)buf;
5940 ok(!strcmp(info->pszObjId, szOID_RSA_signedData),
5941 "Expected %s, got %s\n", szOID_RSA_signedData, info->pszObjId);
5942 ok(info->Content.cbData == 392, "Expected 392, got %d\n",
5943 info->Content.cbData);
5948 static const BYTE emptyPKCSAttr[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
5950 static const BYTE bogusPKCSAttr[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
5952 static const BYTE intPKCSAttr[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
5955 static void test_encodePKCSAttribute(DWORD dwEncoding)
5957 CRYPT_ATTRIBUTE attr = { 0 };
5961 CRYPT_ATTR_BLOB blob;
5962 char oid[] = "1.2.3";
5966 /* Crashes on win9x */
5967 SetLastError(0xdeadbeef);
5968 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, NULL,
5969 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5970 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5971 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5973 SetLastError(0xdeadbeef);
5974 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5975 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5976 ok(!ret && (GetLastError() == E_INVALIDARG ||
5977 GetLastError() == OSS_LIMITED /* Win9x */),
5978 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5979 attr.pszObjId = oid;
5980 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5981 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5982 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5985 ok(size == sizeof(emptyPKCSAttr), "Unexpected size %d\n", size);
5986 ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n");
5989 blob.cbData = sizeof(bogusDER);
5990 blob.pbData = bogusDER;
5992 attr.rgValue = &blob;
5993 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5994 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5995 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5998 ok(size == sizeof(bogusPKCSAttr), "Unexpected size %d\n", size);
5999 ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n");
6002 blob.pbData = (BYTE *)ints[0].encoded;
6003 blob.cbData = ints[0].encoded[1] + 2;
6004 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
6005 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6008 ok(size == sizeof(intPKCSAttr), "Unexpected size %d\n", size);
6009 ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n");
6014 static void test_decodePKCSAttribute(DWORD dwEncoding)
6019 CRYPT_ATTRIBUTE *attr;
6021 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
6022 emptyPKCSAttr, sizeof(emptyPKCSAttr),
6023 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6024 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6027 attr = (CRYPT_ATTRIBUTE *)buf;
6029 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
6031 ok(attr->cValue == 0, "Expected no value, got %d\n", attr->cValue);
6034 SetLastError(0xdeadbeef);
6035 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
6036 bogusPKCSAttr, sizeof(bogusPKCSAttr),
6037 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6038 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
6039 * I doubt an app depends on that.
6041 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
6042 GetLastError() == CRYPT_E_ASN1_CORRUPT ||
6043 GetLastError() == OSS_MORE_INPUT /* Win9x */),
6044 "Expected CRYPT_E_ASN1_EOD, CRYPT_E_ASN1_CORRUPT, or OSS_MORE_INPUT, got %x\n",
6046 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
6047 intPKCSAttr, sizeof(intPKCSAttr),
6048 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6049 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6052 attr = (CRYPT_ATTRIBUTE *)buf;
6054 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
6056 ok(attr->cValue == 1, "Expected 1 value, got %d\n", attr->cValue);
6057 ok(attr->rgValue[0].cbData == ints[0].encoded[1] + 2,
6058 "Unexpected size %d\n", attr->rgValue[0].cbData);
6059 ok(!memcmp(attr->rgValue[0].pbData, ints[0].encoded,
6060 attr->rgValue[0].cbData), "Unexpected value\n");
6065 static const BYTE emptyPKCSAttributes[] = { 0x31,0x00 };
6066 static const BYTE singlePKCSAttributes[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
6067 0x2a,0x03,0x31,0x00 };
6068 static const BYTE doublePKCSAttributes[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
6069 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
6071 static void test_encodePKCSAttributes(DWORD dwEncoding)
6073 CRYPT_ATTRIBUTES attributes = { 0 };
6074 CRYPT_ATTRIBUTE attr[2] = { { 0 } };
6075 CRYPT_ATTR_BLOB blob;
6079 char oid1[] = "1.2.3", oid2[] = "1.5.6";
6081 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6082 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6083 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6086 ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %d\n", size);
6087 ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n");
6090 attributes.cAttr = 1;
6091 attributes.rgAttr = attr;
6092 SetLastError(0xdeadbeef);
6093 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6094 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6095 ok(!ret && (GetLastError() == E_INVALIDARG ||
6096 GetLastError() == OSS_LIMITED /* Win9x */),
6097 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6098 attr[0].pszObjId = oid1;
6099 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6100 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6103 ok(size == sizeof(singlePKCSAttributes), "Unexpected size %d\n", size);
6104 ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n");
6107 attr[1].pszObjId = oid2;
6109 attr[1].rgValue = &blob;
6110 blob.pbData = (BYTE *)ints[0].encoded;
6111 blob.cbData = ints[0].encoded[1] + 2;
6112 attributes.cAttr = 2;
6113 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6114 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6115 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6118 ok(size == sizeof(doublePKCSAttributes), "Unexpected size %d\n", size);
6119 ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n");
6124 static void test_decodePKCSAttributes(DWORD dwEncoding)
6129 CRYPT_ATTRIBUTES *attributes;
6131 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6132 emptyPKCSAttributes, sizeof(emptyPKCSAttributes),
6133 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6134 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6137 attributes = (CRYPT_ATTRIBUTES *)buf;
6138 ok(attributes->cAttr == 0, "Expected no attributes, got %d\n",
6142 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6143 singlePKCSAttributes, sizeof(singlePKCSAttributes),
6144 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6145 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6148 attributes = (CRYPT_ATTRIBUTES *)buf;
6149 ok(attributes->cAttr == 1, "Expected 1 attribute, got %d\n",
6151 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
6152 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
6153 ok(attributes->rgAttr[0].cValue == 0,
6154 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
6157 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6158 doublePKCSAttributes, sizeof(doublePKCSAttributes),
6159 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6160 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6163 attributes = (CRYPT_ATTRIBUTES *)buf;
6164 ok(attributes->cAttr == 2, "Expected 2 attributes, got %d\n",
6166 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
6167 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
6168 ok(attributes->rgAttr[0].cValue == 0,
6169 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
6170 ok(!strcmp(attributes->rgAttr[1].pszObjId, "1.5.6"),
6171 "Expected 1.5.6, got %s\n", attributes->rgAttr[1].pszObjId);
6172 ok(attributes->rgAttr[1].cValue == 1,
6173 "Expected 1 attribute, got %d\n", attributes->rgAttr[1].cValue);
6174 ok(attributes->rgAttr[1].rgValue[0].cbData == ints[0].encoded[1] + 2,
6175 "Unexpected size %d\n", attributes->rgAttr[1].rgValue[0].cbData);
6176 ok(!memcmp(attributes->rgAttr[1].rgValue[0].pbData, ints[0].encoded,
6177 attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n");
6182 static const BYTE singleCapability[] = {
6183 0x30,0x06,0x30,0x04,0x06,0x02,0x2d,0x06 };
6184 static const BYTE twoCapabilities[] = {
6185 0x30,0x0c,0x30,0x04,0x06,0x02,0x2d,0x06,0x30,0x04,0x06,0x02,0x2a,0x03 };
6186 static const BYTE singleCapabilitywithNULL[] = {
6187 0x30,0x08,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
6189 static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding)
6191 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6195 CRYPT_SMIME_CAPABILITY capability[2];
6196 CRYPT_SMIME_CAPABILITIES capabilities;
6198 /* An empty capabilities is allowed */
6199 capabilities.cCapability = 0;
6200 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6201 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6202 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6205 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
6206 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
6209 /* A non-empty capabilities with an empty capability (lacking an OID) is
6212 capability[0].pszObjId = NULL;
6213 capability[0].Parameters.cbData = 0;
6214 capabilities.cCapability = 1;
6215 capabilities.rgCapability = capability;
6216 SetLastError(0xdeadbeef);
6217 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6218 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6219 ok(!ret && (GetLastError() == E_INVALIDARG ||
6220 GetLastError() == OSS_LIMITED /* Win9x */),
6221 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6222 capability[0].pszObjId = oid1;
6223 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6224 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6225 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6228 ok(size == sizeof(singleCapability), "unexpected size %d\n", size);
6229 ok(!memcmp(buf, singleCapability, size), "unexpected value\n");
6232 capability[1].pszObjId = oid2;
6233 capability[1].Parameters.cbData = 0;
6234 capabilities.cCapability = 2;
6235 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6236 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6237 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6240 ok(size == sizeof(twoCapabilities), "unexpected size %d\n", size);
6241 ok(!memcmp(buf, twoCapabilities, size), "unexpected value\n");
6246 static void compareSMimeCapabilities(LPCSTR header,
6247 const CRYPT_SMIME_CAPABILITIES *expected, const CRYPT_SMIME_CAPABILITIES *got)
6251 ok(got->cCapability == expected->cCapability,
6252 "%s: expected %d capabilities, got %d\n", header, expected->cCapability,
6254 for (i = 0; i < expected->cCapability; i++)
6256 ok(!strcmp(expected->rgCapability[i].pszObjId,
6257 got->rgCapability[i].pszObjId), "%s[%d]: expected %s, got %s\n",
6258 header, i, expected->rgCapability[i].pszObjId,
6259 got->rgCapability[i].pszObjId);
6260 ok(expected->rgCapability[i].Parameters.cbData ==
6261 got->rgCapability[i].Parameters.cbData,
6262 "%s[%d]: expected %d bytes, got %d\n", header, i,
6263 expected->rgCapability[i].Parameters.cbData,
6264 got->rgCapability[i].Parameters.cbData);
6265 if (expected->rgCapability[i].Parameters.cbData)
6266 ok(!memcmp(expected->rgCapability[i].Parameters.pbData,
6267 got->rgCapability[i].Parameters.pbData,
6268 expected->rgCapability[i].Parameters.cbData),
6269 "%s[%d]: unexpected value\n", header, i);
6273 static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding)
6275 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6278 CRYPT_SMIME_CAPABILITY capability[2];
6279 CRYPT_SMIME_CAPABILITIES capabilities, *ptr;
6281 SetLastError(0xdeadbeef);
6282 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6283 emptySequence, sizeof(emptySequence),
6284 CRYPT_DECODE_ALLOC_FLAG, NULL, &ptr, &size);
6285 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6288 capabilities.cCapability = 0;
6289 compareSMimeCapabilities("empty capabilities", &capabilities, ptr);
6292 SetLastError(0xdeadbeef);
6293 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6294 singleCapability, sizeof(singleCapability), CRYPT_DECODE_ALLOC_FLAG, NULL,
6296 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6299 capability[0].pszObjId = oid1;
6300 capability[0].Parameters.cbData = 0;
6301 capabilities.cCapability = 1;
6302 capabilities.rgCapability = capability;
6303 compareSMimeCapabilities("single capability", &capabilities, ptr);
6306 SetLastError(0xdeadbeef);
6307 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6308 singleCapabilitywithNULL, sizeof(singleCapabilitywithNULL),
6309 CRYPT_DECODE_ALLOC_FLAG, NULL, &ptr, &size);
6310 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6313 BYTE NULLparam[] = {0x05, 0x00};
6314 capability[0].pszObjId = oid1;
6315 capability[0].Parameters.cbData = 2;
6316 capability[0].Parameters.pbData = NULLparam;
6317 capabilities.cCapability = 1;
6318 capabilities.rgCapability = capability;
6319 compareSMimeCapabilities("single capability with NULL", &capabilities,
6323 SetLastError(0xdeadbeef);
6324 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6325 twoCapabilities, sizeof(twoCapabilities), CRYPT_DECODE_ALLOC_FLAG, NULL,
6327 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6330 capability[0].Parameters.cbData = 0;
6331 capability[1].pszObjId = oid2;
6332 capability[1].Parameters.cbData = 0;
6333 capabilities.cCapability = 2;
6334 compareSMimeCapabilities("two capabilities", &capabilities, ptr);
6339 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
6340 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
6342 static const BYTE minimalPKCSSigner[] = {
6343 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6344 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6345 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6346 static const BYTE PKCSSignerWithSerial[] = {
6347 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6348 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6349 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
6351 static const BYTE PKCSSignerWithHashAlgo[] = {
6352 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6353 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6354 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
6356 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = {
6357 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6358 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6359 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6360 0x06,0x05,0x00,0x04,0x00 };
6361 static const BYTE PKCSSignerWithHash[] = {
6362 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6363 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6364 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6365 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
6366 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6367 static const BYTE PKCSSignerWithAuthAttr[] = {
6368 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6369 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6370 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
6371 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
6372 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
6373 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
6374 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6376 static void test_encodePKCSSignerInfo(DWORD dwEncoding)
6378 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6382 CMSG_SIGNER_INFO info = { 0 };
6383 char oid_common_name[] = szOID_COMMON_NAME;
6384 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
6385 (LPBYTE)encodedCommonName };
6386 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
6388 SetLastError(0xdeadbeef);
6389 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6390 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6391 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6393 skip("no PKCS7_SIGNER_INFO encode support\n");
6396 ok(!ret && (GetLastError() == E_INVALIDARG ||
6397 GetLastError() == OSS_LIMITED /* Win9x */),
6398 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6399 /* To be encoded, a signer must have an issuer at least, and the encoding
6400 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
6401 * see decoding tests.)
6403 info.Issuer.cbData = sizeof(encodedCommonNameNoNull);
6404 info.Issuer.pbData = encodedCommonNameNoNull;
6405 SetLastError(0xdeadbeef);
6406 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6407 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6408 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6409 ok(!ret && GetLastError() == E_INVALIDARG,
6410 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6413 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6414 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6417 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6418 if (size == sizeof(minimalPKCSSigner))
6419 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6421 ok(0, "Unexpected value\n");
6425 info.SerialNumber.cbData = sizeof(serialNum);
6426 info.SerialNumber.pbData = (BYTE *)serialNum;
6427 SetLastError(0xdeadbeef);
6428 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6429 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6430 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6431 ok(!ret && GetLastError() == E_INVALIDARG,
6432 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6435 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6436 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6439 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6441 if (size == sizeof(PKCSSignerWithSerial))
6442 ok(!memcmp(buf, PKCSSignerWithSerial, size),
6443 "Unexpected value\n");
6445 ok(0, "Unexpected value\n");
6449 info.HashAlgorithm.pszObjId = oid1;
6450 SetLastError(0xdeadbeef);
6451 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6452 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6453 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6454 ok(!ret && GetLastError() == E_INVALIDARG,
6455 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6458 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6459 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6462 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6464 if (size == sizeof(PKCSSignerWithHashAlgo))
6465 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6466 "Unexpected value\n");
6468 ok(0, "Unexpected value\n");
6472 info.HashEncryptionAlgorithm.pszObjId = oid2;
6473 SetLastError(0xdeadbeef);
6474 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6475 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6476 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6477 ok(!ret && GetLastError() == E_INVALIDARG,
6478 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6481 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6484 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6485 "Unexpected size %d\n", size);
6486 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo))
6487 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6488 "Unexpected value\n");
6490 ok(0, "Unexpected value\n");
6494 info.EncryptedHash.cbData = sizeof(hash);
6495 info.EncryptedHash.pbData = (BYTE *)hash;
6496 SetLastError(0xdeadbeef);
6497 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6498 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6499 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6500 ok(!ret && GetLastError() == E_INVALIDARG,
6501 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6504 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6507 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6509 if (size == sizeof(PKCSSignerWithHash))
6510 ok(!memcmp(buf, PKCSSignerWithHash, size),
6511 "Unexpected value\n");
6513 ok(0, "Unexpected value\n");
6517 info.AuthAttrs.cAttr = 1;
6518 info.AuthAttrs.rgAttr = &attr;
6519 SetLastError(0xdeadbeef);
6520 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6521 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6522 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6523 ok(!ret && GetLastError() == E_INVALIDARG,
6524 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6527 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6530 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
6532 if (size == sizeof(PKCSSignerWithAuthAttr))
6533 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
6534 "Unexpected value\n");
6536 ok(0, "Unexpected value\n");
6542 static void test_decodePKCSSignerInfo(DWORD dwEncoding)
6547 CMSG_SIGNER_INFO *info;
6549 /* A PKCS signer can't be decoded without a serial number. */
6550 SetLastError(0xdeadbeef);
6551 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6552 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6553 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6554 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
6555 GetLastError() == OSS_DATA_ERROR /* Win9x */),
6556 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %x\n",
6558 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6559 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6560 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6561 ok(ret || broken(GetLastError() == OSS_DATA_ERROR),
6562 "CryptDecodeObjectEx failed: %x\n", GetLastError());
6565 info = (CMSG_SIGNER_INFO *)buf;
6566 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6568 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6569 "Unexpected size %d\n", info->Issuer.cbData);
6570 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6571 info->Issuer.cbData), "Unexpected value\n");
6572 ok(info->SerialNumber.cbData == sizeof(serialNum),
6573 "Unexpected size %d\n", info->SerialNumber.cbData);
6574 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6575 "Unexpected value\n");
6578 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6579 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6580 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6583 info = (CMSG_SIGNER_INFO *)buf;
6584 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6586 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6587 "Unexpected size %d\n", info->Issuer.cbData);
6588 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6589 info->Issuer.cbData), "Unexpected value\n");
6590 ok(info->SerialNumber.cbData == sizeof(serialNum),
6591 "Unexpected size %d\n", info->SerialNumber.cbData);
6592 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6593 "Unexpected value\n");
6594 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6595 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6598 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6599 PKCSSignerWithHashAndEncryptionAlgo,
6600 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6604 info = (CMSG_SIGNER_INFO *)buf;
6605 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6607 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6608 "Unexpected size %d\n", info->Issuer.cbData);
6609 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6610 info->Issuer.cbData), "Unexpected value\n");
6611 ok(info->SerialNumber.cbData == sizeof(serialNum),
6612 "Unexpected size %d\n", info->SerialNumber.cbData);
6613 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6614 "Unexpected value\n");
6615 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6616 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6617 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6618 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6621 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6622 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6623 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6626 info = (CMSG_SIGNER_INFO *)buf;
6627 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6629 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6630 "Unexpected size %d\n", info->Issuer.cbData);
6631 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6632 info->Issuer.cbData), "Unexpected value\n");
6633 ok(info->SerialNumber.cbData == sizeof(serialNum),
6634 "Unexpected size %d\n", info->SerialNumber.cbData);
6635 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6636 "Unexpected value\n");
6637 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6638 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6639 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6640 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6641 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6642 info->EncryptedHash.cbData);
6643 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6644 "Unexpected value\n");
6647 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6648 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
6649 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6652 info = (CMSG_SIGNER_INFO *)buf;
6653 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n",
6654 info->AuthAttrs.cAttr);
6655 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
6656 "Expected %s, got %s\n", szOID_COMMON_NAME,
6657 info->AuthAttrs.rgAttr[0].pszObjId);
6658 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
6659 info->AuthAttrs.rgAttr[0].cValue);
6660 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
6661 sizeof(encodedCommonName), "Unexpected size %d\n",
6662 info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
6663 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
6664 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
6669 static const BYTE CMSSignerWithKeyId[] = {
6670 0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,
6671 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6673 static void test_encodeCMSSignerInfo(DWORD dwEncoding)
6678 CMSG_CMS_SIGNER_INFO info = { 0 };
6679 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6681 SetLastError(0xdeadbeef);
6682 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6683 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6684 ok(!ret, "Expected failure, got %d\n", ret);
6685 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6687 skip("no CMS_SIGNER_INFO encode support\n");
6690 ok(GetLastError() == E_INVALIDARG,
6691 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6692 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6693 SetLastError(0xdeadbeef);
6694 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6695 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6696 ok(!ret, "Expected failure, got %d\n", ret);
6697 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6699 skip("no CMS_SIGNER_INFO encode support\n");
6702 ok(GetLastError() == E_INVALIDARG,
6703 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6704 /* To be encoded, a signer must have a valid cert ID, where a valid ID may
6705 * be a key id or a issuer serial number with at least the issuer set, and
6706 * the encoding must include PKCS_7_ASN_ENCODING.
6707 * (That isn't enough to be decoded, see decoding tests.)
6709 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6710 sizeof(encodedCommonNameNoNull);
6711 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6712 SetLastError(0xdeadbeef);
6713 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6714 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6715 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6716 ok(!ret && GetLastError() == E_INVALIDARG,
6717 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6720 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6723 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6724 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6728 U(info.SignerId).IssuerSerialNumber.SerialNumber.cbData = sizeof(serialNum);
6729 U(info.SignerId).IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
6730 SetLastError(0xdeadbeef);
6731 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6732 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6733 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6734 ok(!ret && GetLastError() == E_INVALIDARG,
6735 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6738 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6741 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6743 ok(!memcmp(buf, PKCSSignerWithSerial, size), "Unexpected value\n");
6747 info.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
6748 U(info.SignerId).KeyId.cbData = sizeof(serialNum);
6749 U(info.SignerId).KeyId.pbData = (BYTE *)serialNum;
6750 SetLastError(0xdeadbeef);
6751 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6752 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6753 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6754 ok(!ret && GetLastError() == E_INVALIDARG,
6755 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6758 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6761 ok(size == sizeof(CMSSignerWithKeyId), "Unexpected size %d\n",
6763 ok(!memcmp(buf, CMSSignerWithKeyId, size), "Unexpected value\n");
6767 /* While a CERT_ID can have a hash type, that's not allowed in CMS, where
6768 * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed
6769 * (see RFC 3852, section 5.3.)
6771 info.SignerId.dwIdChoice = CERT_ID_SHA1_HASH;
6772 U(info.SignerId).HashId.cbData = sizeof(hash);
6773 U(info.SignerId).HashId.pbData = (BYTE *)hash;
6774 SetLastError(0xdeadbeef);
6775 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6776 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6777 ok(!ret && GetLastError() == E_INVALIDARG,
6778 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6779 /* Now with a hash algo */
6780 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6781 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6782 sizeof(encodedCommonNameNoNull);
6783 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6784 info.HashAlgorithm.pszObjId = oid1;
6785 SetLastError(0xdeadbeef);
6786 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6787 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6788 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6789 ok(!ret && GetLastError() == E_INVALIDARG,
6790 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6793 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6796 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6798 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6799 "Unexpected value\n");
6803 info.HashEncryptionAlgorithm.pszObjId = oid2;
6804 SetLastError(0xdeadbeef);
6805 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6806 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6807 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6808 ok(!ret && GetLastError() == E_INVALIDARG,
6809 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6812 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6815 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6816 "Unexpected size %d\n", size);
6817 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6818 "Unexpected value\n");
6822 info.EncryptedHash.cbData = sizeof(hash);
6823 info.EncryptedHash.pbData = (BYTE *)hash;
6824 SetLastError(0xdeadbeef);
6825 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6826 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6827 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6828 ok(!ret && GetLastError() == E_INVALIDARG,
6829 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6832 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6835 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6837 ok(!memcmp(buf, PKCSSignerWithHash, size), "Unexpected value\n");
6843 static void test_decodeCMSSignerInfo(DWORD dwEncoding)
6848 CMSG_CMS_SIGNER_INFO *info;
6849 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6851 /* A CMS signer can't be decoded without a serial number. */
6852 SetLastError(0xdeadbeef);
6853 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6854 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6855 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6856 ok(!ret, "expected failure\n");
6857 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6859 skip("no CMS_SIGNER_INFO decode support\n");
6862 ok(GetLastError() == CRYPT_E_ASN1_CORRUPT,
6863 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
6864 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6865 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6866 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6867 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6870 info = (CMSG_CMS_SIGNER_INFO *)buf;
6871 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6873 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6874 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6875 info->SignerId.dwIdChoice);
6876 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6877 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6878 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6879 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6880 encodedCommonNameNoNull,
6881 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6882 "Unexpected value\n");
6883 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6884 sizeof(serialNum), "Unexpected size %d\n",
6885 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6886 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6887 serialNum, sizeof(serialNum)), "Unexpected value\n");
6890 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6891 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6892 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6893 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6896 info = (CMSG_CMS_SIGNER_INFO *)buf;
6897 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6899 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6900 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6901 info->SignerId.dwIdChoice);
6902 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6903 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6904 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6905 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6906 encodedCommonNameNoNull,
6907 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6908 "Unexpected value\n");
6909 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6910 sizeof(serialNum), "Unexpected size %d\n",
6911 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6912 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6913 serialNum, sizeof(serialNum)), "Unexpected value\n");
6914 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6915 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6918 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6919 PKCSSignerWithHashAndEncryptionAlgo,
6920 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6922 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6925 info = (CMSG_CMS_SIGNER_INFO *)buf;
6926 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6928 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6929 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6930 info->SignerId.dwIdChoice);
6931 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6932 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6933 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6934 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6935 encodedCommonNameNoNull,
6936 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6937 "Unexpected value\n");
6938 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6939 sizeof(serialNum), "Unexpected size %d\n",
6940 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6941 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6942 serialNum, sizeof(serialNum)), "Unexpected value\n");
6943 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6944 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6945 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6946 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6949 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6950 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6951 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6952 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6955 info = (CMSG_CMS_SIGNER_INFO *)buf;
6956 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6958 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6959 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6960 info->SignerId.dwIdChoice);
6961 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6962 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6963 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6964 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6965 encodedCommonNameNoNull,
6966 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6967 "Unexpected value\n");
6968 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6969 sizeof(serialNum), "Unexpected size %d\n",
6970 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6971 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6972 serialNum, sizeof(serialNum)), "Unexpected value\n");
6973 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6974 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6975 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6976 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6977 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6978 info->EncryptedHash.cbData);
6979 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6980 "Unexpected value\n");
6983 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6984 CMSSignerWithKeyId, sizeof(CMSSignerWithKeyId),
6985 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6986 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6989 info = (CMSG_CMS_SIGNER_INFO *)buf;
6990 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6992 ok(info->SignerId.dwIdChoice == CERT_ID_KEY_IDENTIFIER,
6993 "Expected CERT_ID_KEY_IDENTIFIER, got %d\n",
6994 info->SignerId.dwIdChoice);
6995 ok(U(info->SignerId).KeyId.cbData == sizeof(serialNum),
6996 "Unexpected size %d\n", U(info->SignerId).KeyId.cbData);
6997 ok(!memcmp(U(info->SignerId).KeyId.pbData, serialNum, sizeof(serialNum)),
6998 "Unexpected value\n");
7003 static BYTE emptyDNSPermittedConstraints[] = {
7004 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
7005 static BYTE emptyDNSExcludedConstraints[] = {
7006 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
7007 static BYTE DNSExcludedConstraints[] = {
7008 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
7009 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7010 static BYTE permittedAndExcludedConstraints[] = {
7011 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7012 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
7013 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7014 static BYTE permittedAndExcludedWithMinConstraints[] = {
7015 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7016 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
7017 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7018 static BYTE permittedAndExcludedWithMinMaxConstraints[] = {
7019 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7020 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
7021 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7023 static void test_encodeNameConstraints(DWORD dwEncoding)
7026 CERT_NAME_CONSTRAINTS_INFO constraints = { 0 };
7027 CERT_GENERAL_SUBTREE permitted = { { 0 } };
7028 CERT_GENERAL_SUBTREE excluded = { { 0 } };
7032 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7033 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7034 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7036 skip("no X509_NAME_CONSTRAINTS encode support\n");
7039 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7042 ok(size == sizeof(emptySequence), "Unexpected size\n");
7043 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
7046 constraints.cPermittedSubtree = 1;
7047 constraints.rgPermittedSubtree = &permitted;
7048 SetLastError(0xdeadbeef);
7049 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7050 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7051 ok(!ret && GetLastError() == E_INVALIDARG,
7052 "Expected E_INVALIDARG, got %08x\n", GetLastError());
7053 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
7054 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7055 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7056 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7059 ok(size == sizeof(emptyDNSPermittedConstraints), "Unexpected size\n");
7060 ok(!memcmp(buf, emptyDNSPermittedConstraints, size),
7061 "Unexpected value\n");
7064 constraints.cPermittedSubtree = 0;
7065 constraints.cExcludedSubtree = 1;
7066 constraints.rgExcludedSubtree = &excluded;
7067 excluded.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
7068 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7069 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7070 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7073 ok(size == sizeof(emptyDNSExcludedConstraints), "Unexpected size\n");
7074 ok(!memcmp(buf, emptyDNSExcludedConstraints, size),
7075 "Unexpected value\n");
7078 U(excluded.Base).pwszURL = (LPWSTR)url;
7079 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7080 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7081 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7084 ok(size == sizeof(DNSExcludedConstraints), "Unexpected size\n");
7085 ok(!memcmp(buf, DNSExcludedConstraints, size),
7086 "Unexpected value\n");
7089 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
7090 U(permitted.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7091 U(permitted.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7092 constraints.cPermittedSubtree = 1;
7093 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7094 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7095 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7098 ok(size == sizeof(permittedAndExcludedConstraints),
7099 "Unexpected size\n");
7100 ok(!memcmp(buf, permittedAndExcludedConstraints, size),
7101 "Unexpected value\n");
7104 permitted.dwMinimum = 5;
7105 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7106 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7107 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7110 ok(size == sizeof(permittedAndExcludedWithMinConstraints),
7111 "Unexpected size\n");
7112 ok(!memcmp(buf, permittedAndExcludedWithMinConstraints, size),
7113 "Unexpected value\n");
7116 permitted.fMaximum = TRUE;
7117 permitted.dwMaximum = 3;
7118 SetLastError(0xdeadbeef);
7119 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7120 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7121 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7124 ok(size == sizeof(permittedAndExcludedWithMinMaxConstraints),
7125 "Unexpected size\n");
7126 ok(!memcmp(buf, permittedAndExcludedWithMinMaxConstraints, size),
7127 "Unexpected value\n");
7132 struct EncodedNameConstraints
7134 CRYPT_DATA_BLOB encoded;
7135 CERT_NAME_CONSTRAINTS_INFO constraints;
7138 static CERT_GENERAL_SUBTREE emptyDNSSubtree = {
7139 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
7140 static CERT_GENERAL_SUBTREE DNSSubtree = {
7141 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
7142 static CERT_GENERAL_SUBTREE IPAddressSubtree = {
7143 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 0 };
7144 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree = {
7145 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, 0 };
7146 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree = {
7147 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, TRUE, 3 };
7149 struct EncodedNameConstraints encodedNameConstraints[] = {
7150 { { sizeof(emptySequence), (LPBYTE)emptySequence }, { 0 } },
7151 { { sizeof(emptyDNSPermittedConstraints), emptyDNSPermittedConstraints },
7152 { 1, &emptyDNSSubtree, 0, NULL } },
7153 { { sizeof(emptyDNSExcludedConstraints), emptyDNSExcludedConstraints },
7154 { 0, NULL, 1, &emptyDNSSubtree } },
7155 { { sizeof(DNSExcludedConstraints), DNSExcludedConstraints },
7156 { 0, NULL, 1, &DNSSubtree } },
7157 { { sizeof(permittedAndExcludedConstraints), permittedAndExcludedConstraints },
7158 { 1, &IPAddressSubtree, 1, &DNSSubtree } },
7159 { { sizeof(permittedAndExcludedWithMinConstraints),
7160 permittedAndExcludedWithMinConstraints },
7161 { 1, &IPAddressWithMinSubtree, 1, &DNSSubtree } },
7162 { { sizeof(permittedAndExcludedWithMinMaxConstraints),
7163 permittedAndExcludedWithMinMaxConstraints },
7164 { 1, &IPAddressWithMinMaxSubtree, 1, &DNSSubtree } },
7167 static void test_decodeNameConstraints(DWORD dwEncoding)
7171 CERT_NAME_CONSTRAINTS_INFO *constraints;
7173 U(DNSSubtree.Base).pwszURL = (LPWSTR)url;
7174 U(IPAddressSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7175 U(IPAddressSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7176 U(IPAddressWithMinSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7177 U(IPAddressWithMinSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7178 U(IPAddressWithMinMaxSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7179 U(IPAddressWithMinMaxSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7181 i < sizeof(encodedNameConstraints) / sizeof(encodedNameConstraints[0]);
7186 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS,
7187 encodedNameConstraints[i].encoded.pbData,
7188 encodedNameConstraints[i].encoded.cbData,
7189 CRYPT_DECODE_ALLOC_FLAG, NULL, &constraints, &size);
7190 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7192 skip("no X509_NAME_CONSTRAINTS decode support\n");
7195 ok(ret, "%d: CryptDecodeObjectEx failed: %08x\n", i, GetLastError());
7200 if (constraints->cPermittedSubtree !=
7201 encodedNameConstraints[i].constraints.cPermittedSubtree)
7202 fprintf(stderr, "%d: expected %d permitted, got %d\n", i,
7203 encodedNameConstraints[i].constraints.cPermittedSubtree,
7204 constraints->cPermittedSubtree);
7205 if (constraints->cPermittedSubtree ==
7206 encodedNameConstraints[i].constraints.cPermittedSubtree)
7208 for (j = 0; j < constraints->cPermittedSubtree; j++)
7210 compareAltNameEntry(&constraints->rgPermittedSubtree[j].Base,
7211 &encodedNameConstraints[i].constraints.rgPermittedSubtree[j].Base);
7214 if (constraints->cExcludedSubtree !=
7215 encodedNameConstraints[i].constraints.cExcludedSubtree)
7216 fprintf(stderr, "%d: expected %d excluded, got %d\n", i,
7217 encodedNameConstraints[i].constraints.cExcludedSubtree,
7218 constraints->cExcludedSubtree);
7219 if (constraints->cExcludedSubtree ==
7220 encodedNameConstraints[i].constraints.cExcludedSubtree)
7222 for (j = 0; j < constraints->cExcludedSubtree; j++)
7224 compareAltNameEntry(&constraints->rgExcludedSubtree[j].Base,
7225 &encodedNameConstraints[i].constraints.rgExcludedSubtree[j].Base);
7228 LocalFree(constraints);
7233 static WCHAR noticeText[] = { 'T','h','i','s',' ','i','s',' ','a',' ',
7234 'n','o','t','i','c','e',0 };
7235 static const BYTE noticeWithDisplayText[] = {
7236 0x30,0x22,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,0x00,
7237 0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,0x74,
7238 0x00,0x69,0x00,0x63,0x00,0x65
7240 static char org[] = "Wine";
7241 static int noticeNumbers[] = { 2,3 };
7242 static BYTE noticeWithReference[] = {
7243 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7244 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7245 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7246 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7249 static void test_encodePolicyQualifierUserNotice(DWORD dwEncoding)
7254 CERT_POLICY_QUALIFIER_USER_NOTICE notice;
7255 CERT_POLICY_QUALIFIER_NOTICE_REFERENCE reference;
7257 memset(¬ice, 0, sizeof(notice));
7258 ret = pCryptEncodeObjectEx(dwEncoding,
7259 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, ¬ice, CRYPT_ENCODE_ALLOC_FLAG,
7261 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7263 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE encode support\n");
7266 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7269 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size);
7270 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
7273 notice.pszDisplayText = noticeText;
7274 ret = pCryptEncodeObjectEx(dwEncoding,
7275 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, ¬ice, CRYPT_ENCODE_ALLOC_FLAG,
7277 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7280 ok(sizeof(noticeWithDisplayText) == size, "unexpected size %d\n", size);
7281 ok(!memcmp(buf, noticeWithDisplayText, size), "unexpected value\n");
7284 reference.pszOrganization = org;
7285 reference.cNoticeNumbers = 2;
7286 reference.rgNoticeNumbers = noticeNumbers;
7287 notice.pNoticeReference = &reference;
7288 ret = pCryptEncodeObjectEx(dwEncoding,
7289 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, ¬ice, CRYPT_ENCODE_ALLOC_FLAG,
7291 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7294 ok(sizeof(noticeWithReference) == size, "unexpected size %d\n", size);
7295 ok(!memcmp(buf, noticeWithReference, size), "unexpected value\n");
7300 static void test_decodePolicyQualifierUserNotice(DWORD dwEncoding)
7303 CERT_POLICY_QUALIFIER_USER_NOTICE *notice;
7306 ret = pCryptDecodeObjectEx(dwEncoding,
7307 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7308 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7310 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7312 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE decode support\n");
7315 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7318 ok(notice->pszDisplayText == NULL, "unexpected display text\n");
7319 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7322 ret = pCryptDecodeObjectEx(dwEncoding,
7323 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7324 noticeWithDisplayText, sizeof(noticeWithDisplayText),
7325 CRYPT_DECODE_ALLOC_FLAG, NULL, ¬ice, &size);
7326 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7329 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7330 "unexpected display text\n");
7331 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7334 ret = pCryptDecodeObjectEx(dwEncoding,
7335 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7336 noticeWithReference, sizeof(noticeWithReference),
7337 CRYPT_DECODE_ALLOC_FLAG, NULL, ¬ice, &size);
7338 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7341 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7342 "unexpected display text\n");
7343 ok(notice->pNoticeReference != NULL, "expected a notice reference\n");
7344 if (notice->pNoticeReference)
7346 ok(!strcmp(notice->pNoticeReference->pszOrganization, org),
7347 "unexpected organization %s\n",
7348 notice->pNoticeReference->pszOrganization);
7349 ok(notice->pNoticeReference->cNoticeNumbers == 2,
7350 "expected 2 notice numbers, got %d\n",
7351 notice->pNoticeReference->cNoticeNumbers);
7352 ok(notice->pNoticeReference->rgNoticeNumbers[0] == noticeNumbers[0],
7353 "unexpected notice number %d\n",
7354 notice->pNoticeReference->rgNoticeNumbers[0]);
7355 ok(notice->pNoticeReference->rgNoticeNumbers[1] == noticeNumbers[1],
7356 "unexpected notice number %d\n",
7357 notice->pNoticeReference->rgNoticeNumbers[1]);
7363 static char oid_any_policy[] = "2.5.29.32.0";
7364 static const BYTE policiesWithAnyPolicy[] = {
7365 0x30,0x08,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00
7367 static char oid1[] = "1.2.3";
7368 static char oid_user_notice[] = "1.3.6.1.5.5.7.2.2";
7369 static const BYTE twoPolicies[] = {
7370 0x30,0x50,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00,0x30,0x46,0x06,0x02,0x2a,
7371 0x03,0x30,0x40,0x30,0x3e,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x02,
7372 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7373 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7374 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7375 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7378 static void test_encodeCertPolicies(DWORD dwEncoding)
7381 CERT_POLICIES_INFO info;
7382 CERT_POLICY_INFO policy[2];
7383 CERT_POLICY_QUALIFIER_INFO qualifier;
7387 memset(&info, 0, sizeof(info));
7388 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7389 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7390 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7393 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size);
7394 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
7397 memset(policy, 0, sizeof(policy));
7398 info.cPolicyInfo = 1;
7399 info.rgPolicyInfo = policy;
7400 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7401 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7402 ok(!ret && (GetLastError() == E_INVALIDARG ||
7403 GetLastError() == OSS_LIMITED /* Win9x/NT4 */),
7404 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
7405 policy[0].pszPolicyIdentifier = oid_any_policy;
7406 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7407 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7408 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7411 ok(sizeof(policiesWithAnyPolicy) == size, "unexpected size %d\n", size);
7412 ok(!memcmp(buf, policiesWithAnyPolicy, size), "unexpected value\n");
7415 policy[1].pszPolicyIdentifier = oid1;
7416 memset(&qualifier, 0, sizeof(qualifier));
7417 qualifier.pszPolicyQualifierId = oid_user_notice;
7418 qualifier.Qualifier.cbData = sizeof(noticeWithReference);
7419 qualifier.Qualifier.pbData = noticeWithReference;
7420 policy[1].cPolicyQualifier = 1;
7421 policy[1].rgPolicyQualifier = &qualifier;
7422 info.cPolicyInfo = 2;
7423 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7424 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7425 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7428 ok(sizeof(twoPolicies) == size, "unexpected size %d\n", size);
7429 ok(!memcmp(buf, twoPolicies, size), "unexpected value\n");
7434 static void test_decodeCertPolicies(DWORD dwEncoding)
7437 CERT_POLICIES_INFO *info;
7440 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7441 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7443 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7446 ok(info->cPolicyInfo == 0, "unexpected policy info %d\n",
7450 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7451 policiesWithAnyPolicy, sizeof(policiesWithAnyPolicy),
7452 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7453 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7456 ok(info->cPolicyInfo == 1, "unexpected policy info %d\n",
7458 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy),
7459 "unexpected policy id %s\n",
7460 info->rgPolicyInfo[0].pszPolicyIdentifier);
7461 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0,
7462 "unexpected policy qualifier count %d\n",
7463 info->rgPolicyInfo[0].cPolicyQualifier);
7466 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7467 twoPolicies, sizeof(twoPolicies),
7468 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7469 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7472 ok(info->cPolicyInfo == 2, "unexpected policy info %d\n",
7474 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy),
7475 "unexpected policy id %s\n",
7476 info->rgPolicyInfo[0].pszPolicyIdentifier);
7477 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0,
7478 "unexpected policy qualifier count %d\n",
7479 info->rgPolicyInfo[0].cPolicyQualifier);
7480 ok(!strcmp(info->rgPolicyInfo[1].pszPolicyIdentifier, oid1),
7481 "unexpected policy id %s\n",
7482 info->rgPolicyInfo[1].pszPolicyIdentifier);
7483 ok(info->rgPolicyInfo[1].cPolicyQualifier == 1,
7484 "unexpected policy qualifier count %d\n",
7485 info->rgPolicyInfo[1].cPolicyQualifier);
7487 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId,
7488 oid_user_notice), "unexpected policy qualifier id %s\n",
7489 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId);
7490 ok(info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData ==
7491 sizeof(noticeWithReference), "unexpected qualifier size %d\n",
7492 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData);
7494 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.pbData,
7495 noticeWithReference, sizeof(noticeWithReference)),
7496 "unexpected qualifier value\n");
7501 static const BYTE policyMappingWithOneMapping[] = {
7502 0x30,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04 };
7503 static const BYTE policyMappingWithTwoMappings[] = {
7504 0x30,0x14,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04,0x30,0x08,0x06,
7505 0x02,0x2b,0x04,0x06,0x02,0x55,0x06 };
7506 static const LPCSTR mappingOids[] = { X509_POLICY_MAPPINGS,
7507 szOID_POLICY_MAPPINGS, szOID_LEGACY_POLICY_MAPPINGS };
7509 static void test_encodeCertPolicyMappings(DWORD dwEncoding)
7511 static char oid2[] = "2.3.4";
7512 static char oid3[] = "1.3.4";
7513 static char oid4[] = "2.5.6";
7515 CERT_POLICY_MAPPINGS_INFO info = { 0 };
7516 CERT_POLICY_MAPPING mapping[2];
7520 /* Each of the mapping OIDs is equivalent, so check with all of them */
7521 for (i = 0; i < sizeof(mappingOids) / sizeof(mappingOids[0]); i++)
7523 memset(&info, 0, sizeof(info));
7524 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7525 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7526 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7529 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
7530 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
7531 "unexpected value\n");
7534 mapping[0].pszIssuerDomainPolicy = NULL;
7535 mapping[0].pszSubjectDomainPolicy = NULL;
7536 info.cPolicyMapping = 1;
7537 info.rgPolicyMapping = mapping;
7538 SetLastError(0xdeadbeef);
7539 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7540 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7541 ok(!ret && GetLastError() == E_INVALIDARG,
7542 "expected E_INVALIDARG, got %08x\n", GetLastError());
7543 mapping[0].pszIssuerDomainPolicy = oid1;
7544 mapping[0].pszSubjectDomainPolicy = oid2;
7545 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7546 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7547 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7550 ok(size == sizeof(policyMappingWithOneMapping),
7551 "unexpected size %d\n", size);
7552 ok(!memcmp(buf, policyMappingWithOneMapping, size),
7553 "unexpected value\n");
7556 mapping[1].pszIssuerDomainPolicy = oid3;
7557 mapping[1].pszSubjectDomainPolicy = oid4;
7558 info.cPolicyMapping = 2;
7559 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7560 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7561 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7564 ok(size == sizeof(policyMappingWithTwoMappings),
7565 "unexpected size %d\n", size);
7566 ok(!memcmp(buf, policyMappingWithTwoMappings, size),
7567 "unexpected value\n");
7573 static void test_decodeCertPolicyMappings(DWORD dwEncoding)
7576 CERT_POLICY_MAPPINGS_INFO *info;
7579 /* Each of the mapping OIDs is equivalent, so check with all of them */
7580 for (i = 0; i < sizeof(mappingOids) / sizeof(mappingOids[0]); i++)
7582 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7583 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7585 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7588 ok(info->cPolicyMapping == 0,
7589 "expected 0 policy mappings, got %d\n", info->cPolicyMapping);
7592 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7593 policyMappingWithOneMapping, sizeof(policyMappingWithOneMapping),
7594 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7595 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7598 ok(info->cPolicyMapping == 1,
7599 "expected 1 policy mappings, got %d\n", info->cPolicyMapping);
7600 ok(!strcmp(info->rgPolicyMapping[0].pszIssuerDomainPolicy, "1.2.3"),
7601 "unexpected issuer policy %s\n",
7602 info->rgPolicyMapping[0].pszIssuerDomainPolicy);
7603 ok(!strcmp(info->rgPolicyMapping[0].pszSubjectDomainPolicy,
7604 "2.3.4"), "unexpected subject policy %s\n",
7605 info->rgPolicyMapping[0].pszSubjectDomainPolicy);
7608 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7609 policyMappingWithTwoMappings, sizeof(policyMappingWithTwoMappings),
7610 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7611 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7614 ok(info->cPolicyMapping == 2,
7615 "expected 2 policy mappings, got %d\n", info->cPolicyMapping);
7616 ok(!strcmp(info->rgPolicyMapping[0].pszIssuerDomainPolicy, "1.2.3"),
7617 "unexpected issuer policy %s\n",
7618 info->rgPolicyMapping[0].pszIssuerDomainPolicy);
7619 ok(!strcmp(info->rgPolicyMapping[0].pszSubjectDomainPolicy,
7620 "2.3.4"), "unexpected subject policy %s\n",
7621 info->rgPolicyMapping[0].pszSubjectDomainPolicy);
7622 ok(!strcmp(info->rgPolicyMapping[1].pszIssuerDomainPolicy, "1.3.4"),
7623 "unexpected issuer policy %s\n",
7624 info->rgPolicyMapping[1].pszIssuerDomainPolicy);
7625 ok(!strcmp(info->rgPolicyMapping[1].pszSubjectDomainPolicy,
7626 "2.5.6"), "unexpected subject policy %s\n",
7627 info->rgPolicyMapping[1].pszSubjectDomainPolicy);
7633 static const BYTE policyConstraintsWithRequireExplicit[] = {
7634 0x30,0x03,0x80,0x01,0x00 };
7635 static const BYTE policyConstraintsWithInhibitMapping[] = {
7636 0x30,0x03,0x81,0x01,0x01 };
7637 static const BYTE policyConstraintsWithBoth[] = {
7638 0x30,0x06,0x80,0x01,0x01,0x81,0x01,0x01 };
7640 static void test_encodeCertPolicyConstraints(DWORD dwEncoding)
7642 CERT_POLICY_CONSTRAINTS_INFO info = { 0 };
7647 /* Even though RFC 5280 explicitly states CAs must not issue empty
7648 * policy constraints (section 4.2.1.11), the API doesn't prevent it.
7650 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7651 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7652 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7655 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
7656 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
7657 "unexpected value\n");
7660 /* If fRequireExplicitPolicy is set but dwRequireExplicitPolicySkipCerts
7661 * is not, then a skip of 0 is encoded.
7663 info.fRequireExplicitPolicy = TRUE;
7664 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7665 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7666 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7669 ok(size == sizeof(policyConstraintsWithRequireExplicit),
7670 "unexpected size %d\n", size);
7671 ok(!memcmp(buf, policyConstraintsWithRequireExplicit,
7672 sizeof(policyConstraintsWithRequireExplicit)), "unexpected value\n");
7675 /* With inhibit policy mapping */
7676 info.fRequireExplicitPolicy = FALSE;
7677 info.dwRequireExplicitPolicySkipCerts = 0;
7678 info.fInhibitPolicyMapping = TRUE;
7679 info.dwInhibitPolicyMappingSkipCerts = 1;
7680 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7681 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7682 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7685 ok(size == sizeof(policyConstraintsWithInhibitMapping),
7686 "unexpected size %d\n", size);
7687 ok(!memcmp(buf, policyConstraintsWithInhibitMapping,
7688 sizeof(policyConstraintsWithInhibitMapping)), "unexpected value\n");
7692 info.fRequireExplicitPolicy = TRUE;
7693 info.dwRequireExplicitPolicySkipCerts = 1;
7694 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7695 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7696 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7699 ok(size == sizeof(policyConstraintsWithBoth), "unexpected size %d\n",
7701 ok(!memcmp(buf, policyConstraintsWithBoth,
7702 sizeof(policyConstraintsWithBoth)), "unexpected value\n");
7707 static void test_decodeCertPolicyConstraints(DWORD dwEncoding)
7709 CERT_POLICY_CONSTRAINTS_INFO *info;
7713 /* Again, even though CAs must not issue such constraints, they can be
7716 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7717 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7719 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7722 ok(!info->fRequireExplicitPolicy,
7723 "expected require explicit = FALSE\n");
7724 ok(!info->fInhibitPolicyMapping,
7725 "expected implicit mapping = FALSE\n");
7728 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7729 policyConstraintsWithRequireExplicit,
7730 sizeof(policyConstraintsWithRequireExplicit), CRYPT_DECODE_ALLOC_FLAG,
7731 NULL, &info, &size);
7732 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7735 ok(info->fRequireExplicitPolicy,
7736 "expected require explicit = TRUE\n");
7737 ok(info->dwRequireExplicitPolicySkipCerts == 0, "expected 0, got %d\n",
7738 info->dwRequireExplicitPolicySkipCerts);
7739 ok(!info->fInhibitPolicyMapping,
7740 "expected implicit mapping = FALSE\n");
7743 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7744 policyConstraintsWithInhibitMapping,
7745 sizeof(policyConstraintsWithInhibitMapping), CRYPT_DECODE_ALLOC_FLAG,
7746 NULL, &info, &size);
7747 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7750 ok(!info->fRequireExplicitPolicy,
7751 "expected require explicit = FALSE\n");
7752 ok(info->fInhibitPolicyMapping,
7753 "expected implicit mapping = TRUE\n");
7754 ok(info->dwInhibitPolicyMappingSkipCerts == 1, "expected 1, got %d\n",
7755 info->dwInhibitPolicyMappingSkipCerts);
7758 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7759 policyConstraintsWithBoth, sizeof(policyConstraintsWithBoth),
7760 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7761 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7764 ok(info->fRequireExplicitPolicy,
7765 "expected require explicit = TRUE\n");
7766 ok(info->dwRequireExplicitPolicySkipCerts == 1, "expected 1, got %d\n",
7767 info->dwRequireExplicitPolicySkipCerts);
7768 ok(info->fInhibitPolicyMapping,
7769 "expected implicit mapping = TRUE\n");
7770 ok(info->dwInhibitPolicyMappingSkipCerts == 1, "expected 1, got %d\n",
7771 info->dwInhibitPolicyMappingSkipCerts);
7776 /* Free *pInfo with HeapFree */
7777 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
7784 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
7786 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size);
7787 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7788 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7789 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL,
7791 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7792 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7793 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL,
7795 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7796 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7797 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7798 0, NULL, NULL, &size);
7799 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7800 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7801 /* Test with no key */
7802 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7803 0, NULL, NULL, &size);
7804 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n",
7806 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
7807 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
7810 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
7811 NULL, 0, NULL, NULL, &size);
7812 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
7813 *pInfo = HeapAlloc(GetProcessHeap(), 0, size);
7816 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
7817 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size);
7818 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n",
7822 /* By default (we passed NULL as the OID) the OID is
7825 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA),
7826 "Expected %s, got %s\n", szOID_RSA_RSA,
7827 (*pInfo)->Algorithm.pszObjId);
7831 CryptDestroyKey(key);
7834 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
7835 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
7836 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
7837 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7838 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7839 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7840 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
7841 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
7842 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7843 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7844 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7845 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
7846 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
7847 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
7848 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
7849 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
7850 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
7851 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
7852 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
7853 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
7854 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
7855 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
7856 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
7857 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
7858 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
7860 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info)
7864 PCCERT_CONTEXT context;
7869 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
7870 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
7871 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
7872 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7875 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key);
7876 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7877 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7878 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key);
7879 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7880 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7881 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL,
7883 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7884 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7886 /* Export key with standard algorithm (CALG_RSA_KEYX) */
7887 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7889 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7891 dwSize = sizeof(ai);
7892 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7893 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7896 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7897 ok(ai == CALG_RSA_KEYX, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai);
7900 CryptDestroyKey(key);
7902 /* Repeat with forced algorithm */
7903 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, CALG_RSA_SIGN, 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_SIGN, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai);
7916 CryptDestroyKey(key);
7918 /* Test importing a public key from a certificate context */
7919 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert,
7920 sizeof(expiredCert));
7921 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
7925 ok(!strcmp(szOID_RSA_RSA,
7926 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId),
7927 "Expected %s, got %s\n", szOID_RSA_RSA,
7928 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
7929 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING,
7930 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
7931 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7932 CryptDestroyKey(key);
7933 CertFreeCertificateContext(context);
7937 static const char cspName[] = "WineCryptTemp";
7939 static void testPortPublicKeyInfo(void)
7943 PCERT_PUBLIC_KEY_INFO info = NULL;
7945 /* Just in case a previous run failed, delete this thing */
7946 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7947 CRYPT_DELETEKEYSET);
7948 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7951 testExportPublicKey(csp, &info);
7952 testImportPublicKey(csp, info);
7954 HeapFree(GetProcessHeap(), 0, info);
7955 CryptReleaseContext(csp, 0);
7956 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7957 CRYPT_DELETEKEYSET);
7962 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
7963 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING };
7967 hCrypt32 = GetModuleHandleA("crypt32.dll");
7968 pCryptDecodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptDecodeObjectEx");
7969 pCryptEncodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptEncodeObjectEx");
7970 if (!pCryptDecodeObjectEx || !pCryptEncodeObjectEx)
7972 win_skip("CryptDecodeObjectEx() is not available\n");
7976 for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++)
7978 test_encodeInt(encodings[i]);
7979 test_decodeInt(encodings[i]);
7980 test_encodeEnumerated(encodings[i]);
7981 test_decodeEnumerated(encodings[i]);
7982 test_encodeFiletime(encodings[i]);
7983 test_decodeFiletime(encodings[i]);
7984 test_encodeName(encodings[i]);
7985 test_decodeName(encodings[i]);
7986 test_encodeUnicodeName(encodings[i]);
7987 test_decodeUnicodeName(encodings[i]);
7988 test_encodeNameValue(encodings[i]);
7989 test_decodeNameValue(encodings[i]);
7990 test_encodeUnicodeNameValue(encodings[i]);
7991 test_decodeUnicodeNameValue(encodings[i]);
7992 test_encodeAltName(encodings[i]);
7993 test_decodeAltName(encodings[i]);
7994 test_encodeOctets(encodings[i]);
7995 test_decodeOctets(encodings[i]);
7996 test_encodeBits(encodings[i]);
7997 test_decodeBits(encodings[i]);
7998 test_encodeBasicConstraints(encodings[i]);
7999 test_decodeBasicConstraints(encodings[i]);
8000 test_encodeRsaPublicKey(encodings[i]);
8001 test_decodeRsaPublicKey(encodings[i]);
8002 test_encodeSequenceOfAny(encodings[i]);
8003 test_decodeSequenceOfAny(encodings[i]);
8004 test_encodeExtensions(encodings[i]);
8005 test_decodeExtensions(encodings[i]);
8006 test_encodePublicKeyInfo(encodings[i]);
8007 test_decodePublicKeyInfo(encodings[i]);
8008 test_encodeCertToBeSigned(encodings[i]);
8009 test_decodeCertToBeSigned(encodings[i]);
8010 test_encodeCert(encodings[i]);
8011 test_decodeCert(encodings[i]);
8012 test_encodeCRLDistPoints(encodings[i]);
8013 test_decodeCRLDistPoints(encodings[i]);
8014 test_encodeCRLIssuingDistPoint(encodings[i]);
8015 test_decodeCRLIssuingDistPoint(encodings[i]);
8016 test_encodeCRLToBeSigned(encodings[i]);
8017 test_decodeCRLToBeSigned(encodings[i]);
8018 test_encodeEnhancedKeyUsage(encodings[i]);
8019 test_decodeEnhancedKeyUsage(encodings[i]);
8020 test_encodeAuthorityKeyId(encodings[i]);
8021 test_decodeAuthorityKeyId(encodings[i]);
8022 test_encodeAuthorityKeyId2(encodings[i]);
8023 test_decodeAuthorityKeyId2(encodings[i]);
8024 test_encodeAuthorityInfoAccess(encodings[i]);
8025 test_decodeAuthorityInfoAccess(encodings[i]);
8026 test_encodeCTL(encodings[i]);
8027 test_decodeCTL(encodings[i]);
8028 test_encodePKCSContentInfo(encodings[i]);
8029 test_decodePKCSContentInfo(encodings[i]);
8030 test_encodePKCSAttribute(encodings[i]);
8031 test_decodePKCSAttribute(encodings[i]);
8032 test_encodePKCSAttributes(encodings[i]);
8033 test_decodePKCSAttributes(encodings[i]);
8034 test_encodePKCSSMimeCapabilities(encodings[i]);
8035 test_decodePKCSSMimeCapabilities(encodings[i]);
8036 test_encodePKCSSignerInfo(encodings[i]);
8037 test_decodePKCSSignerInfo(encodings[i]);
8038 test_encodeCMSSignerInfo(encodings[i]);
8039 test_decodeCMSSignerInfo(encodings[i]);
8040 test_encodeNameConstraints(encodings[i]);
8041 test_decodeNameConstraints(encodings[i]);
8042 test_encodePolicyQualifierUserNotice(encodings[i]);
8043 test_decodePolicyQualifierUserNotice(encodings[i]);
8044 test_encodeCertPolicies(encodings[i]);
8045 test_decodeCertPolicies(encodings[i]);
8046 test_encodeCertPolicyMappings(encodings[i]);
8047 test_decodeCertPolicyMappings(encodings[i]);
8048 test_encodeCertPolicyConstraints(encodings[i]);
8049 test_decodeCertPolicyConstraints(encodings[i]);
8051 testPortPublicKeyInfo();