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.
1695 ok(!ret, "expected failure\n");
1696 /* An embedded bell character is allowed, however. */
1697 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1698 dns_embedded_bell, sizeof(dns_embedded_bell), CRYPT_DECODE_ALLOC_FLAG,
1699 NULL, &buf, &bufSize);
1700 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1703 info = (CERT_ALT_NAME_INFO *)buf;
1705 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1707 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1708 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1709 info->rgAltEntry[0].dwAltNameChoice);
1712 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1713 url_embedded_null, sizeof(dns_embedded_null), CRYPT_DECODE_ALLOC_FLAG,
1714 NULL, &buf, &bufSize);
1715 /* Again, fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned
1716 * about the particular failure, just that it doesn't decode.
1719 ok(!ret, "expected failure\n");
1722 struct UnicodeExpectedError
1730 static const WCHAR oneW[] = { '1',0 };
1731 static const WCHAR aW[] = { 'a',0 };
1732 static const WCHAR quoteW[] = { '"', 0 };
1734 static struct UnicodeExpectedError unicodeErrors[] = {
1735 { CERT_RDN_ANY_TYPE, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1736 { CERT_RDN_ENCODED_BLOB, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1737 { CERT_RDN_OCTET_STRING, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1738 { CERT_RDN_NUMERIC_STRING, aW, 0, CRYPT_E_INVALID_NUMERIC_STRING },
1739 { CERT_RDN_PRINTABLE_STRING, quoteW, 0, CRYPT_E_INVALID_PRINTABLE_STRING },
1740 { CERT_RDN_IA5_STRING, nihongoURL, 7, CRYPT_E_INVALID_IA5_STRING },
1743 struct UnicodeExpectedResult
1747 CRYPT_DATA_BLOB encoded;
1750 static BYTE oneNumeric[] = { 0x12, 0x01, 0x31 };
1751 static BYTE onePrintable[] = { 0x13, 0x01, 0x31 };
1752 static BYTE oneTeletex[] = { 0x14, 0x01, 0x31 };
1753 static BYTE oneVideotex[] = { 0x15, 0x01, 0x31 };
1754 static BYTE oneIA5[] = { 0x16, 0x01, 0x31 };
1755 static BYTE oneGraphic[] = { 0x19, 0x01, 0x31 };
1756 static BYTE oneVisible[] = { 0x1a, 0x01, 0x31 };
1757 static BYTE oneUniversal[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 };
1758 static BYTE oneGeneral[] = { 0x1b, 0x01, 0x31 };
1759 static BYTE oneBMP[] = { 0x1e, 0x02, 0x00, 0x31 };
1760 static BYTE oneUTF8[] = { 0x0c, 0x01, 0x31 };
1761 static BYTE nihongoT61[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,
1763 static BYTE nihongoGeneral[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1765 static BYTE nihongoBMP[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,
1766 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
1767 static BYTE nihongoUTF8[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1768 0xe2,0x89,0xaf,0xe5,0x9d,0x9b };
1770 static struct UnicodeExpectedResult unicodeResults[] = {
1771 { CERT_RDN_NUMERIC_STRING, oneW, { sizeof(oneNumeric), oneNumeric } },
1772 { CERT_RDN_PRINTABLE_STRING, oneW, { sizeof(onePrintable), onePrintable } },
1773 { CERT_RDN_TELETEX_STRING, oneW, { sizeof(oneTeletex), oneTeletex } },
1774 { CERT_RDN_VIDEOTEX_STRING, oneW, { sizeof(oneVideotex), oneVideotex } },
1775 { CERT_RDN_IA5_STRING, oneW, { sizeof(oneIA5), oneIA5 } },
1776 { CERT_RDN_GRAPHIC_STRING, oneW, { sizeof(oneGraphic), oneGraphic } },
1777 { CERT_RDN_VISIBLE_STRING, oneW, { sizeof(oneVisible), oneVisible } },
1778 { CERT_RDN_UNIVERSAL_STRING, oneW, { sizeof(oneUniversal), oneUniversal } },
1779 { CERT_RDN_GENERAL_STRING, oneW, { sizeof(oneGeneral), oneGeneral } },
1780 { CERT_RDN_BMP_STRING, oneW, { sizeof(oneBMP), oneBMP } },
1781 { CERT_RDN_UTF8_STRING, oneW, { sizeof(oneUTF8), oneUTF8 } },
1782 { CERT_RDN_BMP_STRING, nihongoURL, { sizeof(nihongoBMP), nihongoBMP } },
1783 { CERT_RDN_UTF8_STRING, nihongoURL, { sizeof(nihongoUTF8), nihongoUTF8 } },
1786 static struct UnicodeExpectedResult unicodeWeirdness[] = {
1787 { CERT_RDN_TELETEX_STRING, nihongoURL, { sizeof(nihongoT61), nihongoT61 } },
1788 { CERT_RDN_GENERAL_STRING, nihongoURL, { sizeof(nihongoGeneral), nihongoGeneral } },
1791 static void test_encodeUnicodeNameValue(DWORD dwEncoding)
1796 CERT_NAME_VALUE value;
1800 /* Crashes on win9x */
1801 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, NULL,
1802 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1803 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1804 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1806 /* Have to have a string of some sort */
1807 value.dwValueType = 0; /* aka CERT_RDN_ANY_TYPE */
1808 value.Value.pbData = NULL;
1809 value.Value.cbData = 0;
1810 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1811 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1812 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1813 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1814 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1815 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1816 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1817 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1818 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1819 value.dwValueType = CERT_RDN_ANY_TYPE;
1820 value.Value.pbData = (LPBYTE)oneW;
1821 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1822 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1823 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1824 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1825 value.Value.cbData = sizeof(oneW);
1826 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1827 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1828 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1829 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1830 /* An encoded string with specified length isn't good enough either */
1831 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1832 value.Value.pbData = oneUniversal;
1833 value.Value.cbData = sizeof(oneUniversal);
1834 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1835 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1836 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1837 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1838 /* More failure checking */
1839 value.Value.cbData = 0;
1840 for (i = 0; i < sizeof(unicodeErrors) / sizeof(unicodeErrors[0]); i++)
1842 value.Value.pbData = (LPBYTE)unicodeErrors[i].str;
1843 value.dwValueType = unicodeErrors[i].valueType;
1844 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1845 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1846 ok(!ret && GetLastError() == unicodeErrors[i].error,
1847 "Value type %d: expected %08x, got %08x\n", value.dwValueType,
1848 unicodeErrors[i].error, GetLastError());
1849 ok(size == unicodeErrors[i].errorIndex,
1850 "Expected error index %d, got %d\n", unicodeErrors[i].errorIndex,
1853 /* cbData can be zero if the string is NULL-terminated */
1854 value.Value.cbData = 0;
1855 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1857 value.Value.pbData = (LPBYTE)unicodeResults[i].str;
1858 value.dwValueType = unicodeResults[i].valueType;
1859 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1860 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1861 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
1862 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1865 ok(size == unicodeResults[i].encoded.cbData,
1866 "Value type %d: expected size %d, got %d\n",
1867 value.dwValueType, unicodeResults[i].encoded.cbData, size);
1868 ok(!memcmp(unicodeResults[i].encoded.pbData, buf, size),
1869 "Value type %d: unexpected value\n", value.dwValueType);
1873 /* These "encode," but they do so by truncating each unicode character
1874 * rather than properly encoding it. Kept separate from the proper results,
1875 * because the encoded forms won't decode to their original strings.
1877 for (i = 0; i < sizeof(unicodeWeirdness) / sizeof(unicodeWeirdness[0]); i++)
1879 value.Value.pbData = (LPBYTE)unicodeWeirdness[i].str;
1880 value.dwValueType = unicodeWeirdness[i].valueType;
1881 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1882 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1883 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1886 ok(size == unicodeWeirdness[i].encoded.cbData,
1887 "Value type %d: expected size %d, got %d\n",
1888 value.dwValueType, unicodeWeirdness[i].encoded.cbData, size);
1889 ok(!memcmp(unicodeWeirdness[i].encoded.pbData, buf, size),
1890 "Value type %d: unexpected value\n", value.dwValueType);
1896 static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
1898 if (n <= 0) return 0;
1899 while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
1900 return *str1 - *str2;
1903 static void test_decodeUnicodeNameValue(DWORD dwEncoding)
1907 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1913 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE,
1914 unicodeResults[i].encoded.pbData, unicodeResults[i].encoded.cbData,
1915 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
1916 ok(ret || broken(GetLastError() == CRYPT_E_NOT_CHAR_STRING /* Win9x */),
1917 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1920 PCERT_NAME_VALUE value = (PCERT_NAME_VALUE)buf;
1922 ok(value->dwValueType == unicodeResults[i].valueType,
1923 "Expected value type %d, got %d\n", unicodeResults[i].valueType,
1924 value->dwValueType);
1925 ok(!strncmpW((LPWSTR)value->Value.pbData, unicodeResults[i].str,
1926 value->Value.cbData / sizeof(WCHAR)),
1927 "Unexpected decoded value for index %d (value type %d)\n", i,
1928 unicodeResults[i].valueType);
1934 struct encodedOctets
1937 const BYTE *encoded;
1940 static const unsigned char bin46[] = { 'h','i',0 };
1941 static const unsigned char bin47[] = { 0x04,0x02,'h','i',0 };
1942 static const unsigned char bin48[] = {
1943 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1944 static const unsigned char bin49[] = {
1945 0x04,0x0f,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1946 static const unsigned char bin50[] = { 0 };
1947 static const unsigned char bin51[] = { 0x04,0x00,0 };
1949 static const struct encodedOctets octets[] = {
1955 static void test_encodeOctets(DWORD dwEncoding)
1957 CRYPT_DATA_BLOB blob;
1960 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1966 blob.cbData = strlen((const char*)octets[i].val);
1967 blob.pbData = (BYTE*)octets[i].val;
1968 ret = pCryptEncodeObjectEx(dwEncoding, X509_OCTET_STRING, &blob,
1969 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1970 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
1974 "Got unexpected type %d for octet string (expected 4)\n", buf[0]);
1975 ok(buf[1] == octets[i].encoded[1], "Got length %d, expected %d\n",
1976 buf[1], octets[i].encoded[1]);
1977 ok(!memcmp(buf + 1, octets[i].encoded + 1,
1978 octets[i].encoded[1] + 1), "Got unexpected value\n");
1984 static void test_decodeOctets(DWORD dwEncoding)
1988 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1994 ret = pCryptDecodeObjectEx(dwEncoding, X509_OCTET_STRING,
1995 octets[i].encoded, octets[i].encoded[1] + 2,
1996 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1997 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1998 ok(bufSize >= sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1],
1999 "Expected size >= %d, got %d\n",
2000 (int)sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1], bufSize);
2001 ok(buf != NULL, "Expected allocated buffer\n");
2004 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)buf;
2007 ok(!memcmp(blob->pbData, octets[i].val, blob->cbData),
2008 "Unexpected value\n");
2014 static const BYTE bytesToEncode[] = { 0xff, 0xff };
2019 const BYTE *encoded;
2021 const BYTE *decoded;
2024 static const unsigned char bin52[] = { 0x03,0x03,0x00,0xff,0xff };
2025 static const unsigned char bin53[] = { 0xff,0xff };
2026 static const unsigned char bin54[] = { 0x03,0x03,0x01,0xff,0xfe };
2027 static const unsigned char bin55[] = { 0xff,0xfe };
2028 static const unsigned char bin56[] = { 0x03,0x02,0x01,0xfe };
2029 static const unsigned char bin57[] = { 0xfe };
2030 static const unsigned char bin58[] = { 0x03,0x01,0x00 };
2032 static const struct encodedBits bits[] = {
2033 /* normal test cases */
2034 { 0, bin52, 2, bin53 },
2035 { 1, bin54, 2, bin55 },
2036 /* strange test case, showing cUnusedBits >= 8 is allowed */
2037 { 9, bin56, 1, bin57 },
2040 static void test_encodeBits(DWORD dwEncoding)
2044 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
2046 CRYPT_BIT_BLOB blob;
2051 blob.cbData = sizeof(bytesToEncode);
2052 blob.pbData = (BYTE *)bytesToEncode;
2053 blob.cUnusedBits = bits[i].cUnusedBits;
2054 ret = pCryptEncodeObjectEx(dwEncoding, X509_BITS, &blob,
2055 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2056 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2059 ok(bufSize == bits[i].encoded[1] + 2,
2060 "%d: Got unexpected size %d, expected %d\n", i, bufSize,
2061 bits[i].encoded[1] + 2);
2062 ok(!memcmp(buf, bits[i].encoded, bits[i].encoded[1] + 2),
2063 "%d: Unexpected value\n", i);
2069 static void test_decodeBits(DWORD dwEncoding)
2071 static const BYTE ber[] = "\x03\x02\x01\xff";
2072 static const BYTE berDecoded = 0xfe;
2079 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
2081 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, bits[i].encoded,
2082 bits[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
2084 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2087 CRYPT_BIT_BLOB *blob;
2089 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + bits[i].cbDecoded,
2090 "Got unexpected size %d\n", bufSize);
2091 blob = (CRYPT_BIT_BLOB *)buf;
2092 ok(blob->cbData == bits[i].cbDecoded,
2093 "Got unexpected length %d, expected %d\n", blob->cbData,
2095 if (blob->cbData && bits[i].cbDecoded)
2096 ok(!memcmp(blob->pbData, bits[i].decoded, bits[i].cbDecoded),
2097 "Unexpected value\n");
2101 /* special case: check that something that's valid in BER but not in DER
2102 * decodes successfully
2104 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, ber, ber[1] + 2,
2105 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2106 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2109 CRYPT_BIT_BLOB *blob;
2111 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + sizeof(berDecoded),
2112 "Got unexpected size %d\n", bufSize);
2113 blob = (CRYPT_BIT_BLOB *)buf;
2114 ok(blob->cbData == sizeof(berDecoded),
2115 "Got unexpected length %d\n", blob->cbData);
2117 ok(*blob->pbData == berDecoded, "Unexpected value\n");
2124 CERT_BASIC_CONSTRAINTS2_INFO info;
2125 const BYTE *encoded;
2128 static const unsigned char bin59[] = { 0x30,0x00 };
2129 static const unsigned char bin60[] = { 0x30,0x03,0x01,0x01,0xff };
2130 static const unsigned char bin61[] = { 0x30,0x03,0x02,0x01,0x00 };
2131 static const unsigned char bin62[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2132 static const struct Constraints2 constraints2[] = {
2133 /* empty constraints */
2134 { { FALSE, FALSE, 0}, bin59 },
2136 { { TRUE, FALSE, 0}, bin60 },
2137 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well,
2138 * but that's not the case
2140 { { FALSE, TRUE, 0}, bin61 },
2141 /* can be a CA and has path length constraints set */
2142 { { TRUE, TRUE, 1}, bin62 },
2145 static const BYTE emptyConstraint[] = { 0x30, 0x03, 0x03, 0x01, 0x00 };
2146 static const BYTE encodedDomainName[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11,
2147 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
2148 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
2149 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2150 static const BYTE constraintWithDomainName[] = { 0x30, 0x32, 0x03, 0x01, 0x00,
2151 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
2152 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30,
2153 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
2154 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2156 static void test_encodeBasicConstraints(DWORD dwEncoding)
2158 DWORD i, bufSize = 0;
2159 CERT_BASIC_CONSTRAINTS_INFO info = { { 0 } };
2160 CERT_NAME_BLOB nameBlob = { sizeof(encodedDomainName),
2161 (LPBYTE)encodedDomainName };
2165 /* First test with the simpler info2 */
2166 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2168 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2169 &constraints2[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf,
2171 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2174 ok(bufSize == constraints2[i].encoded[1] + 2,
2175 "Expected %d bytes, got %d\n", constraints2[i].encoded[1] + 2,
2177 ok(!memcmp(buf, constraints2[i].encoded,
2178 constraints2[i].encoded[1] + 2), "Unexpected value\n");
2182 /* Now test with more complex basic constraints */
2183 info.SubjectType.cbData = 0;
2184 info.fPathLenConstraint = FALSE;
2185 info.cSubtreesConstraint = 0;
2186 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2187 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2188 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2189 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2192 ok(bufSize == sizeof(emptyConstraint), "Wrong size %d\n", bufSize);
2193 ok(!memcmp(buf, emptyConstraint, sizeof(emptyConstraint)),
2194 "Unexpected value\n");
2197 /* None of the certs I examined had any subtree constraint, but I test one
2198 * anyway just in case.
2200 info.cSubtreesConstraint = 1;
2201 info.rgSubtreesConstraint = &nameBlob;
2202 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2203 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2204 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2205 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2208 ok(bufSize == sizeof(constraintWithDomainName), "Wrong size %d\n", bufSize);
2209 ok(!memcmp(buf, constraintWithDomainName,
2210 sizeof(constraintWithDomainName)), "Unexpected value\n");
2213 /* FIXME: test encoding with subject type. */
2216 static const unsigned char bin63[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 };
2218 static void test_decodeBasicConstraints(DWORD dwEncoding)
2220 static const BYTE inverted[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01,
2222 static const struct Constraints2 badBool = { { TRUE, TRUE, 1 }, bin63 };
2228 /* First test with simpler info2 */
2229 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2231 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2232 constraints2[i].encoded, constraints2[i].encoded[1] + 2,
2233 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2234 ok(ret, "CryptDecodeObjectEx failed for item %d: %08x\n", i,
2238 CERT_BASIC_CONSTRAINTS2_INFO *info =
2239 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2241 ok(!memcmp(info, &constraints2[i].info, sizeof(*info)),
2242 "Unexpected value for item %d\n", i);
2246 /* Check with the order of encoded elements inverted */
2248 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2249 inverted, inverted[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
2251 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2252 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2253 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2255 ok(!buf, "Expected buf to be set to NULL\n");
2256 /* Check with a non-DER bool */
2257 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2258 badBool.encoded, badBool.encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2260 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2263 CERT_BASIC_CONSTRAINTS2_INFO *info =
2264 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2266 ok(!memcmp(info, &badBool.info, sizeof(*info)), "Unexpected value\n");
2269 /* Check with a non-basic constraints value */
2270 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2271 encodedCommonName, encodedCommonName[1] + 2,
2272 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2273 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2274 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2275 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2277 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */
2278 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2279 emptyConstraint, sizeof(emptyConstraint), CRYPT_DECODE_ALLOC_FLAG, NULL,
2281 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2284 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2286 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2287 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2288 ok(info->cSubtreesConstraint == 0, "Expected no subtree constraints\n");
2291 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2292 constraintWithDomainName, sizeof(constraintWithDomainName),
2293 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2294 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2297 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2299 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2300 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2301 ok(info->cSubtreesConstraint == 1, "Expected a subtree constraint\n");
2302 if (info->cSubtreesConstraint && info->rgSubtreesConstraint)
2304 ok(info->rgSubtreesConstraint[0].cbData ==
2305 sizeof(encodedDomainName), "Wrong size %d\n",
2306 info->rgSubtreesConstraint[0].cbData);
2307 ok(!memcmp(info->rgSubtreesConstraint[0].pbData, encodedDomainName,
2308 sizeof(encodedDomainName)), "Unexpected value\n");
2314 /* These are terrible public keys of course, I'm just testing encoding */
2315 static const BYTE modulus1[] = { 0,0,0,1,1,1,1,1 };
2316 static const BYTE modulus2[] = { 1,1,1,1,1,0,0,0 };
2317 static const BYTE modulus3[] = { 0x80,1,1,1,1,0,0,0 };
2318 static const BYTE modulus4[] = { 1,1,1,1,1,0,0,0x80 };
2319 static const BYTE mod1_encoded[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 };
2320 static const BYTE mod2_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2321 static const BYTE mod3_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 };
2322 static const BYTE mod4_encoded[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2324 struct EncodedRSAPubKey
2326 const BYTE *modulus;
2328 const BYTE *encoded;
2329 size_t decodedModulusLen;
2332 struct EncodedRSAPubKey rsaPubKeys[] = {
2333 { modulus1, sizeof(modulus1), mod1_encoded, sizeof(modulus1) },
2334 { modulus2, sizeof(modulus2), mod2_encoded, 5 },
2335 { modulus3, sizeof(modulus3), mod3_encoded, 5 },
2336 { modulus4, sizeof(modulus4), mod4_encoded, 8 },
2339 static void test_encodeRsaPublicKey(DWORD dwEncoding)
2341 BYTE toEncode[sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + sizeof(modulus1)];
2342 BLOBHEADER *hdr = (BLOBHEADER *)toEncode;
2343 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(toEncode + sizeof(BLOBHEADER));
2346 DWORD bufSize = 0, i;
2348 /* Try with a bogus blob type */
2350 hdr->bVersion = CUR_BLOB_VERSION;
2352 hdr->aiKeyAlg = CALG_RSA_KEYX;
2353 rsaPubKey->magic = 0x31415352;
2354 rsaPubKey->bitlen = sizeof(modulus1) * 8;
2355 rsaPubKey->pubexp = 65537;
2356 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), modulus1,
2359 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2360 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2361 ok(!ret && GetLastError() == E_INVALIDARG,
2362 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2363 /* Now with a bogus reserved field */
2364 hdr->bType = PUBLICKEYBLOB;
2366 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2367 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2370 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2371 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2372 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2375 /* Now with a bogus blob version */
2378 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2379 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2382 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2383 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2384 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2387 /* And with a bogus alg ID */
2388 hdr->bVersion = CUR_BLOB_VERSION;
2389 hdr->aiKeyAlg = CALG_DES;
2390 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2391 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2394 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2395 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2396 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2399 /* Check a couple of RSA-related OIDs */
2400 hdr->aiKeyAlg = CALG_RSA_KEYX;
2401 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_RSA,
2402 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2403 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2404 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2405 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2406 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2407 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2408 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2409 /* Finally, all valid */
2410 hdr->aiKeyAlg = CALG_RSA_KEYX;
2411 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2413 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2414 rsaPubKeys[i].modulus, rsaPubKeys[i].modulusLen);
2415 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2416 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2417 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2420 ok(bufSize == rsaPubKeys[i].encoded[1] + 2,
2421 "Expected size %d, got %d\n", rsaPubKeys[i].encoded[1] + 2,
2423 ok(!memcmp(buf, rsaPubKeys[i].encoded, bufSize),
2424 "Unexpected value\n");
2430 static void test_decodeRsaPublicKey(DWORD dwEncoding)
2437 /* Try with a bad length */
2438 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2439 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1],
2440 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2441 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
2442 GetLastError() == OSS_MORE_INPUT /* Win9x/NT4 */),
2443 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n",
2445 /* Try with a couple of RSA-related OIDs */
2446 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_RSA,
2447 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2448 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2449 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2450 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2451 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2452 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2453 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2454 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2455 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2456 /* Now try success cases */
2457 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2460 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2461 rsaPubKeys[i].encoded, rsaPubKeys[i].encoded[1] + 2,
2462 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2463 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2466 BLOBHEADER *hdr = (BLOBHEADER *)buf;
2467 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER));
2469 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2470 rsaPubKeys[i].decodedModulusLen,
2471 "Wrong size %d\n", bufSize);
2472 ok(hdr->bType == PUBLICKEYBLOB,
2473 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB,
2475 ok(hdr->bVersion == CUR_BLOB_VERSION,
2476 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
2477 CUR_BLOB_VERSION, hdr->bVersion);
2478 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n",
2480 ok(hdr->aiKeyAlg == CALG_RSA_KEYX,
2481 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg);
2482 ok(rsaPubKey->magic == 0x31415352,
2483 "Expected magic RSA1, got %08x\n", rsaPubKey->magic);
2484 ok(rsaPubKey->bitlen == rsaPubKeys[i].decodedModulusLen * 8,
2485 "Wrong bit len %d\n", rsaPubKey->bitlen);
2486 ok(rsaPubKey->pubexp == 65537, "Expected pubexp 65537, got %d\n",
2488 ok(!memcmp(buf + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2489 rsaPubKeys[i].modulus, rsaPubKeys[i].decodedModulusLen),
2490 "Unexpected modulus\n");
2496 static const BYTE intSequence[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01,
2497 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02,
2498 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2500 static const BYTE mixedSequence[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
2501 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f,
2502 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02,
2503 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2505 static void test_encodeSequenceOfAny(DWORD dwEncoding)
2507 CRYPT_DER_BLOB blobs[sizeof(ints) / sizeof(ints[0])];
2508 CRYPT_SEQUENCE_OF_ANY seq;
2514 /* Encode a homogeneous sequence */
2515 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
2517 blobs[i].cbData = ints[i].encoded[1] + 2;
2518 blobs[i].pbData = (BYTE *)ints[i].encoded;
2520 seq.cValue = sizeof(ints) / sizeof(ints[0]);
2521 seq.rgValue = blobs;
2523 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2524 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2525 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2528 ok(bufSize == sizeof(intSequence), "Wrong size %d\n", bufSize);
2529 ok(!memcmp(buf, intSequence, intSequence[1] + 2), "Unexpected value\n");
2532 /* Change the type of the first element in the sequence, and give it
2535 blobs[0].cbData = times[0].encodedTime[1] + 2;
2536 blobs[0].pbData = (BYTE *)times[0].encodedTime;
2537 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2538 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2539 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2542 ok(bufSize == sizeof(mixedSequence), "Wrong size %d\n", bufSize);
2543 ok(!memcmp(buf, mixedSequence, mixedSequence[1] + 2),
2544 "Unexpected value\n");
2549 static void test_decodeSequenceOfAny(DWORD dwEncoding)
2555 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, intSequence,
2556 intSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2557 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2560 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2563 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2564 "Wrong elements %d\n", seq->cValue);
2565 for (i = 0; i < min(seq->cValue, sizeof(ints) / sizeof(ints[0])); i++)
2567 ok(seq->rgValue[i].cbData == ints[i].encoded[1] + 2,
2568 "Expected %d bytes, got %d\n", ints[i].encoded[1] + 2,
2569 seq->rgValue[i].cbData);
2570 ok(!memcmp(seq->rgValue[i].pbData, ints[i].encoded,
2571 ints[i].encoded[1] + 2), "Unexpected value\n");
2575 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, mixedSequence,
2576 mixedSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
2578 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2581 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2583 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2584 "Wrong elements %d\n", seq->cValue);
2585 /* Just check the first element since it's all that changed */
2586 ok(seq->rgValue[0].cbData == times[0].encodedTime[1] + 2,
2587 "Expected %d bytes, got %d\n", times[0].encodedTime[1] + 2,
2588 seq->rgValue[0].cbData);
2589 ok(!memcmp(seq->rgValue[0].pbData, times[0].encodedTime,
2590 times[0].encodedTime[1] + 2), "Unexpected value\n");
2595 struct encodedExtensions
2597 CERT_EXTENSIONS exts;
2598 const BYTE *encoded;
2601 static BYTE crit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2602 static BYTE noncrit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2603 static CHAR oid_basic_constraints2[] = szOID_BASIC_CONSTRAINTS2;
2604 static CERT_EXTENSION criticalExt =
2605 { oid_basic_constraints2, TRUE, { 8, crit_ext_data } };
2606 static CERT_EXTENSION nonCriticalExt =
2607 { oid_basic_constraints2, FALSE, { 8, noncrit_ext_data } };
2608 static CHAR oid_short[] = "1.1";
2609 static CERT_EXTENSION extWithShortOid =
2610 { oid_short, FALSE, { 0, NULL } };
2612 static const BYTE ext0[] = { 0x30,0x00 };
2613 static const BYTE ext1[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2614 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2615 static const BYTE ext2[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2616 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2617 static const BYTE ext3[] = { 0x30,0x07,0x30,0x05,0x06,0x01,0x29,0x04,0x00 };
2619 static const struct encodedExtensions exts[] = {
2620 { { 0, NULL }, ext0 },
2621 { { 1, &criticalExt }, ext1 },
2622 { { 1, &nonCriticalExt }, ext2 },
2623 { { 1, &extWithShortOid }, ext3 }
2626 static void test_encodeExtensions(DWORD dwEncoding)
2630 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2636 ret = pCryptEncodeObjectEx(dwEncoding, X509_EXTENSIONS, &exts[i].exts,
2637 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2638 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2641 ok(bufSize == exts[i].encoded[1] + 2,
2642 "Expected %d bytes, got %d\n", exts[i].encoded[1] + 2, bufSize);
2643 ok(!memcmp(buf, exts[i].encoded, exts[i].encoded[1] + 2),
2644 "Unexpected value\n");
2650 static void test_decodeExtensions(DWORD dwEncoding)
2654 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2660 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS,
2661 exts[i].encoded, exts[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2662 NULL, &buf, &bufSize);
2663 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2666 CERT_EXTENSIONS *ext = (CERT_EXTENSIONS *)buf;
2669 ok(ext->cExtension == exts[i].exts.cExtension,
2670 "Expected %d extensions, see %d\n", exts[i].exts.cExtension,
2672 for (j = 0; j < min(ext->cExtension, exts[i].exts.cExtension); j++)
2674 ok(!strcmp(ext->rgExtension[j].pszObjId,
2675 exts[i].exts.rgExtension[j].pszObjId),
2676 "Expected OID %s, got %s\n",
2677 exts[i].exts.rgExtension[j].pszObjId,
2678 ext->rgExtension[j].pszObjId);
2679 ok(!memcmp(ext->rgExtension[j].Value.pbData,
2680 exts[i].exts.rgExtension[j].Value.pbData,
2681 exts[i].exts.rgExtension[j].Value.cbData),
2682 "Unexpected value\n");
2689 /* MS encodes public key info with a NULL if the algorithm identifier's
2690 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2691 * it encodes them by omitting the algorithm parameters. It accepts either
2692 * form for decoding.
2694 struct encodedPublicKey
2696 CERT_PUBLIC_KEY_INFO info;
2697 const BYTE *encoded;
2698 const BYTE *encodedNoNull;
2699 CERT_PUBLIC_KEY_INFO decoded;
2702 static const BYTE aKey[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2704 static const BYTE params[] = { 0x02, 0x01, 0x01 };
2706 static const unsigned char bin64[] = {
2707 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2708 static const unsigned char bin65[] = {
2709 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2710 static const unsigned char bin66[] = {
2711 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2712 static const unsigned char bin67[] = {
2713 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2714 static const unsigned char bin68[] = {
2715 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01,
2716 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2717 static const unsigned char bin69[] = {
2718 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2719 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2720 static const unsigned char bin70[] = {
2721 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2722 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2724 static const unsigned char bin71[] = {
2725 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2726 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2728 static unsigned char bin72[] = { 0x05,0x00};
2730 static CHAR oid_bogus[] = "1.2.3",
2731 oid_rsa[] = szOID_RSA;
2733 static const struct encodedPublicKey pubKeys[] = {
2734 /* with a bogus OID */
2735 { { { oid_bogus, { 0, NULL } }, { 0, NULL, 0 } },
2737 { { oid_bogus, { 2, bin72 } }, { 0, NULL, 0 } } },
2738 /* some normal keys */
2739 { { { oid_rsa, { 0, NULL } }, { 0, NULL, 0} },
2741 { { oid_rsa, { 2, bin72 } }, { 0, NULL, 0 } } },
2742 { { { oid_rsa, { 0, NULL } }, { sizeof(aKey), (BYTE *)aKey, 0} },
2744 { { oid_rsa, { 2, bin72 } }, { sizeof(aKey), (BYTE *)aKey, 0} } },
2745 /* with add'l parameters--note they must be DER-encoded */
2746 { { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2747 (BYTE *)aKey, 0 } },
2749 { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2750 (BYTE *)aKey, 0 } } },
2753 static void test_encodePublicKeyInfo(DWORD dwEncoding)
2757 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2763 ret = pCryptEncodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2764 &pubKeys[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf,
2766 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2767 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2770 ok(bufSize == pubKeys[i].encoded[1] + 2,
2771 "Expected %d bytes, got %d\n", pubKeys[i].encoded[1] + 2, bufSize);
2772 if (bufSize == pubKeys[i].encoded[1] + 2)
2773 ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2),
2774 "Unexpected value\n");
2780 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO *expected,
2781 const CERT_PUBLIC_KEY_INFO *got)
2783 ok(!strcmp(expected->Algorithm.pszObjId, got->Algorithm.pszObjId),
2784 "Expected OID %s, got %s\n", expected->Algorithm.pszObjId,
2785 got->Algorithm.pszObjId);
2786 ok(expected->Algorithm.Parameters.cbData ==
2787 got->Algorithm.Parameters.cbData,
2788 "Expected parameters of %d bytes, got %d\n",
2789 expected->Algorithm.Parameters.cbData, got->Algorithm.Parameters.cbData);
2790 if (expected->Algorithm.Parameters.cbData)
2791 ok(!memcmp(expected->Algorithm.Parameters.pbData,
2792 got->Algorithm.Parameters.pbData, got->Algorithm.Parameters.cbData),
2793 "Unexpected algorithm parameters\n");
2794 ok(expected->PublicKey.cbData == got->PublicKey.cbData,
2795 "Expected public key of %d bytes, got %d\n",
2796 expected->PublicKey.cbData, got->PublicKey.cbData);
2797 if (expected->PublicKey.cbData)
2798 ok(!memcmp(expected->PublicKey.pbData, got->PublicKey.pbData,
2799 got->PublicKey.cbData), "Unexpected public key value\n");
2802 static void test_decodePublicKeyInfo(DWORD dwEncoding)
2804 static const BYTE bogusPubKeyInfo[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
2805 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
2806 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
2807 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2813 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2815 /* The NULL form decodes to the decoded member */
2816 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2817 pubKeys[i].encoded, pubKeys[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2818 NULL, &buf, &bufSize);
2819 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2822 comparePublicKeyInfo(&pubKeys[i].decoded,
2823 (CERT_PUBLIC_KEY_INFO *)buf);
2826 /* The non-NULL form decodes to the original */
2827 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2828 pubKeys[i].encodedNoNull, pubKeys[i].encodedNoNull[1] + 2,
2829 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2830 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2833 comparePublicKeyInfo(&pubKeys[i].info, (CERT_PUBLIC_KEY_INFO *)buf);
2837 /* Test with bogus (not valid DER) parameters */
2838 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2839 bogusPubKeyInfo, bogusPubKeyInfo[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2840 NULL, &buf, &bufSize);
2841 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2842 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2843 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2847 static const BYTE v1Cert[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
2848 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2849 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
2850 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
2851 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2852 static const BYTE v2Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02,
2853 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2854 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2855 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2856 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2857 static const BYTE v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2858 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2859 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2860 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2861 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2862 static const BYTE v4Cert[] = {
2863 0x30,0x38,0xa0,0x03,0x02,0x01,0x03,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,
2864 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
2865 0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
2866 0x30,0x30,0x30,0x5a,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00 };
2867 static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
2868 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2869 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2870 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2871 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2872 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2873 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2874 static const BYTE v1CertWithSerial[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
2875 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2876 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2877 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2878 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2879 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2880 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2881 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2882 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
2883 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
2884 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
2885 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
2886 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
2887 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
2888 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
2889 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
2890 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2891 static const BYTE v1CertWithPubKey[] = {
2892 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2893 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2894 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2895 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2896 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2897 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2898 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2899 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2900 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
2901 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
2903 static const BYTE v1CertWithPubKeyNoNull[] = {
2904 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2905 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2906 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2907 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2908 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2909 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2910 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2911 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2912 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
2913 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2914 static const BYTE v1CertWithSubjectKeyId[] = {
2915 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2916 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2917 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2918 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2919 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2920 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2921 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
2922 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2923 0x4c,0x61,0x6e,0x67,0x00 };
2924 static const BYTE v1CertWithIssuerUniqueId[] = {
2925 0x30,0x38,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
2926 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
2927 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
2928 0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x81,0x02,0x00,0x01 };
2929 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueId[] = {
2930 0x30,0x81,0x99,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2931 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2932 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2933 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2934 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2935 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2936 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2937 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2938 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,
2939 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
2940 0x01,0x01,0xff,0x02,0x01,0x01 };
2941 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull[] = {
2942 0x30,0x81,0x97,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2943 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2944 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2945 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2946 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2947 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2948 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2949 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2950 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
2951 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
2952 0xff,0x02,0x01,0x01 };
2954 static const BYTE serialNum[] = { 0x01 };
2956 static void test_encodeCertToBeSigned(DWORD dwEncoding)
2961 CERT_INFO info = { 0 };
2962 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2963 static char oid_subject_key_identifier[] = szOID_SUBJECT_KEY_IDENTIFIER;
2968 /* Test with NULL pvStructInfo (crashes on win9x) */
2969 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL,
2970 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
2971 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2972 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2974 /* Test with a V1 cert */
2975 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2976 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
2977 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2978 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2981 ok(size == v1Cert[1] + 2, "Expected size %d, got %d\n",
2982 v1Cert[1] + 2, size);
2983 ok(!memcmp(buf, v1Cert, size), "Got unexpected value\n");
2987 info.dwVersion = CERT_V2;
2988 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2989 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
2990 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2991 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2994 ok(size == sizeof(v2Cert), "Wrong size %d\n", size);
2995 ok(!memcmp(buf, v2Cert, size), "Got unexpected value\n");
2999 info.dwVersion = CERT_V3;
3000 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3001 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3002 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3003 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3006 ok(size == sizeof(v3Cert), "Wrong size %d\n", size);
3007 ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n");
3011 info.dwVersion = 3; /* Not a typo, CERT_V3 is 2 */
3012 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3013 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3016 ok(size == sizeof(v4Cert), "Wrong size %d\n", size);
3017 ok(!memcmp(buf, v4Cert, size), "Unexpected value\n");
3020 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
3021 * API doesn't prevent it)
3023 info.dwVersion = CERT_V1;
3024 info.cExtension = 1;
3025 info.rgExtension = &criticalExt;
3026 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3027 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3028 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3029 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3032 ok(size == sizeof(v1CertWithConstraints), "Wrong size %d\n", size);
3033 ok(!memcmp(buf, v1CertWithConstraints, size), "Got unexpected value\n");
3036 /* test v1 cert with a serial number */
3037 info.SerialNumber.cbData = sizeof(serialNum);
3038 info.SerialNumber.pbData = (BYTE *)serialNum;
3039 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3040 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3043 ok(size == sizeof(v1CertWithSerial), "Wrong size %d\n", size);
3044 ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n");
3047 /* Test v1 cert with an issuer name, serial number, and issuer unique id */
3048 info.dwVersion = CERT_V1;
3049 info.cExtension = 0;
3050 info.IssuerUniqueId.cbData = sizeof(serialNum);
3051 info.IssuerUniqueId.pbData = (BYTE *)serialNum;
3052 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3053 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3054 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3057 ok(size == sizeof(v1CertWithIssuerUniqueId), "Wrong size %d\n", size);
3058 ok(!memcmp(buf, v1CertWithIssuerUniqueId, size),
3059 "Got unexpected value\n");
3062 /* Test v1 cert with an issuer name, a subject name, and a serial number */
3063 info.IssuerUniqueId.cbData = 0;
3064 info.IssuerUniqueId.pbData = NULL;
3065 info.cExtension = 1;
3066 info.rgExtension = &criticalExt;
3067 info.Issuer.cbData = sizeof(encodedCommonName);
3068 info.Issuer.pbData = (BYTE *)encodedCommonName;
3069 info.Subject.cbData = sizeof(encodedCommonName);
3070 info.Subject.pbData = (BYTE *)encodedCommonName;
3071 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3072 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3075 ok(size == sizeof(bigCert), "Wrong size %d\n", size);
3076 ok(!memcmp(buf, bigCert, size), "Got unexpected value\n");
3079 /* Add a public key */
3080 info.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3081 info.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
3082 info.SubjectPublicKeyInfo.PublicKey.pbData = (LPBYTE)aKey;
3083 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3084 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3087 ok(size == sizeof(v1CertWithPubKey) ||
3088 size == sizeof(v1CertWithPubKeyNoNull), "Wrong size %d\n", size);
3089 if (size == sizeof(v1CertWithPubKey))
3090 ok(!memcmp(buf, v1CertWithPubKey, size), "Got unexpected value\n");
3091 else if (size == sizeof(v1CertWithPubKeyNoNull))
3092 ok(!memcmp(buf, v1CertWithPubKeyNoNull, size),
3093 "Got unexpected value\n");
3096 /* Again add an issuer unique id */
3097 info.IssuerUniqueId.cbData = sizeof(serialNum);
3098 info.IssuerUniqueId.pbData = (BYTE *)serialNum;
3099 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3100 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3101 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3104 ok(size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId) ||
3105 size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull),
3106 "Wrong size %d\n", size);
3107 if (size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId))
3108 ok(!memcmp(buf, v1CertWithSubjectIssuerSerialAndIssuerUniqueId,
3109 size), "unexpected value\n");
3111 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull))
3113 v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull, size),
3114 "unexpected value\n");
3117 /* Remove the public key, and add a subject key identifier extension */
3118 info.IssuerUniqueId.cbData = 0;
3119 info.IssuerUniqueId.pbData = NULL;
3120 info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
3121 info.SubjectPublicKeyInfo.PublicKey.cbData = 0;
3122 info.SubjectPublicKeyInfo.PublicKey.pbData = NULL;
3123 ext.pszObjId = oid_subject_key_identifier;
3124 ext.fCritical = FALSE;
3125 ext.Value.cbData = sizeof(octetCommonNameValue);
3126 ext.Value.pbData = octetCommonNameValue;
3127 info.cExtension = 1;
3128 info.rgExtension = &ext;
3129 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3130 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3133 ok(size == sizeof(v1CertWithSubjectKeyId), "Wrong size %d\n", size);
3134 ok(!memcmp(buf, v1CertWithSubjectKeyId, size), "Unexpected value\n");
3139 static void test_decodeCertToBeSigned(DWORD dwEncoding)
3141 static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert, v4Cert,
3142 v1CertWithConstraints, v1CertWithSerial, v1CertWithIssuerUniqueId };
3147 /* Test with NULL pbEncoded */
3148 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 0,
3149 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3150 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
3151 GetLastError() == OSS_BAD_ARG /* Win9x */),
3152 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
3155 /* Crashes on win9x */
3156 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 1,
3157 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3158 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3159 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3161 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT or
3162 * CRYPT_E_ASN1_BADTAG, because at a minimum a cert must have a non-zero
3163 * serial number, an issuer, a subject, and a public key.
3165 for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++)
3167 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3168 corruptCerts[i], corruptCerts[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3170 ok(!ret, "Expected failure\n");
3172 /* The following succeeds, even though v1 certs are not allowed to have
3175 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3176 v1CertWithSubjectKeyId, sizeof(v1CertWithSubjectKeyId),
3177 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3178 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3181 CERT_INFO *info = (CERT_INFO *)buf;
3183 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3184 ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %d\n",
3186 ok(info->cExtension == 1, "expected 1 extension, got %d\n",
3190 /* The following also succeeds, even though V1 certs are not allowed to
3191 * have issuer unique ids.
3193 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3194 v1CertWithSubjectIssuerSerialAndIssuerUniqueId,
3195 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId),
3196 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3197 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3200 CERT_INFO *info = (CERT_INFO *)buf;
3202 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3203 ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %d\n",
3205 ok(info->IssuerUniqueId.cbData == sizeof(serialNum),
3206 "unexpected issuer unique id size %d\n", info->IssuerUniqueId.cbData);
3207 ok(!memcmp(info->IssuerUniqueId.pbData, serialNum, sizeof(serialNum)),
3208 "unexpected issuer unique id value\n");
3211 /* Now check with serial number, subject and issuer specified */
3212 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert,
3213 sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3214 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3217 CERT_INFO *info = (CERT_INFO *)buf;
3219 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3220 ok(info->SerialNumber.cbData == 1,
3221 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3222 ok(*info->SerialNumber.pbData == *serialNum,
3223 "Expected serial number %d, got %d\n", *serialNum,
3224 *info->SerialNumber.pbData);
3225 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3226 "Wrong size %d\n", info->Issuer.cbData);
3227 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3228 "Unexpected issuer\n");
3229 ok(info->Subject.cbData == sizeof(encodedCommonName),
3230 "Wrong size %d\n", info->Subject.cbData);
3231 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3232 info->Subject.cbData), "Unexpected subject\n");
3235 /* Check again with pub key specified */
3236 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3237 v1CertWithPubKey, sizeof(v1CertWithPubKey), CRYPT_DECODE_ALLOC_FLAG, NULL,
3239 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3242 CERT_INFO *info = (CERT_INFO *)buf;
3244 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3245 ok(info->SerialNumber.cbData == 1,
3246 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3247 ok(*info->SerialNumber.pbData == *serialNum,
3248 "Expected serial number %d, got %d\n", *serialNum,
3249 *info->SerialNumber.pbData);
3250 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3251 "Wrong size %d\n", info->Issuer.cbData);
3252 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3253 "Unexpected issuer\n");
3254 ok(info->Subject.cbData == sizeof(encodedCommonName),
3255 "Wrong size %d\n", info->Subject.cbData);
3256 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3257 info->Subject.cbData), "Unexpected subject\n");
3258 ok(!strcmp(info->SubjectPublicKeyInfo.Algorithm.pszObjId,
3259 szOID_RSA_RSA), "Expected szOID_RSA_RSA, got %s\n",
3260 info->SubjectPublicKeyInfo.Algorithm.pszObjId);
3261 ok(info->SubjectPublicKeyInfo.PublicKey.cbData == sizeof(aKey),
3262 "Wrong size %d\n", info->SubjectPublicKeyInfo.PublicKey.cbData);
3263 ok(!memcmp(info->SubjectPublicKeyInfo.PublicKey.pbData, aKey,
3264 sizeof(aKey)), "Unexpected public key\n");
3269 static const BYTE hash[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
3272 static const BYTE signedBigCert[] = {
3273 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
3274 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
3275 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
3276 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3277 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
3278 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
3279 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
3280 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
3281 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
3282 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3283 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
3284 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
3286 static void test_encodeCert(DWORD dwEncoding)
3288 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
3289 * also that bigCert is a NULL-terminated string, so don't count its
3290 * last byte (otherwise the signed cert won't decode.)
3292 CERT_SIGNED_CONTENT_INFO info = { { sizeof(bigCert), (BYTE *)bigCert },
3293 { NULL, { 0, NULL } }, { sizeof(hash), (BYTE *)hash, 0 } };
3298 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT, &info,
3299 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
3300 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3303 ok(bufSize == sizeof(signedBigCert), "Wrong size %d\n", bufSize);
3304 ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n");
3309 static void test_decodeCert(DWORD dwEncoding)
3315 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert,
3316 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3317 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3320 CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf;
3322 ok(info->ToBeSigned.cbData == sizeof(bigCert),
3323 "Wrong cert size %d\n", info->ToBeSigned.cbData);
3324 ok(!memcmp(info->ToBeSigned.pbData, bigCert, info->ToBeSigned.cbData),
3325 "Unexpected cert\n");
3326 ok(info->Signature.cbData == sizeof(hash),
3327 "Wrong signature size %d\n", info->Signature.cbData);
3328 ok(!memcmp(info->Signature.pbData, hash, info->Signature.cbData),
3329 "Unexpected signature\n");
3332 /* A signed cert decodes as a CERT_INFO too */
3333 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCert,
3334 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3335 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3338 CERT_INFO *info = (CERT_INFO *)buf;
3340 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3341 ok(info->SerialNumber.cbData == 1,
3342 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3343 ok(*info->SerialNumber.pbData == *serialNum,
3344 "Expected serial number %d, got %d\n", *serialNum,
3345 *info->SerialNumber.pbData);
3346 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3347 "Wrong size %d\n", info->Issuer.cbData);
3348 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3349 "Unexpected issuer\n");
3350 ok(info->Subject.cbData == sizeof(encodedCommonName),
3351 "Wrong size %d\n", info->Subject.cbData);
3352 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3353 info->Subject.cbData), "Unexpected subject\n");
3358 static const BYTE emptyDistPoint[] = { 0x30, 0x02, 0x30, 0x00 };
3359 static const BYTE distPointWithUrl[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3360 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3361 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3362 static const BYTE distPointWithReason[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3364 static const BYTE distPointWithIssuer[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3365 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3366 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3367 static const BYTE distPointWithUrlAndIssuer[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3368 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3369 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3370 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3371 0x2e, 0x6f, 0x72, 0x67 };
3372 static const BYTE crlReason = CRL_REASON_KEY_COMPROMISE |
3373 CRL_REASON_AFFILIATION_CHANGED;
3375 static void test_encodeCRLDistPoints(DWORD dwEncoding)
3377 CRL_DIST_POINTS_INFO info = { 0 };
3378 CRL_DIST_POINT point = { { 0 } };
3379 CERT_ALT_NAME_ENTRY entry = { 0 };
3384 /* Test with an empty info */
3385 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3386 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3387 ok(!ret && GetLastError() == E_INVALIDARG,
3388 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3389 /* Test with one empty dist point */
3390 info.cDistPoint = 1;
3391 info.rgDistPoint = &point;
3392 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3393 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3394 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3397 ok(size == sizeof(emptyDistPoint), "Wrong size %d\n", size);
3398 ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n");
3401 /* A dist point with an invalid name */
3402 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3403 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3404 U(entry).pwszURL = (LPWSTR)nihongoURL;
3405 U(point.DistPointName).FullName.cAltEntry = 1;
3406 U(point.DistPointName).FullName.rgAltEntry = &entry;
3407 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3408 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3409 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
3410 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
3411 /* The first invalid character is at index 7 */
3412 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
3413 "Expected invalid char at index 7, got %d\n",
3414 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
3415 /* A dist point with (just) a valid name */
3416 U(entry).pwszURL = (LPWSTR)url;
3417 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3418 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3419 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3422 ok(size == sizeof(distPointWithUrl), "Wrong size %d\n", size);
3423 ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n");
3426 /* A dist point with (just) reason flags */
3427 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3428 point.ReasonFlags.cbData = sizeof(crlReason);
3429 point.ReasonFlags.pbData = (LPBYTE)&crlReason;
3430 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3431 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3432 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3435 ok(size == sizeof(distPointWithReason), "Wrong size %d\n", size);
3436 ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n");
3439 /* A dist point with just an issuer */
3440 point.ReasonFlags.cbData = 0;
3441 point.CRLIssuer.cAltEntry = 1;
3442 point.CRLIssuer.rgAltEntry = &entry;
3443 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3444 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3445 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3448 ok(size == sizeof(distPointWithIssuer), "Wrong size %d\n", size);
3449 ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n");
3452 /* A dist point with both a name and an issuer */
3453 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3454 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3455 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3456 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3459 ok(size == sizeof(distPointWithUrlAndIssuer),
3460 "Wrong size %d\n", size);
3461 ok(!memcmp(buf, distPointWithUrlAndIssuer, size), "Unexpected value\n");
3466 static void test_decodeCRLDistPoints(DWORD dwEncoding)
3471 PCRL_DIST_POINTS_INFO info;
3472 PCRL_DIST_POINT point;
3473 PCERT_ALT_NAME_ENTRY entry;
3475 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3476 emptyDistPoint, emptyDistPoint[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3478 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3481 info = (PCRL_DIST_POINTS_INFO)buf;
3482 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3483 "Wrong size %d\n", size);
3484 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3486 point = info->rgDistPoint;
3487 ok(point->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_NO_NAME,
3488 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3489 point->DistPointName.dwDistPointNameChoice);
3490 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3491 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3494 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3495 distPointWithUrl, distPointWithUrl[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3497 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3500 info = (PCRL_DIST_POINTS_INFO)buf;
3501 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3502 "Wrong size %d\n", size);
3503 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3505 point = info->rgDistPoint;
3506 ok(point->DistPointName.dwDistPointNameChoice ==
3507 CRL_DIST_POINT_FULL_NAME,
3508 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3509 point->DistPointName.dwDistPointNameChoice);
3510 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3511 "Expected 1 name entry, got %d\n",
3512 U(point->DistPointName).FullName.cAltEntry);
3513 entry = U(point->DistPointName).FullName.rgAltEntry;
3514 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3515 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3516 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3517 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3518 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3521 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3522 distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
3524 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3527 info = (PCRL_DIST_POINTS_INFO)buf;
3528 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3529 "Wrong size %d\n", size);
3530 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3532 point = info->rgDistPoint;
3533 ok(point->DistPointName.dwDistPointNameChoice ==
3534 CRL_DIST_POINT_NO_NAME,
3535 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3536 point->DistPointName.dwDistPointNameChoice);
3537 ok(point->ReasonFlags.cbData == sizeof(crlReason),
3538 "Expected reason length\n");
3539 ok(!memcmp(point->ReasonFlags.pbData, &crlReason, sizeof(crlReason)),
3540 "Unexpected reason\n");
3541 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3544 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3545 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2,
3546 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3547 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3550 info = (PCRL_DIST_POINTS_INFO)buf;
3551 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3552 "Wrong size %d\n", size);
3553 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3555 point = info->rgDistPoint;
3556 ok(point->DistPointName.dwDistPointNameChoice ==
3557 CRL_DIST_POINT_FULL_NAME,
3558 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3559 point->DistPointName.dwDistPointNameChoice);
3560 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3561 "Expected 1 name entry, got %d\n",
3562 U(point->DistPointName).FullName.cAltEntry);
3563 entry = U(point->DistPointName).FullName.rgAltEntry;
3564 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3565 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3566 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3567 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3568 ok(point->CRLIssuer.cAltEntry == 1,
3569 "Expected 1 issuer entry, got %d\n", point->CRLIssuer.cAltEntry);
3570 entry = point->CRLIssuer.rgAltEntry;
3571 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3572 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3573 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3578 static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3579 static const BYTE emptyNameIDP[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3580 static const BYTE urlIDP[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3581 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3584 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding)
3589 CRL_ISSUING_DIST_POINT point = { { 0 } };
3590 CERT_ALT_NAME_ENTRY entry;
3592 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, NULL,
3593 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3594 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3596 skip("no X509_ISSUING_DIST_POINT encode support\n");
3599 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3600 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3601 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3602 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3603 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3606 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
3607 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
3610 /* nonsensical flags */
3611 point.fOnlyContainsUserCerts = TRUE;
3612 point.fOnlyContainsCACerts = TRUE;
3613 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3614 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3615 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3618 ok(size == sizeof(badFlagsIDP), "Unexpected size %d\n", size);
3619 ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n");
3622 /* unimplemented name type */
3623 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3624 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_ISSUER_RDN_NAME;
3625 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3626 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3627 ok(!ret && GetLastError() == E_INVALIDARG,
3628 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3630 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3631 U(point.DistPointName).FullName.cAltEntry = 0;
3632 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3633 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3634 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3637 ok(size == sizeof(emptyNameIDP), "Unexpected size %d\n", size);
3638 ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n");
3641 /* name with URL entry */
3642 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3643 U(entry).pwszURL = (LPWSTR)url;
3644 U(point.DistPointName).FullName.cAltEntry = 1;
3645 U(point.DistPointName).FullName.rgAltEntry = &entry;
3646 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3647 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3648 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3651 ok(size == sizeof(urlIDP), "Unexpected size %d\n", size);
3652 ok(!memcmp(buf, urlIDP, size), "Unexpected value\n");
3657 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY *expected,
3658 const CERT_ALT_NAME_ENTRY *got)
3660 ok(expected->dwAltNameChoice == got->dwAltNameChoice,
3661 "Expected name choice %d, got %d\n", expected->dwAltNameChoice,
3662 got->dwAltNameChoice);
3663 if (expected->dwAltNameChoice == got->dwAltNameChoice)
3665 switch (got->dwAltNameChoice)
3667 case CERT_ALT_NAME_RFC822_NAME:
3668 case CERT_ALT_NAME_DNS_NAME:
3669 case CERT_ALT_NAME_EDI_PARTY_NAME:
3670 case CERT_ALT_NAME_URL:
3671 case CERT_ALT_NAME_REGISTERED_ID:
3672 ok((!U(*expected).pwszURL && !U(*got).pwszURL) ||
3673 (!U(*expected).pwszURL && !lstrlenW(U(*got).pwszURL)) ||
3674 (!U(*got).pwszURL && !lstrlenW(U(*expected).pwszURL)) ||
3675 !lstrcmpW(U(*expected).pwszURL, U(*got).pwszURL),
3676 "Unexpected name\n");
3678 case CERT_ALT_NAME_X400_ADDRESS:
3679 case CERT_ALT_NAME_DIRECTORY_NAME:
3680 case CERT_ALT_NAME_IP_ADDRESS:
3681 ok(U(*got).IPAddress.cbData == U(*expected).IPAddress.cbData,
3682 "Unexpected IP address length %d\n", U(*got).IPAddress.cbData);
3683 ok(!memcmp(U(*got).IPAddress.pbData, U(*got).IPAddress.pbData,
3684 U(*got).IPAddress.cbData), "Unexpected value\n");
3690 static void compareAltNameInfo(const CERT_ALT_NAME_INFO *expected,
3691 const CERT_ALT_NAME_INFO *got)
3695 ok(expected->cAltEntry == got->cAltEntry, "Expected %d entries, got %d\n",
3696 expected->cAltEntry, got->cAltEntry);
3697 for (i = 0; i < min(expected->cAltEntry, got->cAltEntry); i++)
3698 compareAltNameEntry(&expected->rgAltEntry[i], &got->rgAltEntry[i]);
3701 static void compareDistPointName(const CRL_DIST_POINT_NAME *expected,
3702 const CRL_DIST_POINT_NAME *got)
3704 ok(got->dwDistPointNameChoice == expected->dwDistPointNameChoice,
3705 "Unexpected name choice %d\n", got->dwDistPointNameChoice);
3706 if (got->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME)
3707 compareAltNameInfo(&(U(*expected).FullName), &(U(*got).FullName));
3710 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT *expected,
3711 const CRL_ISSUING_DIST_POINT *got)
3713 compareDistPointName(&expected->DistPointName, &got->DistPointName);
3714 ok(got->fOnlyContainsUserCerts == expected->fOnlyContainsUserCerts,
3715 "Unexpected fOnlyContainsUserCerts\n");
3716 ok(got->fOnlyContainsCACerts == expected->fOnlyContainsCACerts,
3717 "Unexpected fOnlyContainsCACerts\n");
3718 ok(got->OnlySomeReasonFlags.cbData == expected->OnlySomeReasonFlags.cbData,
3719 "Unexpected reason flags\n");
3720 ok(got->fIndirectCRL == expected->fIndirectCRL,
3721 "Unexpected fIndirectCRL\n");
3724 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding)
3729 CRL_ISSUING_DIST_POINT point = { { 0 } };
3731 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3732 emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3734 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3736 skip("no X509_ISSUING_DIST_POINT decode support\n");
3739 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3742 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3745 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3746 badFlagsIDP, badFlagsIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3748 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3751 point.fOnlyContainsUserCerts = point.fOnlyContainsCACerts = TRUE;
3752 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3755 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3756 emptyNameIDP, emptyNameIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3758 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3761 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3762 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3763 U(point.DistPointName).FullName.cAltEntry = 0;
3764 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3767 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3768 urlIDP, urlIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3769 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3772 CERT_ALT_NAME_ENTRY entry;
3774 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3775 U(entry).pwszURL = (LPWSTR)url;
3776 U(point.DistPointName).FullName.cAltEntry = 1;
3777 U(point.DistPointName).FullName.rgAltEntry = &entry;
3778 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3783 static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3784 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3786 static const BYTE v2CRL[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3787 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3788 0x30, 0x30, 0x30, 0x30, 0x5a };
3789 static const BYTE v1CRLWithIssuer[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3790 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3791 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3792 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3794 static const BYTE v1CRLWithIssuerAndEmptyEntry[] = { 0x30, 0x43, 0x30, 0x02,
3795 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3796 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3797 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3798 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3799 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3800 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3801 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3802 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3803 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3804 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3805 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3806 static const BYTE v1CRLWithEntryExt[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3807 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3808 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3809 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3810 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3811 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3812 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3813 static const BYTE v1CRLWithExt[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3814 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3815 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3816 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
3817 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3818 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
3819 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3820 static const BYTE v2CRLWithExt[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
3821 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
3822 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
3823 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
3824 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
3825 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
3826 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3827 static const BYTE v2CRLWithIssuingDistPoint[] = { 0x30,0x5c,0x02,0x01,0x01,
3828 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
3829 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
3830 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
3831 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3832 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
3833 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3835 static void test_encodeCRLToBeSigned(DWORD dwEncoding)
3839 static CHAR oid_issuing_dist_point[] = szOID_ISSUING_DIST_POINT;
3841 CRL_INFO info = { 0 };
3842 CRL_ENTRY entry = { { 0 }, { 0 }, 0, 0 };
3845 /* Test with a V1 CRL */
3846 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3847 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3848 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3849 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3852 ok(size == sizeof(v1CRL), "Wrong size %d\n", size);
3853 ok(!memcmp(buf, v1CRL, size), "Got unexpected value\n");
3857 info.dwVersion = CRL_V2;
3858 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3859 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3860 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3861 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3864 ok(size == v2CRL[1] + 2, "Expected size %d, got %d\n",
3865 v2CRL[1] + 2, size);
3866 ok(!memcmp(buf, v2CRL, size), "Got unexpected value\n");
3869 /* v1 CRL with a name */
3870 info.dwVersion = CRL_V1;
3871 info.Issuer.cbData = sizeof(encodedCommonName);
3872 info.Issuer.pbData = (BYTE *)encodedCommonName;
3873 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3874 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3875 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3878 ok(size == sizeof(v1CRLWithIssuer), "Wrong size %d\n", size);
3879 ok(!memcmp(buf, v1CRLWithIssuer, size), "Got unexpected value\n");
3884 /* v1 CRL with a name and a NULL entry pointer (crashes on win9x) */
3886 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3887 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3888 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3889 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3891 /* now set an empty entry */
3893 info.rgCRLEntry = &entry;
3894 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3895 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3898 ok(size == sizeof(v1CRLWithIssuerAndEmptyEntry),
3899 "Wrong size %d\n", size);
3900 ok(!memcmp(buf, v1CRLWithIssuerAndEmptyEntry, size),
3901 "Got unexpected value\n");
3904 /* an entry with a serial number */
3905 entry.SerialNumber.cbData = sizeof(serialNum);
3906 entry.SerialNumber.pbData = (BYTE *)serialNum;
3907 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3908 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3911 ok(size == sizeof(v1CRLWithIssuerAndEntry),
3912 "Wrong size %d\n", size);
3913 ok(!memcmp(buf, v1CRLWithIssuerAndEntry, size),
3914 "Got unexpected value\n");
3917 /* an entry with an extension */
3918 entry.cExtension = 1;
3919 entry.rgExtension = &criticalExt;
3920 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3921 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3922 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3925 ok(size == sizeof(v1CRLWithEntryExt), "Wrong size %d\n", size);
3926 ok(!memcmp(buf, v1CRLWithEntryExt, size), "Got unexpected value\n");
3929 /* a CRL with an extension */
3930 entry.cExtension = 0;
3931 info.cExtension = 1;
3932 info.rgExtension = &criticalExt;
3933 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3934 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3935 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3938 ok(size == sizeof(v1CRLWithExt), "Wrong size %d\n", size);
3939 ok(!memcmp(buf, v1CRLWithExt, size), "Got unexpected value\n");
3942 /* a v2 CRL with an extension, this time non-critical */
3943 info.dwVersion = CRL_V2;
3944 info.rgExtension = &nonCriticalExt;
3945 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3946 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3947 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3950 ok(size == sizeof(v2CRLWithExt), "Wrong size %d\n", size);
3951 ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n");
3954 /* a v2 CRL with an issuing dist point extension */
3955 ext.pszObjId = oid_issuing_dist_point;
3956 ext.fCritical = TRUE;
3957 ext.Value.cbData = sizeof(urlIDP);
3958 ext.Value.pbData = (LPBYTE)urlIDP;
3959 entry.rgExtension = &ext;
3960 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3961 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3962 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3965 ok(size == sizeof(v2CRLWithIssuingDistPoint), "Wrong size %d\n", size);
3966 ok(!memcmp(buf, v2CRLWithIssuingDistPoint, size), "Unexpected value\n");
3971 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
3972 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
3973 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
3974 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
3975 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
3976 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
3977 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
3978 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
3979 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
3980 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
3981 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
3982 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
3983 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
3984 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
3985 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
3986 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
3987 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
3988 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
3989 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
3990 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
3991 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
3992 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
3993 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
3994 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
3995 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
3996 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
3997 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
3998 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
3999 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
4000 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
4001 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
4002 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
4003 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
4004 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
4006 static const BYTE verisignCRLWithLotsOfEntries[] = {
4007 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
4008 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
4009 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
4010 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
4011 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
4012 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
4013 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
4014 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
4015 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
4016 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
4017 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
4018 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
4019 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
4020 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
4021 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
4022 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
4023 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
4024 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
4025 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
4026 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
4027 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
4028 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
4029 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
4030 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
4031 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
4032 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
4033 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
4034 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
4035 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
4036 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
4037 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
4038 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
4039 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
4040 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
4041 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
4042 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
4043 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
4044 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
4045 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
4046 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
4047 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
4048 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
4049 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
4050 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
4051 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
4052 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
4053 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
4054 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
4055 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
4056 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
4057 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
4058 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
4059 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
4060 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
4061 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
4062 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
4063 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
4064 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
4065 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
4066 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
4067 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
4068 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
4069 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
4070 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
4071 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
4072 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
4073 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
4074 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
4075 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
4076 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
4077 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
4078 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
4079 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
4080 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
4081 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
4082 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
4083 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
4084 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
4085 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
4086 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
4087 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
4088 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
4089 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
4090 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
4091 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
4092 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
4093 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
4094 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
4095 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
4096 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
4097 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
4098 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
4099 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
4100 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
4101 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
4102 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
4103 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
4104 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
4105 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
4106 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
4107 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
4108 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
4109 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
4110 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
4111 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
4112 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
4113 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
4114 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
4115 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
4116 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
4117 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
4118 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
4119 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
4120 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
4121 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
4122 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
4123 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
4124 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
4125 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
4126 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
4127 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
4128 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
4129 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
4130 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
4131 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
4132 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
4133 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
4134 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
4135 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
4136 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
4137 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
4138 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
4139 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
4140 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
4141 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
4142 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
4143 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
4144 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
4145 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
4146 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
4147 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
4148 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
4149 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
4150 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
4151 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
4152 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
4153 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
4154 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
4155 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
4156 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
4157 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
4158 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
4159 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
4160 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
4161 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
4162 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
4163 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
4164 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
4165 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
4166 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
4167 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
4168 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
4169 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
4170 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
4171 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
4172 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
4173 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
4174 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
4175 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
4176 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
4177 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
4178 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
4179 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
4180 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
4181 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
4182 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
4183 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
4184 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
4185 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
4186 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
4187 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
4188 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
4189 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
4190 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
4191 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
4192 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
4193 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
4194 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
4195 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
4196 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
4197 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
4198 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
4199 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
4200 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
4201 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
4202 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
4203 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
4204 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
4205 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
4206 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
4207 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
4208 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
4209 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
4210 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
4211 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
4212 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
4213 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
4214 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
4215 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
4216 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
4217 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
4218 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
4219 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
4220 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
4221 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
4222 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
4223 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
4224 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
4225 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
4226 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
4227 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
4228 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
4229 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
4230 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
4231 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
4232 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
4233 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
4234 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
4235 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
4236 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
4237 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
4238 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
4239 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
4240 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
4241 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
4242 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
4243 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
4244 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
4245 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
4246 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
4247 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
4248 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
4249 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
4250 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
4251 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
4252 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
4253 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
4254 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
4255 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
4256 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
4257 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
4258 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
4259 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
4260 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
4261 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
4262 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
4263 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
4264 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
4265 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
4266 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
4267 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
4268 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
4269 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
4270 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
4271 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
4272 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
4273 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
4274 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
4275 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
4276 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
4277 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
4278 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
4279 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
4280 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
4281 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
4282 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
4283 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
4284 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
4285 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
4286 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
4287 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
4288 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
4289 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
4290 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
4291 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
4292 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
4293 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
4294 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
4295 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
4296 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
4297 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
4298 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
4299 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
4300 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
4301 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
4302 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
4303 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
4304 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
4305 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
4306 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
4307 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
4308 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
4309 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
4310 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4311 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4312 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4313 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4314 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4315 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4316 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4317 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4318 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4319 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4320 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4321 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4322 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4323 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4324 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4325 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4326 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4327 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4328 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4329 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4330 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4331 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4332 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4333 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4334 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4335 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4336 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4337 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4338 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4339 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4340 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4341 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4342 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4343 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4344 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4345 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4346 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4347 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4348 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4349 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4350 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4351 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4352 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4353 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4354 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4355 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4356 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4357 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4358 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4359 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4360 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4361 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4362 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4363 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4364 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4365 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4366 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4367 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4368 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4369 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4370 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4371 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4372 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4373 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4374 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4375 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4376 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4377 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4378 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4379 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4380 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4381 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4382 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4383 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4384 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4385 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4386 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4387 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4388 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4389 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4390 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4391 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4392 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4393 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4394 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4395 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4396 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4397 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4398 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4399 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4400 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4401 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4402 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4403 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4404 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4405 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4406 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4407 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4408 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4409 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4410 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4411 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4412 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4413 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4414 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4415 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4416 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4417 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4418 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4419 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4420 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4421 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4422 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4423 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4424 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4425 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4426 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4427 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4428 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4429 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4430 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4431 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4432 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4433 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4434 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4435 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4436 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4437 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4438 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4439 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4440 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4441 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4442 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4443 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4444 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4445 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4446 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4447 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4448 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4449 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4450 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4451 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4452 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4453 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4454 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4455 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4456 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4457 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4458 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4459 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4460 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4461 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4462 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4463 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4464 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4465 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4466 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4467 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4468 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4469 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4470 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4471 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4472 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4473 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4474 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4475 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4476 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4477 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4478 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4479 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4480 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4481 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4482 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4483 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4484 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4485 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4486 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4487 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4488 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4489 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4490 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4491 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4492 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4493 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4494 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4495 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4496 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4497 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4498 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4499 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4500 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4501 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4502 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4503 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4504 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4505 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4506 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4507 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4508 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4509 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4510 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4511 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4512 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4513 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4514 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4516 static void test_decodeCRLToBeSigned(DWORD dwEncoding)
4518 static const BYTE *corruptCRLs[] = { v1CRL, v2CRL };
4523 for (i = 0; i < sizeof(corruptCRLs) / sizeof(corruptCRLs[0]); i++)
4525 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4526 corruptCRLs[i], corruptCRLs[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4528 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4529 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4530 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4533 /* at a minimum, a CRL must contain an issuer: */
4534 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4535 v1CRLWithIssuer, v1CRLWithIssuer[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4537 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4540 CRL_INFO *info = (CRL_INFO *)buf;
4542 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4543 ok(info->cCRLEntry == 0, "Expected 0 CRL entries, got %d\n",
4545 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4546 "Wrong issuer size %d\n", info->Issuer.cbData);
4547 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4548 "Unexpected issuer\n");
4551 /* check decoding with an empty CRL entry */
4552 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4553 v1CRLWithIssuerAndEmptyEntry, v1CRLWithIssuerAndEmptyEntry[1] + 2,
4554 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4555 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4556 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4557 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4559 /* with a real CRL entry */
4560 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4561 v1CRLWithIssuerAndEntry, v1CRLWithIssuerAndEntry[1] + 2,
4562 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4563 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4566 CRL_INFO *info = (CRL_INFO *)buf;
4569 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4570 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4572 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4573 entry = info->rgCRLEntry;
4574 ok(entry->SerialNumber.cbData == 1,
4575 "Expected serial number size 1, got %d\n",
4576 entry->SerialNumber.cbData);
4577 ok(*entry->SerialNumber.pbData == *serialNum,
4578 "Expected serial number %d, got %d\n", *serialNum,
4579 *entry->SerialNumber.pbData);
4580 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4581 "Wrong issuer size %d\n", info->Issuer.cbData);
4582 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4583 "Unexpected issuer\n");
4586 /* a real CRL from verisign that has extensions */
4587 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4588 verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG,
4590 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4593 CRL_INFO *info = (CRL_INFO *)buf;
4596 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4597 ok(info->cCRLEntry == 3, "Expected 3 CRL entries, got %d\n",
4599 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4600 entry = info->rgCRLEntry;
4601 ok(info->cExtension == 2, "Expected 2 extensions, got %d\n",
4605 /* another real CRL from verisign that has lots of entries */
4606 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4607 verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries),
4608 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4609 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4612 CRL_INFO *info = (CRL_INFO *)buf;
4614 ok(size >= sizeof(CRL_INFO), "Got size %d\n", size);
4615 ok(info->cCRLEntry == 209, "Expected 209 CRL entries, got %d\n",
4617 ok(info->cExtension == 0, "Expected 0 extensions, got %d\n",
4621 /* and finally, with an extension */
4622 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4623 v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4625 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4628 CRL_INFO *info = (CRL_INFO *)buf;
4631 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4632 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4634 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4635 entry = info->rgCRLEntry;
4636 ok(entry->SerialNumber.cbData == 1,
4637 "Expected serial number size 1, got %d\n",
4638 entry->SerialNumber.cbData);
4639 ok(*entry->SerialNumber.pbData == *serialNum,
4640 "Expected serial number %d, got %d\n", *serialNum,
4641 *entry->SerialNumber.pbData);
4642 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4643 "Wrong issuer size %d\n", info->Issuer.cbData);
4644 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4645 "Unexpected issuer\n");
4646 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4650 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4651 v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4653 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4656 CRL_INFO *info = (CRL_INFO *)buf;
4658 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4662 /* And again, with an issuing dist point */
4663 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4664 v2CRLWithIssuingDistPoint, sizeof(v2CRLWithIssuingDistPoint),
4665 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4666 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4669 CRL_INFO *info = (CRL_INFO *)buf;
4671 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4677 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
4678 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
4679 static const BYTE encodedUsage[] = {
4680 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4681 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4682 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4684 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding)
4689 CERT_ENHKEY_USAGE usage;
4691 /* Test with empty usage */
4692 usage.cUsageIdentifier = 0;
4693 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4694 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4695 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4698 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
4699 ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n");
4702 /* Test with a few usages */
4703 usage.cUsageIdentifier = sizeof(keyUsages) / sizeof(keyUsages[0]);
4704 usage.rgpszUsageIdentifier = (LPSTR *)keyUsages;
4705 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4706 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4707 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4710 ok(size == sizeof(encodedUsage), "Wrong size %d\n", size);
4711 ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n");
4716 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding)
4722 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4723 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4725 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4728 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4730 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4731 "Wrong size %d\n", size);
4732 ok(usage->cUsageIdentifier == 0, "Expected 0 CRL entries, got %d\n",
4733 usage->cUsageIdentifier);
4736 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4737 encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL,
4739 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4742 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4745 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4746 "Wrong size %d\n", size);
4747 ok(usage->cUsageIdentifier == sizeof(keyUsages) / sizeof(keyUsages[0]),
4748 "Wrong CRL entries count %d\n", usage->cUsageIdentifier);
4749 for (i = 0; i < usage->cUsageIdentifier; i++)
4750 ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]),
4751 "Expected OID %s, got %s\n", keyUsages[i],
4752 usage->rgpszUsageIdentifier[i]);
4757 static BYTE keyId[] = { 1,2,3,4 };
4758 static const BYTE authorityKeyIdWithId[] = {
4759 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4760 static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4761 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4762 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4763 static const BYTE authorityKeyIdWithSerial[] = { 0x30,0x03,0x82,0x01,0x01 };
4765 static void test_encodeAuthorityKeyId(DWORD dwEncoding)
4767 CERT_AUTHORITY_KEY_ID_INFO info = { { 0 } };
4772 /* Test with empty id */
4773 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4774 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4775 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4778 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4779 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4782 /* With just a key id */
4783 info.KeyId.cbData = sizeof(keyId);
4784 info.KeyId.pbData = keyId;
4785 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4786 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4787 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4790 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", size);
4791 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4794 /* With just an issuer */
4795 info.KeyId.cbData = 0;
4796 info.CertIssuer.cbData = sizeof(encodedCommonName);
4797 info.CertIssuer.pbData = (BYTE *)encodedCommonName;
4798 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4799 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4800 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4803 ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %d\n",
4805 ok(!memcmp(buf, authorityKeyIdWithIssuer, size), "Unexpected value\n");
4808 /* With just a serial number */
4809 info.CertIssuer.cbData = 0;
4810 info.CertSerialNumber.cbData = sizeof(serialNum);
4811 info.CertSerialNumber.pbData = (BYTE *)serialNum;
4812 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4813 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4814 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4817 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4819 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4824 static void test_decodeAuthorityKeyId(DWORD dwEncoding)
4830 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4831 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4833 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4836 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4838 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4840 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4841 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4842 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4845 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4846 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4847 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4848 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4851 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4853 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4855 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4856 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4857 "Unexpected key id\n");
4858 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4859 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4862 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4863 authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer),
4864 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4865 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4868 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4870 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4872 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4873 ok(info->CertIssuer.cbData == sizeof(encodedCommonName),
4874 "Unexpected issuer len\n");
4875 ok(!memcmp(info->CertIssuer.pbData, encodedCommonName,
4876 sizeof(encodedCommonName)), "Unexpected issuer\n");
4877 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4880 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4881 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4882 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4883 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4886 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4888 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4890 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4891 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4892 ok(info->CertSerialNumber.cbData == sizeof(serialNum),
4893 "Unexpected serial number len\n");
4894 ok(!memcmp(info->CertSerialNumber.pbData, serialNum, sizeof(serialNum)),
4895 "Unexpected serial number\n");
4900 static const BYTE authorityKeyIdWithIssuerUrl[] = { 0x30,0x15,0xa1,0x13,0x86,
4901 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
4904 static void test_encodeAuthorityKeyId2(DWORD dwEncoding)
4906 CERT_AUTHORITY_KEY_ID2_INFO info = { { 0 } };
4907 CERT_ALT_NAME_ENTRY entry = { 0 };
4912 /* Test with empty id */
4913 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4914 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4915 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4918 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4919 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4922 /* With just a key id */
4923 info.KeyId.cbData = sizeof(keyId);
4924 info.KeyId.pbData = keyId;
4925 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4926 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4927 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4930 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n",
4932 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4935 /* With a bogus issuer name */
4936 info.KeyId.cbData = 0;
4937 info.AuthorityCertIssuer.cAltEntry = 1;
4938 info.AuthorityCertIssuer.rgAltEntry = &entry;
4939 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4940 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4941 ok(!ret && GetLastError() == E_INVALIDARG,
4942 "Expected E_INVALIDARG, got %08x\n", GetLastError());
4943 /* With an issuer name */
4944 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
4945 U(entry).pwszURL = (LPWSTR)url;
4946 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4947 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4948 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4951 ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %d\n",
4953 ok(!memcmp(buf, authorityKeyIdWithIssuerUrl, size),
4954 "Unexpected value\n");
4957 /* With just a serial number */
4958 info.AuthorityCertIssuer.cAltEntry = 0;
4959 info.AuthorityCertSerialNumber.cbData = sizeof(serialNum);
4960 info.AuthorityCertSerialNumber.pbData = (BYTE *)serialNum;
4961 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4962 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4963 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4966 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4968 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4973 static void test_decodeAuthorityKeyId2(DWORD dwEncoding)
4979 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4980 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4982 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4985 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4987 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4989 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4990 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4991 "Expected no issuer name entries\n");
4992 ok(info->AuthorityCertSerialNumber.cbData == 0,
4993 "Expected no serial number\n");
4996 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4997 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4998 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4999 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5002 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
5004 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
5006 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
5007 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
5008 "Unexpected key id\n");
5009 ok(info->AuthorityCertIssuer.cAltEntry == 0,
5010 "Expected no issuer name entries\n");
5011 ok(info->AuthorityCertSerialNumber.cbData == 0,
5012 "Expected no serial number\n");
5015 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
5016 authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl),
5017 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5018 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5021 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
5023 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
5025 ok(info->KeyId.cbData == 0, "Expected no key id\n");
5026 ok(info->AuthorityCertIssuer.cAltEntry == 1,
5027 "Expected 1 issuer entry, got %d\n",
5028 info->AuthorityCertIssuer.cAltEntry);
5029 ok(info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice ==
5030 CERT_ALT_NAME_URL, "Expected CERT_ALT_NAME_URL, got %d\n",
5031 info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice);
5032 ok(!lstrcmpW(U(info->AuthorityCertIssuer.rgAltEntry[0]).pwszURL,
5033 url), "Unexpected URL\n");
5034 ok(info->AuthorityCertSerialNumber.cbData == 0,
5035 "Expected no serial number\n");
5038 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
5039 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
5040 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5041 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5044 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
5046 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
5048 ok(info->KeyId.cbData == 0, "Expected no key id\n");
5049 ok(info->AuthorityCertIssuer.cAltEntry == 0,
5050 "Expected no issuer name entries\n");
5051 ok(info->AuthorityCertSerialNumber.cbData == sizeof(serialNum),
5052 "Unexpected serial number len\n");
5053 ok(!memcmp(info->AuthorityCertSerialNumber.pbData, serialNum,
5054 sizeof(serialNum)), "Unexpected serial number\n");
5059 static const BYTE authorityInfoAccessWithUrl[] = {
5060 0x30,0x19,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
5061 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5062 static const BYTE authorityInfoAccessWithUrlAndIPAddr[] = {
5063 0x30,0x29,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
5064 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x0e,0x06,
5065 0x02,0x2d,0x06,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5067 static void test_encodeAuthorityInfoAccess(DWORD dwEncoding)
5069 static char oid1[] = "1.2.3";
5070 static char oid2[] = "1.5.6";
5074 CERT_ACCESS_DESCRIPTION accessDescription[2];
5075 CERT_AUTHORITY_INFO_ACCESS aia;
5077 memset(accessDescription, 0, sizeof(accessDescription));
5079 aia.rgAccDescr = NULL;
5080 /* Having no access descriptions is allowed */
5081 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5082 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5083 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5086 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
5087 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
5091 /* It can't have an empty access method */
5093 aia.rgAccDescr = accessDescription;
5094 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5095 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5096 ok(!ret && (GetLastError() == E_INVALIDARG ||
5097 GetLastError() == OSS_LIMITED /* Win9x */),
5098 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
5099 /* It can't have an empty location */
5100 accessDescription[0].pszAccessMethod = oid1;
5101 SetLastError(0xdeadbeef);
5102 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5103 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5104 ok(!ret && GetLastError() == E_INVALIDARG,
5105 "expected E_INVALIDARG, got %08x\n", GetLastError());
5106 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5107 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
5108 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5109 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5110 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5113 ok(size == sizeof(authorityInfoAccessWithUrl), "unexpected size %d\n",
5115 ok(!memcmp(buf, authorityInfoAccessWithUrl, size),
5116 "unexpected value\n");
5120 accessDescription[1].pszAccessMethod = oid2;
5121 accessDescription[1].AccessLocation.dwAltNameChoice =
5122 CERT_ALT_NAME_IP_ADDRESS;
5123 U(accessDescription[1].AccessLocation).IPAddress.cbData =
5124 sizeof(encodedIPAddr);
5125 U(accessDescription[1].AccessLocation).IPAddress.pbData =
5126 (LPBYTE)encodedIPAddr;
5128 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5129 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5130 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5133 ok(size == sizeof(authorityInfoAccessWithUrlAndIPAddr),
5134 "unexpected size %d\n", size);
5135 ok(!memcmp(buf, authorityInfoAccessWithUrlAndIPAddr, size),
5136 "unexpected value\n");
5142 static void compareAuthorityInfoAccess(LPCSTR header,
5143 const CERT_AUTHORITY_INFO_ACCESS *expected,
5144 const CERT_AUTHORITY_INFO_ACCESS *got)
5148 ok(expected->cAccDescr == got->cAccDescr,
5149 "%s: expected %d access descriptions, got %d\n", header,
5150 expected->cAccDescr, got->cAccDescr);
5151 for (i = 0; i < expected->cAccDescr; i++)
5153 ok(!strcmp(expected->rgAccDescr[i].pszAccessMethod,
5154 got->rgAccDescr[i].pszAccessMethod), "%s[%d]: expected %s, got %s\n",
5155 header, i, expected->rgAccDescr[i].pszAccessMethod,
5156 got->rgAccDescr[i].pszAccessMethod);
5157 compareAltNameEntry(&expected->rgAccDescr[i].AccessLocation,
5158 &got->rgAccDescr[i].AccessLocation);
5162 static void test_decodeAuthorityInfoAccess(DWORD dwEncoding)
5164 static char oid1[] = "1.2.3";
5165 static char oid2[] = "1.5.6";
5170 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5171 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
5173 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5176 CERT_AUTHORITY_INFO_ACCESS aia = { 0, NULL };
5178 compareAuthorityInfoAccess("empty AIA", &aia,
5179 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5183 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5184 authorityInfoAccessWithUrl, sizeof(authorityInfoAccessWithUrl),
5185 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5186 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5189 CERT_ACCESS_DESCRIPTION accessDescription;
5190 CERT_AUTHORITY_INFO_ACCESS aia;
5192 accessDescription.pszAccessMethod = oid1;
5193 accessDescription.AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5194 U(accessDescription.AccessLocation).pwszURL = (LPWSTR)url;
5196 aia.rgAccDescr = &accessDescription;
5197 compareAuthorityInfoAccess("AIA with URL", &aia,
5198 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5202 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5203 authorityInfoAccessWithUrlAndIPAddr,
5204 sizeof(authorityInfoAccessWithUrlAndIPAddr), CRYPT_DECODE_ALLOC_FLAG,
5206 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5209 CERT_ACCESS_DESCRIPTION accessDescription[2];
5210 CERT_AUTHORITY_INFO_ACCESS aia;
5212 accessDescription[0].pszAccessMethod = oid1;
5213 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5214 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
5215 accessDescription[1].pszAccessMethod = oid2;
5216 accessDescription[1].AccessLocation.dwAltNameChoice =
5217 CERT_ALT_NAME_IP_ADDRESS;
5218 U(accessDescription[1].AccessLocation).IPAddress.cbData =
5219 sizeof(encodedIPAddr);
5220 U(accessDescription[1].AccessLocation).IPAddress.pbData =
5221 (LPBYTE)encodedIPAddr;
5223 aia.rgAccDescr = accessDescription;
5224 compareAuthorityInfoAccess("AIA with URL and IP addr", &aia,
5225 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5231 static const BYTE emptyCTL[] = {
5232 0x30,0x17,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5233 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5234 static const BYTE emptyCTLWithVersion1[] = {
5235 0x30,0x1a,0x02,0x01,0x01,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5236 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5237 static const BYTE ctlWithUsageIdentifier[] = {
5238 0x30,0x1b,0x30,0x04,0x06,0x02,0x2a,0x03,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
5239 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5240 static const BYTE ctlWithListIdentifier[] = {
5241 0x30,0x1a,0x30,0x00,0x04,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5242 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5243 static const BYTE ctlWithSequenceNumber[] = {
5244 0x30,0x1a,0x30,0x00,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5245 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5246 static const BYTE ctlWithThisUpdate[] = {
5247 0x30,0x15,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5248 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5249 static const BYTE ctlWithThisAndNextUpdate[] = {
5250 0x30,0x24,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5251 0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5252 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5253 static const BYTE ctlWithAlgId[] = {
5254 0x30,0x1b,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5255 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5256 static const BYTE ctlWithBogusEntry[] = {
5257 0x30,0x29,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5258 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x10,0x30,0x0e,0x04,
5259 0x01,0x01,0x31,0x09,0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,0x01 };
5260 static const BYTE ctlWithOneEntry[] = {
5261 0x30,0x2a,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5262 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x11,0x30,0x0f,0x04,
5263 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00 };
5264 static const BYTE ctlWithTwoEntries[] = {
5265 0x30,0x41,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5266 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x28,0x30,0x0f,0x04,
5267 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00,0x30,
5268 0x15,0x04,0x01,0x01,0x31,0x10,0x30,0x0e,0x06,0x02,0x2d,0x06,0x31,0x08,0x30,
5269 0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5271 static void test_encodeCTL(DWORD dwEncoding)
5273 static char oid1[] = "1.2.3";
5274 static char oid2[] = "1.5.6";
5280 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5281 CTL_ENTRY ctlEntry[2];
5282 CRYPT_ATTRIBUTE attr1, attr2;
5283 CRYPT_ATTR_BLOB value1, value2;
5285 memset(&info, 0, sizeof(info));
5286 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5287 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5288 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5291 ok(size == sizeof(emptyCTL), "unexpected size %d\n", size);
5292 ok(!memcmp(buf, emptyCTL, size), "unexpected value\n");
5297 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5298 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5299 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5302 ok(size == sizeof(emptyCTLWithVersion1), "unexpected size %d\n", size);
5303 ok(!memcmp(buf, emptyCTLWithVersion1, size), "unexpected value\n");
5308 info.SubjectUsage.cUsageIdentifier = 1;
5309 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5310 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5311 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5312 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5315 ok(size == sizeof(ctlWithUsageIdentifier), "unexpected size %d\n",
5317 ok(!memcmp(buf, ctlWithUsageIdentifier, size), "unexpected value\n");
5321 info.SubjectUsage.cUsageIdentifier = 0;
5322 info.ListIdentifier.cbData = sizeof(serialNum);
5323 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5324 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5325 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5326 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5329 ok(size == sizeof(ctlWithListIdentifier), "unexpected size %d\n", size);
5330 ok(!memcmp(buf, ctlWithListIdentifier, size), "unexpected value\n");
5334 info.ListIdentifier.cbData = 0;
5335 info.SequenceNumber.cbData = sizeof(serialNum);
5336 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5337 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5338 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5339 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5342 ok(size == sizeof(ctlWithSequenceNumber), "unexpected size %d\n",
5344 ok(!memcmp(buf, ctlWithSequenceNumber, size), "unexpected value\n");
5348 info.SequenceNumber.cbData = 0;
5349 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5350 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5351 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5352 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5355 ok(size == sizeof(ctlWithThisUpdate), "unexpected size %d\n", size);
5356 ok(!memcmp(buf, ctlWithThisUpdate, size), "unexpected value\n");
5360 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5361 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5362 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5363 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5366 ok(size == sizeof(ctlWithThisAndNextUpdate), "unexpected size %d\n",
5368 ok(!memcmp(buf, ctlWithThisAndNextUpdate, size), "unexpected value\n");
5372 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5373 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5374 info.SubjectAlgorithm.pszObjId = oid2;
5375 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5376 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5377 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5380 ok(size == sizeof(ctlWithAlgId), "unexpected size %d\n", size);
5381 ok(!memcmp(buf, ctlWithAlgId, size), "unexpected value\n");
5385 /* The value is supposed to be asn.1 encoded, so this'll fail to decode
5386 * (see tests below) but it'll encode fine.
5388 info.SubjectAlgorithm.pszObjId = NULL;
5389 value1.cbData = sizeof(serialNum);
5390 value1.pbData = (LPBYTE)serialNum;
5391 attr1.pszObjId = oid1;
5393 attr1.rgValue = &value1;
5394 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5395 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5396 ctlEntry[0].cAttribute = 1;
5397 ctlEntry[0].rgAttribute = &attr1;
5399 info.rgCTLEntry = ctlEntry;
5400 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5401 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5402 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5405 ok(size == sizeof(ctlWithBogusEntry), "unexpected size %d\n", size);
5406 ok(!memcmp(buf, ctlWithBogusEntry, size), "unexpected value\n");
5410 value1.cbData = sizeof(emptySequence);
5411 value1.pbData = (LPBYTE)emptySequence;
5412 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5413 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5414 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5417 ok(size == sizeof(ctlWithOneEntry), "unexpected size %d\n", size);
5418 ok(!memcmp(buf, ctlWithOneEntry, size), "unexpected value\n");
5422 value2.cbData = sizeof(encodedIPAddr);
5423 value2.pbData = (LPBYTE)encodedIPAddr;
5424 attr2.pszObjId = oid2;
5426 attr2.rgValue = &value2;
5427 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5428 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5429 ctlEntry[1].cAttribute = 1;
5430 ctlEntry[1].rgAttribute = &attr2;
5432 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5433 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5434 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5437 ok(size == sizeof(ctlWithTwoEntries), "unexpected size %d\n", size);
5438 ok(!memcmp(buf, ctlWithTwoEntries, size), "unexpected value\n");
5444 static void compareCTLInfo(LPCSTR header, const CTL_INFO *expected,
5445 const CTL_INFO *got)
5449 ok(expected->dwVersion == got->dwVersion,
5450 "%s: expected version %d, got %d\n", header, expected->dwVersion,
5452 ok(expected->SubjectUsage.cUsageIdentifier ==
5453 got->SubjectUsage.cUsageIdentifier,
5454 "%s: expected %d usage identifiers, got %d\n", header,
5455 expected->SubjectUsage.cUsageIdentifier,
5456 got->SubjectUsage.cUsageIdentifier);
5457 for (i = 0; i < expected->SubjectUsage.cUsageIdentifier; i++)
5458 ok(!strcmp(expected->SubjectUsage.rgpszUsageIdentifier[i],
5459 got->SubjectUsage.rgpszUsageIdentifier[i]),
5460 "%s[%d]: expected %s, got %s\n", header, i,
5461 expected->SubjectUsage.rgpszUsageIdentifier[i],
5462 got->SubjectUsage.rgpszUsageIdentifier[i]);
5463 ok(expected->ListIdentifier.cbData == got->ListIdentifier.cbData,
5464 "%s: expected list identifier of %d bytes, got %d\n", header,
5465 expected->ListIdentifier.cbData, got->ListIdentifier.cbData);
5466 if (expected->ListIdentifier.cbData)
5467 ok(!memcmp(expected->ListIdentifier.pbData, got->ListIdentifier.pbData,
5468 expected->ListIdentifier.cbData),
5469 "%s: unexpected list identifier value\n", header);
5470 ok(expected->SequenceNumber.cbData == got->SequenceNumber.cbData,
5471 "%s: expected sequence number of %d bytes, got %d\n", header,
5472 expected->SequenceNumber.cbData, got->SequenceNumber.cbData);
5473 if (expected->SequenceNumber.cbData)
5474 ok(!memcmp(expected->SequenceNumber.pbData, got->SequenceNumber.pbData,
5475 expected->SequenceNumber.cbData),
5476 "%s: unexpected sequence number value\n", header);
5477 ok(!memcmp(&expected->ThisUpdate, &got->ThisUpdate, sizeof(FILETIME)),
5478 "%s: expected this update = (%d, %d), got (%d, %d)\n", header,
5479 expected->ThisUpdate.dwLowDateTime, expected->ThisUpdate.dwHighDateTime,
5480 got->ThisUpdate.dwLowDateTime, got->ThisUpdate.dwHighDateTime);
5481 ok(!memcmp(&expected->NextUpdate, &got->NextUpdate, sizeof(FILETIME)),
5482 "%s: expected next update = (%d, %d), got (%d, %d)\n", header,
5483 expected->NextUpdate.dwLowDateTime, expected->NextUpdate.dwHighDateTime,
5484 got->NextUpdate.dwLowDateTime, got->NextUpdate.dwHighDateTime);
5485 if (expected->SubjectAlgorithm.pszObjId &&
5486 *expected->SubjectAlgorithm.pszObjId && !got->SubjectAlgorithm.pszObjId)
5487 ok(0, "%s: expected subject algorithm %s, got NULL\n", header,
5488 expected->SubjectAlgorithm.pszObjId);
5489 if (expected->SubjectAlgorithm.pszObjId && got->SubjectAlgorithm.pszObjId)
5490 ok(!strcmp(expected->SubjectAlgorithm.pszObjId,
5491 got->SubjectAlgorithm.pszObjId),
5492 "%s: expected subject algorithm %s, got %s\n", header,
5493 expected->SubjectAlgorithm.pszObjId, got->SubjectAlgorithm.pszObjId);
5494 ok(expected->SubjectAlgorithm.Parameters.cbData ==
5495 got->SubjectAlgorithm.Parameters.cbData,
5496 "%s: expected subject algorithm parameters of %d bytes, got %d\n", header,
5497 expected->SubjectAlgorithm.Parameters.cbData,
5498 got->SubjectAlgorithm.Parameters.cbData);
5499 if (expected->SubjectAlgorithm.Parameters.cbData)
5500 ok(!memcmp(expected->SubjectAlgorithm.Parameters.pbData,
5501 got->SubjectAlgorithm.Parameters.pbData,
5502 expected->SubjectAlgorithm.Parameters.cbData),
5503 "%s: unexpected subject algorithm parameter value\n", header);
5504 ok(expected->cCTLEntry == got->cCTLEntry,
5505 "%s: expected %d CTL entries, got %d\n", header, expected->cCTLEntry,
5507 for (i = 0; i < expected->cCTLEntry; i++)
5509 ok(expected->rgCTLEntry[i].SubjectIdentifier.cbData ==
5510 got->rgCTLEntry[i].SubjectIdentifier.cbData,
5511 "%s[%d]: expected subject identifier of %d bytes, got %d\n",
5512 header, i, expected->rgCTLEntry[i].SubjectIdentifier.cbData,
5513 got->rgCTLEntry[i].SubjectIdentifier.cbData);
5514 if (expected->rgCTLEntry[i].SubjectIdentifier.cbData)
5515 ok(!memcmp(expected->rgCTLEntry[i].SubjectIdentifier.pbData,
5516 got->rgCTLEntry[i].SubjectIdentifier.pbData,
5517 expected->rgCTLEntry[i].SubjectIdentifier.cbData),
5518 "%s[%d]: unexpected subject identifier value\n",
5520 for (j = 0; j < expected->rgCTLEntry[i].cAttribute; j++)
5522 ok(!strcmp(expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5523 got->rgCTLEntry[i].rgAttribute[j].pszObjId),
5524 "%s[%d][%d]: expected attribute OID %s, got %s\n", header, i, j,
5525 expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5526 got->rgCTLEntry[i].rgAttribute[j].pszObjId);
5527 for (k = 0; k < expected->rgCTLEntry[i].rgAttribute[j].cValue; k++)
5529 ok(expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData ==
5530 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5531 "%s[%d][%d][%d]: expected value of %d bytes, got %d\n",
5533 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5534 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData);
5535 if (expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData)
5537 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5538 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5539 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData),
5540 "%s[%d][%d][%d]: unexpected value\n",
5545 ok(expected->cExtension == got->cExtension,
5546 "%s: expected %d extensions, got %d\n", header, expected->cExtension,
5548 for (i = 0; i < expected->cExtension; i++)
5550 ok(!strcmp(expected->rgExtension[i].pszObjId,
5551 got->rgExtension[i].pszObjId), "%s[%d]: expected %s, got %s\n",
5552 header, i, expected->rgExtension[i].pszObjId,
5553 got->rgExtension[i].pszObjId);
5554 ok(expected->rgExtension[i].fCritical == got->rgExtension[i].fCritical,
5555 "%s[%d]: expected fCritical = %d, got %d\n", header, i,
5556 expected->rgExtension[i].fCritical, got->rgExtension[i].fCritical);
5557 ok(expected->rgExtension[i].Value.cbData ==
5558 got->rgExtension[i].Value.cbData,
5559 "%s[%d]: expected extension value to have %d bytes, got %d\n",
5560 header, i, expected->rgExtension[i].Value.cbData,
5561 got->rgExtension[i].Value.cbData);
5562 if (expected->rgExtension[i].Value.cbData)
5563 ok(!memcmp(expected->rgExtension[i].Value.pbData,
5564 got->rgExtension[i].Value.pbData,
5565 expected->rgExtension[i].Value.cbData),
5566 "%s[%d]: unexpected extension value\n", header, i);
5570 static const BYTE signedCTL[] = {
5571 0x30,0x81,0xc7,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
5572 0x81,0xb9,0x30,0x81,0xb6,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
5573 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x28,0x06,0x09,0x2a,0x86,
5574 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x1b,0x04,0x19,0x30,0x17,0x30,0x00,
5575 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5576 0x30,0x5a,0x30,0x02,0x06,0x00,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
5577 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
5578 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
5579 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5580 0x00,0x04,0x40,0xca,0xd8,0x32,0xd1,0xbd,0x97,0x61,0x54,0xd6,0x80,0xcf,0x0d,
5581 0xbd,0xa2,0x42,0xc7,0xca,0x37,0x91,0x7d,0x9d,0xac,0x8c,0xdf,0x05,0x8a,0x39,
5582 0xc6,0x07,0xc1,0x37,0xe6,0xb9,0xd1,0x0d,0x26,0xec,0xa5,0xb0,0x8a,0x51,0x26,
5583 0x2b,0x4f,0x73,0x44,0x86,0x83,0x5e,0x2b,0x6e,0xcc,0xf8,0x1b,0x85,0x53,0xe9,
5584 0x7a,0x80,0x8f,0x6b,0x42,0x19,0x93 };
5585 static const BYTE signedCTLWithCTLInnerContent[] = {
5586 0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
5587 0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
5588 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
5589 0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
5590 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5591 0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
5592 0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
5593 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
5594 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
5595 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
5596 0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
5597 0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
5598 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
5599 0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5600 0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
5601 0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
5602 0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
5603 0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
5604 0x57,0x6c,0x0b,0x47,0xb8 };
5606 static void test_decodeCTL(DWORD dwEncoding)
5608 static char oid1[] = "1.2.3";
5609 static char oid2[] = "1.5.6";
5610 static BYTE nullData[] = { 5,0 };
5616 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5617 CTL_ENTRY ctlEntry[2];
5618 CRYPT_ATTRIBUTE attr1, attr2;
5619 CRYPT_ATTR_BLOB value1, value2;
5621 memset(&info, 0, sizeof(info));
5622 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTL, sizeof(emptyCTL),
5623 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5624 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5627 compareCTLInfo("empty CTL", &info, (CTL_INFO *)buf);
5632 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTLWithVersion1,
5633 sizeof(emptyCTLWithVersion1), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
5635 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5638 compareCTLInfo("v1 CTL", &info, (CTL_INFO *)buf);
5643 info.SubjectUsage.cUsageIdentifier = 1;
5644 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5645 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithUsageIdentifier,
5646 sizeof(ctlWithUsageIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5648 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5651 compareCTLInfo("CTL with usage identifier", &info, (CTL_INFO *)buf);
5655 info.SubjectUsage.cUsageIdentifier = 0;
5656 info.ListIdentifier.cbData = sizeof(serialNum);
5657 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5658 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithListIdentifier,
5659 sizeof(ctlWithListIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5660 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5663 compareCTLInfo("CTL with list identifier", &info, (CTL_INFO *)buf);
5667 info.ListIdentifier.cbData = 0;
5668 info.SequenceNumber.cbData = sizeof(serialNum);
5669 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5670 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithSequenceNumber,
5671 sizeof(ctlWithSequenceNumber), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5672 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5675 compareCTLInfo("CTL with sequence number", &info, (CTL_INFO *)buf);
5679 info.SequenceNumber.cbData = 0;
5680 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5681 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisUpdate,
5682 sizeof(ctlWithThisUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5683 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5686 compareCTLInfo("CTL with this update", &info, (CTL_INFO *)buf);
5690 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5691 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisAndNextUpdate,
5692 sizeof(ctlWithThisAndNextUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5694 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5697 compareCTLInfo("CTL with this and next update", &info, (CTL_INFO *)buf);
5701 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5702 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5703 info.SubjectAlgorithm.pszObjId = oid2;
5704 info.SubjectAlgorithm.Parameters.cbData = sizeof(nullData);
5705 info.SubjectAlgorithm.Parameters.pbData = nullData;
5706 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithAlgId,
5707 sizeof(ctlWithAlgId), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5708 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5711 compareCTLInfo("CTL with algorithm identifier", &info, (CTL_INFO *)buf);
5715 SetLastError(0xdeadbeef);
5716 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithBogusEntry,
5717 sizeof(ctlWithBogusEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5719 (GetLastError() == CRYPT_E_ASN1_EOD ||
5720 GetLastError() == CRYPT_E_ASN1_CORRUPT ||
5721 GetLastError() == OSS_MORE_INPUT), /* Win9x */
5722 "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n",
5724 info.SubjectAlgorithm.Parameters.cbData = 0;
5725 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5726 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5727 info.SubjectAlgorithm.pszObjId = oid2;
5728 info.SubjectAlgorithm.pszObjId = NULL;
5729 value1.cbData = sizeof(emptySequence);
5730 value1.pbData = (LPBYTE)emptySequence;
5731 attr1.pszObjId = oid1;
5733 attr1.rgValue = &value1;
5734 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5735 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5736 ctlEntry[0].cAttribute = 1;
5737 ctlEntry[0].rgAttribute = &attr1;
5739 info.rgCTLEntry = ctlEntry;
5740 SetLastError(0xdeadbeef);
5741 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithOneEntry,
5742 sizeof(ctlWithOneEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5743 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5746 compareCTLInfo("CTL with one entry", &info, (CTL_INFO *)buf);
5750 value2.cbData = sizeof(encodedIPAddr);
5751 value2.pbData = (LPBYTE)encodedIPAddr;
5752 attr2.pszObjId = oid2;
5754 attr2.rgValue = &value2;
5755 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5756 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5757 ctlEntry[1].cAttribute = 1;
5758 ctlEntry[1].rgAttribute = &attr2;
5760 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithTwoEntries,
5761 sizeof(ctlWithTwoEntries), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5762 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5765 compareCTLInfo("CTL with two entries", &info, (CTL_INFO *)buf);
5769 /* A signed CTL isn't decodable, even if the inner content is a CTL */
5770 SetLastError(0xdeadbeef);
5771 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, signedCTL,
5772 sizeof(signedCTL), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5773 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5774 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5775 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5777 SetLastError(0xdeadbeef);
5778 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL,
5779 signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent),
5780 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5781 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5782 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5783 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5787 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
5788 static const BYTE emptyPKCSContentInfoExtraBytes[] = { 0x30,0x04,0x06,0x02,0x2a,
5790 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
5792 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
5793 0x03,0x02,0x01,0x01 };
5794 static BYTE bogusDER[] = { 1 };
5796 static void test_encodePKCSContentInfo(DWORD dwEncoding)
5801 CRYPT_CONTENT_INFO info = { 0 };
5802 char oid1[] = "1.2.3";
5806 /* Crashes on win9x */
5807 SetLastError(0xdeadbeef);
5808 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL,
5809 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5810 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5811 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5813 SetLastError(0xdeadbeef);
5814 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5815 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5816 ok(!ret && (GetLastError() == E_INVALIDARG ||
5817 GetLastError() == OSS_LIMITED /* Win9x */),
5818 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5819 info.pszObjId = oid1;
5820 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5821 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5822 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5825 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size);
5826 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n");
5829 info.Content.pbData = bogusDER;
5830 info.Content.cbData = sizeof(bogusDER);
5831 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5832 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5833 ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError());
5836 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size);
5837 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n");
5840 info.Content.pbData = (BYTE *)ints[0].encoded;
5841 info.Content.cbData = ints[0].encoded[1] + 2;
5842 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5843 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5846 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size);
5847 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n");
5852 static const BYTE indefiniteSignedPKCSContent[] = {
5853 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
5854 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
5855 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
5856 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
5857 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
5858 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
5859 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5860 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5861 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
5862 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5863 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5864 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
5865 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
5866 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
5867 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
5868 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
5869 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
5870 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
5871 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
5872 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5873 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5874 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
5875 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
5876 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
5877 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
5878 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
5879 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
5880 0x00,0x00,0x00,0x00,0x00,0x00 };
5882 static void test_decodePKCSContentInfo(DWORD dwEncoding)
5887 CRYPT_CONTENT_INFO *info;
5889 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5890 emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo),
5891 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5892 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5895 info = (CRYPT_CONTENT_INFO *)buf;
5897 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5899 ok(info->Content.cbData == 0, "Expected no data, got %d\n",
5900 info->Content.cbData);
5903 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5904 emptyPKCSContentInfoExtraBytes, sizeof(emptyPKCSContentInfoExtraBytes),
5905 0, NULL, NULL, &size);
5906 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5907 SetLastError(0xdeadbeef);
5908 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5909 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo),
5910 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5911 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5912 * I doubt an app depends on that.
5914 ok((!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5915 GetLastError() == CRYPT_E_ASN1_CORRUPT)) || broken(ret),
5916 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5918 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5919 intPKCSContentInfo, sizeof(intPKCSContentInfo),
5920 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5921 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5924 info = (CRYPT_CONTENT_INFO *)buf;
5926 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5928 ok(info->Content.cbData == ints[0].encoded[1] + 2,
5929 "Unexpected size %d\n", info->Content.cbData);
5930 ok(!memcmp(info->Content.pbData, ints[0].encoded,
5931 info->Content.cbData), "Unexpected value\n");
5934 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5935 indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent),
5936 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5937 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5940 info = (CRYPT_CONTENT_INFO *)buf;
5942 ok(!strcmp(info->pszObjId, szOID_RSA_signedData),
5943 "Expected %s, got %s\n", szOID_RSA_signedData, info->pszObjId);
5944 ok(info->Content.cbData == 392, "Expected 392, got %d\n",
5945 info->Content.cbData);
5950 static const BYTE emptyPKCSAttr[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
5952 static const BYTE bogusPKCSAttr[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
5954 static const BYTE intPKCSAttr[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
5957 static void test_encodePKCSAttribute(DWORD dwEncoding)
5959 CRYPT_ATTRIBUTE attr = { 0 };
5963 CRYPT_ATTR_BLOB blob;
5964 char oid[] = "1.2.3";
5968 /* Crashes on win9x */
5969 SetLastError(0xdeadbeef);
5970 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, NULL,
5971 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5972 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5973 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5975 SetLastError(0xdeadbeef);
5976 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5977 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5978 ok(!ret && (GetLastError() == E_INVALIDARG ||
5979 GetLastError() == OSS_LIMITED /* Win9x */),
5980 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5981 attr.pszObjId = oid;
5982 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5983 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5984 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5987 ok(size == sizeof(emptyPKCSAttr), "Unexpected size %d\n", size);
5988 ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n");
5991 blob.cbData = sizeof(bogusDER);
5992 blob.pbData = bogusDER;
5994 attr.rgValue = &blob;
5995 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5996 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5997 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6000 ok(size == sizeof(bogusPKCSAttr), "Unexpected size %d\n", size);
6001 ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n");
6004 blob.pbData = (BYTE *)ints[0].encoded;
6005 blob.cbData = ints[0].encoded[1] + 2;
6006 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
6007 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6010 ok(size == sizeof(intPKCSAttr), "Unexpected size %d\n", size);
6011 ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n");
6016 static void test_decodePKCSAttribute(DWORD dwEncoding)
6021 CRYPT_ATTRIBUTE *attr;
6023 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
6024 emptyPKCSAttr, sizeof(emptyPKCSAttr),
6025 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6026 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6029 attr = (CRYPT_ATTRIBUTE *)buf;
6031 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
6033 ok(attr->cValue == 0, "Expected no value, got %d\n", attr->cValue);
6036 SetLastError(0xdeadbeef);
6037 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
6038 bogusPKCSAttr, sizeof(bogusPKCSAttr),
6039 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6040 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
6041 * I doubt an app depends on that.
6043 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
6044 GetLastError() == CRYPT_E_ASN1_CORRUPT ||
6045 GetLastError() == OSS_MORE_INPUT /* Win9x */),
6046 "Expected CRYPT_E_ASN1_EOD, CRYPT_E_ASN1_CORRUPT, or OSS_MORE_INPUT, got %x\n",
6048 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
6049 intPKCSAttr, sizeof(intPKCSAttr),
6050 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6051 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6054 attr = (CRYPT_ATTRIBUTE *)buf;
6056 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
6058 ok(attr->cValue == 1, "Expected 1 value, got %d\n", attr->cValue);
6059 ok(attr->rgValue[0].cbData == ints[0].encoded[1] + 2,
6060 "Unexpected size %d\n", attr->rgValue[0].cbData);
6061 ok(!memcmp(attr->rgValue[0].pbData, ints[0].encoded,
6062 attr->rgValue[0].cbData), "Unexpected value\n");
6067 static const BYTE emptyPKCSAttributes[] = { 0x31,0x00 };
6068 static const BYTE singlePKCSAttributes[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
6069 0x2a,0x03,0x31,0x00 };
6070 static const BYTE doublePKCSAttributes[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
6071 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
6073 static void test_encodePKCSAttributes(DWORD dwEncoding)
6075 CRYPT_ATTRIBUTES attributes = { 0 };
6076 CRYPT_ATTRIBUTE attr[2] = { { 0 } };
6077 CRYPT_ATTR_BLOB blob;
6081 char oid1[] = "1.2.3", oid2[] = "1.5.6";
6083 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6084 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6085 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6088 ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %d\n", size);
6089 ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n");
6092 attributes.cAttr = 1;
6093 attributes.rgAttr = attr;
6094 SetLastError(0xdeadbeef);
6095 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6096 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6097 ok(!ret && (GetLastError() == E_INVALIDARG ||
6098 GetLastError() == OSS_LIMITED /* Win9x */),
6099 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6100 attr[0].pszObjId = oid1;
6101 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6102 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6105 ok(size == sizeof(singlePKCSAttributes), "Unexpected size %d\n", size);
6106 ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n");
6109 attr[1].pszObjId = oid2;
6111 attr[1].rgValue = &blob;
6112 blob.pbData = (BYTE *)ints[0].encoded;
6113 blob.cbData = ints[0].encoded[1] + 2;
6114 attributes.cAttr = 2;
6115 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6116 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6117 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6120 ok(size == sizeof(doublePKCSAttributes), "Unexpected size %d\n", size);
6121 ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n");
6126 static void test_decodePKCSAttributes(DWORD dwEncoding)
6131 CRYPT_ATTRIBUTES *attributes;
6133 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6134 emptyPKCSAttributes, sizeof(emptyPKCSAttributes),
6135 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6136 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6139 attributes = (CRYPT_ATTRIBUTES *)buf;
6140 ok(attributes->cAttr == 0, "Expected no attributes, got %d\n",
6144 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6145 singlePKCSAttributes, sizeof(singlePKCSAttributes),
6146 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6147 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6150 attributes = (CRYPT_ATTRIBUTES *)buf;
6151 ok(attributes->cAttr == 1, "Expected 1 attribute, got %d\n",
6153 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
6154 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
6155 ok(attributes->rgAttr[0].cValue == 0,
6156 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
6159 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6160 doublePKCSAttributes, sizeof(doublePKCSAttributes),
6161 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6162 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6165 attributes = (CRYPT_ATTRIBUTES *)buf;
6166 ok(attributes->cAttr == 2, "Expected 2 attributes, got %d\n",
6168 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
6169 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
6170 ok(attributes->rgAttr[0].cValue == 0,
6171 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
6172 ok(!strcmp(attributes->rgAttr[1].pszObjId, "1.5.6"),
6173 "Expected 1.5.6, got %s\n", attributes->rgAttr[1].pszObjId);
6174 ok(attributes->rgAttr[1].cValue == 1,
6175 "Expected 1 attribute, got %d\n", attributes->rgAttr[1].cValue);
6176 ok(attributes->rgAttr[1].rgValue[0].cbData == ints[0].encoded[1] + 2,
6177 "Unexpected size %d\n", attributes->rgAttr[1].rgValue[0].cbData);
6178 ok(!memcmp(attributes->rgAttr[1].rgValue[0].pbData, ints[0].encoded,
6179 attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n");
6184 static const BYTE singleCapability[] = {
6185 0x30,0x06,0x30,0x04,0x06,0x02,0x2d,0x06 };
6186 static const BYTE twoCapabilities[] = {
6187 0x30,0x0c,0x30,0x04,0x06,0x02,0x2d,0x06,0x30,0x04,0x06,0x02,0x2a,0x03 };
6188 static const BYTE singleCapabilitywithNULL[] = {
6189 0x30,0x08,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
6191 static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding)
6193 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6197 CRYPT_SMIME_CAPABILITY capability[2];
6198 CRYPT_SMIME_CAPABILITIES capabilities;
6200 /* An empty capabilities is allowed */
6201 capabilities.cCapability = 0;
6202 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6203 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6204 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6207 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
6208 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
6211 /* A non-empty capabilities with an empty capability (lacking an OID) is
6214 capability[0].pszObjId = NULL;
6215 capability[0].Parameters.cbData = 0;
6216 capabilities.cCapability = 1;
6217 capabilities.rgCapability = capability;
6218 SetLastError(0xdeadbeef);
6219 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6220 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6221 ok(!ret && (GetLastError() == E_INVALIDARG ||
6222 GetLastError() == OSS_LIMITED /* Win9x */),
6223 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6224 capability[0].pszObjId = oid1;
6225 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6226 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6227 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6230 ok(size == sizeof(singleCapability), "unexpected size %d\n", size);
6231 ok(!memcmp(buf, singleCapability, size), "unexpected value\n");
6234 capability[1].pszObjId = oid2;
6235 capability[1].Parameters.cbData = 0;
6236 capabilities.cCapability = 2;
6237 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6238 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6239 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6242 ok(size == sizeof(twoCapabilities), "unexpected size %d\n", size);
6243 ok(!memcmp(buf, twoCapabilities, size), "unexpected value\n");
6248 static void compareSMimeCapabilities(LPCSTR header,
6249 const CRYPT_SMIME_CAPABILITIES *expected, const CRYPT_SMIME_CAPABILITIES *got)
6253 ok(got->cCapability == expected->cCapability,
6254 "%s: expected %d capabilities, got %d\n", header, expected->cCapability,
6256 for (i = 0; i < expected->cCapability; i++)
6258 ok(!strcmp(expected->rgCapability[i].pszObjId,
6259 got->rgCapability[i].pszObjId), "%s[%d]: expected %s, got %s\n",
6260 header, i, expected->rgCapability[i].pszObjId,
6261 got->rgCapability[i].pszObjId);
6262 ok(expected->rgCapability[i].Parameters.cbData ==
6263 got->rgCapability[i].Parameters.cbData,
6264 "%s[%d]: expected %d bytes, got %d\n", header, i,
6265 expected->rgCapability[i].Parameters.cbData,
6266 got->rgCapability[i].Parameters.cbData);
6267 if (expected->rgCapability[i].Parameters.cbData)
6268 ok(!memcmp(expected->rgCapability[i].Parameters.pbData,
6269 got->rgCapability[i].Parameters.pbData,
6270 expected->rgCapability[i].Parameters.cbData),
6271 "%s[%d]: unexpected value\n", header, i);
6275 static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding)
6277 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6280 CRYPT_SMIME_CAPABILITY capability[2];
6281 CRYPT_SMIME_CAPABILITIES capabilities, *ptr;
6283 SetLastError(0xdeadbeef);
6284 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6285 emptySequence, sizeof(emptySequence),
6286 CRYPT_DECODE_ALLOC_FLAG, NULL, &ptr, &size);
6287 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6290 capabilities.cCapability = 0;
6291 compareSMimeCapabilities("empty capabilities", &capabilities, ptr);
6294 SetLastError(0xdeadbeef);
6295 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6296 singleCapability, sizeof(singleCapability), CRYPT_DECODE_ALLOC_FLAG, NULL,
6298 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6301 capability[0].pszObjId = oid1;
6302 capability[0].Parameters.cbData = 0;
6303 capabilities.cCapability = 1;
6304 capabilities.rgCapability = capability;
6305 compareSMimeCapabilities("single capability", &capabilities, ptr);
6308 SetLastError(0xdeadbeef);
6309 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6310 singleCapabilitywithNULL, sizeof(singleCapabilitywithNULL),
6311 CRYPT_DECODE_ALLOC_FLAG, NULL, &ptr, &size);
6312 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6315 BYTE NULLparam[] = {0x05, 0x00};
6316 capability[0].pszObjId = oid1;
6317 capability[0].Parameters.cbData = 2;
6318 capability[0].Parameters.pbData = NULLparam;
6319 capabilities.cCapability = 1;
6320 capabilities.rgCapability = capability;
6321 compareSMimeCapabilities("single capability with NULL", &capabilities,
6325 SetLastError(0xdeadbeef);
6326 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6327 twoCapabilities, sizeof(twoCapabilities), CRYPT_DECODE_ALLOC_FLAG, NULL,
6329 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6332 capability[0].Parameters.cbData = 0;
6333 capability[1].pszObjId = oid2;
6334 capability[1].Parameters.cbData = 0;
6335 capabilities.cCapability = 2;
6336 compareSMimeCapabilities("two capabilities", &capabilities, ptr);
6341 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
6342 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
6344 static const BYTE minimalPKCSSigner[] = {
6345 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6346 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6347 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6348 static const BYTE PKCSSignerWithSerial[] = {
6349 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6350 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6351 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
6353 static const BYTE PKCSSignerWithHashAlgo[] = {
6354 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6355 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6356 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
6358 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = {
6359 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6360 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6361 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6362 0x06,0x05,0x00,0x04,0x00 };
6363 static const BYTE PKCSSignerWithHash[] = {
6364 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6365 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6366 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6367 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
6368 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6369 static const BYTE PKCSSignerWithAuthAttr[] = {
6370 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6371 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6372 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
6373 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
6374 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
6375 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
6376 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6378 static void test_encodePKCSSignerInfo(DWORD dwEncoding)
6380 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6384 CMSG_SIGNER_INFO info = { 0 };
6385 char oid_common_name[] = szOID_COMMON_NAME;
6386 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
6387 (LPBYTE)encodedCommonName };
6388 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
6390 SetLastError(0xdeadbeef);
6391 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6392 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6393 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6395 skip("no PKCS7_SIGNER_INFO encode support\n");
6398 ok(!ret && (GetLastError() == E_INVALIDARG ||
6399 GetLastError() == OSS_LIMITED /* Win9x */),
6400 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6401 /* To be encoded, a signer must have an issuer at least, and the encoding
6402 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
6403 * see decoding tests.)
6405 info.Issuer.cbData = sizeof(encodedCommonNameNoNull);
6406 info.Issuer.pbData = encodedCommonNameNoNull;
6407 SetLastError(0xdeadbeef);
6408 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6409 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6410 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6411 ok(!ret && GetLastError() == E_INVALIDARG,
6412 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6415 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6416 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6419 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6420 if (size == sizeof(minimalPKCSSigner))
6421 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6423 ok(0, "Unexpected value\n");
6427 info.SerialNumber.cbData = sizeof(serialNum);
6428 info.SerialNumber.pbData = (BYTE *)serialNum;
6429 SetLastError(0xdeadbeef);
6430 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6431 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6432 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6433 ok(!ret && GetLastError() == E_INVALIDARG,
6434 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6437 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6438 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6441 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6443 if (size == sizeof(PKCSSignerWithSerial))
6444 ok(!memcmp(buf, PKCSSignerWithSerial, size),
6445 "Unexpected value\n");
6447 ok(0, "Unexpected value\n");
6451 info.HashAlgorithm.pszObjId = oid1;
6452 SetLastError(0xdeadbeef);
6453 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6454 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6455 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6456 ok(!ret && GetLastError() == E_INVALIDARG,
6457 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6460 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6461 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6464 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6466 if (size == sizeof(PKCSSignerWithHashAlgo))
6467 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6468 "Unexpected value\n");
6470 ok(0, "Unexpected value\n");
6474 info.HashEncryptionAlgorithm.pszObjId = oid2;
6475 SetLastError(0xdeadbeef);
6476 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6477 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6478 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6479 ok(!ret && GetLastError() == E_INVALIDARG,
6480 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6483 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6486 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6487 "Unexpected size %d\n", size);
6488 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo))
6489 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6490 "Unexpected value\n");
6492 ok(0, "Unexpected value\n");
6496 info.EncryptedHash.cbData = sizeof(hash);
6497 info.EncryptedHash.pbData = (BYTE *)hash;
6498 SetLastError(0xdeadbeef);
6499 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6500 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6501 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6502 ok(!ret && GetLastError() == E_INVALIDARG,
6503 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6506 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6509 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6511 if (size == sizeof(PKCSSignerWithHash))
6512 ok(!memcmp(buf, PKCSSignerWithHash, size),
6513 "Unexpected value\n");
6515 ok(0, "Unexpected value\n");
6519 info.AuthAttrs.cAttr = 1;
6520 info.AuthAttrs.rgAttr = &attr;
6521 SetLastError(0xdeadbeef);
6522 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6523 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6524 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6525 ok(!ret && GetLastError() == E_INVALIDARG,
6526 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6529 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6532 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
6534 if (size == sizeof(PKCSSignerWithAuthAttr))
6535 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
6536 "Unexpected value\n");
6538 ok(0, "Unexpected value\n");
6544 static void test_decodePKCSSignerInfo(DWORD dwEncoding)
6549 CMSG_SIGNER_INFO *info;
6551 /* A PKCS signer can't be decoded without a serial number. */
6552 SetLastError(0xdeadbeef);
6553 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6554 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6555 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6556 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
6557 GetLastError() == OSS_DATA_ERROR /* Win9x */),
6558 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %x\n",
6560 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6561 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6562 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6563 ok(ret || broken(GetLastError() == OSS_DATA_ERROR),
6564 "CryptDecodeObjectEx failed: %x\n", GetLastError());
6567 info = (CMSG_SIGNER_INFO *)buf;
6568 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6570 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6571 "Unexpected size %d\n", info->Issuer.cbData);
6572 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6573 info->Issuer.cbData), "Unexpected value\n");
6574 ok(info->SerialNumber.cbData == sizeof(serialNum),
6575 "Unexpected size %d\n", info->SerialNumber.cbData);
6576 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6577 "Unexpected value\n");
6580 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6581 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6582 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6585 info = (CMSG_SIGNER_INFO *)buf;
6586 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6588 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6589 "Unexpected size %d\n", info->Issuer.cbData);
6590 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6591 info->Issuer.cbData), "Unexpected value\n");
6592 ok(info->SerialNumber.cbData == sizeof(serialNum),
6593 "Unexpected size %d\n", info->SerialNumber.cbData);
6594 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6595 "Unexpected value\n");
6596 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6597 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6600 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6601 PKCSSignerWithHashAndEncryptionAlgo,
6602 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6606 info = (CMSG_SIGNER_INFO *)buf;
6607 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6609 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6610 "Unexpected size %d\n", info->Issuer.cbData);
6611 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6612 info->Issuer.cbData), "Unexpected value\n");
6613 ok(info->SerialNumber.cbData == sizeof(serialNum),
6614 "Unexpected size %d\n", info->SerialNumber.cbData);
6615 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6616 "Unexpected value\n");
6617 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6618 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6619 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6620 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6623 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6624 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6625 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6628 info = (CMSG_SIGNER_INFO *)buf;
6629 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6631 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6632 "Unexpected size %d\n", info->Issuer.cbData);
6633 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6634 info->Issuer.cbData), "Unexpected value\n");
6635 ok(info->SerialNumber.cbData == sizeof(serialNum),
6636 "Unexpected size %d\n", info->SerialNumber.cbData);
6637 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6638 "Unexpected value\n");
6639 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6640 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6641 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6642 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6643 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6644 info->EncryptedHash.cbData);
6645 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6646 "Unexpected value\n");
6649 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6650 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
6651 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6654 info = (CMSG_SIGNER_INFO *)buf;
6655 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n",
6656 info->AuthAttrs.cAttr);
6657 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
6658 "Expected %s, got %s\n", szOID_COMMON_NAME,
6659 info->AuthAttrs.rgAttr[0].pszObjId);
6660 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
6661 info->AuthAttrs.rgAttr[0].cValue);
6662 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
6663 sizeof(encodedCommonName), "Unexpected size %d\n",
6664 info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
6665 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
6666 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
6671 static const BYTE CMSSignerWithKeyId[] = {
6672 0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,
6673 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6675 static void test_encodeCMSSignerInfo(DWORD dwEncoding)
6680 CMSG_CMS_SIGNER_INFO info = { 0 };
6681 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6683 SetLastError(0xdeadbeef);
6684 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6685 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6686 ok(!ret, "Expected failure, got %d\n", ret);
6687 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6689 skip("no CMS_SIGNER_INFO encode support\n");
6692 ok(GetLastError() == E_INVALIDARG,
6693 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6694 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6695 SetLastError(0xdeadbeef);
6696 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6697 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6698 ok(!ret, "Expected failure, got %d\n", ret);
6699 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6701 skip("no CMS_SIGNER_INFO encode support\n");
6704 ok(GetLastError() == E_INVALIDARG,
6705 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6706 /* To be encoded, a signer must have a valid cert ID, where a valid ID may
6707 * be a key id or a issuer serial number with at least the issuer set, and
6708 * the encoding must include PKCS_7_ASN_ENCODING.
6709 * (That isn't enough to be decoded, see decoding tests.)
6711 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6712 sizeof(encodedCommonNameNoNull);
6713 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6714 SetLastError(0xdeadbeef);
6715 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6716 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6717 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6718 ok(!ret && GetLastError() == E_INVALIDARG,
6719 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6722 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6725 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6726 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6730 U(info.SignerId).IssuerSerialNumber.SerialNumber.cbData = sizeof(serialNum);
6731 U(info.SignerId).IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
6732 SetLastError(0xdeadbeef);
6733 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6734 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6735 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6736 ok(!ret && GetLastError() == E_INVALIDARG,
6737 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6740 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6743 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6745 ok(!memcmp(buf, PKCSSignerWithSerial, size), "Unexpected value\n");
6749 info.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
6750 U(info.SignerId).KeyId.cbData = sizeof(serialNum);
6751 U(info.SignerId).KeyId.pbData = (BYTE *)serialNum;
6752 SetLastError(0xdeadbeef);
6753 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6754 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6755 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6756 ok(!ret && GetLastError() == E_INVALIDARG,
6757 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6760 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6763 ok(size == sizeof(CMSSignerWithKeyId), "Unexpected size %d\n",
6765 ok(!memcmp(buf, CMSSignerWithKeyId, size), "Unexpected value\n");
6769 /* While a CERT_ID can have a hash type, that's not allowed in CMS, where
6770 * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed
6771 * (see RFC 3852, section 5.3.)
6773 info.SignerId.dwIdChoice = CERT_ID_SHA1_HASH;
6774 U(info.SignerId).HashId.cbData = sizeof(hash);
6775 U(info.SignerId).HashId.pbData = (BYTE *)hash;
6776 SetLastError(0xdeadbeef);
6777 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6778 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6779 ok(!ret && GetLastError() == E_INVALIDARG,
6780 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6781 /* Now with a hash algo */
6782 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6783 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6784 sizeof(encodedCommonNameNoNull);
6785 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6786 info.HashAlgorithm.pszObjId = oid1;
6787 SetLastError(0xdeadbeef);
6788 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6789 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6790 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6791 ok(!ret && GetLastError() == E_INVALIDARG,
6792 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6795 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6798 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6800 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6801 "Unexpected value\n");
6805 info.HashEncryptionAlgorithm.pszObjId = oid2;
6806 SetLastError(0xdeadbeef);
6807 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6808 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6809 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6810 ok(!ret && GetLastError() == E_INVALIDARG,
6811 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6814 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6817 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6818 "Unexpected size %d\n", size);
6819 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6820 "Unexpected value\n");
6824 info.EncryptedHash.cbData = sizeof(hash);
6825 info.EncryptedHash.pbData = (BYTE *)hash;
6826 SetLastError(0xdeadbeef);
6827 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6828 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6829 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6830 ok(!ret && GetLastError() == E_INVALIDARG,
6831 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6834 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6837 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6839 ok(!memcmp(buf, PKCSSignerWithHash, size), "Unexpected value\n");
6845 static void test_decodeCMSSignerInfo(DWORD dwEncoding)
6850 CMSG_CMS_SIGNER_INFO *info;
6851 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6853 /* A CMS signer can't be decoded without a serial number. */
6854 SetLastError(0xdeadbeef);
6855 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6856 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6857 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6858 ok(!ret, "expected failure\n");
6859 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6861 skip("no CMS_SIGNER_INFO decode support\n");
6864 ok(GetLastError() == CRYPT_E_ASN1_CORRUPT,
6865 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
6866 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6867 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6868 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6869 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6872 info = (CMSG_CMS_SIGNER_INFO *)buf;
6873 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6875 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6876 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6877 info->SignerId.dwIdChoice);
6878 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6879 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6880 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6881 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6882 encodedCommonNameNoNull,
6883 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6884 "Unexpected value\n");
6885 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6886 sizeof(serialNum), "Unexpected size %d\n",
6887 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6888 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6889 serialNum, sizeof(serialNum)), "Unexpected value\n");
6892 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6893 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6894 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6895 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6898 info = (CMSG_CMS_SIGNER_INFO *)buf;
6899 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6901 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6902 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6903 info->SignerId.dwIdChoice);
6904 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6905 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6906 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6907 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6908 encodedCommonNameNoNull,
6909 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6910 "Unexpected value\n");
6911 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6912 sizeof(serialNum), "Unexpected size %d\n",
6913 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6914 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6915 serialNum, sizeof(serialNum)), "Unexpected value\n");
6916 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6917 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6920 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6921 PKCSSignerWithHashAndEncryptionAlgo,
6922 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6924 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6927 info = (CMSG_CMS_SIGNER_INFO *)buf;
6928 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6930 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6931 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6932 info->SignerId.dwIdChoice);
6933 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6934 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6935 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6936 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6937 encodedCommonNameNoNull,
6938 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6939 "Unexpected value\n");
6940 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6941 sizeof(serialNum), "Unexpected size %d\n",
6942 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6943 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6944 serialNum, sizeof(serialNum)), "Unexpected value\n");
6945 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6946 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6947 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6948 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6951 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6952 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6953 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6954 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6957 info = (CMSG_CMS_SIGNER_INFO *)buf;
6958 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6960 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6961 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6962 info->SignerId.dwIdChoice);
6963 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6964 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6965 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6966 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6967 encodedCommonNameNoNull,
6968 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6969 "Unexpected value\n");
6970 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6971 sizeof(serialNum), "Unexpected size %d\n",
6972 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6973 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6974 serialNum, sizeof(serialNum)), "Unexpected value\n");
6975 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6976 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6977 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6978 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6979 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6980 info->EncryptedHash.cbData);
6981 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6982 "Unexpected value\n");
6985 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6986 CMSSignerWithKeyId, sizeof(CMSSignerWithKeyId),
6987 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6988 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6991 info = (CMSG_CMS_SIGNER_INFO *)buf;
6992 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6994 ok(info->SignerId.dwIdChoice == CERT_ID_KEY_IDENTIFIER,
6995 "Expected CERT_ID_KEY_IDENTIFIER, got %d\n",
6996 info->SignerId.dwIdChoice);
6997 ok(U(info->SignerId).KeyId.cbData == sizeof(serialNum),
6998 "Unexpected size %d\n", U(info->SignerId).KeyId.cbData);
6999 ok(!memcmp(U(info->SignerId).KeyId.pbData, serialNum, sizeof(serialNum)),
7000 "Unexpected value\n");
7005 static BYTE emptyDNSPermittedConstraints[] = {
7006 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
7007 static BYTE emptyDNSExcludedConstraints[] = {
7008 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
7009 static BYTE DNSExcludedConstraints[] = {
7010 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
7011 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7012 static BYTE permittedAndExcludedConstraints[] = {
7013 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7014 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
7015 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7016 static BYTE permittedAndExcludedWithMinConstraints[] = {
7017 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7018 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
7019 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7020 static BYTE permittedAndExcludedWithMinMaxConstraints[] = {
7021 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7022 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
7023 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7025 static void test_encodeNameConstraints(DWORD dwEncoding)
7028 CERT_NAME_CONSTRAINTS_INFO constraints = { 0 };
7029 CERT_GENERAL_SUBTREE permitted = { { 0 } };
7030 CERT_GENERAL_SUBTREE excluded = { { 0 } };
7034 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7035 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7036 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7038 skip("no X509_NAME_CONSTRAINTS encode support\n");
7041 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7044 ok(size == sizeof(emptySequence), "Unexpected size\n");
7045 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
7048 constraints.cPermittedSubtree = 1;
7049 constraints.rgPermittedSubtree = &permitted;
7050 SetLastError(0xdeadbeef);
7051 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7052 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7053 ok(!ret && GetLastError() == E_INVALIDARG,
7054 "Expected E_INVALIDARG, got %08x\n", GetLastError());
7055 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
7056 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7057 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7058 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7061 ok(size == sizeof(emptyDNSPermittedConstraints), "Unexpected size\n");
7062 ok(!memcmp(buf, emptyDNSPermittedConstraints, size),
7063 "Unexpected value\n");
7066 constraints.cPermittedSubtree = 0;
7067 constraints.cExcludedSubtree = 1;
7068 constraints.rgExcludedSubtree = &excluded;
7069 excluded.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
7070 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7071 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7072 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7075 ok(size == sizeof(emptyDNSExcludedConstraints), "Unexpected size\n");
7076 ok(!memcmp(buf, emptyDNSExcludedConstraints, size),
7077 "Unexpected value\n");
7080 U(excluded.Base).pwszURL = (LPWSTR)url;
7081 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7082 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7083 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7086 ok(size == sizeof(DNSExcludedConstraints), "Unexpected size\n");
7087 ok(!memcmp(buf, DNSExcludedConstraints, size),
7088 "Unexpected value\n");
7091 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
7092 U(permitted.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7093 U(permitted.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7094 constraints.cPermittedSubtree = 1;
7095 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7096 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7097 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7100 ok(size == sizeof(permittedAndExcludedConstraints),
7101 "Unexpected size\n");
7102 ok(!memcmp(buf, permittedAndExcludedConstraints, size),
7103 "Unexpected value\n");
7106 permitted.dwMinimum = 5;
7107 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7108 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7109 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7112 ok(size == sizeof(permittedAndExcludedWithMinConstraints),
7113 "Unexpected size\n");
7114 ok(!memcmp(buf, permittedAndExcludedWithMinConstraints, size),
7115 "Unexpected value\n");
7118 permitted.fMaximum = TRUE;
7119 permitted.dwMaximum = 3;
7120 SetLastError(0xdeadbeef);
7121 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7122 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7123 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7126 ok(size == sizeof(permittedAndExcludedWithMinMaxConstraints),
7127 "Unexpected size\n");
7128 ok(!memcmp(buf, permittedAndExcludedWithMinMaxConstraints, size),
7129 "Unexpected value\n");
7134 struct EncodedNameConstraints
7136 CRYPT_DATA_BLOB encoded;
7137 CERT_NAME_CONSTRAINTS_INFO constraints;
7140 static CERT_GENERAL_SUBTREE emptyDNSSubtree = {
7141 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
7142 static CERT_GENERAL_SUBTREE DNSSubtree = {
7143 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
7144 static CERT_GENERAL_SUBTREE IPAddressSubtree = {
7145 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 0 };
7146 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree = {
7147 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, 0 };
7148 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree = {
7149 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, TRUE, 3 };
7151 struct EncodedNameConstraints encodedNameConstraints[] = {
7152 { { sizeof(emptySequence), (LPBYTE)emptySequence }, { 0 } },
7153 { { sizeof(emptyDNSPermittedConstraints), emptyDNSPermittedConstraints },
7154 { 1, &emptyDNSSubtree, 0, NULL } },
7155 { { sizeof(emptyDNSExcludedConstraints), emptyDNSExcludedConstraints },
7156 { 0, NULL, 1, &emptyDNSSubtree } },
7157 { { sizeof(DNSExcludedConstraints), DNSExcludedConstraints },
7158 { 0, NULL, 1, &DNSSubtree } },
7159 { { sizeof(permittedAndExcludedConstraints), permittedAndExcludedConstraints },
7160 { 1, &IPAddressSubtree, 1, &DNSSubtree } },
7161 { { sizeof(permittedAndExcludedWithMinConstraints),
7162 permittedAndExcludedWithMinConstraints },
7163 { 1, &IPAddressWithMinSubtree, 1, &DNSSubtree } },
7164 { { sizeof(permittedAndExcludedWithMinMaxConstraints),
7165 permittedAndExcludedWithMinMaxConstraints },
7166 { 1, &IPAddressWithMinMaxSubtree, 1, &DNSSubtree } },
7169 static void test_decodeNameConstraints(DWORD dwEncoding)
7173 CERT_NAME_CONSTRAINTS_INFO *constraints;
7175 U(DNSSubtree.Base).pwszURL = (LPWSTR)url;
7176 U(IPAddressSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7177 U(IPAddressSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7178 U(IPAddressWithMinSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7179 U(IPAddressWithMinSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7180 U(IPAddressWithMinMaxSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7181 U(IPAddressWithMinMaxSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7183 i < sizeof(encodedNameConstraints) / sizeof(encodedNameConstraints[0]);
7188 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS,
7189 encodedNameConstraints[i].encoded.pbData,
7190 encodedNameConstraints[i].encoded.cbData,
7191 CRYPT_DECODE_ALLOC_FLAG, NULL, &constraints, &size);
7192 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7194 skip("no X509_NAME_CONSTRAINTS decode support\n");
7197 ok(ret, "%d: CryptDecodeObjectEx failed: %08x\n", i, GetLastError());
7202 if (constraints->cPermittedSubtree !=
7203 encodedNameConstraints[i].constraints.cPermittedSubtree)
7204 fprintf(stderr, "%d: expected %d permitted, got %d\n", i,
7205 encodedNameConstraints[i].constraints.cPermittedSubtree,
7206 constraints->cPermittedSubtree);
7207 if (constraints->cPermittedSubtree ==
7208 encodedNameConstraints[i].constraints.cPermittedSubtree)
7210 for (j = 0; j < constraints->cPermittedSubtree; j++)
7212 compareAltNameEntry(&constraints->rgPermittedSubtree[j].Base,
7213 &encodedNameConstraints[i].constraints.rgPermittedSubtree[j].Base);
7216 if (constraints->cExcludedSubtree !=
7217 encodedNameConstraints[i].constraints.cExcludedSubtree)
7218 fprintf(stderr, "%d: expected %d excluded, got %d\n", i,
7219 encodedNameConstraints[i].constraints.cExcludedSubtree,
7220 constraints->cExcludedSubtree);
7221 if (constraints->cExcludedSubtree ==
7222 encodedNameConstraints[i].constraints.cExcludedSubtree)
7224 for (j = 0; j < constraints->cExcludedSubtree; j++)
7226 compareAltNameEntry(&constraints->rgExcludedSubtree[j].Base,
7227 &encodedNameConstraints[i].constraints.rgExcludedSubtree[j].Base);
7230 LocalFree(constraints);
7235 static WCHAR noticeText[] = { 'T','h','i','s',' ','i','s',' ','a',' ',
7236 'n','o','t','i','c','e',0 };
7237 static const BYTE noticeWithDisplayText[] = {
7238 0x30,0x22,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,0x00,
7239 0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,0x74,
7240 0x00,0x69,0x00,0x63,0x00,0x65
7242 static char org[] = "Wine";
7243 static int noticeNumbers[] = { 2,3 };
7244 static BYTE noticeWithReference[] = {
7245 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7246 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7247 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7248 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7251 static void test_encodePolicyQualifierUserNotice(DWORD dwEncoding)
7256 CERT_POLICY_QUALIFIER_USER_NOTICE notice;
7257 CERT_POLICY_QUALIFIER_NOTICE_REFERENCE reference;
7259 memset(¬ice, 0, sizeof(notice));
7260 ret = pCryptEncodeObjectEx(dwEncoding,
7261 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, ¬ice, CRYPT_ENCODE_ALLOC_FLAG,
7263 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7265 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE encode support\n");
7268 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7271 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size);
7272 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
7275 notice.pszDisplayText = noticeText;
7276 ret = pCryptEncodeObjectEx(dwEncoding,
7277 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, ¬ice, CRYPT_ENCODE_ALLOC_FLAG,
7279 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7282 ok(sizeof(noticeWithDisplayText) == size, "unexpected size %d\n", size);
7283 ok(!memcmp(buf, noticeWithDisplayText, size), "unexpected value\n");
7286 reference.pszOrganization = org;
7287 reference.cNoticeNumbers = 2;
7288 reference.rgNoticeNumbers = noticeNumbers;
7289 notice.pNoticeReference = &reference;
7290 ret = pCryptEncodeObjectEx(dwEncoding,
7291 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, ¬ice, CRYPT_ENCODE_ALLOC_FLAG,
7293 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7296 ok(sizeof(noticeWithReference) == size, "unexpected size %d\n", size);
7297 ok(!memcmp(buf, noticeWithReference, size), "unexpected value\n");
7302 static void test_decodePolicyQualifierUserNotice(DWORD dwEncoding)
7305 CERT_POLICY_QUALIFIER_USER_NOTICE *notice;
7308 ret = pCryptDecodeObjectEx(dwEncoding,
7309 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7310 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7312 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7314 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE decode support\n");
7317 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7320 ok(notice->pszDisplayText == NULL, "unexpected display text\n");
7321 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7324 ret = pCryptDecodeObjectEx(dwEncoding,
7325 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7326 noticeWithDisplayText, sizeof(noticeWithDisplayText),
7327 CRYPT_DECODE_ALLOC_FLAG, NULL, ¬ice, &size);
7328 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7331 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7332 "unexpected display text\n");
7333 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7336 ret = pCryptDecodeObjectEx(dwEncoding,
7337 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7338 noticeWithReference, sizeof(noticeWithReference),
7339 CRYPT_DECODE_ALLOC_FLAG, NULL, ¬ice, &size);
7340 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7343 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7344 "unexpected display text\n");
7345 ok(notice->pNoticeReference != NULL, "expected a notice reference\n");
7346 if (notice->pNoticeReference)
7348 ok(!strcmp(notice->pNoticeReference->pszOrganization, org),
7349 "unexpected organization %s\n",
7350 notice->pNoticeReference->pszOrganization);
7351 ok(notice->pNoticeReference->cNoticeNumbers == 2,
7352 "expected 2 notice numbers, got %d\n",
7353 notice->pNoticeReference->cNoticeNumbers);
7354 ok(notice->pNoticeReference->rgNoticeNumbers[0] == noticeNumbers[0],
7355 "unexpected notice number %d\n",
7356 notice->pNoticeReference->rgNoticeNumbers[0]);
7357 ok(notice->pNoticeReference->rgNoticeNumbers[1] == noticeNumbers[1],
7358 "unexpected notice number %d\n",
7359 notice->pNoticeReference->rgNoticeNumbers[1]);
7365 static char oid_any_policy[] = "2.5.29.32.0";
7366 static const BYTE policiesWithAnyPolicy[] = {
7367 0x30,0x08,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00
7369 static char oid1[] = "1.2.3";
7370 static char oid_user_notice[] = "1.3.6.1.5.5.7.2.2";
7371 static const BYTE twoPolicies[] = {
7372 0x30,0x50,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00,0x30,0x46,0x06,0x02,0x2a,
7373 0x03,0x30,0x40,0x30,0x3e,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x02,
7374 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7375 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7376 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7377 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7380 static void test_encodeCertPolicies(DWORD dwEncoding)
7383 CERT_POLICIES_INFO info;
7384 CERT_POLICY_INFO policy[2];
7385 CERT_POLICY_QUALIFIER_INFO qualifier;
7389 memset(&info, 0, sizeof(info));
7390 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7391 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7392 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7395 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size);
7396 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
7399 memset(policy, 0, sizeof(policy));
7400 info.cPolicyInfo = 1;
7401 info.rgPolicyInfo = policy;
7402 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7403 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7404 ok(!ret && (GetLastError() == E_INVALIDARG ||
7405 GetLastError() == OSS_LIMITED /* Win9x/NT4 */),
7406 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
7407 policy[0].pszPolicyIdentifier = oid_any_policy;
7408 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7409 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7410 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7413 ok(sizeof(policiesWithAnyPolicy) == size, "unexpected size %d\n", size);
7414 ok(!memcmp(buf, policiesWithAnyPolicy, size), "unexpected value\n");
7417 policy[1].pszPolicyIdentifier = oid1;
7418 memset(&qualifier, 0, sizeof(qualifier));
7419 qualifier.pszPolicyQualifierId = oid_user_notice;
7420 qualifier.Qualifier.cbData = sizeof(noticeWithReference);
7421 qualifier.Qualifier.pbData = noticeWithReference;
7422 policy[1].cPolicyQualifier = 1;
7423 policy[1].rgPolicyQualifier = &qualifier;
7424 info.cPolicyInfo = 2;
7425 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7426 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7427 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7430 ok(sizeof(twoPolicies) == size, "unexpected size %d\n", size);
7431 ok(!memcmp(buf, twoPolicies, size), "unexpected value\n");
7436 static void test_decodeCertPolicies(DWORD dwEncoding)
7439 CERT_POLICIES_INFO *info;
7442 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7443 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7445 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7448 ok(info->cPolicyInfo == 0, "unexpected policy info %d\n",
7452 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7453 policiesWithAnyPolicy, sizeof(policiesWithAnyPolicy),
7454 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7455 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7458 ok(info->cPolicyInfo == 1, "unexpected policy info %d\n",
7460 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy),
7461 "unexpected policy id %s\n",
7462 info->rgPolicyInfo[0].pszPolicyIdentifier);
7463 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0,
7464 "unexpected policy qualifier count %d\n",
7465 info->rgPolicyInfo[0].cPolicyQualifier);
7468 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7469 twoPolicies, sizeof(twoPolicies),
7470 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7471 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7474 ok(info->cPolicyInfo == 2, "unexpected policy info %d\n",
7476 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy),
7477 "unexpected policy id %s\n",
7478 info->rgPolicyInfo[0].pszPolicyIdentifier);
7479 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0,
7480 "unexpected policy qualifier count %d\n",
7481 info->rgPolicyInfo[0].cPolicyQualifier);
7482 ok(!strcmp(info->rgPolicyInfo[1].pszPolicyIdentifier, oid1),
7483 "unexpected policy id %s\n",
7484 info->rgPolicyInfo[1].pszPolicyIdentifier);
7485 ok(info->rgPolicyInfo[1].cPolicyQualifier == 1,
7486 "unexpected policy qualifier count %d\n",
7487 info->rgPolicyInfo[1].cPolicyQualifier);
7489 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId,
7490 oid_user_notice), "unexpected policy qualifier id %s\n",
7491 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId);
7492 ok(info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData ==
7493 sizeof(noticeWithReference), "unexpected qualifier size %d\n",
7494 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData);
7496 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.pbData,
7497 noticeWithReference, sizeof(noticeWithReference)),
7498 "unexpected qualifier value\n");
7503 static const BYTE policyMappingWithOneMapping[] = {
7504 0x30,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04 };
7505 static const BYTE policyMappingWithTwoMappings[] = {
7506 0x30,0x14,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04,0x30,0x08,0x06,
7507 0x02,0x2b,0x04,0x06,0x02,0x55,0x06 };
7508 static const LPCSTR mappingOids[] = { X509_POLICY_MAPPINGS,
7509 szOID_POLICY_MAPPINGS, szOID_LEGACY_POLICY_MAPPINGS };
7511 static void test_encodeCertPolicyMappings(DWORD dwEncoding)
7513 static char oid2[] = "2.3.4";
7514 static char oid3[] = "1.3.4";
7515 static char oid4[] = "2.5.6";
7517 CERT_POLICY_MAPPINGS_INFO info = { 0 };
7518 CERT_POLICY_MAPPING mapping[2];
7522 /* Each of the mapping OIDs is equivalent, so check with all of them */
7523 for (i = 0; i < sizeof(mappingOids) / sizeof(mappingOids[0]); i++)
7525 memset(&info, 0, sizeof(info));
7526 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7527 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7528 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7531 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
7532 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
7533 "unexpected value\n");
7536 mapping[0].pszIssuerDomainPolicy = NULL;
7537 mapping[0].pszSubjectDomainPolicy = NULL;
7538 info.cPolicyMapping = 1;
7539 info.rgPolicyMapping = mapping;
7540 SetLastError(0xdeadbeef);
7541 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7542 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7543 ok(!ret && GetLastError() == E_INVALIDARG,
7544 "expected E_INVALIDARG, got %08x\n", GetLastError());
7545 mapping[0].pszIssuerDomainPolicy = oid1;
7546 mapping[0].pszSubjectDomainPolicy = oid2;
7547 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7548 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7549 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7552 ok(size == sizeof(policyMappingWithOneMapping),
7553 "unexpected size %d\n", size);
7554 ok(!memcmp(buf, policyMappingWithOneMapping, size),
7555 "unexpected value\n");
7558 mapping[1].pszIssuerDomainPolicy = oid3;
7559 mapping[1].pszSubjectDomainPolicy = oid4;
7560 info.cPolicyMapping = 2;
7561 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7562 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7563 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7566 ok(size == sizeof(policyMappingWithTwoMappings),
7567 "unexpected size %d\n", size);
7568 ok(!memcmp(buf, policyMappingWithTwoMappings, size),
7569 "unexpected value\n");
7575 static void test_decodeCertPolicyMappings(DWORD dwEncoding)
7578 CERT_POLICY_MAPPINGS_INFO *info;
7581 /* Each of the mapping OIDs is equivalent, so check with all of them */
7582 for (i = 0; i < sizeof(mappingOids) / sizeof(mappingOids[0]); i++)
7584 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7585 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7587 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7590 ok(info->cPolicyMapping == 0,
7591 "expected 0 policy mappings, got %d\n", info->cPolicyMapping);
7594 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7595 policyMappingWithOneMapping, sizeof(policyMappingWithOneMapping),
7596 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7597 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7600 ok(info->cPolicyMapping == 1,
7601 "expected 1 policy mappings, got %d\n", info->cPolicyMapping);
7602 ok(!strcmp(info->rgPolicyMapping[0].pszIssuerDomainPolicy, "1.2.3"),
7603 "unexpected issuer policy %s\n",
7604 info->rgPolicyMapping[0].pszIssuerDomainPolicy);
7605 ok(!strcmp(info->rgPolicyMapping[0].pszSubjectDomainPolicy,
7606 "2.3.4"), "unexpected subject policy %s\n",
7607 info->rgPolicyMapping[0].pszSubjectDomainPolicy);
7610 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7611 policyMappingWithTwoMappings, sizeof(policyMappingWithTwoMappings),
7612 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7613 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7616 ok(info->cPolicyMapping == 2,
7617 "expected 2 policy mappings, got %d\n", info->cPolicyMapping);
7618 ok(!strcmp(info->rgPolicyMapping[0].pszIssuerDomainPolicy, "1.2.3"),
7619 "unexpected issuer policy %s\n",
7620 info->rgPolicyMapping[0].pszIssuerDomainPolicy);
7621 ok(!strcmp(info->rgPolicyMapping[0].pszSubjectDomainPolicy,
7622 "2.3.4"), "unexpected subject policy %s\n",
7623 info->rgPolicyMapping[0].pszSubjectDomainPolicy);
7624 ok(!strcmp(info->rgPolicyMapping[1].pszIssuerDomainPolicy, "1.3.4"),
7625 "unexpected issuer policy %s\n",
7626 info->rgPolicyMapping[1].pszIssuerDomainPolicy);
7627 ok(!strcmp(info->rgPolicyMapping[1].pszSubjectDomainPolicy,
7628 "2.5.6"), "unexpected subject policy %s\n",
7629 info->rgPolicyMapping[1].pszSubjectDomainPolicy);
7635 static const BYTE policyConstraintsWithRequireExplicit[] = {
7636 0x30,0x03,0x80,0x01,0x00 };
7637 static const BYTE policyConstraintsWithInhibitMapping[] = {
7638 0x30,0x03,0x81,0x01,0x01 };
7639 static const BYTE policyConstraintsWithBoth[] = {
7640 0x30,0x06,0x80,0x01,0x01,0x81,0x01,0x01 };
7642 static void test_encodeCertPolicyConstraints(DWORD dwEncoding)
7644 CERT_POLICY_CONSTRAINTS_INFO info = { 0 };
7649 /* Even though RFC 5280 explicitly states CAs must not issue empty
7650 * policy constraints (section 4.2.1.11), the API doesn't prevent it.
7652 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7653 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7654 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7657 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
7658 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
7659 "unexpected value\n");
7662 /* If fRequireExplicitPolicy is set but dwRequireExplicitPolicySkipCerts
7663 * is not, then a skip of 0 is encoded.
7665 info.fRequireExplicitPolicy = TRUE;
7666 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7667 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7668 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7671 ok(size == sizeof(policyConstraintsWithRequireExplicit),
7672 "unexpected size %d\n", size);
7673 ok(!memcmp(buf, policyConstraintsWithRequireExplicit,
7674 sizeof(policyConstraintsWithRequireExplicit)), "unexpected value\n");
7677 /* With inhibit policy mapping */
7678 info.fRequireExplicitPolicy = FALSE;
7679 info.dwRequireExplicitPolicySkipCerts = 0;
7680 info.fInhibitPolicyMapping = TRUE;
7681 info.dwInhibitPolicyMappingSkipCerts = 1;
7682 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7683 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7684 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7687 ok(size == sizeof(policyConstraintsWithInhibitMapping),
7688 "unexpected size %d\n", size);
7689 ok(!memcmp(buf, policyConstraintsWithInhibitMapping,
7690 sizeof(policyConstraintsWithInhibitMapping)), "unexpected value\n");
7694 info.fRequireExplicitPolicy = TRUE;
7695 info.dwRequireExplicitPolicySkipCerts = 1;
7696 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7697 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7698 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7701 ok(size == sizeof(policyConstraintsWithBoth), "unexpected size %d\n",
7703 ok(!memcmp(buf, policyConstraintsWithBoth,
7704 sizeof(policyConstraintsWithBoth)), "unexpected value\n");
7709 static void test_decodeCertPolicyConstraints(DWORD dwEncoding)
7711 CERT_POLICY_CONSTRAINTS_INFO *info;
7715 /* Again, even though CAs must not issue such constraints, they can be
7718 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7719 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7721 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7724 ok(!info->fRequireExplicitPolicy,
7725 "expected require explicit = FALSE\n");
7726 ok(!info->fInhibitPolicyMapping,
7727 "expected implicit mapping = FALSE\n");
7730 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7731 policyConstraintsWithRequireExplicit,
7732 sizeof(policyConstraintsWithRequireExplicit), CRYPT_DECODE_ALLOC_FLAG,
7733 NULL, &info, &size);
7734 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7737 ok(info->fRequireExplicitPolicy,
7738 "expected require explicit = TRUE\n");
7739 ok(info->dwRequireExplicitPolicySkipCerts == 0, "expected 0, got %d\n",
7740 info->dwRequireExplicitPolicySkipCerts);
7741 ok(!info->fInhibitPolicyMapping,
7742 "expected implicit mapping = FALSE\n");
7745 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7746 policyConstraintsWithInhibitMapping,
7747 sizeof(policyConstraintsWithInhibitMapping), CRYPT_DECODE_ALLOC_FLAG,
7748 NULL, &info, &size);
7749 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7752 ok(!info->fRequireExplicitPolicy,
7753 "expected require explicit = FALSE\n");
7754 ok(info->fInhibitPolicyMapping,
7755 "expected implicit mapping = TRUE\n");
7756 ok(info->dwInhibitPolicyMappingSkipCerts == 1, "expected 1, got %d\n",
7757 info->dwInhibitPolicyMappingSkipCerts);
7760 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7761 policyConstraintsWithBoth, sizeof(policyConstraintsWithBoth),
7762 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7763 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7766 ok(info->fRequireExplicitPolicy,
7767 "expected require explicit = TRUE\n");
7768 ok(info->dwRequireExplicitPolicySkipCerts == 1, "expected 1, got %d\n",
7769 info->dwRequireExplicitPolicySkipCerts);
7770 ok(info->fInhibitPolicyMapping,
7771 "expected implicit mapping = TRUE\n");
7772 ok(info->dwInhibitPolicyMappingSkipCerts == 1, "expected 1, got %d\n",
7773 info->dwInhibitPolicyMappingSkipCerts);
7778 /* Free *pInfo with HeapFree */
7779 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
7786 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
7788 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size);
7789 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7790 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7791 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL,
7793 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7794 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7795 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL,
7797 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7798 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7799 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7800 0, NULL, NULL, &size);
7801 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7802 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7803 /* Test with no key */
7804 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7805 0, NULL, NULL, &size);
7806 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n",
7808 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
7809 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
7812 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
7813 NULL, 0, NULL, NULL, &size);
7814 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
7815 *pInfo = HeapAlloc(GetProcessHeap(), 0, size);
7818 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
7819 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size);
7820 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n",
7824 /* By default (we passed NULL as the OID) the OID is
7827 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA),
7828 "Expected %s, got %s\n", szOID_RSA_RSA,
7829 (*pInfo)->Algorithm.pszObjId);
7833 CryptDestroyKey(key);
7836 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
7837 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
7838 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
7839 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7840 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7841 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7842 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
7843 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
7844 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7845 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7846 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7847 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
7848 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
7849 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
7850 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
7851 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
7852 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
7853 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
7854 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
7855 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
7856 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
7857 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
7858 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
7859 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
7860 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
7862 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info)
7866 PCCERT_CONTEXT context;
7871 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
7872 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
7873 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
7874 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7877 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key);
7878 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7879 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7880 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key);
7881 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7882 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7883 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL,
7885 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7886 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7888 /* Export key with standard algorithm (CALG_RSA_KEYX) */
7889 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7891 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7893 dwSize = sizeof(ai);
7894 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7895 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7898 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7899 ok(ai == CALG_RSA_KEYX, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai);
7902 CryptDestroyKey(key);
7904 /* Repeat with forced algorithm */
7905 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, CALG_RSA_SIGN, 0, NULL,
7907 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7909 dwSize = sizeof(ai);
7910 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7911 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7914 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7915 ok(ai == CALG_RSA_SIGN, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai);
7918 CryptDestroyKey(key);
7920 /* Test importing a public key from a certificate context */
7921 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert,
7922 sizeof(expiredCert));
7923 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
7927 ok(!strcmp(szOID_RSA_RSA,
7928 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId),
7929 "Expected %s, got %s\n", szOID_RSA_RSA,
7930 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
7931 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING,
7932 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
7933 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7934 CryptDestroyKey(key);
7935 CertFreeCertificateContext(context);
7939 static const char cspName[] = "WineCryptTemp";
7941 static void testPortPublicKeyInfo(void)
7945 PCERT_PUBLIC_KEY_INFO info = NULL;
7947 /* Just in case a previous run failed, delete this thing */
7948 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7949 CRYPT_DELETEKEYSET);
7950 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7953 testExportPublicKey(csp, &info);
7954 testImportPublicKey(csp, info);
7956 HeapFree(GetProcessHeap(), 0, info);
7957 CryptReleaseContext(csp, 0);
7958 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7959 CRYPT_DELETEKEYSET);
7964 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
7965 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING };
7969 hCrypt32 = GetModuleHandleA("crypt32.dll");
7970 pCryptDecodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptDecodeObjectEx");
7971 pCryptEncodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptEncodeObjectEx");
7972 if (!pCryptDecodeObjectEx || !pCryptEncodeObjectEx)
7974 win_skip("CryptDecodeObjectEx() is not available\n");
7978 for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++)
7980 test_encodeInt(encodings[i]);
7981 test_decodeInt(encodings[i]);
7982 test_encodeEnumerated(encodings[i]);
7983 test_decodeEnumerated(encodings[i]);
7984 test_encodeFiletime(encodings[i]);
7985 test_decodeFiletime(encodings[i]);
7986 test_encodeName(encodings[i]);
7987 test_decodeName(encodings[i]);
7988 test_encodeUnicodeName(encodings[i]);
7989 test_decodeUnicodeName(encodings[i]);
7990 test_encodeNameValue(encodings[i]);
7991 test_decodeNameValue(encodings[i]);
7992 test_encodeUnicodeNameValue(encodings[i]);
7993 test_decodeUnicodeNameValue(encodings[i]);
7994 test_encodeAltName(encodings[i]);
7995 test_decodeAltName(encodings[i]);
7996 test_encodeOctets(encodings[i]);
7997 test_decodeOctets(encodings[i]);
7998 test_encodeBits(encodings[i]);
7999 test_decodeBits(encodings[i]);
8000 test_encodeBasicConstraints(encodings[i]);
8001 test_decodeBasicConstraints(encodings[i]);
8002 test_encodeRsaPublicKey(encodings[i]);
8003 test_decodeRsaPublicKey(encodings[i]);
8004 test_encodeSequenceOfAny(encodings[i]);
8005 test_decodeSequenceOfAny(encodings[i]);
8006 test_encodeExtensions(encodings[i]);
8007 test_decodeExtensions(encodings[i]);
8008 test_encodePublicKeyInfo(encodings[i]);
8009 test_decodePublicKeyInfo(encodings[i]);
8010 test_encodeCertToBeSigned(encodings[i]);
8011 test_decodeCertToBeSigned(encodings[i]);
8012 test_encodeCert(encodings[i]);
8013 test_decodeCert(encodings[i]);
8014 test_encodeCRLDistPoints(encodings[i]);
8015 test_decodeCRLDistPoints(encodings[i]);
8016 test_encodeCRLIssuingDistPoint(encodings[i]);
8017 test_decodeCRLIssuingDistPoint(encodings[i]);
8018 test_encodeCRLToBeSigned(encodings[i]);
8019 test_decodeCRLToBeSigned(encodings[i]);
8020 test_encodeEnhancedKeyUsage(encodings[i]);
8021 test_decodeEnhancedKeyUsage(encodings[i]);
8022 test_encodeAuthorityKeyId(encodings[i]);
8023 test_decodeAuthorityKeyId(encodings[i]);
8024 test_encodeAuthorityKeyId2(encodings[i]);
8025 test_decodeAuthorityKeyId2(encodings[i]);
8026 test_encodeAuthorityInfoAccess(encodings[i]);
8027 test_decodeAuthorityInfoAccess(encodings[i]);
8028 test_encodeCTL(encodings[i]);
8029 test_decodeCTL(encodings[i]);
8030 test_encodePKCSContentInfo(encodings[i]);
8031 test_decodePKCSContentInfo(encodings[i]);
8032 test_encodePKCSAttribute(encodings[i]);
8033 test_decodePKCSAttribute(encodings[i]);
8034 test_encodePKCSAttributes(encodings[i]);
8035 test_decodePKCSAttributes(encodings[i]);
8036 test_encodePKCSSMimeCapabilities(encodings[i]);
8037 test_decodePKCSSMimeCapabilities(encodings[i]);
8038 test_encodePKCSSignerInfo(encodings[i]);
8039 test_decodePKCSSignerInfo(encodings[i]);
8040 test_encodeCMSSignerInfo(encodings[i]);
8041 test_decodeCMSSignerInfo(encodings[i]);
8042 test_encodeNameConstraints(encodings[i]);
8043 test_decodeNameConstraints(encodings[i]);
8044 test_encodePolicyQualifierUserNotice(encodings[i]);
8045 test_decodePolicyQualifierUserNotice(encodings[i]);
8046 test_encodeCertPolicies(encodings[i]);
8047 test_decodeCertPolicies(encodings[i]);
8048 test_encodeCertPolicyMappings(encodings[i]);
8049 test_decodeCertPolicyMappings(encodings[i]);
8050 test_encodeCertPolicyConstraints(encodings[i]);
8051 test_decodeCertPolicyConstraints(encodings[i]);
8053 testPortPublicKeyInfo();