2 * Unit test suite for crypt32.dll's CryptEncodeObjectEx/CryptDecodeObjectEx
4 * Copyright 2005 Juan Lang
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wine/test.h"
30 static BOOL (WINAPI *pCryptDecodeObjectEx)(DWORD,LPCSTR,const BYTE*,DWORD,DWORD,PCRYPT_DECODE_PARA,void*,DWORD*);
31 static BOOL (WINAPI *pCryptEncodeObjectEx)(DWORD,LPCSTR,const void*,DWORD,PCRYPT_ENCODE_PARA,void*,DWORD*);
39 static const BYTE bin1[] = {0x02,0x01,0x01};
40 static const BYTE bin2[] = {0x02,0x01,0x7f};
41 static const BYTE bin3[] = {0x02,0x02,0x00,0x80};
42 static const BYTE bin4[] = {0x02,0x02,0x01,0x00};
43 static const BYTE bin5[] = {0x02,0x01,0x80};
44 static const BYTE bin6[] = {0x02,0x02,0xff,0x7f};
45 static const BYTE bin7[] = {0x02,0x04,0xba,0xdd,0xf0,0x0d};
47 static const struct encodedInt ints[] = {
64 static const BYTE bin8[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
65 static const BYTE bin9[] = {0x02,0x0a,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0};
66 static const BYTE bin10[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
68 static const BYTE bin11[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0xff,0};
69 static const BYTE bin12[] = {0x02,0x09,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
70 static const BYTE bin13[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0};
72 static const struct encodedBigInt bigInts[] = {
73 { bin8, bin9, bin10 },
74 { bin11, bin12, bin13 },
77 static const BYTE bin14[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
78 static const BYTE bin15[] = {0x02,0x0a,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0};
79 static const BYTE bin16[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0xff,0};
80 static const BYTE bin17[] = {0x02,0x0c,0x00,0xff,0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
82 /* Decoded is the same as original, so don't bother storing a separate copy */
83 static const struct encodedBigInt bigUInts[] = {
84 { bin14, bin15, NULL },
85 { bin16, bin17, NULL },
88 static void test_encodeInt(DWORD dwEncoding)
93 CRYPT_INTEGER_BLOB blob;
96 /* CryptEncodeObjectEx with NULL bufSize crashes..
97 ret = pCryptEncodeObjectEx(3, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
100 /* check bogus encoding */
101 ret = pCryptEncodeObjectEx(0, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
103 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
104 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
107 /* check with NULL integer buffer. Windows XP incorrectly returns an
108 * NTSTATUS (crashes on win9x).
110 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, NULL, 0, NULL, NULL,
112 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
113 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
115 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
117 /* encode as normal integer */
118 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, &ints[i].val, 0,
119 NULL, NULL, &bufSize);
120 ok(ret, "Expected success, got %d\n", GetLastError());
121 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, &ints[i].val,
122 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
123 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
126 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
128 ok(buf[1] == ints[i].encoded[1], "Got length %d, expected %d\n",
129 buf[1], ints[i].encoded[1]);
130 ok(!memcmp(buf + 1, ints[i].encoded + 1, ints[i].encoded[1] + 1),
131 "Encoded value of 0x%08x didn't match expected\n", ints[i].val);
134 /* encode as multibyte integer */
135 blob.cbData = sizeof(ints[i].val);
136 blob.pbData = (BYTE *)&ints[i].val;
137 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
138 0, NULL, NULL, &bufSize);
139 ok(ret, "Expected success, got %d\n", GetLastError());
140 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
141 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
142 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
145 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
147 ok(buf[1] == ints[i].encoded[1], "Got length %d, expected %d\n",
148 buf[1], ints[i].encoded[1]);
149 ok(!memcmp(buf + 1, ints[i].encoded + 1, ints[i].encoded[1] + 1),
150 "Encoded value of 0x%08x didn't match expected\n", ints[i].val);
154 /* encode a couple bigger ints, just to show it's little-endian and leading
155 * sign bytes are dropped
157 for (i = 0; i < sizeof(bigInts) / sizeof(bigInts[0]); i++)
159 blob.cbData = strlen((const char*)bigInts[i].val);
160 blob.pbData = (BYTE *)bigInts[i].val;
161 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
162 0, NULL, NULL, &bufSize);
163 ok(ret, "Expected success, got %d\n", GetLastError());
164 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
165 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
166 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
169 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
171 ok(buf[1] == bigInts[i].encoded[1], "Got length %d, expected %d\n",
172 buf[1], bigInts[i].encoded[1]);
173 ok(!memcmp(buf + 1, bigInts[i].encoded + 1,
174 bigInts[i].encoded[1] + 1),
175 "Encoded value didn't match expected\n");
179 /* and, encode some uints */
180 for (i = 0; i < sizeof(bigUInts) / sizeof(bigUInts[0]); i++)
182 blob.cbData = strlen((const char*)bigUInts[i].val);
183 blob.pbData = (BYTE*)bigUInts[i].val;
184 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, &blob,
185 0, NULL, NULL, &bufSize);
186 ok(ret, "Expected success, got %d\n", GetLastError());
187 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, &blob,
188 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
189 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
192 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
194 ok(buf[1] == bigUInts[i].encoded[1], "Got length %d, expected %d\n",
195 buf[1], bigUInts[i].encoded[1]);
196 ok(!memcmp(buf + 1, bigUInts[i].encoded + 1,
197 bigUInts[i].encoded[1] + 1),
198 "Encoded value didn't match expected\n");
204 static void test_decodeInt(DWORD dwEncoding)
206 static const BYTE bigInt[] = { 2, 5, 0xff, 0xfe, 0xff, 0xfe, 0xff };
207 static const BYTE testStr[] = { 0x16, 4, 't', 'e', 's', 't' };
208 static const BYTE longForm[] = { 2, 0x81, 0x01, 0x01 };
209 static const BYTE bigBogus[] = { 0x02, 0x84, 0x01, 0xff, 0xff, 0xf9 };
210 static const BYTE extraBytes[] = { 2, 1, 1, 0, 0, 0, 0 };
216 /* CryptDecodeObjectEx with NULL bufSize crashes..
217 ret = pCryptDecodeObjectEx(3, X509_INTEGER, &ints[0].encoded,
218 ints[0].encoded[1] + 2, 0, NULL, NULL, NULL);
220 /* check bogus encoding */
221 ret = pCryptDecodeObjectEx(3, X509_INTEGER, (BYTE *)&ints[0].encoded,
222 ints[0].encoded[1] + 2, 0, NULL, NULL, &bufSize);
223 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
224 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
225 /* check with NULL integer buffer */
226 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, NULL, 0, 0, NULL, NULL,
228 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
229 GetLastError() == OSS_BAD_ARG /* Win9x */),
230 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
231 /* check with a valid, but too large, integer */
232 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, bigInt, bigInt[1] + 2,
233 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
234 ok((!ret && GetLastError() == CRYPT_E_ASN1_LARGE) ||
235 broken(ret) /* Win9x */,
236 "Expected CRYPT_E_ASN1_LARGE, got %d\n", GetLastError());
237 /* check with a DER-encoded string */
238 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, testStr, testStr[1] + 2,
239 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
240 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
241 GetLastError() == OSS_PDU_MISMATCH /* Win9x */ ),
242 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %08x\n",
244 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
246 /* When the output buffer is NULL, this always succeeds */
247 SetLastError(0xdeadbeef);
248 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER,
249 ints[i].encoded, ints[i].encoded[1] + 2, 0, NULL, NULL,
251 ok(ret && GetLastError() == NOERROR,
252 "Expected success and NOERROR, got %d\n", GetLastError());
253 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER,
254 ints[i].encoded, ints[i].encoded[1] + 2,
255 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
256 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
257 ok(bufSize == sizeof(int), "Wrong size %d\n", bufSize);
258 ok(buf != NULL, "Expected allocated buffer\n");
261 ok(!memcmp(buf, &ints[i].val, bufSize), "Expected %d, got %d\n",
262 ints[i].val, *(int *)buf);
266 for (i = 0; i < sizeof(bigInts) / sizeof(bigInts[0]); i++)
268 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER,
269 bigInts[i].encoded, bigInts[i].encoded[1] + 2, 0, NULL, NULL,
271 ok(ret && GetLastError() == NOERROR,
272 "Expected success and NOERROR, got %d\n", GetLastError());
273 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER,
274 bigInts[i].encoded, bigInts[i].encoded[1] + 2,
275 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
276 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
277 ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %d\n", bufSize);
278 ok(buf != NULL, "Expected allocated buffer\n");
281 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
283 ok(blob->cbData == strlen((const char*)bigInts[i].decoded),
284 "Expected len %d, got %d\n", lstrlenA((const char*)bigInts[i].decoded),
286 ok(!memcmp(blob->pbData, bigInts[i].decoded, blob->cbData),
287 "Unexpected value\n");
291 for (i = 0; i < sizeof(bigUInts) / sizeof(bigUInts[0]); i++)
293 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT,
294 bigUInts[i].encoded, bigUInts[i].encoded[1] + 2, 0, NULL, NULL,
296 ok(ret && GetLastError() == NOERROR,
297 "Expected success and NOERROR, got %d\n", GetLastError());
298 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT,
299 bigUInts[i].encoded, bigUInts[i].encoded[1] + 2,
300 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
301 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
302 ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %d\n", bufSize);
303 ok(buf != NULL, "Expected allocated buffer\n");
306 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
308 ok(blob->cbData == strlen((const char*)bigUInts[i].val),
309 "Expected len %d, got %d\n", lstrlenA((const char*)bigUInts[i].val),
311 ok(!memcmp(blob->pbData, bigUInts[i].val, blob->cbData),
312 "Unexpected value\n");
316 /* Decode the value 1 with long-form length */
317 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, longForm,
318 sizeof(longForm), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
319 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
322 ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf);
325 /* check with extra bytes at the end */
326 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, extraBytes,
327 sizeof(extraBytes), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
328 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
331 ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf);
334 /* Try to decode some bogus large items */
335 /* The buffer size is smaller than the encoded length, so this should fail
336 * with CRYPT_E_ASN1_EOD if it's being decoded.
337 * Under XP it fails with CRYPT_E_ASN1_LARGE, which means there's a limit
338 * on the size decoded, but in ME it fails with CRYPT_E_ASN1_EOD or crashes.
339 * So this test unfortunately isn't useful.
340 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, tooBig,
341 0x7fffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
342 ok(!ret && GetLastError() == CRYPT_E_ASN1_LARGE,
343 "Expected CRYPT_E_ASN1_LARGE, got %08x\n", GetLastError());
345 /* This will try to decode the buffer and overflow it, check that it's
350 /* a large buffer isn't guaranteed to crash, it depends on memory allocation order */
351 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, bigBogus,
352 0x01ffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
353 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
354 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
358 static const BYTE bin18[] = {0x0a,0x01,0x01};
359 static const BYTE bin19[] = {0x0a,0x05,0x00,0xff,0xff,0xff,0x80};
361 /* These are always encoded unsigned, and aren't constrained to be any
364 static const struct encodedInt enums[] = {
369 /* X509_CRL_REASON_CODE is also an enumerated type, but it's #defined to
372 static const LPCSTR enumeratedTypes[] = { X509_ENUMERATED,
373 szOID_CRL_REASON_CODE };
375 static void test_encodeEnumerated(DWORD dwEncoding)
379 for (i = 0; i < sizeof(enumeratedTypes) / sizeof(enumeratedTypes[0]); i++)
381 for (j = 0; j < sizeof(enums) / sizeof(enums[0]); j++)
387 ret = pCryptEncodeObjectEx(dwEncoding, enumeratedTypes[i],
388 &enums[j].val, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf,
390 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
394 "Got unexpected type %d for enumerated (expected 0xa)\n",
396 ok(buf[1] == enums[j].encoded[1],
397 "Got length %d, expected %d\n", buf[1], enums[j].encoded[1]);
398 ok(!memcmp(buf + 1, enums[j].encoded + 1,
399 enums[j].encoded[1] + 1),
400 "Encoded value of 0x%08x didn't match expected\n",
408 static void test_decodeEnumerated(DWORD dwEncoding)
412 for (i = 0; i < sizeof(enumeratedTypes) / sizeof(enumeratedTypes[0]); i++)
414 for (j = 0; j < sizeof(enums) / sizeof(enums[0]); j++)
417 DWORD bufSize = sizeof(int);
420 ret = pCryptDecodeObjectEx(dwEncoding, enumeratedTypes[i],
421 enums[j].encoded, enums[j].encoded[1] + 2, 0, NULL,
423 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
424 ok(bufSize == sizeof(int),
425 "Got unexpected size %d for enumerated\n", bufSize);
426 ok(val == enums[j].val, "Unexpected value %d, expected %d\n",
432 struct encodedFiletime
435 const BYTE *encodedTime;
438 static void testTimeEncoding(DWORD dwEncoding, LPCSTR structType,
439 const struct encodedFiletime *time)
446 ret = SystemTimeToFileTime(&time->sysTime, &ft);
447 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
448 ret = pCryptEncodeObjectEx(dwEncoding, structType, &ft,
449 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
450 /* years other than 1950-2050 are not allowed for encodings other than
451 * X509_CHOICE_OF_TIME.
453 if (structType == X509_CHOICE_OF_TIME ||
454 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050))
456 ok(ret, "CryptEncodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
458 ok(buf != NULL, "Expected an allocated buffer\n");
461 ok(buf[0] == time->encodedTime[0],
462 "Expected type 0x%02x, got 0x%02x\n", time->encodedTime[0],
464 ok(buf[1] == time->encodedTime[1], "Expected %d bytes, got %d\n",
465 time->encodedTime[1], bufSize);
466 ok(!memcmp(time->encodedTime + 2, buf + 2, time->encodedTime[1]),
467 "Got unexpected value for time encoding\n");
472 ok((!ret && GetLastError() == CRYPT_E_BAD_ENCODE) ||
473 broken(GetLastError() == ERROR_SUCCESS),
474 "Expected CRYPT_E_BAD_ENCODE, got 0x%08x\n", GetLastError());
477 static const char *printSystemTime(const SYSTEMTIME *st)
481 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st->wMonth, st->wDay,
482 st->wYear, st->wHour, st->wMinute, st->wSecond, st->wMilliseconds);
486 static const char *printFileTime(const FILETIME *ft)
491 FileTimeToSystemTime(ft, &st);
492 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st.wMonth, st.wDay,
493 st.wYear, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
497 static void compareTime(const SYSTEMTIME *expected, const FILETIME *got)
501 FileTimeToSystemTime(got, &st);
502 ok((expected->wYear == st.wYear &&
503 expected->wMonth == st.wMonth &&
504 expected->wDay == st.wDay &&
505 expected->wHour == st.wHour &&
506 expected->wMinute == st.wMinute &&
507 expected->wSecond == st.wSecond &&
508 abs(expected->wMilliseconds - st.wMilliseconds) <= 1) ||
509 /* Some Windows systems only seem to be accurate in their time decoding to
510 * within about an hour.
512 broken(expected->wYear == st.wYear &&
513 expected->wMonth == st.wMonth &&
514 expected->wDay == st.wDay &&
515 abs(expected->wHour - st.wHour) <= 1),
516 "Got unexpected value for time decoding:\nexpected %s, got %s\n",
517 printSystemTime(expected), printFileTime(got));
520 static void testTimeDecoding(DWORD dwEncoding, LPCSTR structType,
521 const struct encodedFiletime *time)
524 DWORD size = sizeof(ft);
527 ret = pCryptDecodeObjectEx(dwEncoding, structType, time->encodedTime,
528 time->encodedTime[1] + 2, 0, NULL, &ft, &size);
529 /* years other than 1950-2050 are not allowed for encodings other than
530 * X509_CHOICE_OF_TIME.
532 if (structType == X509_CHOICE_OF_TIME ||
533 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050))
535 ok(ret || broken(GetLastError() == OSS_DATA_ERROR),
536 "CryptDecodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
539 compareTime(&time->sysTime, &ft);
542 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
543 GetLastError() == OSS_PDU_MISMATCH /* Win9x */ ),
544 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %08x\n",
548 static const BYTE bin20[] = {
549 0x17,0x0d,'0','5','0','6','0','6','1','6','1','0','0','0','Z'};
550 static const BYTE bin21[] = {
551 0x18,0x0f,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
552 static const BYTE bin22[] = {
553 0x18,0x0f,'2','1','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
555 static const struct encodedFiletime times[] = {
556 { { 2005, 6, 1, 6, 16, 10, 0, 0 }, bin20 },
557 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin21 },
558 { { 2145, 6, 1, 6, 16, 10, 0, 0 }, bin22 },
561 static void test_encodeFiletime(DWORD dwEncoding)
565 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
567 testTimeEncoding(dwEncoding, X509_CHOICE_OF_TIME, ×[i]);
568 testTimeEncoding(dwEncoding, PKCS_UTC_TIME, ×[i]);
569 testTimeEncoding(dwEncoding, szOID_RSA_signingTime, ×[i]);
573 static const BYTE bin23[] = {
574 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','0','0','0','Z'};
575 static const BYTE bin24[] = {
576 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','9','9','9','Z'};
577 static const BYTE bin25[] = {
578 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','+','0','1','0','0'};
579 static const BYTE bin26[] = {
580 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','0','0'};
581 static const BYTE bin27[] = {
582 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','1','5'};
583 static const BYTE bin28[] = {
584 0x18,0x0a,'2','1','4','5','0','6','0','6','1','6'};
585 static const BYTE bin29[] = {
586 0x17,0x0a,'4','5','0','6','0','6','1','6','1','0'};
587 static const BYTE bin30[] = {
588 0x17,0x0b,'4','5','0','6','0','6','1','6','1','0','Z'};
589 static const BYTE bin31[] = {
590 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','+','0','1'};
591 static const BYTE bin32[] = {
592 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','-','0','1'};
593 static const BYTE bin33[] = {
594 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','+','0','1','0','0'};
595 static const BYTE bin34[] = {
596 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','-','0','1','0','0'};
597 static const BYTE bin35[] = {
598 0x17,0x08, '4','5','0','6','0','6','1','6'};
599 static const BYTE bin36[] = {
600 0x18,0x0f, 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','Z'};
601 static const BYTE bin37[] = {
602 0x18,0x04, '2','1','4','5'};
603 static const BYTE bin38[] = {
604 0x18,0x08, '2','1','4','5','0','6','0','6'};
606 static void test_decodeFiletime(DWORD dwEncoding)
608 static const struct encodedFiletime otherTimes[] = {
609 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin23 },
610 { { 1945, 6, 1, 6, 16, 10, 0, 999 }, bin24 },
611 { { 1945, 6, 1, 6, 17, 10, 0, 0 }, bin25 },
612 { { 1945, 6, 1, 6, 15, 10, 0, 0 }, bin26 },
613 { { 1945, 6, 1, 6, 14, 55, 0, 0 }, bin27 },
614 { { 2145, 6, 1, 6, 16, 0, 0, 0 }, bin28 },
615 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin29 },
616 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin30 },
617 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin31 },
618 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin32 },
619 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin33 },
620 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin34 },
622 /* An oddball case that succeeds in Windows, but doesn't seem correct
623 { { 2145, 6, 1, 2, 11, 31, 0, 0 }, "\x18" "\x13" "21450606161000-9999" },
625 static const unsigned char *bogusTimes[] = {
626 /* oddly, this succeeds on Windows, with year 2765
627 "\x18" "\x0f" "21r50606161000Z",
635 FILETIME ft1 = { 0 }, ft2 = { 0 };
638 /* Check bogus length with non-NULL buffer */
639 ret = SystemTimeToFileTime(×[0].sysTime, &ft1);
640 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
642 ret = pCryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
643 times[0].encodedTime, times[0].encodedTime[1] + 2, 0, NULL, &ft2, &size);
644 ok(!ret && GetLastError() == ERROR_MORE_DATA,
645 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
647 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
649 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, ×[i]);
650 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, ×[i]);
651 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, ×[i]);
653 for (i = 0; i < sizeof(otherTimes) / sizeof(otherTimes[0]); i++)
655 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &otherTimes[i]);
656 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &otherTimes[i]);
657 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &otherTimes[i]);
659 for (i = 0; i < sizeof(bogusTimes) / sizeof(bogusTimes[0]); i++)
662 ret = pCryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
663 bogusTimes[i], bogusTimes[i][1] + 2, 0, NULL, &ft1, &size);
664 ok((!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
665 GetLastError() == OSS_DATA_ERROR /* Win9x */)) ||
666 broken(ret), /* Win9x and NT4 for bin38 */
667 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
672 static const char commonName[] = "Juan Lang";
673 static const char surName[] = "Lang";
675 static const BYTE emptySequence[] = { 0x30, 0 };
676 static const BYTE emptyRDNs[] = { 0x30, 0x02, 0x31, 0 };
677 static const BYTE twoRDNs[] = {
678 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
679 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
680 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0};
681 static const BYTE encodedTwoRDNs[] = {
682 0x30,0x2e,0x31,0x2c,0x30,0x2a,0x06,0x03,0x55,0x04,0x03,0x30,0x23,0x31,0x21,
683 0x30,0x0c,0x06,0x03,0x55,0x04,0x04,0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,
684 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
688 static const BYTE us[] = { 0x55, 0x53 };
689 static const BYTE minnesota[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x73, 0x6f,
691 static const BYTE minneapolis[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x61, 0x70,
692 0x6f, 0x6c, 0x69, 0x73 };
693 static const BYTE codeweavers[] = { 0x43, 0x6f, 0x64, 0x65, 0x57, 0x65, 0x61,
694 0x76, 0x65, 0x72, 0x73 };
695 static const BYTE wine[] = { 0x57, 0x69, 0x6e, 0x65, 0x20, 0x44, 0x65, 0x76,
696 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74 };
697 static const BYTE localhostAttr[] = { 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
699 static const BYTE aric[] = { 0x61, 0x72, 0x69, 0x63, 0x40, 0x63, 0x6f, 0x64,
700 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d };
702 #define RDNA(arr) oid_ ## arr, CERT_RDN_PRINTABLE_STRING, { sizeof(arr), (LPBYTE)arr }
703 #define RDNIA5(arr) oid_ ## arr, CERT_RDN_IA5_STRING, { sizeof(arr), (LPBYTE)arr }
705 static CHAR oid_us[] = "2.5.4.6",
706 oid_minnesota[] = "2.5.4.8",
707 oid_minneapolis[] = "2.5.4.7",
708 oid_codeweavers[] = "2.5.4.10",
709 oid_wine[] = "2.5.4.11",
710 oid_localhostAttr[] = "2.5.4.3",
711 oid_aric[] = "1.2.840.113549.1.9.1";
712 static CERT_RDN_ATTR rdnAttrs[] = { { RDNA(us) },
714 { RDNA(minneapolis) },
715 { RDNA(codeweavers) },
717 { RDNA(localhostAttr) },
719 static CERT_RDN_ATTR decodedRdnAttrs[] = { { RDNA(us) },
720 { RDNA(localhostAttr) },
722 { RDNA(minneapolis) },
723 { RDNA(codeweavers) },
730 static const BYTE encodedRDNAttrs[] = {
731 0x30,0x81,0x96,0x31,0x81,0x93,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
732 0x53,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x68,
733 0x6f,0x73,0x74,0x30,0x10,0x06,0x03,0x55,0x04,0x08,0x13,0x09,0x4d,0x69,0x6e,0x6e,
734 0x65,0x73,0x6f,0x74,0x61,0x30,0x12,0x06,0x03,0x55,0x04,0x07,0x13,0x0b,0x4d,0x69,
735 0x6e,0x6e,0x65,0x61,0x70,0x6f,0x6c,0x69,0x73,0x30,0x12,0x06,0x03,0x55,0x04,0x0a,
736 0x13,0x0b,0x43,0x6f,0x64,0x65,0x57,0x65,0x61,0x76,0x65,0x72,0x73,0x30,0x17,0x06,
737 0x03,0x55,0x04,0x0b,0x13,0x10,0x57,0x69,0x6e,0x65,0x20,0x44,0x65,0x76,0x65,0x6c,
738 0x6f,0x70,0x6d,0x65,0x6e,0x74,0x30,0x21,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
739 0x01,0x09,0x01,0x16,0x14,0x61,0x72,0x69,0x63,0x40,0x63,0x6f,0x64,0x65,0x77,0x65,
740 0x61,0x76,0x65,0x72,0x73,0x2e,0x63,0x6f,0x6d
743 static void test_encodeName(DWORD dwEncoding)
745 CERT_RDN_ATTR attrs[2];
748 static CHAR oid_common_name[] = szOID_COMMON_NAME,
749 oid_sur_name[] = szOID_SUR_NAME;
756 /* Test with NULL pvStructInfo (crashes on win9x) */
757 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, NULL,
758 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
759 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
760 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
762 /* Test with empty CERT_NAME_INFO */
765 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
766 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
767 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
770 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
771 "Got unexpected encoding for empty name\n");
776 /* Test with bogus CERT_RDN (crashes on win9x) */
778 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
779 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
780 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
781 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
783 /* Test with empty CERT_RDN */
785 rdn.rgRDNAttr = NULL;
788 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
789 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
790 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
793 ok(!memcmp(buf, emptyRDNs, sizeof(emptyRDNs)),
794 "Got unexpected encoding for empty RDN array\n");
799 /* Test with bogus attr array (crashes on win9x) */
801 rdn.rgRDNAttr = NULL;
802 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
803 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
804 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
805 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
807 /* oddly, a bogus OID is accepted by Windows XP; not testing.
808 attrs[0].pszObjId = "bogus";
809 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
810 attrs[0].Value.cbData = sizeof(commonName);
811 attrs[0].Value.pbData = commonName;
813 rdn.rgRDNAttr = attrs;
814 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
815 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
816 ok(!ret, "Expected failure, got success\n");
818 /* Check with two CERT_RDN_ATTRs. Note DER encoding forces the order of
819 * the encoded attributes to be swapped.
821 attrs[0].pszObjId = oid_common_name;
822 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
823 attrs[0].Value.cbData = sizeof(commonName);
824 attrs[0].Value.pbData = (BYTE *)commonName;
825 attrs[1].pszObjId = oid_sur_name;
826 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
827 attrs[1].Value.cbData = sizeof(surName);
828 attrs[1].Value.pbData = (BYTE *)surName;
830 rdn.rgRDNAttr = attrs;
831 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
832 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
833 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
836 ok(!memcmp(buf, twoRDNs, sizeof(twoRDNs)),
837 "Got unexpected encoding for two RDN array\n");
840 /* A name can be "encoded" with previously encoded RDN attrs. */
841 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
842 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
843 attrs[0].Value.cbData = sizeof(twoRDNs);
845 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
846 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
847 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
850 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
851 ok(!memcmp(buf, encodedTwoRDNs, size),
852 "Unexpected value for re-endoded two RDN array\n");
855 /* CERT_RDN_ANY_TYPE is too vague for X509_NAMEs, check the return */
857 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
858 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
859 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
860 ok(!ret && GetLastError() == E_INVALIDARG,
861 "Expected E_INVALIDARG, got %08x\n", GetLastError());
862 /* Test a more complex name */
863 rdn.cRDNAttr = sizeof(rdnAttrs) / sizeof(rdnAttrs[0]);
864 rdn.rgRDNAttr = rdnAttrs;
869 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, X509_NAME, &info,
870 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
871 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
874 ok(size == sizeof(encodedRDNAttrs), "Wrong size %d\n", size);
875 ok(!memcmp(buf, encodedRDNAttrs, size), "Unexpected value\n");
880 static WCHAR commonNameW[] = { 'J','u','a','n',' ','L','a','n','g',0 };
881 static WCHAR surNameW[] = { 'L','a','n','g',0 };
883 static const BYTE twoRDNsNoNull[] = {
884 0x30,0x21,0x31,0x1f,0x30,0x0b,0x06,0x03,0x55,0x04,0x04,0x13,0x04,0x4c,0x61,
885 0x6e,0x67,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,
886 0x20,0x4c,0x61,0x6e,0x67 };
887 static const BYTE anyType[] = {
888 0x30,0x2f,0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x1e,0x24,0x23,0x30,
889 0x21,0x31,0x0c,0x30,0x03,0x06,0x04,0x55,0x13,0x04,0x4c,0x05,0x6e,0x61,0x00,
890 0x67,0x11,0x30,0x03,0x06,0x04,0x55,0x13,0x03,0x4a,0x0a,0x61,0x75,0x20,0x6e,
891 0x61,0x4c,0x67,0x6e };
893 static void test_encodeUnicodeName(DWORD dwEncoding)
895 CERT_RDN_ATTR attrs[2];
898 static CHAR oid_common_name[] = szOID_COMMON_NAME,
899 oid_sur_name[] = szOID_SUR_NAME;
906 /* Test with NULL pvStructInfo (crashes on win9x) */
907 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, NULL,
908 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
909 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
910 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
912 /* Test with empty CERT_NAME_INFO */
915 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
916 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
917 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
920 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
921 "Got unexpected encoding for empty name\n");
924 /* Check with one CERT_RDN_ATTR, that has an invalid character for the
925 * encoding (the NULL).
927 attrs[0].pszObjId = oid_common_name;
928 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
929 attrs[0].Value.cbData = sizeof(commonNameW);
930 attrs[0].Value.pbData = (BYTE *)commonNameW;
932 rdn.rgRDNAttr = attrs;
935 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
936 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
937 ok(!ret && GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING,
938 "Expected CRYPT_E_INVALID_PRINTABLE_STRING, got %08x\n", GetLastError());
939 ok(size == 9, "Unexpected error index %08x\n", size);
940 /* Check with two NULL-terminated CERT_RDN_ATTRs. Note DER encoding
941 * forces the order of the encoded attributes to be swapped.
943 attrs[0].pszObjId = oid_common_name;
944 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
945 attrs[0].Value.cbData = 0;
946 attrs[0].Value.pbData = (BYTE *)commonNameW;
947 attrs[1].pszObjId = oid_sur_name;
948 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
949 attrs[1].Value.cbData = 0;
950 attrs[1].Value.pbData = (BYTE *)surNameW;
952 rdn.rgRDNAttr = attrs;
955 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
956 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
957 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
960 ok(!memcmp(buf, twoRDNsNoNull, sizeof(twoRDNsNoNull)),
961 "Got unexpected encoding for two RDN array\n");
964 /* A name can be "encoded" with previously encoded RDN attrs. */
965 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
966 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
967 attrs[0].Value.cbData = sizeof(twoRDNs);
969 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
970 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
971 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
974 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
975 ok(!memcmp(buf, encodedTwoRDNs, size),
976 "Unexpected value for re-endoded two RDN array\n");
979 /* Unicode names infer the type for CERT_RDN_ANY_TYPE */
981 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
982 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
983 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
984 todo_wine ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
987 ok(size == sizeof(anyType), "Unexpected size %d\n", size);
988 ok(!memcmp(buf, anyType, size), "Unexpected value\n");
993 static void compareNameValues(const CERT_NAME_VALUE *expected,
994 const CERT_NAME_VALUE *got)
996 if (expected->dwValueType == CERT_RDN_UTF8_STRING &&
997 got->dwValueType == CERT_RDN_ENCODED_BLOB)
999 win_skip("Can't handle CERT_RDN_UTF8_STRING\n");
1003 ok(got->dwValueType == expected->dwValueType,
1004 "Expected string type %d, got %d\n", expected->dwValueType,
1006 ok(got->Value.cbData == expected->Value.cbData,
1007 "String type %d: unexpected data size, got %d, expected %d\n",
1008 expected->dwValueType, got->Value.cbData, expected->Value.cbData);
1009 if (got->Value.cbData && got->Value.pbData)
1010 ok(!memcmp(got->Value.pbData, expected->Value.pbData,
1011 min(got->Value.cbData, expected->Value.cbData)),
1012 "String type %d: unexpected value\n", expected->dwValueType);
1015 static void compareRDNAttrs(const CERT_RDN_ATTR *expected,
1016 const CERT_RDN_ATTR *got)
1018 if (expected->pszObjId && strlen(expected->pszObjId))
1020 ok(got->pszObjId != NULL, "Expected OID %s, got NULL\n",
1021 expected->pszObjId);
1024 ok(!strcmp(got->pszObjId, expected->pszObjId),
1025 "Got unexpected OID %s, expected %s\n", got->pszObjId,
1026 expected->pszObjId);
1029 compareNameValues((const CERT_NAME_VALUE *)&expected->dwValueType,
1030 (const CERT_NAME_VALUE *)&got->dwValueType);
1033 static void compareRDNs(const CERT_RDN *expected, const CERT_RDN *got)
1035 ok(got->cRDNAttr == expected->cRDNAttr,
1036 "Expected %d RDN attrs, got %d\n", expected->cRDNAttr, got->cRDNAttr);
1041 for (i = 0; i < got->cRDNAttr; i++)
1042 compareRDNAttrs(&expected->rgRDNAttr[i], &got->rgRDNAttr[i]);
1046 static void compareNames(const CERT_NAME_INFO *expected,
1047 const CERT_NAME_INFO *got)
1049 ok(got->cRDN == expected->cRDN, "Expected %d RDNs, got %d\n",
1050 expected->cRDN, got->cRDN);
1055 for (i = 0; i < got->cRDN; i++)
1056 compareRDNs(&expected->rgRDN[i], &got->rgRDN[i]);
1060 static const BYTE emptyIndefiniteSequence[] = { 0x30,0x80,0x00,0x00 };
1061 static const BYTE twoRDNsExtraBytes[] = {
1062 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
1063 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1064 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0,0,0,0,0,0};
1066 static void test_decodeName(DWORD dwEncoding)
1072 CERT_NAME_INFO info = { 1, &rdn };
1074 /* test empty name */
1076 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptySequence,
1077 emptySequence[1] + 2,
1078 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1080 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1081 /* Interestingly, in Windows, if cRDN is 0, rgRGN may not be NULL. My
1082 * decoder works the same way, so only test the count.
1086 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1087 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1088 "Expected 0 RDNs in empty info, got %d\n",
1089 ((CERT_NAME_INFO *)buf)->cRDN);
1092 /* test empty name with indefinite-length encoding */
1093 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyIndefiniteSequence,
1094 sizeof(emptyIndefiniteSequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
1096 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1099 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1100 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1101 "Expected 0 RDNs in empty info, got %d\n",
1102 ((CERT_NAME_INFO *)buf)->cRDN);
1105 /* test empty RDN */
1107 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyRDNs,
1109 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1111 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1114 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1116 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1117 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1118 "Got unexpected value for empty RDN\n");
1121 /* test two RDN attrs */
1123 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNs,
1125 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1127 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1130 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1131 oid_common_name[] = szOID_COMMON_NAME;
1133 CERT_RDN_ATTR attrs[] = {
1134 { oid_sur_name, CERT_RDN_PRINTABLE_STRING, { sizeof(surName),
1135 (BYTE *)surName } },
1136 { oid_common_name, CERT_RDN_PRINTABLE_STRING, { sizeof(commonName),
1137 (BYTE *)commonName } },
1140 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1141 rdn.rgRDNAttr = attrs;
1142 compareNames(&info, (CERT_NAME_INFO *)buf);
1145 /* test that two RDN attrs with extra bytes succeeds */
1147 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNsExtraBytes,
1148 sizeof(twoRDNsExtraBytes), 0, NULL, NULL, &bufSize);
1149 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1150 /* And, a slightly more complicated name */
1153 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME, encodedRDNAttrs,
1154 sizeof(encodedRDNAttrs), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1155 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1158 rdn.cRDNAttr = sizeof(decodedRdnAttrs) / sizeof(decodedRdnAttrs[0]);
1159 rdn.rgRDNAttr = decodedRdnAttrs;
1160 compareNames(&info, (CERT_NAME_INFO *)buf);
1165 static void test_decodeUnicodeName(DWORD dwEncoding)
1171 CERT_NAME_INFO info = { 1, &rdn };
1173 /* test empty name */
1175 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptySequence,
1176 emptySequence[1] + 2,
1177 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1179 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1182 ok(bufSize == sizeof(CERT_NAME_INFO),
1183 "Got wrong bufSize %d\n", bufSize);
1184 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1185 "Expected 0 RDNs in empty info, got %d\n",
1186 ((CERT_NAME_INFO *)buf)->cRDN);
1189 /* test empty RDN */
1191 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptyRDNs,
1193 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1195 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1198 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1200 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1201 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1202 "Got unexpected value for empty RDN\n");
1205 /* test two RDN attrs */
1207 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, twoRDNsNoNull,
1208 sizeof(twoRDNsNoNull),
1209 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1211 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1214 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1215 oid_common_name[] = szOID_COMMON_NAME;
1217 CERT_RDN_ATTR attrs[] = {
1218 { oid_sur_name, CERT_RDN_PRINTABLE_STRING,
1219 { lstrlenW(surNameW) * sizeof(WCHAR), (BYTE *)surNameW } },
1220 { oid_common_name, CERT_RDN_PRINTABLE_STRING,
1221 { lstrlenW(commonNameW) * sizeof(WCHAR), (BYTE *)commonNameW } },
1224 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1225 rdn.rgRDNAttr = attrs;
1226 compareNames(&info, (CERT_NAME_INFO *)buf);
1231 struct EncodedNameValue
1233 CERT_NAME_VALUE value;
1234 const BYTE *encoded;
1238 static const char bogusIA5[] = "\x80";
1239 static const char bogusPrintable[] = "~";
1240 static const char bogusNumeric[] = "A";
1241 static const BYTE bin42[] = { 0x16,0x02,0x80,0x00 };
1242 static const BYTE bin43[] = { 0x13,0x02,0x7e,0x00 };
1243 static const BYTE bin44[] = { 0x12,0x02,0x41,0x00 };
1244 static BYTE octetCommonNameValue[] = {
1245 0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1246 static BYTE numericCommonNameValue[] = {
1247 0x12,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1248 static BYTE printableCommonNameValue[] = {
1249 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1250 static BYTE t61CommonNameValue[] = {
1251 0x14,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1252 static BYTE videotexCommonNameValue[] = {
1253 0x15,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1254 static BYTE ia5CommonNameValue[] = {
1255 0x16,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1256 static BYTE graphicCommonNameValue[] = {
1257 0x19,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1258 static BYTE visibleCommonNameValue[] = {
1259 0x1a,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1260 static BYTE generalCommonNameValue[] = {
1261 0x1b,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1262 static BYTE bmpCommonNameValue[] = {
1263 0x1e,0x14,0x00,0x4a,0x00,0x75,0x00,0x61,0x00,0x6e,0x00,0x20,0x00,0x4c,0x00,
1264 0x61,0x00,0x6e,0x00,0x67,0x00,0x00 };
1265 static BYTE utf8CommonNameValue[] = {
1266 0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1267 static char embedded_null[] = "foo\0com";
1268 static BYTE ia5EmbeddedNull[] = {
1269 0x16,0x07,0x66,0x6f,0x6f,0x00,0x63,0x6f,0x6d };
1271 static struct EncodedNameValue nameValues[] = {
1272 { { CERT_RDN_OCTET_STRING, { sizeof(commonName), (BYTE *)commonName } },
1273 octetCommonNameValue, sizeof(octetCommonNameValue) },
1274 { { CERT_RDN_NUMERIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1275 numericCommonNameValue, sizeof(numericCommonNameValue) },
1276 { { CERT_RDN_PRINTABLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1277 printableCommonNameValue, sizeof(printableCommonNameValue) },
1278 { { CERT_RDN_T61_STRING, { sizeof(commonName), (BYTE *)commonName } },
1279 t61CommonNameValue, sizeof(t61CommonNameValue) },
1280 { { CERT_RDN_VIDEOTEX_STRING, { sizeof(commonName), (BYTE *)commonName } },
1281 videotexCommonNameValue, sizeof(videotexCommonNameValue) },
1282 { { CERT_RDN_IA5_STRING, { sizeof(commonName), (BYTE *)commonName } },
1283 ia5CommonNameValue, sizeof(ia5CommonNameValue) },
1284 { { CERT_RDN_GRAPHIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1285 graphicCommonNameValue, sizeof(graphicCommonNameValue) },
1286 { { CERT_RDN_VISIBLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1287 visibleCommonNameValue, sizeof(visibleCommonNameValue) },
1288 { { CERT_RDN_GENERAL_STRING, { sizeof(commonName), (BYTE *)commonName } },
1289 generalCommonNameValue, sizeof(generalCommonNameValue) },
1290 { { CERT_RDN_BMP_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1291 bmpCommonNameValue, sizeof(bmpCommonNameValue) },
1292 { { CERT_RDN_UTF8_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1293 utf8CommonNameValue, sizeof(utf8CommonNameValue) },
1294 /* The following tests succeed under Windows, but really should fail,
1295 * they contain characters that are illegal for the encoding. I'm
1296 * including them to justify my lazy encoding.
1298 { { CERT_RDN_IA5_STRING, { sizeof(bogusIA5), (BYTE *)bogusIA5 } }, bin42,
1300 { { CERT_RDN_PRINTABLE_STRING, { sizeof(bogusPrintable),
1301 (BYTE *)bogusPrintable } }, bin43, sizeof(bin43) },
1302 { { CERT_RDN_NUMERIC_STRING, { sizeof(bogusNumeric), (BYTE *)bogusNumeric } },
1303 bin44, sizeof(bin44) },
1305 /* This is kept separate, because the decoding doesn't return to the original
1308 static struct EncodedNameValue embeddedNullNameValue = {
1309 { CERT_RDN_IA5_STRING, { sizeof(embedded_null) - 1, (BYTE *)embedded_null } },
1310 ia5EmbeddedNull, sizeof(ia5EmbeddedNull) };
1312 static void test_encodeNameValue(DWORD dwEncoding)
1317 CERT_NAME_VALUE value = { 0, { 0, NULL } };
1319 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1320 value.Value.pbData = printableCommonNameValue;
1321 value.Value.cbData = sizeof(printableCommonNameValue);
1322 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, &value,
1323 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1324 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1327 ok(size == sizeof(printableCommonNameValue), "Unexpected size %d\n",
1329 ok(!memcmp(buf, printableCommonNameValue, size),
1330 "Unexpected encoding\n");
1333 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1335 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE,
1336 &nameValues[i].value, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1337 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH) /* NT4/Win9x */,
1338 "Type %d: CryptEncodeObjectEx failed: %08x\n",
1339 nameValues[i].value.dwValueType, GetLastError());
1342 ok(size == nameValues[i].encodedSize,
1343 "Expected size %d, got %d\n", nameValues[i].encodedSize, size);
1344 ok(!memcmp(buf, nameValues[i].encoded, size),
1345 "Got unexpected encoding\n");
1349 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE,
1350 &embeddedNullNameValue.value, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1351 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH) /* NT4/Win9x */,
1352 "Type %d: CryptEncodeObjectEx failed: %08x\n",
1353 embeddedNullNameValue.value.dwValueType, GetLastError());
1356 ok(size == embeddedNullNameValue.encodedSize,
1357 "Expected size %d, got %d\n", embeddedNullNameValue.encodedSize, size);
1358 ok(!memcmp(buf, embeddedNullNameValue.encoded, size),
1359 "Got unexpected encoding\n");
1364 static void test_decodeNameValue(DWORD dwEncoding)
1371 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1373 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE,
1374 nameValues[i].encoded, nameValues[i].encoded[1] + 2,
1375 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1377 ok(ret, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
1378 nameValues[i].value.dwValueType, GetLastError());
1381 compareNameValues(&nameValues[i].value,
1382 (const CERT_NAME_VALUE *)buf);
1386 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE,
1387 embeddedNullNameValue.encoded, embeddedNullNameValue.encodedSize,
1388 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1390 ok(ret, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
1391 embeddedNullNameValue.value.dwValueType, GetLastError());
1394 CERT_NAME_VALUE rdnEncodedValue = { CERT_RDN_ENCODED_BLOB,
1395 { sizeof(ia5EmbeddedNull), ia5EmbeddedNull } };
1396 CERT_NAME_VALUE embeddedNullValue = { CERT_RDN_IA5_STRING,
1397 { sizeof(embedded_null) - 1, (BYTE *)embedded_null } };
1398 const CERT_NAME_VALUE *got = (const CERT_NAME_VALUE *)buf,
1401 /* Some Windows versions decode name values with embedded NULLs,
1402 * others leave them encoded, even with the same version of crypt32.
1405 ok(got->dwValueType == CERT_RDN_ENCODED_BLOB ||
1406 got->dwValueType == CERT_RDN_IA5_STRING,
1407 "Expected CERT_RDN_ENCODED_BLOB or CERT_RDN_IA5_STRING, got %d\n",
1409 if (got->dwValueType == CERT_RDN_ENCODED_BLOB)
1410 expected = &rdnEncodedValue;
1411 else if (got->dwValueType == CERT_RDN_IA5_STRING)
1412 expected = &embeddedNullValue;
1415 ok(got->Value.cbData == expected->Value.cbData,
1416 "String type %d: unexpected data size, got %d, expected %d\n",
1417 got->dwValueType, got->Value.cbData, expected->Value.cbData);
1418 if (got->Value.cbData && got->Value.pbData)
1419 ok(!memcmp(got->Value.pbData, expected->Value.pbData,
1420 min(got->Value.cbData, expected->Value.cbData)),
1421 "String type %d: unexpected value\n", expected->dwValueType);
1427 static const BYTE emptyURL[] = { 0x30, 0x02, 0x86, 0x00 };
1428 static const BYTE emptyURLExtraBytes[] = { 0x30, 0x02, 0x86, 0x00, 0, 0, 0 };
1429 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e',
1430 'h','q','.','o','r','g',0 };
1431 static const BYTE encodedURL[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74,
1432 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e,
1434 static const WCHAR nihongoURL[] = { 'h','t','t','p',':','/','/',0x226f,
1436 static const WCHAR dnsName[] = { 'w','i','n','e','h','q','.','o','r','g',0 };
1437 static const BYTE encodedDnsName[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69,
1438 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
1439 static const BYTE localhost[] = { 127, 0, 0, 1 };
1440 static const BYTE encodedIPAddr[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00,
1442 static const unsigned char encodedCommonName[] = {
1443 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0};
1444 static const BYTE encodedOidName[] = { 0x30,0x04,0x88,0x02,0x2a,0x03 };
1445 static const BYTE encodedDirectoryName[] = {
1446 0x30,0x19,0xa4,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1447 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1449 static void test_encodeAltName(DWORD dwEncoding)
1451 CERT_ALT_NAME_INFO info = { 0 };
1452 CERT_ALT_NAME_ENTRY entry = { 0 };
1456 char oid[] = "1.2.3";
1458 /* Test with empty info */
1459 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1460 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1463 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
1464 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
1467 /* Test with an empty entry */
1469 info.rgAltEntry = &entry;
1470 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1471 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1472 ok(!ret && GetLastError() == E_INVALIDARG,
1473 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1474 /* Test with an empty pointer */
1475 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
1476 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1477 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1480 ok(size == sizeof(emptyURL), "Wrong size %d\n", size);
1481 ok(!memcmp(buf, emptyURL, size), "Unexpected value\n");
1484 /* Test with a real URL */
1485 U(entry).pwszURL = (LPWSTR)url;
1486 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1487 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1490 ok(size == sizeof(encodedURL), "Wrong size %d\n", size);
1491 ok(!memcmp(buf, encodedURL, size), "Unexpected value\n");
1494 /* Now with the URL containing an invalid IA5 char */
1495 U(entry).pwszURL = (LPWSTR)nihongoURL;
1496 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1497 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1498 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
1499 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
1500 /* The first invalid character is at index 7 */
1501 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
1502 "Expected invalid char at index 7, got %d\n",
1503 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
1504 /* Now with the URL missing a scheme */
1505 U(entry).pwszURL = (LPWSTR)dnsName;
1506 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1507 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1508 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1511 /* This succeeds, but it shouldn't, so don't worry about conforming */
1514 /* Now with a DNS name */
1515 entry.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
1516 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1517 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1518 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1521 ok(size == sizeof(encodedDnsName), "Wrong size %d\n", size);
1522 ok(!memcmp(buf, encodedDnsName, size), "Unexpected value\n");
1525 /* Test with an IP address */
1526 entry.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
1527 U(entry).IPAddress.cbData = sizeof(localhost);
1528 U(entry).IPAddress.pbData = (LPBYTE)localhost;
1529 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1530 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1533 ok(size == sizeof(encodedIPAddr), "Wrong size %d\n", size);
1534 ok(!memcmp(buf, encodedIPAddr, size), "Unexpected value\n");
1538 entry.dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID;
1539 U(entry).pszRegisteredID = oid;
1540 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1541 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1544 ok(size == sizeof(encodedOidName), "Wrong size %d\n", size);
1545 ok(!memcmp(buf, encodedOidName, size), "Unexpected value\n");
1548 /* Test with directory name */
1549 entry.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
1550 U(entry).DirectoryName.cbData = sizeof(encodedCommonName);
1551 U(entry).DirectoryName.pbData = (LPBYTE)encodedCommonName;
1552 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1553 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1556 ok(size == sizeof(encodedDirectoryName), "Wrong size %d\n", size);
1557 ok(!memcmp(buf, encodedDirectoryName, size), "Unexpected value\n");
1562 static void test_decodeAltName(DWORD dwEncoding)
1564 static const BYTE unimplementedType[] = { 0x30, 0x06, 0x85, 0x04, 0x7f,
1566 static const BYTE bogusType[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00,
1568 static const BYTE dns_embedded_null[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f,
1569 0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 };
1570 static const BYTE dns_embedded_bell[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f,
1571 0x6f,0x2e,0x63,0x6f,0x6d,0x07,0x62,0x61,0x64,0x64,0x69,0x65 };
1572 static const BYTE url_embedded_null[] = { 0x30,0x10,0x86,0x0e,0x66,0x6f,
1573 0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 };
1577 CERT_ALT_NAME_INFO *info;
1579 /* Test some bogus ones first */
1580 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1581 unimplementedType, sizeof(unimplementedType), CRYPT_DECODE_ALLOC_FLAG,
1582 NULL, &buf, &bufSize);
1583 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
1584 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1585 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
1587 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1588 bogusType, sizeof(bogusType), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
1590 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
1591 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1592 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
1594 /* Now expected cases */
1595 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptySequence,
1596 emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1597 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1600 info = (CERT_ALT_NAME_INFO *)buf;
1602 ok(info->cAltEntry == 0, "Expected 0 entries, got %d\n",
1606 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptyURL,
1607 emptyURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1608 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1611 info = (CERT_ALT_NAME_INFO *)buf;
1613 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1615 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1616 "Expected CERT_ALT_NAME_URL, got %d\n",
1617 info->rgAltEntry[0].dwAltNameChoice);
1618 ok(U(info->rgAltEntry[0]).pwszURL == NULL || !*U(info->rgAltEntry[0]).pwszURL,
1619 "Expected empty URL\n");
1622 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1623 emptyURLExtraBytes, sizeof(emptyURLExtraBytes), 0, NULL, NULL, &bufSize);
1624 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1625 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedURL,
1626 encodedURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1627 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1630 info = (CERT_ALT_NAME_INFO *)buf;
1632 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1634 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1635 "Expected CERT_ALT_NAME_URL, got %d\n",
1636 info->rgAltEntry[0].dwAltNameChoice);
1637 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszURL, url), "Unexpected URL\n");
1640 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedDnsName,
1641 encodedDnsName[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1642 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1645 info = (CERT_ALT_NAME_INFO *)buf;
1647 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1649 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1650 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1651 info->rgAltEntry[0].dwAltNameChoice);
1652 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszDNSName, dnsName),
1653 "Unexpected DNS name\n");
1656 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedIPAddr,
1657 encodedIPAddr[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1658 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1661 info = (CERT_ALT_NAME_INFO *)buf;
1663 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1665 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS,
1666 "Expected CERT_ALT_NAME_IP_ADDRESS, got %d\n",
1667 info->rgAltEntry[0].dwAltNameChoice);
1668 ok(U(info->rgAltEntry[0]).IPAddress.cbData == sizeof(localhost),
1669 "Unexpected IP address length %d\n",
1670 U(info->rgAltEntry[0]).IPAddress.cbData);
1671 ok(!memcmp(U(info->rgAltEntry[0]).IPAddress.pbData, localhost,
1672 sizeof(localhost)), "Unexpected IP address value\n");
1675 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedOidName,
1676 sizeof(encodedOidName), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1677 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1680 info = (CERT_ALT_NAME_INFO *)buf;
1682 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1684 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_REGISTERED_ID,
1685 "Expected CERT_ALT_NAME_REGISTERED_ID, got %d\n",
1686 info->rgAltEntry[0].dwAltNameChoice);
1687 ok(!strcmp(U(info->rgAltEntry[0]).pszRegisteredID, "1.2.3"),
1688 "Expected OID 1.2.3, got %s\n", U(info->rgAltEntry[0]).pszRegisteredID);
1691 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1692 encodedDirectoryName, sizeof(encodedDirectoryName),
1693 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1694 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1697 info = (CERT_ALT_NAME_INFO *)buf;
1699 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1701 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME,
1702 "Expected CERT_ALT_NAME_DIRECTORY_NAME, got %d\n",
1703 info->rgAltEntry[0].dwAltNameChoice);
1704 ok(U(info->rgAltEntry[0]).DirectoryName.cbData ==
1705 sizeof(encodedCommonName), "Unexpected directory name length %d\n",
1706 U(info->rgAltEntry[0]).DirectoryName.cbData);
1707 ok(!memcmp(U(info->rgAltEntry[0]).DirectoryName.pbData,
1708 encodedCommonName, sizeof(encodedCommonName)),
1709 "Unexpected directory name value\n");
1712 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1713 dns_embedded_null, sizeof(dns_embedded_null), CRYPT_DECODE_ALLOC_FLAG,
1714 NULL, &buf, &bufSize);
1715 /* Fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned about the
1716 * particular failure, just that it doesn't decode.
1718 ok(!ret, "expected failure\n");
1719 /* An embedded bell character is allowed, however. */
1720 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1721 dns_embedded_bell, sizeof(dns_embedded_bell), CRYPT_DECODE_ALLOC_FLAG,
1722 NULL, &buf, &bufSize);
1723 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1726 info = (CERT_ALT_NAME_INFO *)buf;
1728 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1730 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1731 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1732 info->rgAltEntry[0].dwAltNameChoice);
1735 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1736 url_embedded_null, sizeof(dns_embedded_null), CRYPT_DECODE_ALLOC_FLAG,
1737 NULL, &buf, &bufSize);
1738 /* Again, fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned
1739 * about the particular failure, just that it doesn't decode.
1741 ok(!ret, "expected failure\n");
1744 struct UnicodeExpectedError
1752 static const WCHAR oneW[] = { '1',0 };
1753 static const WCHAR aW[] = { 'a',0 };
1754 static const WCHAR quoteW[] = { '"', 0 };
1756 static struct UnicodeExpectedError unicodeErrors[] = {
1757 { CERT_RDN_ANY_TYPE, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1758 { CERT_RDN_ENCODED_BLOB, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1759 { CERT_RDN_OCTET_STRING, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1760 { CERT_RDN_NUMERIC_STRING, aW, 0, CRYPT_E_INVALID_NUMERIC_STRING },
1761 { CERT_RDN_PRINTABLE_STRING, quoteW, 0, CRYPT_E_INVALID_PRINTABLE_STRING },
1762 { CERT_RDN_IA5_STRING, nihongoURL, 7, CRYPT_E_INVALID_IA5_STRING },
1765 struct UnicodeExpectedResult
1769 CRYPT_DATA_BLOB encoded;
1772 static BYTE oneNumeric[] = { 0x12, 0x01, 0x31 };
1773 static BYTE onePrintable[] = { 0x13, 0x01, 0x31 };
1774 static BYTE oneTeletex[] = { 0x14, 0x01, 0x31 };
1775 static BYTE oneVideotex[] = { 0x15, 0x01, 0x31 };
1776 static BYTE oneIA5[] = { 0x16, 0x01, 0x31 };
1777 static BYTE oneGraphic[] = { 0x19, 0x01, 0x31 };
1778 static BYTE oneVisible[] = { 0x1a, 0x01, 0x31 };
1779 static BYTE oneUniversal[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 };
1780 static BYTE oneGeneral[] = { 0x1b, 0x01, 0x31 };
1781 static BYTE oneBMP[] = { 0x1e, 0x02, 0x00, 0x31 };
1782 static BYTE oneUTF8[] = { 0x0c, 0x01, 0x31 };
1783 static BYTE nihongoT61[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,
1785 static BYTE nihongoGeneral[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1787 static BYTE nihongoBMP[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,
1788 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
1789 static BYTE nihongoUTF8[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1790 0xe2,0x89,0xaf,0xe5,0x9d,0x9b };
1792 static struct UnicodeExpectedResult unicodeResults[] = {
1793 { CERT_RDN_NUMERIC_STRING, oneW, { sizeof(oneNumeric), oneNumeric } },
1794 { CERT_RDN_PRINTABLE_STRING, oneW, { sizeof(onePrintable), onePrintable } },
1795 { CERT_RDN_TELETEX_STRING, oneW, { sizeof(oneTeletex), oneTeletex } },
1796 { CERT_RDN_VIDEOTEX_STRING, oneW, { sizeof(oneVideotex), oneVideotex } },
1797 { CERT_RDN_IA5_STRING, oneW, { sizeof(oneIA5), oneIA5 } },
1798 { CERT_RDN_GRAPHIC_STRING, oneW, { sizeof(oneGraphic), oneGraphic } },
1799 { CERT_RDN_VISIBLE_STRING, oneW, { sizeof(oneVisible), oneVisible } },
1800 { CERT_RDN_UNIVERSAL_STRING, oneW, { sizeof(oneUniversal), oneUniversal } },
1801 { CERT_RDN_GENERAL_STRING, oneW, { sizeof(oneGeneral), oneGeneral } },
1802 { CERT_RDN_BMP_STRING, oneW, { sizeof(oneBMP), oneBMP } },
1803 { CERT_RDN_UTF8_STRING, oneW, { sizeof(oneUTF8), oneUTF8 } },
1804 { CERT_RDN_BMP_STRING, nihongoURL, { sizeof(nihongoBMP), nihongoBMP } },
1805 { CERT_RDN_UTF8_STRING, nihongoURL, { sizeof(nihongoUTF8), nihongoUTF8 } },
1808 static struct UnicodeExpectedResult unicodeWeirdness[] = {
1809 { CERT_RDN_TELETEX_STRING, nihongoURL, { sizeof(nihongoT61), nihongoT61 } },
1810 { CERT_RDN_GENERAL_STRING, nihongoURL, { sizeof(nihongoGeneral), nihongoGeneral } },
1813 static void test_encodeUnicodeNameValue(DWORD dwEncoding)
1818 CERT_NAME_VALUE value;
1822 /* Crashes on win9x */
1823 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, NULL,
1824 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1825 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1826 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1828 /* Have to have a string of some sort */
1829 value.dwValueType = 0; /* aka CERT_RDN_ANY_TYPE */
1830 value.Value.pbData = NULL;
1831 value.Value.cbData = 0;
1832 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1833 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1834 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1835 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1836 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1837 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1838 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1839 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1840 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1841 value.dwValueType = CERT_RDN_ANY_TYPE;
1842 value.Value.pbData = (LPBYTE)oneW;
1843 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1844 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1845 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1846 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1847 value.Value.cbData = sizeof(oneW);
1848 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1849 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1850 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1851 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1852 /* An encoded string with specified length isn't good enough either */
1853 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1854 value.Value.pbData = oneUniversal;
1855 value.Value.cbData = sizeof(oneUniversal);
1856 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1857 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1858 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1859 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1860 /* More failure checking */
1861 value.Value.cbData = 0;
1862 for (i = 0; i < sizeof(unicodeErrors) / sizeof(unicodeErrors[0]); i++)
1864 value.Value.pbData = (LPBYTE)unicodeErrors[i].str;
1865 value.dwValueType = unicodeErrors[i].valueType;
1866 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1867 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1868 ok(!ret && GetLastError() == unicodeErrors[i].error,
1869 "Value type %d: expected %08x, got %08x\n", value.dwValueType,
1870 unicodeErrors[i].error, GetLastError());
1871 ok(size == unicodeErrors[i].errorIndex,
1872 "Expected error index %d, got %d\n", unicodeErrors[i].errorIndex,
1875 /* cbData can be zero if the string is NULL-terminated */
1876 value.Value.cbData = 0;
1877 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1879 value.Value.pbData = (LPBYTE)unicodeResults[i].str;
1880 value.dwValueType = unicodeResults[i].valueType;
1881 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1882 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1883 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
1884 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1887 ok(size == unicodeResults[i].encoded.cbData,
1888 "Value type %d: expected size %d, got %d\n",
1889 value.dwValueType, unicodeResults[i].encoded.cbData, size);
1890 ok(!memcmp(unicodeResults[i].encoded.pbData, buf, size),
1891 "Value type %d: unexpected value\n", value.dwValueType);
1895 /* These "encode," but they do so by truncating each unicode character
1896 * rather than properly encoding it. Kept separate from the proper results,
1897 * because the encoded forms won't decode to their original strings.
1899 for (i = 0; i < sizeof(unicodeWeirdness) / sizeof(unicodeWeirdness[0]); i++)
1901 value.Value.pbData = (LPBYTE)unicodeWeirdness[i].str;
1902 value.dwValueType = unicodeWeirdness[i].valueType;
1903 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1904 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1905 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1908 ok(size == unicodeWeirdness[i].encoded.cbData,
1909 "Value type %d: expected size %d, got %d\n",
1910 value.dwValueType, unicodeWeirdness[i].encoded.cbData, size);
1911 ok(!memcmp(unicodeWeirdness[i].encoded.pbData, buf, size),
1912 "Value type %d: unexpected value\n", value.dwValueType);
1918 static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
1920 if (n <= 0) return 0;
1921 while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
1922 return *str1 - *str2;
1925 static void test_decodeUnicodeNameValue(DWORD dwEncoding)
1929 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1935 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE,
1936 unicodeResults[i].encoded.pbData, unicodeResults[i].encoded.cbData,
1937 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
1938 ok(ret || broken(GetLastError() == CRYPT_E_NOT_CHAR_STRING /* Win9x */),
1939 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1942 PCERT_NAME_VALUE value = (PCERT_NAME_VALUE)buf;
1944 ok(value->dwValueType == unicodeResults[i].valueType,
1945 "Expected value type %d, got %d\n", unicodeResults[i].valueType,
1946 value->dwValueType);
1947 ok(!strncmpW((LPWSTR)value->Value.pbData, unicodeResults[i].str,
1948 value->Value.cbData / sizeof(WCHAR)),
1949 "Unexpected decoded value for index %d (value type %d)\n", i,
1950 unicodeResults[i].valueType);
1956 struct encodedOctets
1959 const BYTE *encoded;
1962 static const unsigned char bin46[] = { 'h','i',0 };
1963 static const unsigned char bin47[] = { 0x04,0x02,'h','i',0 };
1964 static const unsigned char bin48[] = {
1965 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1966 static const unsigned char bin49[] = {
1967 0x04,0x0f,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1968 static const unsigned char bin50[] = { 0 };
1969 static const unsigned char bin51[] = { 0x04,0x00,0 };
1971 static const struct encodedOctets octets[] = {
1977 static void test_encodeOctets(DWORD dwEncoding)
1979 CRYPT_DATA_BLOB blob;
1982 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1988 blob.cbData = strlen((const char*)octets[i].val);
1989 blob.pbData = (BYTE*)octets[i].val;
1990 ret = pCryptEncodeObjectEx(dwEncoding, X509_OCTET_STRING, &blob,
1991 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1992 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
1996 "Got unexpected type %d for octet string (expected 4)\n", buf[0]);
1997 ok(buf[1] == octets[i].encoded[1], "Got length %d, expected %d\n",
1998 buf[1], octets[i].encoded[1]);
1999 ok(!memcmp(buf + 1, octets[i].encoded + 1,
2000 octets[i].encoded[1] + 1), "Got unexpected value\n");
2006 static void test_decodeOctets(DWORD dwEncoding)
2010 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
2016 ret = pCryptDecodeObjectEx(dwEncoding, X509_OCTET_STRING,
2017 octets[i].encoded, octets[i].encoded[1] + 2,
2018 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2019 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2020 ok(bufSize >= sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1],
2021 "Expected size >= %d, got %d\n",
2022 (int)sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1], bufSize);
2023 ok(buf != NULL, "Expected allocated buffer\n");
2026 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)buf;
2029 ok(!memcmp(blob->pbData, octets[i].val, blob->cbData),
2030 "Unexpected value\n");
2036 static const BYTE bytesToEncode[] = { 0xff, 0xff };
2041 const BYTE *encoded;
2043 const BYTE *decoded;
2046 static const unsigned char bin52[] = { 0x03,0x03,0x00,0xff,0xff };
2047 static const unsigned char bin53[] = { 0xff,0xff };
2048 static const unsigned char bin54[] = { 0x03,0x03,0x01,0xff,0xfe };
2049 static const unsigned char bin55[] = { 0xff,0xfe };
2050 static const unsigned char bin56[] = { 0x03,0x02,0x01,0xfe };
2051 static const unsigned char bin57[] = { 0xfe };
2052 static const unsigned char bin58[] = { 0x03,0x01,0x00 };
2054 static const struct encodedBits bits[] = {
2055 /* normal test cases */
2056 { 0, bin52, 2, bin53 },
2057 { 1, bin54, 2, bin55 },
2058 /* strange test case, showing cUnusedBits >= 8 is allowed */
2059 { 9, bin56, 1, bin57 },
2062 static void test_encodeBits(DWORD dwEncoding)
2066 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
2068 CRYPT_BIT_BLOB blob;
2073 blob.cbData = sizeof(bytesToEncode);
2074 blob.pbData = (BYTE *)bytesToEncode;
2075 blob.cUnusedBits = bits[i].cUnusedBits;
2076 ret = pCryptEncodeObjectEx(dwEncoding, X509_BITS, &blob,
2077 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2078 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2081 ok(bufSize == bits[i].encoded[1] + 2,
2082 "%d: Got unexpected size %d, expected %d\n", i, bufSize,
2083 bits[i].encoded[1] + 2);
2084 ok(!memcmp(buf, bits[i].encoded, bits[i].encoded[1] + 2),
2085 "%d: Unexpected value\n", i);
2091 static void test_decodeBits(DWORD dwEncoding)
2093 static const BYTE ber[] = "\x03\x02\x01\xff";
2094 static const BYTE berDecoded = 0xfe;
2101 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
2103 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, bits[i].encoded,
2104 bits[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
2106 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2109 CRYPT_BIT_BLOB *blob;
2111 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + bits[i].cbDecoded,
2112 "Got unexpected size %d\n", bufSize);
2113 blob = (CRYPT_BIT_BLOB *)buf;
2114 ok(blob->cbData == bits[i].cbDecoded,
2115 "Got unexpected length %d, expected %d\n", blob->cbData,
2117 if (blob->cbData && bits[i].cbDecoded)
2118 ok(!memcmp(blob->pbData, bits[i].decoded, bits[i].cbDecoded),
2119 "Unexpected value\n");
2123 /* special case: check that something that's valid in BER but not in DER
2124 * decodes successfully
2126 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, ber, ber[1] + 2,
2127 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2128 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2131 CRYPT_BIT_BLOB *blob;
2133 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + sizeof(berDecoded),
2134 "Got unexpected size %d\n", bufSize);
2135 blob = (CRYPT_BIT_BLOB *)buf;
2136 ok(blob->cbData == sizeof(berDecoded),
2137 "Got unexpected length %d\n", blob->cbData);
2139 ok(*blob->pbData == berDecoded, "Unexpected value\n");
2146 CERT_BASIC_CONSTRAINTS2_INFO info;
2147 const BYTE *encoded;
2150 static const unsigned char bin59[] = { 0x30,0x00 };
2151 static const unsigned char bin60[] = { 0x30,0x03,0x01,0x01,0xff };
2152 static const unsigned char bin61[] = { 0x30,0x03,0x02,0x01,0x00 };
2153 static const unsigned char bin62[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2154 static const struct Constraints2 constraints2[] = {
2155 /* empty constraints */
2156 { { FALSE, FALSE, 0}, bin59 },
2158 { { TRUE, FALSE, 0}, bin60 },
2159 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well,
2160 * but that's not the case
2162 { { FALSE, TRUE, 0}, bin61 },
2163 /* can be a CA and has path length constraints set */
2164 { { TRUE, TRUE, 1}, bin62 },
2167 static const BYTE emptyConstraint[] = { 0x30, 0x03, 0x03, 0x01, 0x00 };
2168 static const BYTE encodedDomainName[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11,
2169 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
2170 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
2171 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2172 static const BYTE constraintWithDomainName[] = { 0x30, 0x32, 0x03, 0x01, 0x00,
2173 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
2174 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30,
2175 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
2176 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2178 static void test_encodeBasicConstraints(DWORD dwEncoding)
2180 DWORD i, bufSize = 0;
2181 CERT_BASIC_CONSTRAINTS_INFO info = { { 0 } };
2182 CERT_NAME_BLOB nameBlob = { sizeof(encodedDomainName),
2183 (LPBYTE)encodedDomainName };
2187 /* First test with the simpler info2 */
2188 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2190 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2191 &constraints2[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf,
2193 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2196 ok(bufSize == constraints2[i].encoded[1] + 2,
2197 "Expected %d bytes, got %d\n", constraints2[i].encoded[1] + 2,
2199 ok(!memcmp(buf, constraints2[i].encoded,
2200 constraints2[i].encoded[1] + 2), "Unexpected value\n");
2204 /* Now test with more complex basic constraints */
2205 info.SubjectType.cbData = 0;
2206 info.fPathLenConstraint = FALSE;
2207 info.cSubtreesConstraint = 0;
2208 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2209 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2210 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2211 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2214 ok(bufSize == sizeof(emptyConstraint), "Wrong size %d\n", bufSize);
2215 ok(!memcmp(buf, emptyConstraint, sizeof(emptyConstraint)),
2216 "Unexpected value\n");
2219 /* None of the certs I examined had any subtree constraint, but I test one
2220 * anyway just in case.
2222 info.cSubtreesConstraint = 1;
2223 info.rgSubtreesConstraint = &nameBlob;
2224 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2225 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2226 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2227 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2230 ok(bufSize == sizeof(constraintWithDomainName), "Wrong size %d\n", bufSize);
2231 ok(!memcmp(buf, constraintWithDomainName,
2232 sizeof(constraintWithDomainName)), "Unexpected value\n");
2235 /* FIXME: test encoding with subject type. */
2238 static const unsigned char bin63[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 };
2240 static void test_decodeBasicConstraints(DWORD dwEncoding)
2242 static const BYTE inverted[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01,
2244 static const struct Constraints2 badBool = { { TRUE, TRUE, 1 }, bin63 };
2250 /* First test with simpler info2 */
2251 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2253 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2254 constraints2[i].encoded, constraints2[i].encoded[1] + 2,
2255 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2256 ok(ret, "CryptDecodeObjectEx failed for item %d: %08x\n", i,
2260 CERT_BASIC_CONSTRAINTS2_INFO *info =
2261 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2263 ok(!memcmp(info, &constraints2[i].info, sizeof(*info)),
2264 "Unexpected value for item %d\n", i);
2268 /* Check with the order of encoded elements inverted */
2270 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2271 inverted, inverted[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
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 ok(!buf, "Expected buf to be set to NULL\n");
2278 /* Check with a non-DER bool */
2279 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2280 badBool.encoded, badBool.encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2282 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2285 CERT_BASIC_CONSTRAINTS2_INFO *info =
2286 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2288 ok(!memcmp(info, &badBool.info, sizeof(*info)), "Unexpected value\n");
2291 /* Check with a non-basic constraints value */
2292 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2293 encodedCommonName, encodedCommonName[1] + 2,
2294 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2295 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2296 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2297 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2299 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */
2300 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2301 emptyConstraint, sizeof(emptyConstraint), CRYPT_DECODE_ALLOC_FLAG, NULL,
2303 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2306 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2308 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2309 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2310 ok(info->cSubtreesConstraint == 0, "Expected no subtree constraints\n");
2313 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2314 constraintWithDomainName, sizeof(constraintWithDomainName),
2315 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2316 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2319 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2321 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2322 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2323 ok(info->cSubtreesConstraint == 1, "Expected a subtree constraint\n");
2324 if (info->cSubtreesConstraint && info->rgSubtreesConstraint)
2326 ok(info->rgSubtreesConstraint[0].cbData ==
2327 sizeof(encodedDomainName), "Wrong size %d\n",
2328 info->rgSubtreesConstraint[0].cbData);
2329 ok(!memcmp(info->rgSubtreesConstraint[0].pbData, encodedDomainName,
2330 sizeof(encodedDomainName)), "Unexpected value\n");
2336 /* These are terrible public keys of course, I'm just testing encoding */
2337 static const BYTE modulus1[] = { 0,0,0,1,1,1,1,1 };
2338 static const BYTE modulus2[] = { 1,1,1,1,1,0,0,0 };
2339 static const BYTE modulus3[] = { 0x80,1,1,1,1,0,0,0 };
2340 static const BYTE modulus4[] = { 1,1,1,1,1,0,0,0x80 };
2341 static const BYTE mod1_encoded[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 };
2342 static const BYTE mod2_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2343 static const BYTE mod3_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 };
2344 static const BYTE mod4_encoded[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2346 struct EncodedRSAPubKey
2348 const BYTE *modulus;
2350 const BYTE *encoded;
2351 size_t decodedModulusLen;
2354 struct EncodedRSAPubKey rsaPubKeys[] = {
2355 { modulus1, sizeof(modulus1), mod1_encoded, sizeof(modulus1) },
2356 { modulus2, sizeof(modulus2), mod2_encoded, 5 },
2357 { modulus3, sizeof(modulus3), mod3_encoded, 5 },
2358 { modulus4, sizeof(modulus4), mod4_encoded, 8 },
2361 static void test_encodeRsaPublicKey(DWORD dwEncoding)
2363 BYTE toEncode[sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + sizeof(modulus1)];
2364 BLOBHEADER *hdr = (BLOBHEADER *)toEncode;
2365 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(toEncode + sizeof(BLOBHEADER));
2368 DWORD bufSize = 0, i;
2370 /* Try with a bogus blob type */
2372 hdr->bVersion = CUR_BLOB_VERSION;
2374 hdr->aiKeyAlg = CALG_RSA_KEYX;
2375 rsaPubKey->magic = 0x31415352;
2376 rsaPubKey->bitlen = sizeof(modulus1) * 8;
2377 rsaPubKey->pubexp = 65537;
2378 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), modulus1,
2381 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2382 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2383 ok(!ret && GetLastError() == E_INVALIDARG,
2384 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2385 /* Now with a bogus reserved field */
2386 hdr->bType = PUBLICKEYBLOB;
2388 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2389 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2392 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2393 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2394 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2397 /* Now with a bogus blob version */
2400 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2401 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2404 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2405 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2406 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2409 /* And with a bogus alg ID */
2410 hdr->bVersion = CUR_BLOB_VERSION;
2411 hdr->aiKeyAlg = CALG_DES;
2412 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2413 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2416 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2417 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2418 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2421 /* Check a couple of RSA-related OIDs */
2422 hdr->aiKeyAlg = CALG_RSA_KEYX;
2423 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_RSA,
2424 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2425 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2426 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2427 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2428 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2429 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2430 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2431 /* Finally, all valid */
2432 hdr->aiKeyAlg = CALG_RSA_KEYX;
2433 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2435 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2436 rsaPubKeys[i].modulus, rsaPubKeys[i].modulusLen);
2437 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2438 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2439 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2442 ok(bufSize == rsaPubKeys[i].encoded[1] + 2,
2443 "Expected size %d, got %d\n", rsaPubKeys[i].encoded[1] + 2,
2445 ok(!memcmp(buf, rsaPubKeys[i].encoded, bufSize),
2446 "Unexpected value\n");
2452 static void test_decodeRsaPublicKey(DWORD dwEncoding)
2459 /* Try with a bad length */
2460 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2461 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1],
2462 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2463 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
2464 GetLastError() == OSS_MORE_INPUT /* Win9x/NT4 */),
2465 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n",
2467 /* Try with a couple of RSA-related OIDs */
2468 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_RSA,
2469 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2470 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2471 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2472 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2473 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2474 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2475 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2476 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2477 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2478 /* Now try success cases */
2479 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2482 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2483 rsaPubKeys[i].encoded, rsaPubKeys[i].encoded[1] + 2,
2484 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2485 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2488 BLOBHEADER *hdr = (BLOBHEADER *)buf;
2489 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER));
2491 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2492 rsaPubKeys[i].decodedModulusLen,
2493 "Wrong size %d\n", bufSize);
2494 ok(hdr->bType == PUBLICKEYBLOB,
2495 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB,
2497 ok(hdr->bVersion == CUR_BLOB_VERSION,
2498 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
2499 CUR_BLOB_VERSION, hdr->bVersion);
2500 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n",
2502 ok(hdr->aiKeyAlg == CALG_RSA_KEYX,
2503 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg);
2504 ok(rsaPubKey->magic == 0x31415352,
2505 "Expected magic RSA1, got %08x\n", rsaPubKey->magic);
2506 ok(rsaPubKey->bitlen == rsaPubKeys[i].decodedModulusLen * 8,
2507 "Wrong bit len %d\n", rsaPubKey->bitlen);
2508 ok(rsaPubKey->pubexp == 65537, "Expected pubexp 65537, got %d\n",
2510 ok(!memcmp(buf + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2511 rsaPubKeys[i].modulus, rsaPubKeys[i].decodedModulusLen),
2512 "Unexpected modulus\n");
2518 static const BYTE intSequence[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01,
2519 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02,
2520 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2522 static const BYTE mixedSequence[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
2523 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f,
2524 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02,
2525 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2527 static void test_encodeSequenceOfAny(DWORD dwEncoding)
2529 CRYPT_DER_BLOB blobs[sizeof(ints) / sizeof(ints[0])];
2530 CRYPT_SEQUENCE_OF_ANY seq;
2536 /* Encode a homogeneous sequence */
2537 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
2539 blobs[i].cbData = ints[i].encoded[1] + 2;
2540 blobs[i].pbData = (BYTE *)ints[i].encoded;
2542 seq.cValue = sizeof(ints) / sizeof(ints[0]);
2543 seq.rgValue = blobs;
2545 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2546 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2547 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2550 ok(bufSize == sizeof(intSequence), "Wrong size %d\n", bufSize);
2551 ok(!memcmp(buf, intSequence, intSequence[1] + 2), "Unexpected value\n");
2554 /* Change the type of the first element in the sequence, and give it
2557 blobs[0].cbData = times[0].encodedTime[1] + 2;
2558 blobs[0].pbData = (BYTE *)times[0].encodedTime;
2559 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2560 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2561 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2564 ok(bufSize == sizeof(mixedSequence), "Wrong size %d\n", bufSize);
2565 ok(!memcmp(buf, mixedSequence, mixedSequence[1] + 2),
2566 "Unexpected value\n");
2571 static void test_decodeSequenceOfAny(DWORD dwEncoding)
2577 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, intSequence,
2578 intSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2579 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2582 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2585 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2586 "Wrong elements %d\n", seq->cValue);
2587 for (i = 0; i < min(seq->cValue, sizeof(ints) / sizeof(ints[0])); i++)
2589 ok(seq->rgValue[i].cbData == ints[i].encoded[1] + 2,
2590 "Expected %d bytes, got %d\n", ints[i].encoded[1] + 2,
2591 seq->rgValue[i].cbData);
2592 ok(!memcmp(seq->rgValue[i].pbData, ints[i].encoded,
2593 ints[i].encoded[1] + 2), "Unexpected value\n");
2597 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, mixedSequence,
2598 mixedSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
2600 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2603 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2605 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2606 "Wrong elements %d\n", seq->cValue);
2607 /* Just check the first element since it's all that changed */
2608 ok(seq->rgValue[0].cbData == times[0].encodedTime[1] + 2,
2609 "Expected %d bytes, got %d\n", times[0].encodedTime[1] + 2,
2610 seq->rgValue[0].cbData);
2611 ok(!memcmp(seq->rgValue[0].pbData, times[0].encodedTime,
2612 times[0].encodedTime[1] + 2), "Unexpected value\n");
2617 struct encodedExtensions
2619 CERT_EXTENSIONS exts;
2620 const BYTE *encoded;
2623 static BYTE crit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2624 static BYTE noncrit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2625 static CHAR oid_basic_constraints2[] = szOID_BASIC_CONSTRAINTS2;
2626 static CERT_EXTENSION criticalExt =
2627 { oid_basic_constraints2, TRUE, { 8, crit_ext_data } };
2628 static CERT_EXTENSION nonCriticalExt =
2629 { oid_basic_constraints2, FALSE, { 8, noncrit_ext_data } };
2630 static CHAR oid_short[] = "1.1";
2631 static CERT_EXTENSION extWithShortOid =
2632 { oid_short, FALSE, { 0, NULL } };
2634 static const BYTE ext0[] = { 0x30,0x00 };
2635 static const BYTE ext1[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2636 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2637 static const BYTE ext2[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2638 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2639 static const BYTE ext3[] = { 0x30,0x07,0x30,0x05,0x06,0x01,0x29,0x04,0x00 };
2641 static const struct encodedExtensions exts[] = {
2642 { { 0, NULL }, ext0 },
2643 { { 1, &criticalExt }, ext1 },
2644 { { 1, &nonCriticalExt }, ext2 },
2645 { { 1, &extWithShortOid }, ext3 }
2648 static void test_encodeExtensions(DWORD dwEncoding)
2652 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2658 ret = pCryptEncodeObjectEx(dwEncoding, X509_EXTENSIONS, &exts[i].exts,
2659 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2660 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2663 ok(bufSize == exts[i].encoded[1] + 2,
2664 "Expected %d bytes, got %d\n", exts[i].encoded[1] + 2, bufSize);
2665 ok(!memcmp(buf, exts[i].encoded, exts[i].encoded[1] + 2),
2666 "Unexpected value\n");
2672 static void test_decodeExtensions(DWORD dwEncoding)
2676 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2682 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS,
2683 exts[i].encoded, exts[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2684 NULL, &buf, &bufSize);
2685 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2688 CERT_EXTENSIONS *ext = (CERT_EXTENSIONS *)buf;
2691 ok(ext->cExtension == exts[i].exts.cExtension,
2692 "Expected %d extensions, see %d\n", exts[i].exts.cExtension,
2694 for (j = 0; j < min(ext->cExtension, exts[i].exts.cExtension); j++)
2696 ok(!strcmp(ext->rgExtension[j].pszObjId,
2697 exts[i].exts.rgExtension[j].pszObjId),
2698 "Expected OID %s, got %s\n",
2699 exts[i].exts.rgExtension[j].pszObjId,
2700 ext->rgExtension[j].pszObjId);
2701 ok(!memcmp(ext->rgExtension[j].Value.pbData,
2702 exts[i].exts.rgExtension[j].Value.pbData,
2703 exts[i].exts.rgExtension[j].Value.cbData),
2704 "Unexpected value\n");
2711 /* MS encodes public key info with a NULL if the algorithm identifier's
2712 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2713 * it encodes them by omitting the algorithm parameters. It accepts either
2714 * form for decoding.
2716 struct encodedPublicKey
2718 CERT_PUBLIC_KEY_INFO info;
2719 const BYTE *encoded;
2720 const BYTE *encodedNoNull;
2721 CERT_PUBLIC_KEY_INFO decoded;
2724 static const BYTE aKey[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2726 static const BYTE params[] = { 0x02, 0x01, 0x01 };
2728 static const unsigned char bin64[] = {
2729 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2730 static const unsigned char bin65[] = {
2731 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2732 static const unsigned char bin66[] = {
2733 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2734 static const unsigned char bin67[] = {
2735 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2736 static const unsigned char bin68[] = {
2737 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01,
2738 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2739 static const unsigned char bin69[] = {
2740 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2741 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2742 static const unsigned char bin70[] = {
2743 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2744 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2746 static const unsigned char bin71[] = {
2747 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2748 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2750 static unsigned char bin72[] = { 0x05,0x00};
2752 static CHAR oid_bogus[] = "1.2.3",
2753 oid_rsa[] = szOID_RSA;
2755 static const struct encodedPublicKey pubKeys[] = {
2756 /* with a bogus OID */
2757 { { { oid_bogus, { 0, NULL } }, { 0, NULL, 0 } },
2759 { { oid_bogus, { 2, bin72 } }, { 0, NULL, 0 } } },
2760 /* some normal keys */
2761 { { { oid_rsa, { 0, NULL } }, { 0, NULL, 0} },
2763 { { oid_rsa, { 2, bin72 } }, { 0, NULL, 0 } } },
2764 { { { oid_rsa, { 0, NULL } }, { sizeof(aKey), (BYTE *)aKey, 0} },
2766 { { oid_rsa, { 2, bin72 } }, { sizeof(aKey), (BYTE *)aKey, 0} } },
2767 /* with add'l parameters--note they must be DER-encoded */
2768 { { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2769 (BYTE *)aKey, 0 } },
2771 { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2772 (BYTE *)aKey, 0 } } },
2775 static void test_encodePublicKeyInfo(DWORD dwEncoding)
2779 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2785 ret = pCryptEncodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2786 &pubKeys[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf,
2788 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2789 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2792 ok(bufSize == pubKeys[i].encoded[1] + 2,
2793 "Expected %d bytes, got %d\n", pubKeys[i].encoded[1] + 2, bufSize);
2794 if (bufSize == pubKeys[i].encoded[1] + 2)
2795 ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2),
2796 "Unexpected value\n");
2802 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO *expected,
2803 const CERT_PUBLIC_KEY_INFO *got)
2805 ok(!strcmp(expected->Algorithm.pszObjId, got->Algorithm.pszObjId),
2806 "Expected OID %s, got %s\n", expected->Algorithm.pszObjId,
2807 got->Algorithm.pszObjId);
2808 ok(expected->Algorithm.Parameters.cbData ==
2809 got->Algorithm.Parameters.cbData,
2810 "Expected parameters of %d bytes, got %d\n",
2811 expected->Algorithm.Parameters.cbData, got->Algorithm.Parameters.cbData);
2812 if (expected->Algorithm.Parameters.cbData)
2813 ok(!memcmp(expected->Algorithm.Parameters.pbData,
2814 got->Algorithm.Parameters.pbData, got->Algorithm.Parameters.cbData),
2815 "Unexpected algorithm parameters\n");
2816 ok(expected->PublicKey.cbData == got->PublicKey.cbData,
2817 "Expected public key of %d bytes, got %d\n",
2818 expected->PublicKey.cbData, got->PublicKey.cbData);
2819 if (expected->PublicKey.cbData)
2820 ok(!memcmp(expected->PublicKey.pbData, got->PublicKey.pbData,
2821 got->PublicKey.cbData), "Unexpected public key value\n");
2824 static void test_decodePublicKeyInfo(DWORD dwEncoding)
2826 static const BYTE bogusPubKeyInfo[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
2827 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
2828 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
2829 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2835 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2837 /* The NULL form decodes to the decoded member */
2838 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2839 pubKeys[i].encoded, pubKeys[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2840 NULL, &buf, &bufSize);
2841 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2844 comparePublicKeyInfo(&pubKeys[i].decoded,
2845 (CERT_PUBLIC_KEY_INFO *)buf);
2848 /* The non-NULL form decodes to the original */
2849 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2850 pubKeys[i].encodedNoNull, pubKeys[i].encodedNoNull[1] + 2,
2851 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2852 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2855 comparePublicKeyInfo(&pubKeys[i].info, (CERT_PUBLIC_KEY_INFO *)buf);
2859 /* Test with bogus (not valid DER) parameters */
2860 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2861 bogusPubKeyInfo, bogusPubKeyInfo[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2862 NULL, &buf, &bufSize);
2863 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2864 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2865 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2869 static const BYTE v1Cert[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
2870 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2871 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
2872 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
2873 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2874 static const BYTE v2Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02,
2875 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2876 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2877 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2878 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2879 static const BYTE v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2880 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2881 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2882 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2883 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2884 static const BYTE v4Cert[] = {
2885 0x30,0x38,0xa0,0x03,0x02,0x01,0x03,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,
2886 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
2887 0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
2888 0x30,0x30,0x30,0x5a,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00 };
2889 static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
2890 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2891 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2892 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2893 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2894 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2895 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2896 static const BYTE v1CertWithSerial[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
2897 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2898 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2899 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2900 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2901 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2902 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2903 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2904 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
2905 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
2906 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
2907 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
2908 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
2909 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
2910 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
2911 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
2912 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2913 static const BYTE v1CertWithPubKey[] = {
2914 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2915 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2916 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2917 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2918 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2919 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2920 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2921 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2922 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
2923 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
2925 static const BYTE v1CertWithPubKeyNoNull[] = {
2926 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2927 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2928 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2929 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2930 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2931 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2932 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2933 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2934 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
2935 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2936 static const BYTE v1CertWithSubjectKeyId[] = {
2937 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2938 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2939 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2940 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2941 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2942 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2943 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
2944 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2945 0x4c,0x61,0x6e,0x67,0x00 };
2946 static const BYTE v1CertWithIssuerUniqueId[] = {
2947 0x30,0x38,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
2948 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
2949 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
2950 0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x81,0x02,0x00,0x01 };
2951 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueId[] = {
2952 0x30,0x81,0x99,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2953 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2954 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2955 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2956 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2957 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2958 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2959 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2960 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,
2961 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
2962 0x01,0x01,0xff,0x02,0x01,0x01 };
2963 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull[] = {
2964 0x30,0x81,0x97,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2965 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2966 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2967 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2968 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2969 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2970 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2971 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2972 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
2973 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
2974 0xff,0x02,0x01,0x01 };
2976 static const BYTE serialNum[] = { 0x01 };
2978 static void test_encodeCertToBeSigned(DWORD dwEncoding)
2983 CERT_INFO info = { 0 };
2984 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2985 static char oid_subject_key_identifier[] = szOID_SUBJECT_KEY_IDENTIFIER;
2990 /* Test with NULL pvStructInfo (crashes on win9x) */
2991 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL,
2992 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
2993 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2994 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2996 /* Test with a V1 cert */
2997 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2998 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
2999 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3000 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3003 ok(size == v1Cert[1] + 2, "Expected size %d, got %d\n",
3004 v1Cert[1] + 2, size);
3005 ok(!memcmp(buf, v1Cert, size), "Got unexpected value\n");
3009 info.dwVersion = CERT_V2;
3010 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3011 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3012 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3013 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3016 ok(size == sizeof(v2Cert), "Wrong size %d\n", size);
3017 ok(!memcmp(buf, v2Cert, size), "Got unexpected value\n");
3021 info.dwVersion = CERT_V3;
3022 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3023 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3024 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3025 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3028 ok(size == sizeof(v3Cert), "Wrong size %d\n", size);
3029 ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n");
3033 info.dwVersion = 3; /* Not a typo, CERT_V3 is 2 */
3034 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3035 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3038 ok(size == sizeof(v4Cert), "Wrong size %d\n", size);
3039 ok(!memcmp(buf, v4Cert, size), "Unexpected value\n");
3042 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
3043 * API doesn't prevent it)
3045 info.dwVersion = CERT_V1;
3046 info.cExtension = 1;
3047 info.rgExtension = &criticalExt;
3048 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3049 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3050 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3051 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3054 ok(size == sizeof(v1CertWithConstraints), "Wrong size %d\n", size);
3055 ok(!memcmp(buf, v1CertWithConstraints, size), "Got unexpected value\n");
3058 /* test v1 cert with a serial number */
3059 info.SerialNumber.cbData = sizeof(serialNum);
3060 info.SerialNumber.pbData = (BYTE *)serialNum;
3061 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3062 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3065 ok(size == sizeof(v1CertWithSerial), "Wrong size %d\n", size);
3066 ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n");
3069 /* Test v1 cert with an issuer name, serial number, and issuer unique id */
3070 info.dwVersion = CERT_V1;
3071 info.cExtension = 0;
3072 info.IssuerUniqueId.cbData = sizeof(serialNum);
3073 info.IssuerUniqueId.pbData = (BYTE *)serialNum;
3074 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3075 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3076 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3079 ok(size == sizeof(v1CertWithIssuerUniqueId), "Wrong size %d\n", size);
3080 ok(!memcmp(buf, v1CertWithIssuerUniqueId, size),
3081 "Got unexpected value\n");
3084 /* Test v1 cert with an issuer name, a subject name, and a serial number */
3085 info.IssuerUniqueId.cbData = 0;
3086 info.IssuerUniqueId.pbData = NULL;
3087 info.cExtension = 1;
3088 info.rgExtension = &criticalExt;
3089 info.Issuer.cbData = sizeof(encodedCommonName);
3090 info.Issuer.pbData = (BYTE *)encodedCommonName;
3091 info.Subject.cbData = sizeof(encodedCommonName);
3092 info.Subject.pbData = (BYTE *)encodedCommonName;
3093 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3094 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3097 ok(size == sizeof(bigCert), "Wrong size %d\n", size);
3098 ok(!memcmp(buf, bigCert, size), "Got unexpected value\n");
3101 /* Add a public key */
3102 info.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3103 info.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
3104 info.SubjectPublicKeyInfo.PublicKey.pbData = (LPBYTE)aKey;
3105 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3106 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3109 ok(size == sizeof(v1CertWithPubKey) ||
3110 size == sizeof(v1CertWithPubKeyNoNull), "Wrong size %d\n", size);
3111 if (size == sizeof(v1CertWithPubKey))
3112 ok(!memcmp(buf, v1CertWithPubKey, size), "Got unexpected value\n");
3113 else if (size == sizeof(v1CertWithPubKeyNoNull))
3114 ok(!memcmp(buf, v1CertWithPubKeyNoNull, size),
3115 "Got unexpected value\n");
3118 /* Again add an issuer unique id */
3119 info.IssuerUniqueId.cbData = sizeof(serialNum);
3120 info.IssuerUniqueId.pbData = (BYTE *)serialNum;
3121 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3122 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3123 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3126 ok(size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId) ||
3127 size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull),
3128 "Wrong size %d\n", size);
3129 if (size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId))
3130 ok(!memcmp(buf, v1CertWithSubjectIssuerSerialAndIssuerUniqueId,
3131 size), "unexpected value\n");
3133 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull))
3135 v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull, size),
3136 "unexpected value\n");
3139 /* Remove the public key, and add a subject key identifier extension */
3140 info.IssuerUniqueId.cbData = 0;
3141 info.IssuerUniqueId.pbData = NULL;
3142 info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
3143 info.SubjectPublicKeyInfo.PublicKey.cbData = 0;
3144 info.SubjectPublicKeyInfo.PublicKey.pbData = NULL;
3145 ext.pszObjId = oid_subject_key_identifier;
3146 ext.fCritical = FALSE;
3147 ext.Value.cbData = sizeof(octetCommonNameValue);
3148 ext.Value.pbData = octetCommonNameValue;
3149 info.cExtension = 1;
3150 info.rgExtension = &ext;
3151 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3152 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3155 ok(size == sizeof(v1CertWithSubjectKeyId), "Wrong size %d\n", size);
3156 ok(!memcmp(buf, v1CertWithSubjectKeyId, size), "Unexpected value\n");
3161 static void test_decodeCertToBeSigned(DWORD dwEncoding)
3163 static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert, v4Cert,
3164 v1CertWithConstraints, v1CertWithSerial, v1CertWithIssuerUniqueId };
3169 /* Test with NULL pbEncoded */
3170 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 0,
3171 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3172 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
3173 GetLastError() == OSS_BAD_ARG /* Win9x */),
3174 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
3177 /* Crashes on win9x */
3178 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 1,
3179 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3180 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3181 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3183 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT or
3184 * CRYPT_E_ASN1_BADTAG, because at a minimum a cert must have a non-zero
3185 * serial number, an issuer, a subject, and a public key.
3187 for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++)
3189 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3190 corruptCerts[i], corruptCerts[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3192 ok(!ret, "Expected failure\n");
3194 /* The following succeeds, even though v1 certs are not allowed to have
3197 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3198 v1CertWithSubjectKeyId, sizeof(v1CertWithSubjectKeyId),
3199 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3200 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3203 CERT_INFO *info = (CERT_INFO *)buf;
3205 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3206 ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %d\n",
3208 ok(info->cExtension == 1, "expected 1 extension, got %d\n",
3212 /* The following also succeeds, even though V1 certs are not allowed to
3213 * have issuer unique ids.
3215 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3216 v1CertWithSubjectIssuerSerialAndIssuerUniqueId,
3217 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId),
3218 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3219 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3222 CERT_INFO *info = (CERT_INFO *)buf;
3224 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3225 ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %d\n",
3227 ok(info->IssuerUniqueId.cbData == sizeof(serialNum),
3228 "unexpected issuer unique id size %d\n", info->IssuerUniqueId.cbData);
3229 ok(!memcmp(info->IssuerUniqueId.pbData, serialNum, sizeof(serialNum)),
3230 "unexpected issuer unique id value\n");
3233 /* Now check with serial number, subject and issuer specified */
3234 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert,
3235 sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3236 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3239 CERT_INFO *info = (CERT_INFO *)buf;
3241 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3242 ok(info->SerialNumber.cbData == 1,
3243 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3244 ok(*info->SerialNumber.pbData == *serialNum,
3245 "Expected serial number %d, got %d\n", *serialNum,
3246 *info->SerialNumber.pbData);
3247 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3248 "Wrong size %d\n", info->Issuer.cbData);
3249 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3250 "Unexpected issuer\n");
3251 ok(info->Subject.cbData == sizeof(encodedCommonName),
3252 "Wrong size %d\n", info->Subject.cbData);
3253 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3254 info->Subject.cbData), "Unexpected subject\n");
3257 /* Check again with pub key specified */
3258 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3259 v1CertWithPubKey, sizeof(v1CertWithPubKey), CRYPT_DECODE_ALLOC_FLAG, NULL,
3261 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3264 CERT_INFO *info = (CERT_INFO *)buf;
3266 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3267 ok(info->SerialNumber.cbData == 1,
3268 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3269 ok(*info->SerialNumber.pbData == *serialNum,
3270 "Expected serial number %d, got %d\n", *serialNum,
3271 *info->SerialNumber.pbData);
3272 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3273 "Wrong size %d\n", info->Issuer.cbData);
3274 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3275 "Unexpected issuer\n");
3276 ok(info->Subject.cbData == sizeof(encodedCommonName),
3277 "Wrong size %d\n", info->Subject.cbData);
3278 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3279 info->Subject.cbData), "Unexpected subject\n");
3280 ok(!strcmp(info->SubjectPublicKeyInfo.Algorithm.pszObjId,
3281 szOID_RSA_RSA), "Expected szOID_RSA_RSA, got %s\n",
3282 info->SubjectPublicKeyInfo.Algorithm.pszObjId);
3283 ok(info->SubjectPublicKeyInfo.PublicKey.cbData == sizeof(aKey),
3284 "Wrong size %d\n", info->SubjectPublicKeyInfo.PublicKey.cbData);
3285 ok(!memcmp(info->SubjectPublicKeyInfo.PublicKey.pbData, aKey,
3286 sizeof(aKey)), "Unexpected public key\n");
3291 static const BYTE hash[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
3294 static const BYTE signedBigCert[] = {
3295 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
3296 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
3297 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
3298 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3299 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
3300 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
3301 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
3302 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
3303 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
3304 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3305 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
3306 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
3308 static void test_encodeCert(DWORD dwEncoding)
3310 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
3311 * also that bigCert is a NULL-terminated string, so don't count its
3312 * last byte (otherwise the signed cert won't decode.)
3314 CERT_SIGNED_CONTENT_INFO info = { { sizeof(bigCert), (BYTE *)bigCert },
3315 { NULL, { 0, NULL } }, { sizeof(hash), (BYTE *)hash, 0 } };
3320 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT, &info,
3321 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
3322 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3325 ok(bufSize == sizeof(signedBigCert), "Wrong size %d\n", bufSize);
3326 ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n");
3331 static void test_decodeCert(DWORD dwEncoding)
3337 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert,
3338 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3339 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3342 CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf;
3344 ok(info->ToBeSigned.cbData == sizeof(bigCert),
3345 "Wrong cert size %d\n", info->ToBeSigned.cbData);
3346 ok(!memcmp(info->ToBeSigned.pbData, bigCert, info->ToBeSigned.cbData),
3347 "Unexpected cert\n");
3348 ok(info->Signature.cbData == sizeof(hash),
3349 "Wrong signature size %d\n", info->Signature.cbData);
3350 ok(!memcmp(info->Signature.pbData, hash, info->Signature.cbData),
3351 "Unexpected signature\n");
3354 /* A signed cert decodes as a CERT_INFO too */
3355 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCert,
3356 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3357 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3360 CERT_INFO *info = (CERT_INFO *)buf;
3362 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3363 ok(info->SerialNumber.cbData == 1,
3364 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3365 ok(*info->SerialNumber.pbData == *serialNum,
3366 "Expected serial number %d, got %d\n", *serialNum,
3367 *info->SerialNumber.pbData);
3368 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3369 "Wrong size %d\n", info->Issuer.cbData);
3370 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3371 "Unexpected issuer\n");
3372 ok(info->Subject.cbData == sizeof(encodedCommonName),
3373 "Wrong size %d\n", info->Subject.cbData);
3374 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3375 info->Subject.cbData), "Unexpected subject\n");
3380 static const BYTE emptyDistPoint[] = { 0x30, 0x02, 0x30, 0x00 };
3381 static const BYTE distPointWithUrl[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3382 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3383 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3384 static const BYTE distPointWithReason[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3386 static const BYTE distPointWithIssuer[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3387 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3388 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3389 static const BYTE distPointWithUrlAndIssuer[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3390 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3391 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3392 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3393 0x2e, 0x6f, 0x72, 0x67 };
3394 static const BYTE crlReason = CRL_REASON_KEY_COMPROMISE |
3395 CRL_REASON_AFFILIATION_CHANGED;
3397 static void test_encodeCRLDistPoints(DWORD dwEncoding)
3399 CRL_DIST_POINTS_INFO info = { 0 };
3400 CRL_DIST_POINT point = { { 0 } };
3401 CERT_ALT_NAME_ENTRY entry = { 0 };
3406 /* Test with an empty info */
3407 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3408 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3409 ok(!ret && GetLastError() == E_INVALIDARG,
3410 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3411 /* Test with one empty dist point */
3412 info.cDistPoint = 1;
3413 info.rgDistPoint = &point;
3414 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3415 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3416 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3419 ok(size == sizeof(emptyDistPoint), "Wrong size %d\n", size);
3420 ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n");
3423 /* A dist point with an invalid name */
3424 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3425 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3426 U(entry).pwszURL = (LPWSTR)nihongoURL;
3427 U(point.DistPointName).FullName.cAltEntry = 1;
3428 U(point.DistPointName).FullName.rgAltEntry = &entry;
3429 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3430 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3431 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
3432 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
3433 /* The first invalid character is at index 7 */
3434 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
3435 "Expected invalid char at index 7, got %d\n",
3436 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
3437 /* A dist point with (just) a valid name */
3438 U(entry).pwszURL = (LPWSTR)url;
3439 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3440 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3441 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3444 ok(size == sizeof(distPointWithUrl), "Wrong size %d\n", size);
3445 ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n");
3448 /* A dist point with (just) reason flags */
3449 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3450 point.ReasonFlags.cbData = sizeof(crlReason);
3451 point.ReasonFlags.pbData = (LPBYTE)&crlReason;
3452 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3453 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3454 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3457 ok(size == sizeof(distPointWithReason), "Wrong size %d\n", size);
3458 ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n");
3461 /* A dist point with just an issuer */
3462 point.ReasonFlags.cbData = 0;
3463 point.CRLIssuer.cAltEntry = 1;
3464 point.CRLIssuer.rgAltEntry = &entry;
3465 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3466 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3467 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3470 ok(size == sizeof(distPointWithIssuer), "Wrong size %d\n", size);
3471 ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n");
3474 /* A dist point with both a name and an issuer */
3475 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3476 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3477 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3478 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3481 ok(size == sizeof(distPointWithUrlAndIssuer),
3482 "Wrong size %d\n", size);
3483 ok(!memcmp(buf, distPointWithUrlAndIssuer, size), "Unexpected value\n");
3488 static void test_decodeCRLDistPoints(DWORD dwEncoding)
3493 PCRL_DIST_POINTS_INFO info;
3494 PCRL_DIST_POINT point;
3495 PCERT_ALT_NAME_ENTRY entry;
3497 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3498 emptyDistPoint, emptyDistPoint[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3500 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3503 info = (PCRL_DIST_POINTS_INFO)buf;
3504 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3505 "Wrong size %d\n", size);
3506 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3508 point = info->rgDistPoint;
3509 ok(point->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_NO_NAME,
3510 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3511 point->DistPointName.dwDistPointNameChoice);
3512 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3513 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3516 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3517 distPointWithUrl, distPointWithUrl[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3519 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3522 info = (PCRL_DIST_POINTS_INFO)buf;
3523 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3524 "Wrong size %d\n", size);
3525 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3527 point = info->rgDistPoint;
3528 ok(point->DistPointName.dwDistPointNameChoice ==
3529 CRL_DIST_POINT_FULL_NAME,
3530 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3531 point->DistPointName.dwDistPointNameChoice);
3532 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3533 "Expected 1 name entry, got %d\n",
3534 U(point->DistPointName).FullName.cAltEntry);
3535 entry = U(point->DistPointName).FullName.rgAltEntry;
3536 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3537 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3538 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3539 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3540 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3543 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3544 distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
3546 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3549 info = (PCRL_DIST_POINTS_INFO)buf;
3550 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3551 "Wrong size %d\n", size);
3552 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3554 point = info->rgDistPoint;
3555 ok(point->DistPointName.dwDistPointNameChoice ==
3556 CRL_DIST_POINT_NO_NAME,
3557 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3558 point->DistPointName.dwDistPointNameChoice);
3559 ok(point->ReasonFlags.cbData == sizeof(crlReason),
3560 "Expected reason length\n");
3561 ok(!memcmp(point->ReasonFlags.pbData, &crlReason, sizeof(crlReason)),
3562 "Unexpected reason\n");
3563 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3566 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3567 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2,
3568 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3569 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3572 info = (PCRL_DIST_POINTS_INFO)buf;
3573 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3574 "Wrong size %d\n", size);
3575 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3577 point = info->rgDistPoint;
3578 ok(point->DistPointName.dwDistPointNameChoice ==
3579 CRL_DIST_POINT_FULL_NAME,
3580 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3581 point->DistPointName.dwDistPointNameChoice);
3582 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3583 "Expected 1 name entry, got %d\n",
3584 U(point->DistPointName).FullName.cAltEntry);
3585 entry = U(point->DistPointName).FullName.rgAltEntry;
3586 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3587 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3588 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3589 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3590 ok(point->CRLIssuer.cAltEntry == 1,
3591 "Expected 1 issuer entry, got %d\n", point->CRLIssuer.cAltEntry);
3592 entry = point->CRLIssuer.rgAltEntry;
3593 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3594 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3595 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3600 static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3601 static const BYTE emptyNameIDP[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3602 static const BYTE urlIDP[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3603 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3606 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding)
3611 CRL_ISSUING_DIST_POINT point = { { 0 } };
3612 CERT_ALT_NAME_ENTRY entry;
3614 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, NULL,
3615 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3616 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3618 skip("no X509_ISSUING_DIST_POINT encode support\n");
3621 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3622 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3623 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3624 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3625 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3628 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
3629 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
3632 /* nonsensical flags */
3633 point.fOnlyContainsUserCerts = TRUE;
3634 point.fOnlyContainsCACerts = TRUE;
3635 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3636 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3637 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3640 ok(size == sizeof(badFlagsIDP), "Unexpected size %d\n", size);
3641 ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n");
3644 /* unimplemented name type */
3645 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3646 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_ISSUER_RDN_NAME;
3647 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3648 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3649 ok(!ret && GetLastError() == E_INVALIDARG,
3650 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3652 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3653 U(point.DistPointName).FullName.cAltEntry = 0;
3654 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3655 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3656 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3659 ok(size == sizeof(emptyNameIDP), "Unexpected size %d\n", size);
3660 ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n");
3663 /* name with URL entry */
3664 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3665 U(entry).pwszURL = (LPWSTR)url;
3666 U(point.DistPointName).FullName.cAltEntry = 1;
3667 U(point.DistPointName).FullName.rgAltEntry = &entry;
3668 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3669 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3670 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3673 ok(size == sizeof(urlIDP), "Unexpected size %d\n", size);
3674 ok(!memcmp(buf, urlIDP, size), "Unexpected value\n");
3679 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY *expected,
3680 const CERT_ALT_NAME_ENTRY *got)
3682 ok(expected->dwAltNameChoice == got->dwAltNameChoice,
3683 "Expected name choice %d, got %d\n", expected->dwAltNameChoice,
3684 got->dwAltNameChoice);
3685 if (expected->dwAltNameChoice == got->dwAltNameChoice)
3687 switch (got->dwAltNameChoice)
3689 case CERT_ALT_NAME_RFC822_NAME:
3690 case CERT_ALT_NAME_DNS_NAME:
3691 case CERT_ALT_NAME_EDI_PARTY_NAME:
3692 case CERT_ALT_NAME_URL:
3693 case CERT_ALT_NAME_REGISTERED_ID:
3694 ok((!U(*expected).pwszURL && !U(*got).pwszURL) ||
3695 (!U(*expected).pwszURL && !lstrlenW(U(*got).pwszURL)) ||
3696 (!U(*got).pwszURL && !lstrlenW(U(*expected).pwszURL)) ||
3697 !lstrcmpW(U(*expected).pwszURL, U(*got).pwszURL),
3698 "Unexpected name\n");
3700 case CERT_ALT_NAME_X400_ADDRESS:
3701 case CERT_ALT_NAME_DIRECTORY_NAME:
3702 case CERT_ALT_NAME_IP_ADDRESS:
3703 ok(U(*got).IPAddress.cbData == U(*expected).IPAddress.cbData,
3704 "Unexpected IP address length %d\n", U(*got).IPAddress.cbData);
3705 ok(!memcmp(U(*got).IPAddress.pbData, U(*got).IPAddress.pbData,
3706 U(*got).IPAddress.cbData), "Unexpected value\n");
3712 static void compareAltNameInfo(const CERT_ALT_NAME_INFO *expected,
3713 const CERT_ALT_NAME_INFO *got)
3717 ok(expected->cAltEntry == got->cAltEntry, "Expected %d entries, got %d\n",
3718 expected->cAltEntry, got->cAltEntry);
3719 for (i = 0; i < min(expected->cAltEntry, got->cAltEntry); i++)
3720 compareAltNameEntry(&expected->rgAltEntry[i], &got->rgAltEntry[i]);
3723 static void compareDistPointName(const CRL_DIST_POINT_NAME *expected,
3724 const CRL_DIST_POINT_NAME *got)
3726 ok(got->dwDistPointNameChoice == expected->dwDistPointNameChoice,
3727 "Unexpected name choice %d\n", got->dwDistPointNameChoice);
3728 if (got->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME)
3729 compareAltNameInfo(&(U(*expected).FullName), &(U(*got).FullName));
3732 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT *expected,
3733 const CRL_ISSUING_DIST_POINT *got)
3735 compareDistPointName(&expected->DistPointName, &got->DistPointName);
3736 ok(got->fOnlyContainsUserCerts == expected->fOnlyContainsUserCerts,
3737 "Unexpected fOnlyContainsUserCerts\n");
3738 ok(got->fOnlyContainsCACerts == expected->fOnlyContainsCACerts,
3739 "Unexpected fOnlyContainsCACerts\n");
3740 ok(got->OnlySomeReasonFlags.cbData == expected->OnlySomeReasonFlags.cbData,
3741 "Unexpected reason flags\n");
3742 ok(got->fIndirectCRL == expected->fIndirectCRL,
3743 "Unexpected fIndirectCRL\n");
3746 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding)
3751 CRL_ISSUING_DIST_POINT point = { { 0 } };
3753 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3754 emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3756 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3758 skip("no X509_ISSUING_DIST_POINT decode support\n");
3761 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3764 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3767 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3768 badFlagsIDP, badFlagsIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3770 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3773 point.fOnlyContainsUserCerts = point.fOnlyContainsCACerts = TRUE;
3774 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3777 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3778 emptyNameIDP, emptyNameIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3780 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3783 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3784 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3785 U(point.DistPointName).FullName.cAltEntry = 0;
3786 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3789 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3790 urlIDP, urlIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3791 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3794 CERT_ALT_NAME_ENTRY entry;
3796 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3797 U(entry).pwszURL = (LPWSTR)url;
3798 U(point.DistPointName).FullName.cAltEntry = 1;
3799 U(point.DistPointName).FullName.rgAltEntry = &entry;
3800 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3805 static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3806 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3808 static const BYTE v2CRL[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3809 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3810 0x30, 0x30, 0x30, 0x30, 0x5a };
3811 static const BYTE v1CRLWithIssuer[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3812 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3813 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3814 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3816 static const BYTE v1CRLWithIssuerAndEmptyEntry[] = { 0x30, 0x43, 0x30, 0x02,
3817 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3818 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3819 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3820 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3821 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3822 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3823 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3824 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3825 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3826 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3827 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3828 static const BYTE v1CRLWithEntryExt[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3829 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3830 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3831 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3832 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3833 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3834 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3835 static const BYTE v1CRLWithExt[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3836 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3837 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3838 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
3839 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3840 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
3841 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3842 static const BYTE v2CRLWithExt[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
3843 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
3844 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
3845 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
3846 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
3847 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
3848 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3849 static const BYTE v2CRLWithIssuingDistPoint[] = { 0x30,0x5c,0x02,0x01,0x01,
3850 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
3851 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
3852 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
3853 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3854 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
3855 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3857 static void test_encodeCRLToBeSigned(DWORD dwEncoding)
3861 static CHAR oid_issuing_dist_point[] = szOID_ISSUING_DIST_POINT;
3863 CRL_INFO info = { 0 };
3864 CRL_ENTRY entry = { { 0 }, { 0 }, 0, 0 };
3867 /* Test with a V1 CRL */
3868 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3869 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3870 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3871 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3874 ok(size == sizeof(v1CRL), "Wrong size %d\n", size);
3875 ok(!memcmp(buf, v1CRL, size), "Got unexpected value\n");
3879 info.dwVersion = CRL_V2;
3880 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3881 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3882 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3883 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3886 ok(size == v2CRL[1] + 2, "Expected size %d, got %d\n",
3887 v2CRL[1] + 2, size);
3888 ok(!memcmp(buf, v2CRL, size), "Got unexpected value\n");
3891 /* v1 CRL with a name */
3892 info.dwVersion = CRL_V1;
3893 info.Issuer.cbData = sizeof(encodedCommonName);
3894 info.Issuer.pbData = (BYTE *)encodedCommonName;
3895 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3896 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3897 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3900 ok(size == sizeof(v1CRLWithIssuer), "Wrong size %d\n", size);
3901 ok(!memcmp(buf, v1CRLWithIssuer, size), "Got unexpected value\n");
3906 /* v1 CRL with a name and a NULL entry pointer (crashes on win9x) */
3908 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3909 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3910 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3911 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3913 /* now set an empty entry */
3915 info.rgCRLEntry = &entry;
3916 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3917 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3920 ok(size == sizeof(v1CRLWithIssuerAndEmptyEntry),
3921 "Wrong size %d\n", size);
3922 ok(!memcmp(buf, v1CRLWithIssuerAndEmptyEntry, size),
3923 "Got unexpected value\n");
3926 /* an entry with a serial number */
3927 entry.SerialNumber.cbData = sizeof(serialNum);
3928 entry.SerialNumber.pbData = (BYTE *)serialNum;
3929 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3930 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3933 ok(size == sizeof(v1CRLWithIssuerAndEntry),
3934 "Wrong size %d\n", size);
3935 ok(!memcmp(buf, v1CRLWithIssuerAndEntry, size),
3936 "Got unexpected value\n");
3939 /* an entry with an extension */
3940 entry.cExtension = 1;
3941 entry.rgExtension = &criticalExt;
3942 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3943 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3944 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3947 ok(size == sizeof(v1CRLWithEntryExt), "Wrong size %d\n", size);
3948 ok(!memcmp(buf, v1CRLWithEntryExt, size), "Got unexpected value\n");
3951 /* a CRL with an extension */
3952 entry.cExtension = 0;
3953 info.cExtension = 1;
3954 info.rgExtension = &criticalExt;
3955 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3956 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3957 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3960 ok(size == sizeof(v1CRLWithExt), "Wrong size %d\n", size);
3961 ok(!memcmp(buf, v1CRLWithExt, size), "Got unexpected value\n");
3964 /* a v2 CRL with an extension, this time non-critical */
3965 info.dwVersion = CRL_V2;
3966 info.rgExtension = &nonCriticalExt;
3967 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3968 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3969 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3972 ok(size == sizeof(v2CRLWithExt), "Wrong size %d\n", size);
3973 ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n");
3976 /* a v2 CRL with an issuing dist point extension */
3977 ext.pszObjId = oid_issuing_dist_point;
3978 ext.fCritical = TRUE;
3979 ext.Value.cbData = sizeof(urlIDP);
3980 ext.Value.pbData = (LPBYTE)urlIDP;
3981 entry.rgExtension = &ext;
3982 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3983 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3984 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3987 ok(size == sizeof(v2CRLWithIssuingDistPoint), "Wrong size %d\n", size);
3988 ok(!memcmp(buf, v2CRLWithIssuingDistPoint, size), "Unexpected value\n");
3993 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
3994 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
3995 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
3996 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
3997 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
3998 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
3999 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
4000 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
4001 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
4002 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
4003 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
4004 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
4005 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
4006 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
4007 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
4008 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
4009 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
4010 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
4011 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
4012 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
4013 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
4014 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
4015 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
4016 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
4017 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
4018 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
4019 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
4020 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
4021 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
4022 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
4023 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
4024 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
4025 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
4026 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
4028 static const BYTE verisignCRLWithLotsOfEntries[] = {
4029 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
4030 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
4031 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
4032 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
4033 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
4034 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
4035 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
4036 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
4037 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
4038 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
4039 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
4040 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
4041 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
4042 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
4043 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
4044 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
4045 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
4046 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
4047 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
4048 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
4049 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
4050 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
4051 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
4052 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
4053 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
4054 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
4055 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
4056 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
4057 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
4058 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
4059 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
4060 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
4061 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
4062 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
4063 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
4064 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
4065 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
4066 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
4067 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
4068 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
4069 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
4070 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
4071 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
4072 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
4073 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
4074 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
4075 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
4076 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
4077 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
4078 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
4079 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
4080 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
4081 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
4082 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
4083 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
4084 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
4085 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
4086 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
4087 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
4088 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
4089 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
4090 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
4091 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
4092 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
4093 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
4094 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
4095 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
4096 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
4097 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
4098 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
4099 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
4100 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
4101 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
4102 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
4103 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
4104 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
4105 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
4106 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
4107 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
4108 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
4109 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
4110 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
4111 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
4112 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
4113 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
4114 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
4115 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
4116 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
4117 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
4118 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
4119 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
4120 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
4121 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
4122 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
4123 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
4124 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
4125 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
4126 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
4127 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
4128 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
4129 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
4130 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
4131 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
4132 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
4133 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
4134 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
4135 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
4136 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
4137 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
4138 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
4139 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
4140 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
4141 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
4142 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
4143 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
4144 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
4145 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
4146 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
4147 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
4148 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
4149 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
4150 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
4151 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
4152 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
4153 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
4154 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
4155 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
4156 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
4157 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
4158 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
4159 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
4160 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
4161 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
4162 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
4163 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
4164 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
4165 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
4166 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
4167 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
4168 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
4169 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
4170 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
4171 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
4172 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
4173 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
4174 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
4175 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
4176 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
4177 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
4178 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
4179 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
4180 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
4181 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
4182 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
4183 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
4184 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
4185 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
4186 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
4187 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
4188 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
4189 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
4190 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
4191 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
4192 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
4193 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
4194 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
4195 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
4196 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
4197 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
4198 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
4199 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
4200 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
4201 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
4202 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
4203 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
4204 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
4205 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
4206 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
4207 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
4208 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
4209 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
4210 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
4211 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
4212 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
4213 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
4214 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
4215 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
4216 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
4217 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
4218 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
4219 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
4220 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
4221 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
4222 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
4223 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
4224 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
4225 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
4226 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
4227 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
4228 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
4229 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
4230 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
4231 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
4232 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
4233 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
4234 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
4235 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
4236 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
4237 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
4238 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
4239 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
4240 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
4241 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
4242 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
4243 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
4244 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
4245 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
4246 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
4247 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
4248 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
4249 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
4250 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
4251 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
4252 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
4253 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
4254 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
4255 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
4256 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
4257 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
4258 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
4259 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
4260 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
4261 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
4262 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
4263 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
4264 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
4265 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
4266 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
4267 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
4268 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
4269 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
4270 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
4271 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
4272 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
4273 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
4274 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
4275 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
4276 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
4277 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
4278 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
4279 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
4280 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
4281 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
4282 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
4283 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
4284 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
4285 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
4286 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
4287 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
4288 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
4289 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
4290 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
4291 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
4292 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
4293 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
4294 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
4295 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
4296 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
4297 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
4298 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
4299 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
4300 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
4301 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
4302 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
4303 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
4304 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
4305 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
4306 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
4307 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
4308 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
4309 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
4310 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
4311 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
4312 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
4313 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
4314 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
4315 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
4316 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
4317 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
4318 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
4319 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
4320 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
4321 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
4322 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
4323 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
4324 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
4325 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
4326 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
4327 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
4328 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
4329 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
4330 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
4331 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
4332 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4333 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4334 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4335 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4336 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4337 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4338 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4339 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4340 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4341 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4342 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4343 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4344 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4345 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4346 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4347 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4348 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4349 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4350 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4351 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4352 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4353 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4354 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4355 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4356 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4357 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4358 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4359 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4360 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4361 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4362 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4363 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4364 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4365 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4366 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4367 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4368 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4369 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4370 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4371 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4372 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4373 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4374 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4375 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4376 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4377 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4378 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4379 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4380 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4381 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4382 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4383 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4384 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4385 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4386 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4387 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4388 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4389 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4390 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4391 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4392 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4393 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4394 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4395 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4396 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4397 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4398 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4399 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4400 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4401 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4402 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4403 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4404 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4405 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4406 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4407 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4408 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4409 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4410 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4411 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4412 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4413 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4414 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4415 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4416 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4417 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4418 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4419 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4420 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4421 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4422 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4423 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4424 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4425 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4426 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4427 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4428 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4429 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4430 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4431 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4432 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4433 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4434 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4435 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4436 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4437 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4438 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4439 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4440 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4441 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4442 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4443 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4444 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4445 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4446 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4447 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4448 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4449 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4450 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4451 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4452 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4453 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4454 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4455 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4456 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4457 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4458 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4459 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4460 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4461 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4462 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4463 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4464 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4465 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4466 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4467 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4468 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4469 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4470 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4471 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4472 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4473 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4474 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4475 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4476 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4477 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4478 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4479 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4480 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4481 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4482 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4483 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4484 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4485 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4486 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4487 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4488 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4489 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4490 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4491 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4492 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4493 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4494 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4495 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4496 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4497 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4498 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4499 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4500 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4501 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4502 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4503 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4504 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4505 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4506 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4507 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4508 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4509 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4510 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4511 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4512 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4513 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4514 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4515 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4516 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4517 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4518 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4519 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4520 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4521 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4522 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4523 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4524 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4525 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4526 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4527 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4528 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4529 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4530 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4531 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4532 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4533 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4534 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4535 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4536 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4538 static void test_decodeCRLToBeSigned(DWORD dwEncoding)
4540 static const BYTE *corruptCRLs[] = { v1CRL, v2CRL };
4545 for (i = 0; i < sizeof(corruptCRLs) / sizeof(corruptCRLs[0]); i++)
4547 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4548 corruptCRLs[i], corruptCRLs[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4550 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4551 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4552 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4555 /* at a minimum, a CRL must contain an issuer: */
4556 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4557 v1CRLWithIssuer, v1CRLWithIssuer[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4559 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4562 CRL_INFO *info = (CRL_INFO *)buf;
4564 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4565 ok(info->cCRLEntry == 0, "Expected 0 CRL entries, got %d\n",
4567 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4568 "Wrong issuer size %d\n", info->Issuer.cbData);
4569 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4570 "Unexpected issuer\n");
4573 /* check decoding with an empty CRL entry */
4574 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4575 v1CRLWithIssuerAndEmptyEntry, v1CRLWithIssuerAndEmptyEntry[1] + 2,
4576 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4577 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4578 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4579 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4581 /* with a real CRL entry */
4582 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4583 v1CRLWithIssuerAndEntry, v1CRLWithIssuerAndEntry[1] + 2,
4584 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4585 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4588 CRL_INFO *info = (CRL_INFO *)buf;
4591 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4592 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4594 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4595 entry = info->rgCRLEntry;
4596 ok(entry->SerialNumber.cbData == 1,
4597 "Expected serial number size 1, got %d\n",
4598 entry->SerialNumber.cbData);
4599 ok(*entry->SerialNumber.pbData == *serialNum,
4600 "Expected serial number %d, got %d\n", *serialNum,
4601 *entry->SerialNumber.pbData);
4602 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4603 "Wrong issuer size %d\n", info->Issuer.cbData);
4604 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4605 "Unexpected issuer\n");
4608 /* a real CRL from verisign that has extensions */
4609 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4610 verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG,
4612 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4615 CRL_INFO *info = (CRL_INFO *)buf;
4618 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4619 ok(info->cCRLEntry == 3, "Expected 3 CRL entries, got %d\n",
4621 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4622 entry = info->rgCRLEntry;
4623 ok(info->cExtension == 2, "Expected 2 extensions, got %d\n",
4627 /* another real CRL from verisign that has lots of entries */
4628 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4629 verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries),
4630 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4631 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4634 CRL_INFO *info = (CRL_INFO *)buf;
4636 ok(size >= sizeof(CRL_INFO), "Got size %d\n", size);
4637 ok(info->cCRLEntry == 209, "Expected 209 CRL entries, got %d\n",
4639 ok(info->cExtension == 0, "Expected 0 extensions, got %d\n",
4643 /* and finally, with an extension */
4644 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4645 v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4647 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4650 CRL_INFO *info = (CRL_INFO *)buf;
4653 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4654 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4656 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4657 entry = info->rgCRLEntry;
4658 ok(entry->SerialNumber.cbData == 1,
4659 "Expected serial number size 1, got %d\n",
4660 entry->SerialNumber.cbData);
4661 ok(*entry->SerialNumber.pbData == *serialNum,
4662 "Expected serial number %d, got %d\n", *serialNum,
4663 *entry->SerialNumber.pbData);
4664 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4665 "Wrong issuer size %d\n", info->Issuer.cbData);
4666 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4667 "Unexpected issuer\n");
4668 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4672 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4673 v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4675 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4678 CRL_INFO *info = (CRL_INFO *)buf;
4680 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4684 /* And again, with an issuing dist point */
4685 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4686 v2CRLWithIssuingDistPoint, sizeof(v2CRLWithIssuingDistPoint),
4687 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4688 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4691 CRL_INFO *info = (CRL_INFO *)buf;
4693 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4699 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
4700 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
4701 static const BYTE encodedUsage[] = {
4702 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4703 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4704 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4706 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding)
4711 CERT_ENHKEY_USAGE usage;
4713 /* Test with empty usage */
4714 usage.cUsageIdentifier = 0;
4715 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4716 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4717 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4720 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
4721 ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n");
4724 /* Test with a few usages */
4725 usage.cUsageIdentifier = sizeof(keyUsages) / sizeof(keyUsages[0]);
4726 usage.rgpszUsageIdentifier = (LPSTR *)keyUsages;
4727 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4728 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4729 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4732 ok(size == sizeof(encodedUsage), "Wrong size %d\n", size);
4733 ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n");
4738 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding)
4744 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4745 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4747 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4750 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4752 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4753 "Wrong size %d\n", size);
4754 ok(usage->cUsageIdentifier == 0, "Expected 0 CRL entries, got %d\n",
4755 usage->cUsageIdentifier);
4758 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4759 encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL,
4761 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4764 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4767 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4768 "Wrong size %d\n", size);
4769 ok(usage->cUsageIdentifier == sizeof(keyUsages) / sizeof(keyUsages[0]),
4770 "Wrong CRL entries count %d\n", usage->cUsageIdentifier);
4771 for (i = 0; i < usage->cUsageIdentifier; i++)
4772 ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]),
4773 "Expected OID %s, got %s\n", keyUsages[i],
4774 usage->rgpszUsageIdentifier[i]);
4779 static BYTE keyId[] = { 1,2,3,4 };
4780 static const BYTE authorityKeyIdWithId[] = {
4781 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4782 static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4783 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4784 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4785 static const BYTE authorityKeyIdWithSerial[] = { 0x30,0x03,0x82,0x01,0x01 };
4787 static void test_encodeAuthorityKeyId(DWORD dwEncoding)
4789 CERT_AUTHORITY_KEY_ID_INFO info = { { 0 } };
4794 /* Test with empty id */
4795 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4796 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4797 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4800 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4801 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4804 /* With just a key id */
4805 info.KeyId.cbData = sizeof(keyId);
4806 info.KeyId.pbData = keyId;
4807 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4808 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4809 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4812 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", size);
4813 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4816 /* With just an issuer */
4817 info.KeyId.cbData = 0;
4818 info.CertIssuer.cbData = sizeof(encodedCommonName);
4819 info.CertIssuer.pbData = (BYTE *)encodedCommonName;
4820 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4821 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4822 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4825 ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %d\n",
4827 ok(!memcmp(buf, authorityKeyIdWithIssuer, size), "Unexpected value\n");
4830 /* With just a serial number */
4831 info.CertIssuer.cbData = 0;
4832 info.CertSerialNumber.cbData = sizeof(serialNum);
4833 info.CertSerialNumber.pbData = (BYTE *)serialNum;
4834 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4835 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4836 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4839 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4841 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4846 static void test_decodeAuthorityKeyId(DWORD dwEncoding)
4852 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4853 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4855 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4858 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4860 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4862 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4863 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4864 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4867 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4868 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4869 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4870 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4873 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4875 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4877 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4878 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4879 "Unexpected key id\n");
4880 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4881 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4884 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4885 authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer),
4886 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4887 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4890 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4892 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4894 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4895 ok(info->CertIssuer.cbData == sizeof(encodedCommonName),
4896 "Unexpected issuer len\n");
4897 ok(!memcmp(info->CertIssuer.pbData, encodedCommonName,
4898 sizeof(encodedCommonName)), "Unexpected issuer\n");
4899 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4902 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4903 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4904 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4905 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4908 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4910 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4912 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4913 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4914 ok(info->CertSerialNumber.cbData == sizeof(serialNum),
4915 "Unexpected serial number len\n");
4916 ok(!memcmp(info->CertSerialNumber.pbData, serialNum, sizeof(serialNum)),
4917 "Unexpected serial number\n");
4922 static const BYTE authorityKeyIdWithIssuerUrl[] = { 0x30,0x15,0xa1,0x13,0x86,
4923 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
4926 static void test_encodeAuthorityKeyId2(DWORD dwEncoding)
4928 CERT_AUTHORITY_KEY_ID2_INFO info = { { 0 } };
4929 CERT_ALT_NAME_ENTRY entry = { 0 };
4934 /* Test with empty id */
4935 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4936 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4937 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4940 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4941 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4944 /* With just a key id */
4945 info.KeyId.cbData = sizeof(keyId);
4946 info.KeyId.pbData = keyId;
4947 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4948 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4949 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4952 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n",
4954 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4957 /* With a bogus issuer name */
4958 info.KeyId.cbData = 0;
4959 info.AuthorityCertIssuer.cAltEntry = 1;
4960 info.AuthorityCertIssuer.rgAltEntry = &entry;
4961 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4962 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4963 ok(!ret && GetLastError() == E_INVALIDARG,
4964 "Expected E_INVALIDARG, got %08x\n", GetLastError());
4965 /* With an issuer name */
4966 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
4967 U(entry).pwszURL = (LPWSTR)url;
4968 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4969 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4970 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4973 ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %d\n",
4975 ok(!memcmp(buf, authorityKeyIdWithIssuerUrl, size),
4976 "Unexpected value\n");
4979 /* With just a serial number */
4980 info.AuthorityCertIssuer.cAltEntry = 0;
4981 info.AuthorityCertSerialNumber.cbData = sizeof(serialNum);
4982 info.AuthorityCertSerialNumber.pbData = (BYTE *)serialNum;
4983 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4984 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4985 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4988 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4990 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4995 static void test_decodeAuthorityKeyId2(DWORD dwEncoding)
5001 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
5002 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
5004 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5007 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
5009 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
5011 ok(info->KeyId.cbData == 0, "Expected no key id\n");
5012 ok(info->AuthorityCertIssuer.cAltEntry == 0,
5013 "Expected no issuer name entries\n");
5014 ok(info->AuthorityCertSerialNumber.cbData == 0,
5015 "Expected no serial number\n");
5018 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
5019 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
5020 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5021 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5024 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
5026 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
5028 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
5029 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
5030 "Unexpected key id\n");
5031 ok(info->AuthorityCertIssuer.cAltEntry == 0,
5032 "Expected no issuer name entries\n");
5033 ok(info->AuthorityCertSerialNumber.cbData == 0,
5034 "Expected no serial number\n");
5037 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
5038 authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl),
5039 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5040 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5043 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
5045 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
5047 ok(info->KeyId.cbData == 0, "Expected no key id\n");
5048 ok(info->AuthorityCertIssuer.cAltEntry == 1,
5049 "Expected 1 issuer entry, got %d\n",
5050 info->AuthorityCertIssuer.cAltEntry);
5051 ok(info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice ==
5052 CERT_ALT_NAME_URL, "Expected CERT_ALT_NAME_URL, got %d\n",
5053 info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice);
5054 ok(!lstrcmpW(U(info->AuthorityCertIssuer.rgAltEntry[0]).pwszURL,
5055 url), "Unexpected URL\n");
5056 ok(info->AuthorityCertSerialNumber.cbData == 0,
5057 "Expected no serial number\n");
5060 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
5061 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
5062 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5063 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5066 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
5068 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
5070 ok(info->KeyId.cbData == 0, "Expected no key id\n");
5071 ok(info->AuthorityCertIssuer.cAltEntry == 0,
5072 "Expected no issuer name entries\n");
5073 ok(info->AuthorityCertSerialNumber.cbData == sizeof(serialNum),
5074 "Unexpected serial number len\n");
5075 ok(!memcmp(info->AuthorityCertSerialNumber.pbData, serialNum,
5076 sizeof(serialNum)), "Unexpected serial number\n");
5081 static const BYTE authorityInfoAccessWithUrl[] = {
5082 0x30,0x19,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
5083 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5084 static const BYTE authorityInfoAccessWithUrlAndIPAddr[] = {
5085 0x30,0x29,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
5086 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x0e,0x06,
5087 0x02,0x2d,0x06,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5089 static void test_encodeAuthorityInfoAccess(DWORD dwEncoding)
5091 static char oid1[] = "1.2.3";
5092 static char oid2[] = "1.5.6";
5096 CERT_ACCESS_DESCRIPTION accessDescription[2];
5097 CERT_AUTHORITY_INFO_ACCESS aia;
5099 memset(accessDescription, 0, sizeof(accessDescription));
5101 aia.rgAccDescr = NULL;
5102 /* Having no access descriptions is allowed */
5103 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5104 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5105 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5108 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
5109 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
5113 /* It can't have an empty access method */
5115 aia.rgAccDescr = accessDescription;
5116 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5117 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5118 ok(!ret && (GetLastError() == E_INVALIDARG ||
5119 GetLastError() == OSS_LIMITED /* Win9x */),
5120 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
5121 /* It can't have an empty location */
5122 accessDescription[0].pszAccessMethod = oid1;
5123 SetLastError(0xdeadbeef);
5124 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5125 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5126 ok(!ret && GetLastError() == E_INVALIDARG,
5127 "expected E_INVALIDARG, got %08x\n", GetLastError());
5128 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5129 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
5130 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5131 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5132 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5135 ok(size == sizeof(authorityInfoAccessWithUrl), "unexpected size %d\n",
5137 ok(!memcmp(buf, authorityInfoAccessWithUrl, size),
5138 "unexpected value\n");
5142 accessDescription[1].pszAccessMethod = oid2;
5143 accessDescription[1].AccessLocation.dwAltNameChoice =
5144 CERT_ALT_NAME_IP_ADDRESS;
5145 U(accessDescription[1].AccessLocation).IPAddress.cbData =
5146 sizeof(encodedIPAddr);
5147 U(accessDescription[1].AccessLocation).IPAddress.pbData =
5148 (LPBYTE)encodedIPAddr;
5150 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5151 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5152 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5155 ok(size == sizeof(authorityInfoAccessWithUrlAndIPAddr),
5156 "unexpected size %d\n", size);
5157 ok(!memcmp(buf, authorityInfoAccessWithUrlAndIPAddr, size),
5158 "unexpected value\n");
5164 static void compareAuthorityInfoAccess(LPCSTR header,
5165 const CERT_AUTHORITY_INFO_ACCESS *expected,
5166 const CERT_AUTHORITY_INFO_ACCESS *got)
5170 ok(expected->cAccDescr == got->cAccDescr,
5171 "%s: expected %d access descriptions, got %d\n", header,
5172 expected->cAccDescr, got->cAccDescr);
5173 for (i = 0; i < expected->cAccDescr; i++)
5175 ok(!strcmp(expected->rgAccDescr[i].pszAccessMethod,
5176 got->rgAccDescr[i].pszAccessMethod), "%s[%d]: expected %s, got %s\n",
5177 header, i, expected->rgAccDescr[i].pszAccessMethod,
5178 got->rgAccDescr[i].pszAccessMethod);
5179 compareAltNameEntry(&expected->rgAccDescr[i].AccessLocation,
5180 &got->rgAccDescr[i].AccessLocation);
5184 static void test_decodeAuthorityInfoAccess(DWORD dwEncoding)
5186 static char oid1[] = "1.2.3";
5187 static char oid2[] = "1.5.6";
5192 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5193 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
5195 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5198 CERT_AUTHORITY_INFO_ACCESS aia = { 0, NULL };
5200 compareAuthorityInfoAccess("empty AIA", &aia,
5201 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5205 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5206 authorityInfoAccessWithUrl, sizeof(authorityInfoAccessWithUrl),
5207 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5208 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5211 CERT_ACCESS_DESCRIPTION accessDescription;
5212 CERT_AUTHORITY_INFO_ACCESS aia;
5214 accessDescription.pszAccessMethod = oid1;
5215 accessDescription.AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5216 U(accessDescription.AccessLocation).pwszURL = (LPWSTR)url;
5218 aia.rgAccDescr = &accessDescription;
5219 compareAuthorityInfoAccess("AIA with URL", &aia,
5220 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5224 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5225 authorityInfoAccessWithUrlAndIPAddr,
5226 sizeof(authorityInfoAccessWithUrlAndIPAddr), CRYPT_DECODE_ALLOC_FLAG,
5228 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5231 CERT_ACCESS_DESCRIPTION accessDescription[2];
5232 CERT_AUTHORITY_INFO_ACCESS aia;
5234 accessDescription[0].pszAccessMethod = oid1;
5235 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5236 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
5237 accessDescription[1].pszAccessMethod = oid2;
5238 accessDescription[1].AccessLocation.dwAltNameChoice =
5239 CERT_ALT_NAME_IP_ADDRESS;
5240 U(accessDescription[1].AccessLocation).IPAddress.cbData =
5241 sizeof(encodedIPAddr);
5242 U(accessDescription[1].AccessLocation).IPAddress.pbData =
5243 (LPBYTE)encodedIPAddr;
5245 aia.rgAccDescr = accessDescription;
5246 compareAuthorityInfoAccess("AIA with URL and IP addr", &aia,
5247 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5253 static const BYTE emptyCTL[] = {
5254 0x30,0x17,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5255 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5256 static const BYTE emptyCTLWithVersion1[] = {
5257 0x30,0x1a,0x02,0x01,0x01,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5258 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5259 static const BYTE ctlWithUsageIdentifier[] = {
5260 0x30,0x1b,0x30,0x04,0x06,0x02,0x2a,0x03,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
5261 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5262 static const BYTE ctlWithListIdentifier[] = {
5263 0x30,0x1a,0x30,0x00,0x04,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5264 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5265 static const BYTE ctlWithSequenceNumber[] = {
5266 0x30,0x1a,0x30,0x00,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5267 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5268 static const BYTE ctlWithThisUpdate[] = {
5269 0x30,0x15,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5270 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5271 static const BYTE ctlWithThisAndNextUpdate[] = {
5272 0x30,0x24,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5273 0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5274 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5275 static const BYTE ctlWithAlgId[] = {
5276 0x30,0x1b,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5277 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5278 static const BYTE ctlWithBogusEntry[] = {
5279 0x30,0x29,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5280 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x10,0x30,0x0e,0x04,
5281 0x01,0x01,0x31,0x09,0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,0x01 };
5282 static const BYTE ctlWithOneEntry[] = {
5283 0x30,0x2a,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5284 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x11,0x30,0x0f,0x04,
5285 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00 };
5286 static const BYTE ctlWithTwoEntries[] = {
5287 0x30,0x41,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5288 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x28,0x30,0x0f,0x04,
5289 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00,0x30,
5290 0x15,0x04,0x01,0x01,0x31,0x10,0x30,0x0e,0x06,0x02,0x2d,0x06,0x31,0x08,0x30,
5291 0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5293 static void test_encodeCTL(DWORD dwEncoding)
5295 static char oid1[] = "1.2.3";
5296 static char oid2[] = "1.5.6";
5302 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5303 CTL_ENTRY ctlEntry[2];
5304 CRYPT_ATTRIBUTE attr1, attr2;
5305 CRYPT_ATTR_BLOB value1, value2;
5307 memset(&info, 0, sizeof(info));
5308 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5309 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5310 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5313 ok(size == sizeof(emptyCTL), "unexpected size %d\n", size);
5314 ok(!memcmp(buf, emptyCTL, size), "unexpected value\n");
5319 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5320 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5321 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5324 ok(size == sizeof(emptyCTLWithVersion1), "unexpected size %d\n", size);
5325 ok(!memcmp(buf, emptyCTLWithVersion1, size), "unexpected value\n");
5330 info.SubjectUsage.cUsageIdentifier = 1;
5331 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5332 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5333 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5334 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5337 ok(size == sizeof(ctlWithUsageIdentifier), "unexpected size %d\n",
5339 ok(!memcmp(buf, ctlWithUsageIdentifier, size), "unexpected value\n");
5343 info.SubjectUsage.cUsageIdentifier = 0;
5344 info.ListIdentifier.cbData = sizeof(serialNum);
5345 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5346 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5347 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5348 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5351 ok(size == sizeof(ctlWithListIdentifier), "unexpected size %d\n", size);
5352 ok(!memcmp(buf, ctlWithListIdentifier, size), "unexpected value\n");
5356 info.ListIdentifier.cbData = 0;
5357 info.SequenceNumber.cbData = sizeof(serialNum);
5358 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5359 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5360 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5361 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5364 ok(size == sizeof(ctlWithSequenceNumber), "unexpected size %d\n",
5366 ok(!memcmp(buf, ctlWithSequenceNumber, size), "unexpected value\n");
5370 info.SequenceNumber.cbData = 0;
5371 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5372 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5373 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5374 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5377 ok(size == sizeof(ctlWithThisUpdate), "unexpected size %d\n", size);
5378 ok(!memcmp(buf, ctlWithThisUpdate, size), "unexpected value\n");
5382 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5383 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5384 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5385 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5388 ok(size == sizeof(ctlWithThisAndNextUpdate), "unexpected size %d\n",
5390 ok(!memcmp(buf, ctlWithThisAndNextUpdate, size), "unexpected value\n");
5394 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5395 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5396 info.SubjectAlgorithm.pszObjId = oid2;
5397 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5398 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5399 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5402 ok(size == sizeof(ctlWithAlgId), "unexpected size %d\n", size);
5403 ok(!memcmp(buf, ctlWithAlgId, size), "unexpected value\n");
5407 /* The value is supposed to be asn.1 encoded, so this'll fail to decode
5408 * (see tests below) but it'll encode fine.
5410 info.SubjectAlgorithm.pszObjId = NULL;
5411 value1.cbData = sizeof(serialNum);
5412 value1.pbData = (LPBYTE)serialNum;
5413 attr1.pszObjId = oid1;
5415 attr1.rgValue = &value1;
5416 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5417 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5418 ctlEntry[0].cAttribute = 1;
5419 ctlEntry[0].rgAttribute = &attr1;
5421 info.rgCTLEntry = ctlEntry;
5422 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5423 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5424 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5427 ok(size == sizeof(ctlWithBogusEntry), "unexpected size %d\n", size);
5428 ok(!memcmp(buf, ctlWithBogusEntry, size), "unexpected value\n");
5432 value1.cbData = sizeof(emptySequence);
5433 value1.pbData = (LPBYTE)emptySequence;
5434 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5435 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5436 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5439 ok(size == sizeof(ctlWithOneEntry), "unexpected size %d\n", size);
5440 ok(!memcmp(buf, ctlWithOneEntry, size), "unexpected value\n");
5444 value2.cbData = sizeof(encodedIPAddr);
5445 value2.pbData = (LPBYTE)encodedIPAddr;
5446 attr2.pszObjId = oid2;
5448 attr2.rgValue = &value2;
5449 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5450 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5451 ctlEntry[1].cAttribute = 1;
5452 ctlEntry[1].rgAttribute = &attr2;
5454 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5455 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5456 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5459 ok(size == sizeof(ctlWithTwoEntries), "unexpected size %d\n", size);
5460 ok(!memcmp(buf, ctlWithTwoEntries, size), "unexpected value\n");
5466 static void compareCTLInfo(LPCSTR header, const CTL_INFO *expected,
5467 const CTL_INFO *got)
5471 ok(expected->dwVersion == got->dwVersion,
5472 "%s: expected version %d, got %d\n", header, expected->dwVersion,
5474 ok(expected->SubjectUsage.cUsageIdentifier ==
5475 got->SubjectUsage.cUsageIdentifier,
5476 "%s: expected %d usage identifiers, got %d\n", header,
5477 expected->SubjectUsage.cUsageIdentifier,
5478 got->SubjectUsage.cUsageIdentifier);
5479 for (i = 0; i < expected->SubjectUsage.cUsageIdentifier; i++)
5480 ok(!strcmp(expected->SubjectUsage.rgpszUsageIdentifier[i],
5481 got->SubjectUsage.rgpszUsageIdentifier[i]),
5482 "%s[%d]: expected %s, got %s\n", header, i,
5483 expected->SubjectUsage.rgpszUsageIdentifier[i],
5484 got->SubjectUsage.rgpszUsageIdentifier[i]);
5485 ok(expected->ListIdentifier.cbData == got->ListIdentifier.cbData,
5486 "%s: expected list identifier of %d bytes, got %d\n", header,
5487 expected->ListIdentifier.cbData, got->ListIdentifier.cbData);
5488 if (expected->ListIdentifier.cbData)
5489 ok(!memcmp(expected->ListIdentifier.pbData, got->ListIdentifier.pbData,
5490 expected->ListIdentifier.cbData),
5491 "%s: unexpected list identifier value\n", header);
5492 ok(expected->SequenceNumber.cbData == got->SequenceNumber.cbData,
5493 "%s: expected sequence number of %d bytes, got %d\n", header,
5494 expected->SequenceNumber.cbData, got->SequenceNumber.cbData);
5495 if (expected->SequenceNumber.cbData)
5496 ok(!memcmp(expected->SequenceNumber.pbData, got->SequenceNumber.pbData,
5497 expected->SequenceNumber.cbData),
5498 "%s: unexpected sequence number value\n", header);
5499 ok(!memcmp(&expected->ThisUpdate, &got->ThisUpdate, sizeof(FILETIME)),
5500 "%s: expected this update = (%d, %d), got (%d, %d)\n", header,
5501 expected->ThisUpdate.dwLowDateTime, expected->ThisUpdate.dwHighDateTime,
5502 got->ThisUpdate.dwLowDateTime, got->ThisUpdate.dwHighDateTime);
5503 ok(!memcmp(&expected->NextUpdate, &got->NextUpdate, sizeof(FILETIME)),
5504 "%s: expected next update = (%d, %d), got (%d, %d)\n", header,
5505 expected->NextUpdate.dwLowDateTime, expected->NextUpdate.dwHighDateTime,
5506 got->NextUpdate.dwLowDateTime, got->NextUpdate.dwHighDateTime);
5507 if (expected->SubjectAlgorithm.pszObjId &&
5508 *expected->SubjectAlgorithm.pszObjId && !got->SubjectAlgorithm.pszObjId)
5509 ok(0, "%s: expected subject algorithm %s, got NULL\n", header,
5510 expected->SubjectAlgorithm.pszObjId);
5511 if (expected->SubjectAlgorithm.pszObjId && got->SubjectAlgorithm.pszObjId)
5512 ok(!strcmp(expected->SubjectAlgorithm.pszObjId,
5513 got->SubjectAlgorithm.pszObjId),
5514 "%s: expected subject algorithm %s, got %s\n", header,
5515 expected->SubjectAlgorithm.pszObjId, got->SubjectAlgorithm.pszObjId);
5516 ok(expected->SubjectAlgorithm.Parameters.cbData ==
5517 got->SubjectAlgorithm.Parameters.cbData,
5518 "%s: expected subject algorithm parameters of %d bytes, got %d\n", header,
5519 expected->SubjectAlgorithm.Parameters.cbData,
5520 got->SubjectAlgorithm.Parameters.cbData);
5521 if (expected->SubjectAlgorithm.Parameters.cbData)
5522 ok(!memcmp(expected->SubjectAlgorithm.Parameters.pbData,
5523 got->SubjectAlgorithm.Parameters.pbData,
5524 expected->SubjectAlgorithm.Parameters.cbData),
5525 "%s: unexpected subject algorithm parameter value\n", header);
5526 ok(expected->cCTLEntry == got->cCTLEntry,
5527 "%s: expected %d CTL entries, got %d\n", header, expected->cCTLEntry,
5529 for (i = 0; i < expected->cCTLEntry; i++)
5531 ok(expected->rgCTLEntry[i].SubjectIdentifier.cbData ==
5532 got->rgCTLEntry[i].SubjectIdentifier.cbData,
5533 "%s[%d]: expected subject identifier of %d bytes, got %d\n",
5534 header, i, expected->rgCTLEntry[i].SubjectIdentifier.cbData,
5535 got->rgCTLEntry[i].SubjectIdentifier.cbData);
5536 if (expected->rgCTLEntry[i].SubjectIdentifier.cbData)
5537 ok(!memcmp(expected->rgCTLEntry[i].SubjectIdentifier.pbData,
5538 got->rgCTLEntry[i].SubjectIdentifier.pbData,
5539 expected->rgCTLEntry[i].SubjectIdentifier.cbData),
5540 "%s[%d]: unexpected subject identifier value\n",
5542 for (j = 0; j < expected->rgCTLEntry[i].cAttribute; j++)
5544 ok(!strcmp(expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5545 got->rgCTLEntry[i].rgAttribute[j].pszObjId),
5546 "%s[%d][%d]: expected attribute OID %s, got %s\n", header, i, j,
5547 expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5548 got->rgCTLEntry[i].rgAttribute[j].pszObjId);
5549 for (k = 0; k < expected->rgCTLEntry[i].rgAttribute[j].cValue; k++)
5551 ok(expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData ==
5552 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5553 "%s[%d][%d][%d]: expected value of %d bytes, got %d\n",
5555 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5556 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData);
5557 if (expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData)
5559 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5560 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5561 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData),
5562 "%s[%d][%d][%d]: unexpected value\n",
5567 ok(expected->cExtension == got->cExtension,
5568 "%s: expected %d extensions, got %d\n", header, expected->cExtension,
5570 for (i = 0; i < expected->cExtension; i++)
5572 ok(!strcmp(expected->rgExtension[i].pszObjId,
5573 got->rgExtension[i].pszObjId), "%s[%d]: expected %s, got %s\n",
5574 header, i, expected->rgExtension[i].pszObjId,
5575 got->rgExtension[i].pszObjId);
5576 ok(expected->rgExtension[i].fCritical == got->rgExtension[i].fCritical,
5577 "%s[%d]: expected fCritical = %d, got %d\n", header, i,
5578 expected->rgExtension[i].fCritical, got->rgExtension[i].fCritical);
5579 ok(expected->rgExtension[i].Value.cbData ==
5580 got->rgExtension[i].Value.cbData,
5581 "%s[%d]: expected extension value to have %d bytes, got %d\n",
5582 header, i, expected->rgExtension[i].Value.cbData,
5583 got->rgExtension[i].Value.cbData);
5584 if (expected->rgExtension[i].Value.cbData)
5585 ok(!memcmp(expected->rgExtension[i].Value.pbData,
5586 got->rgExtension[i].Value.pbData,
5587 expected->rgExtension[i].Value.cbData),
5588 "%s[%d]: unexpected extension value\n", header, i);
5592 static const BYTE signedCTL[] = {
5593 0x30,0x81,0xc7,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
5594 0x81,0xb9,0x30,0x81,0xb6,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
5595 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x28,0x06,0x09,0x2a,0x86,
5596 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x1b,0x04,0x19,0x30,0x17,0x30,0x00,
5597 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5598 0x30,0x5a,0x30,0x02,0x06,0x00,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
5599 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
5600 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
5601 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5602 0x00,0x04,0x40,0xca,0xd8,0x32,0xd1,0xbd,0x97,0x61,0x54,0xd6,0x80,0xcf,0x0d,
5603 0xbd,0xa2,0x42,0xc7,0xca,0x37,0x91,0x7d,0x9d,0xac,0x8c,0xdf,0x05,0x8a,0x39,
5604 0xc6,0x07,0xc1,0x37,0xe6,0xb9,0xd1,0x0d,0x26,0xec,0xa5,0xb0,0x8a,0x51,0x26,
5605 0x2b,0x4f,0x73,0x44,0x86,0x83,0x5e,0x2b,0x6e,0xcc,0xf8,0x1b,0x85,0x53,0xe9,
5606 0x7a,0x80,0x8f,0x6b,0x42,0x19,0x93 };
5607 static const BYTE signedCTLWithCTLInnerContent[] = {
5608 0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
5609 0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
5610 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
5611 0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
5612 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5613 0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
5614 0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
5615 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
5616 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
5617 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
5618 0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
5619 0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
5620 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
5621 0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5622 0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
5623 0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
5624 0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
5625 0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
5626 0x57,0x6c,0x0b,0x47,0xb8 };
5628 static void test_decodeCTL(DWORD dwEncoding)
5630 static char oid1[] = "1.2.3";
5631 static char oid2[] = "1.5.6";
5632 static BYTE nullData[] = { 5,0 };
5638 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5639 CTL_ENTRY ctlEntry[2];
5640 CRYPT_ATTRIBUTE attr1, attr2;
5641 CRYPT_ATTR_BLOB value1, value2;
5643 memset(&info, 0, sizeof(info));
5644 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTL, sizeof(emptyCTL),
5645 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5646 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5649 compareCTLInfo("empty CTL", &info, (CTL_INFO *)buf);
5654 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTLWithVersion1,
5655 sizeof(emptyCTLWithVersion1), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
5657 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5660 compareCTLInfo("v1 CTL", &info, (CTL_INFO *)buf);
5665 info.SubjectUsage.cUsageIdentifier = 1;
5666 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5667 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithUsageIdentifier,
5668 sizeof(ctlWithUsageIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5670 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5673 compareCTLInfo("CTL with usage identifier", &info, (CTL_INFO *)buf);
5677 info.SubjectUsage.cUsageIdentifier = 0;
5678 info.ListIdentifier.cbData = sizeof(serialNum);
5679 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5680 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithListIdentifier,
5681 sizeof(ctlWithListIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5682 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5685 compareCTLInfo("CTL with list identifier", &info, (CTL_INFO *)buf);
5689 info.ListIdentifier.cbData = 0;
5690 info.SequenceNumber.cbData = sizeof(serialNum);
5691 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5692 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithSequenceNumber,
5693 sizeof(ctlWithSequenceNumber), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5694 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5697 compareCTLInfo("CTL with sequence number", &info, (CTL_INFO *)buf);
5701 info.SequenceNumber.cbData = 0;
5702 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5703 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisUpdate,
5704 sizeof(ctlWithThisUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5705 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5708 compareCTLInfo("CTL with this update", &info, (CTL_INFO *)buf);
5712 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5713 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisAndNextUpdate,
5714 sizeof(ctlWithThisAndNextUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5716 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5719 compareCTLInfo("CTL with this and next update", &info, (CTL_INFO *)buf);
5723 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5724 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5725 info.SubjectAlgorithm.pszObjId = oid2;
5726 info.SubjectAlgorithm.Parameters.cbData = sizeof(nullData);
5727 info.SubjectAlgorithm.Parameters.pbData = nullData;
5728 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithAlgId,
5729 sizeof(ctlWithAlgId), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5730 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5733 compareCTLInfo("CTL with algorithm identifier", &info, (CTL_INFO *)buf);
5737 SetLastError(0xdeadbeef);
5738 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithBogusEntry,
5739 sizeof(ctlWithBogusEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5741 (GetLastError() == CRYPT_E_ASN1_EOD ||
5742 GetLastError() == CRYPT_E_ASN1_CORRUPT ||
5743 GetLastError() == OSS_MORE_INPUT), /* Win9x */
5744 "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n",
5746 info.SubjectAlgorithm.Parameters.cbData = 0;
5747 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5748 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5749 info.SubjectAlgorithm.pszObjId = oid2;
5750 info.SubjectAlgorithm.pszObjId = NULL;
5751 value1.cbData = sizeof(emptySequence);
5752 value1.pbData = (LPBYTE)emptySequence;
5753 attr1.pszObjId = oid1;
5755 attr1.rgValue = &value1;
5756 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5757 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5758 ctlEntry[0].cAttribute = 1;
5759 ctlEntry[0].rgAttribute = &attr1;
5761 info.rgCTLEntry = ctlEntry;
5762 SetLastError(0xdeadbeef);
5763 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithOneEntry,
5764 sizeof(ctlWithOneEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5765 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5768 compareCTLInfo("CTL with one entry", &info, (CTL_INFO *)buf);
5772 value2.cbData = sizeof(encodedIPAddr);
5773 value2.pbData = (LPBYTE)encodedIPAddr;
5774 attr2.pszObjId = oid2;
5776 attr2.rgValue = &value2;
5777 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5778 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5779 ctlEntry[1].cAttribute = 1;
5780 ctlEntry[1].rgAttribute = &attr2;
5782 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithTwoEntries,
5783 sizeof(ctlWithTwoEntries), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5784 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5787 compareCTLInfo("CTL with two entries", &info, (CTL_INFO *)buf);
5791 /* A signed CTL isn't decodable, even if the inner content is a CTL */
5792 SetLastError(0xdeadbeef);
5793 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, signedCTL,
5794 sizeof(signedCTL), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5795 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5796 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5797 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5799 SetLastError(0xdeadbeef);
5800 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL,
5801 signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent),
5802 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5803 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5804 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5805 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5809 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
5810 static const BYTE emptyPKCSContentInfoExtraBytes[] = { 0x30,0x04,0x06,0x02,0x2a,
5812 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
5814 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
5815 0x03,0x02,0x01,0x01 };
5816 static BYTE bogusDER[] = { 1 };
5818 static void test_encodePKCSContentInfo(DWORD dwEncoding)
5823 CRYPT_CONTENT_INFO info = { 0 };
5824 char oid1[] = "1.2.3";
5828 /* Crashes on win9x */
5829 SetLastError(0xdeadbeef);
5830 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL,
5831 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5832 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5833 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5835 SetLastError(0xdeadbeef);
5836 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5837 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5838 ok(!ret && (GetLastError() == E_INVALIDARG ||
5839 GetLastError() == OSS_LIMITED /* Win9x */),
5840 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5841 info.pszObjId = oid1;
5842 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5843 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5844 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5847 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size);
5848 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n");
5851 info.Content.pbData = bogusDER;
5852 info.Content.cbData = sizeof(bogusDER);
5853 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5854 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5855 ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError());
5858 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size);
5859 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n");
5862 info.Content.pbData = (BYTE *)ints[0].encoded;
5863 info.Content.cbData = ints[0].encoded[1] + 2;
5864 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5865 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5868 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size);
5869 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n");
5874 static const BYTE indefiniteSignedPKCSContent[] = {
5875 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
5876 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
5877 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
5878 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
5879 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
5880 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
5881 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5882 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5883 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
5884 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5885 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5886 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
5887 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
5888 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
5889 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
5890 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
5891 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
5892 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
5893 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
5894 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5895 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5896 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
5897 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
5898 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
5899 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
5900 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
5901 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
5902 0x00,0x00,0x00,0x00,0x00,0x00 };
5904 static void test_decodePKCSContentInfo(DWORD dwEncoding)
5909 CRYPT_CONTENT_INFO *info;
5911 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5912 emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo),
5913 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5914 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5917 info = (CRYPT_CONTENT_INFO *)buf;
5919 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5921 ok(info->Content.cbData == 0, "Expected no data, got %d\n",
5922 info->Content.cbData);
5925 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5926 emptyPKCSContentInfoExtraBytes, sizeof(emptyPKCSContentInfoExtraBytes),
5927 0, NULL, NULL, &size);
5928 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5929 SetLastError(0xdeadbeef);
5930 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5931 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo),
5932 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5933 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5934 * I doubt an app depends on that.
5936 ok((!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5937 GetLastError() == CRYPT_E_ASN1_CORRUPT)) || broken(ret),
5938 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5940 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5941 intPKCSContentInfo, sizeof(intPKCSContentInfo),
5942 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5943 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5946 info = (CRYPT_CONTENT_INFO *)buf;
5948 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5950 ok(info->Content.cbData == ints[0].encoded[1] + 2,
5951 "Unexpected size %d\n", info->Content.cbData);
5952 ok(!memcmp(info->Content.pbData, ints[0].encoded,
5953 info->Content.cbData), "Unexpected value\n");
5956 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5957 indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent),
5958 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5959 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5962 info = (CRYPT_CONTENT_INFO *)buf;
5964 ok(!strcmp(info->pszObjId, szOID_RSA_signedData),
5965 "Expected %s, got %s\n", szOID_RSA_signedData, info->pszObjId);
5966 ok(info->Content.cbData == 392, "Expected 392, got %d\n",
5967 info->Content.cbData);
5972 static const BYTE emptyPKCSAttr[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
5974 static const BYTE bogusPKCSAttr[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
5976 static const BYTE intPKCSAttr[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
5979 static void test_encodePKCSAttribute(DWORD dwEncoding)
5981 CRYPT_ATTRIBUTE attr = { 0 };
5985 CRYPT_ATTR_BLOB blob;
5986 char oid[] = "1.2.3";
5990 /* Crashes on win9x */
5991 SetLastError(0xdeadbeef);
5992 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, NULL,
5993 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5994 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5995 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5997 SetLastError(0xdeadbeef);
5998 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5999 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6000 ok(!ret && (GetLastError() == E_INVALIDARG ||
6001 GetLastError() == OSS_LIMITED /* Win9x */),
6002 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
6003 attr.pszObjId = oid;
6004 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
6005 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6006 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6009 ok(size == sizeof(emptyPKCSAttr), "Unexpected size %d\n", size);
6010 ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n");
6013 blob.cbData = sizeof(bogusDER);
6014 blob.pbData = bogusDER;
6016 attr.rgValue = &blob;
6017 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
6018 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6019 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6022 ok(size == sizeof(bogusPKCSAttr), "Unexpected size %d\n", size);
6023 ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n");
6026 blob.pbData = (BYTE *)ints[0].encoded;
6027 blob.cbData = ints[0].encoded[1] + 2;
6028 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
6029 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6032 ok(size == sizeof(intPKCSAttr), "Unexpected size %d\n", size);
6033 ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n");
6038 static void test_decodePKCSAttribute(DWORD dwEncoding)
6043 CRYPT_ATTRIBUTE *attr;
6045 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
6046 emptyPKCSAttr, sizeof(emptyPKCSAttr),
6047 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6048 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6051 attr = (CRYPT_ATTRIBUTE *)buf;
6053 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
6055 ok(attr->cValue == 0, "Expected no value, got %d\n", attr->cValue);
6058 SetLastError(0xdeadbeef);
6059 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
6060 bogusPKCSAttr, sizeof(bogusPKCSAttr),
6061 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6062 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
6063 * I doubt an app depends on that.
6065 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
6066 GetLastError() == CRYPT_E_ASN1_CORRUPT ||
6067 GetLastError() == OSS_MORE_INPUT /* Win9x */),
6068 "Expected CRYPT_E_ASN1_EOD, CRYPT_E_ASN1_CORRUPT, or OSS_MORE_INPUT, got %x\n",
6070 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
6071 intPKCSAttr, sizeof(intPKCSAttr),
6072 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6073 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6076 attr = (CRYPT_ATTRIBUTE *)buf;
6078 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
6080 ok(attr->cValue == 1, "Expected 1 value, got %d\n", attr->cValue);
6081 ok(attr->rgValue[0].cbData == ints[0].encoded[1] + 2,
6082 "Unexpected size %d\n", attr->rgValue[0].cbData);
6083 ok(!memcmp(attr->rgValue[0].pbData, ints[0].encoded,
6084 attr->rgValue[0].cbData), "Unexpected value\n");
6089 static const BYTE emptyPKCSAttributes[] = { 0x31,0x00 };
6090 static const BYTE singlePKCSAttributes[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
6091 0x2a,0x03,0x31,0x00 };
6092 static const BYTE doublePKCSAttributes[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
6093 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
6095 static void test_encodePKCSAttributes(DWORD dwEncoding)
6097 CRYPT_ATTRIBUTES attributes = { 0 };
6098 CRYPT_ATTRIBUTE attr[2] = { { 0 } };
6099 CRYPT_ATTR_BLOB blob;
6103 char oid1[] = "1.2.3", oid2[] = "1.5.6";
6105 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6106 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6107 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6110 ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %d\n", size);
6111 ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n");
6114 attributes.cAttr = 1;
6115 attributes.rgAttr = attr;
6116 SetLastError(0xdeadbeef);
6117 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6118 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6119 ok(!ret && (GetLastError() == E_INVALIDARG ||
6120 GetLastError() == OSS_LIMITED /* Win9x */),
6121 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6122 attr[0].pszObjId = oid1;
6123 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6124 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6127 ok(size == sizeof(singlePKCSAttributes), "Unexpected size %d\n", size);
6128 ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n");
6131 attr[1].pszObjId = oid2;
6133 attr[1].rgValue = &blob;
6134 blob.pbData = (BYTE *)ints[0].encoded;
6135 blob.cbData = ints[0].encoded[1] + 2;
6136 attributes.cAttr = 2;
6137 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6138 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6139 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6142 ok(size == sizeof(doublePKCSAttributes), "Unexpected size %d\n", size);
6143 ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n");
6148 static void test_decodePKCSAttributes(DWORD dwEncoding)
6153 CRYPT_ATTRIBUTES *attributes;
6155 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6156 emptyPKCSAttributes, sizeof(emptyPKCSAttributes),
6157 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6158 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6161 attributes = (CRYPT_ATTRIBUTES *)buf;
6162 ok(attributes->cAttr == 0, "Expected no attributes, got %d\n",
6166 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6167 singlePKCSAttributes, sizeof(singlePKCSAttributes),
6168 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6169 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6172 attributes = (CRYPT_ATTRIBUTES *)buf;
6173 ok(attributes->cAttr == 1, "Expected 1 attribute, got %d\n",
6175 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
6176 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
6177 ok(attributes->rgAttr[0].cValue == 0,
6178 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
6181 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6182 doublePKCSAttributes, sizeof(doublePKCSAttributes),
6183 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6184 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6187 attributes = (CRYPT_ATTRIBUTES *)buf;
6188 ok(attributes->cAttr == 2, "Expected 2 attributes, got %d\n",
6190 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
6191 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
6192 ok(attributes->rgAttr[0].cValue == 0,
6193 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
6194 ok(!strcmp(attributes->rgAttr[1].pszObjId, "1.5.6"),
6195 "Expected 1.5.6, got %s\n", attributes->rgAttr[1].pszObjId);
6196 ok(attributes->rgAttr[1].cValue == 1,
6197 "Expected 1 attribute, got %d\n", attributes->rgAttr[1].cValue);
6198 ok(attributes->rgAttr[1].rgValue[0].cbData == ints[0].encoded[1] + 2,
6199 "Unexpected size %d\n", attributes->rgAttr[1].rgValue[0].cbData);
6200 ok(!memcmp(attributes->rgAttr[1].rgValue[0].pbData, ints[0].encoded,
6201 attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n");
6206 static const BYTE singleCapability[] = {
6207 0x30,0x06,0x30,0x04,0x06,0x02,0x2d,0x06 };
6208 static const BYTE twoCapabilities[] = {
6209 0x30,0x0c,0x30,0x04,0x06,0x02,0x2d,0x06,0x30,0x04,0x06,0x02,0x2a,0x03 };
6210 static const BYTE singleCapabilitywithNULL[] = {
6211 0x30,0x08,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
6213 static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding)
6215 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6219 CRYPT_SMIME_CAPABILITY capability[2];
6220 CRYPT_SMIME_CAPABILITIES capabilities;
6222 /* An empty capabilities is allowed */
6223 capabilities.cCapability = 0;
6224 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6225 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6226 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6229 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
6230 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
6233 /* A non-empty capabilities with an empty capability (lacking an OID) is
6236 capability[0].pszObjId = NULL;
6237 capability[0].Parameters.cbData = 0;
6238 capabilities.cCapability = 1;
6239 capabilities.rgCapability = capability;
6240 SetLastError(0xdeadbeef);
6241 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6242 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6243 ok(!ret && (GetLastError() == E_INVALIDARG ||
6244 GetLastError() == OSS_LIMITED /* Win9x */),
6245 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6246 capability[0].pszObjId = oid1;
6247 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6248 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6249 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6252 ok(size == sizeof(singleCapability), "unexpected size %d\n", size);
6253 ok(!memcmp(buf, singleCapability, size), "unexpected value\n");
6256 capability[1].pszObjId = oid2;
6257 capability[1].Parameters.cbData = 0;
6258 capabilities.cCapability = 2;
6259 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6260 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6261 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6264 ok(size == sizeof(twoCapabilities), "unexpected size %d\n", size);
6265 ok(!memcmp(buf, twoCapabilities, size), "unexpected value\n");
6270 static void compareSMimeCapabilities(LPCSTR header,
6271 const CRYPT_SMIME_CAPABILITIES *expected, const CRYPT_SMIME_CAPABILITIES *got)
6275 ok(got->cCapability == expected->cCapability,
6276 "%s: expected %d capabilities, got %d\n", header, expected->cCapability,
6278 for (i = 0; i < expected->cCapability; i++)
6280 ok(!strcmp(expected->rgCapability[i].pszObjId,
6281 got->rgCapability[i].pszObjId), "%s[%d]: expected %s, got %s\n",
6282 header, i, expected->rgCapability[i].pszObjId,
6283 got->rgCapability[i].pszObjId);
6284 ok(expected->rgCapability[i].Parameters.cbData ==
6285 got->rgCapability[i].Parameters.cbData,
6286 "%s[%d]: expected %d bytes, got %d\n", header, i,
6287 expected->rgCapability[i].Parameters.cbData,
6288 got->rgCapability[i].Parameters.cbData);
6289 if (expected->rgCapability[i].Parameters.cbData)
6290 ok(!memcmp(expected->rgCapability[i].Parameters.pbData,
6291 got->rgCapability[i].Parameters.pbData,
6292 expected->rgCapability[i].Parameters.cbData),
6293 "%s[%d]: unexpected value\n", header, i);
6297 static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding)
6299 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6302 CRYPT_SMIME_CAPABILITY capability[2];
6303 CRYPT_SMIME_CAPABILITIES capabilities, *ptr;
6305 SetLastError(0xdeadbeef);
6306 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6307 emptySequence, sizeof(emptySequence),
6308 CRYPT_DECODE_ALLOC_FLAG, NULL, &ptr, &size);
6309 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6312 capabilities.cCapability = 0;
6313 compareSMimeCapabilities("empty capabilities", &capabilities, ptr);
6316 SetLastError(0xdeadbeef);
6317 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6318 singleCapability, sizeof(singleCapability), CRYPT_DECODE_ALLOC_FLAG, NULL,
6320 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6323 capability[0].pszObjId = oid1;
6324 capability[0].Parameters.cbData = 0;
6325 capabilities.cCapability = 1;
6326 capabilities.rgCapability = capability;
6327 compareSMimeCapabilities("single capability", &capabilities, ptr);
6330 SetLastError(0xdeadbeef);
6331 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6332 singleCapabilitywithNULL, sizeof(singleCapabilitywithNULL),
6333 CRYPT_DECODE_ALLOC_FLAG, NULL, &ptr, &size);
6334 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6337 BYTE NULLparam[] = {0x05, 0x00};
6338 capability[0].pszObjId = oid1;
6339 capability[0].Parameters.cbData = 2;
6340 capability[0].Parameters.pbData = NULLparam;
6341 capabilities.cCapability = 1;
6342 capabilities.rgCapability = capability;
6343 compareSMimeCapabilities("single capability with NULL", &capabilities,
6347 SetLastError(0xdeadbeef);
6348 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6349 twoCapabilities, sizeof(twoCapabilities), CRYPT_DECODE_ALLOC_FLAG, NULL,
6351 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6354 capability[0].Parameters.cbData = 0;
6355 capability[1].pszObjId = oid2;
6356 capability[1].Parameters.cbData = 0;
6357 capabilities.cCapability = 2;
6358 compareSMimeCapabilities("two capabilities", &capabilities, ptr);
6363 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
6364 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
6366 static const BYTE minimalPKCSSigner[] = {
6367 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6368 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6369 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6370 static const BYTE PKCSSignerWithSerial[] = {
6371 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6372 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6373 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
6375 static const BYTE PKCSSignerWithHashAlgo[] = {
6376 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6377 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6378 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
6380 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = {
6381 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6382 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6383 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6384 0x06,0x05,0x00,0x04,0x00 };
6385 static const BYTE PKCSSignerWithHash[] = {
6386 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6387 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6388 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6389 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
6390 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6391 static const BYTE PKCSSignerWithAuthAttr[] = {
6392 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6393 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6394 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
6395 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
6396 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
6397 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
6398 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6400 static void test_encodePKCSSignerInfo(DWORD dwEncoding)
6402 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6406 CMSG_SIGNER_INFO info = { 0 };
6407 char oid_common_name[] = szOID_COMMON_NAME;
6408 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
6409 (LPBYTE)encodedCommonName };
6410 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
6412 SetLastError(0xdeadbeef);
6413 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6414 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6415 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6417 skip("no PKCS7_SIGNER_INFO encode support\n");
6420 ok(!ret && (GetLastError() == E_INVALIDARG ||
6421 GetLastError() == OSS_LIMITED /* Win9x */),
6422 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6423 /* To be encoded, a signer must have an issuer at least, and the encoding
6424 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
6425 * see decoding tests.)
6427 info.Issuer.cbData = sizeof(encodedCommonNameNoNull);
6428 info.Issuer.pbData = encodedCommonNameNoNull;
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(minimalPKCSSigner), "Unexpected size %d\n", size);
6442 if (size == sizeof(minimalPKCSSigner))
6443 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6445 ok(0, "Unexpected value\n");
6449 info.SerialNumber.cbData = sizeof(serialNum);
6450 info.SerialNumber.pbData = (BYTE *)serialNum;
6451 SetLastError(0xdeadbeef);
6452 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6453 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6454 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6455 ok(!ret && GetLastError() == E_INVALIDARG,
6456 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6459 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6460 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6463 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6465 if (size == sizeof(PKCSSignerWithSerial))
6466 ok(!memcmp(buf, PKCSSignerWithSerial, size),
6467 "Unexpected value\n");
6469 ok(0, "Unexpected value\n");
6473 info.HashAlgorithm.pszObjId = oid1;
6474 SetLastError(0xdeadbeef);
6475 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6476 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6477 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6478 ok(!ret && GetLastError() == E_INVALIDARG,
6479 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6482 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6483 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6486 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6488 if (size == sizeof(PKCSSignerWithHashAlgo))
6489 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6490 "Unexpected value\n");
6492 ok(0, "Unexpected value\n");
6496 info.HashEncryptionAlgorithm.pszObjId = oid2;
6497 SetLastError(0xdeadbeef);
6498 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6499 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6500 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6501 ok(!ret && GetLastError() == E_INVALIDARG,
6502 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6505 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6508 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6509 "Unexpected size %d\n", size);
6510 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo))
6511 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6512 "Unexpected value\n");
6514 ok(0, "Unexpected value\n");
6518 info.EncryptedHash.cbData = sizeof(hash);
6519 info.EncryptedHash.pbData = (BYTE *)hash;
6520 SetLastError(0xdeadbeef);
6521 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6522 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6523 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6524 ok(!ret && GetLastError() == E_INVALIDARG,
6525 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6528 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6531 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6533 if (size == sizeof(PKCSSignerWithHash))
6534 ok(!memcmp(buf, PKCSSignerWithHash, size),
6535 "Unexpected value\n");
6537 ok(0, "Unexpected value\n");
6541 info.AuthAttrs.cAttr = 1;
6542 info.AuthAttrs.rgAttr = &attr;
6543 SetLastError(0xdeadbeef);
6544 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6545 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6546 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6547 ok(!ret && GetLastError() == E_INVALIDARG,
6548 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6551 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6554 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
6556 if (size == sizeof(PKCSSignerWithAuthAttr))
6557 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
6558 "Unexpected value\n");
6560 ok(0, "Unexpected value\n");
6566 static void test_decodePKCSSignerInfo(DWORD dwEncoding)
6571 CMSG_SIGNER_INFO *info;
6573 /* A PKCS signer can't be decoded without a serial number. */
6574 SetLastError(0xdeadbeef);
6575 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6576 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6577 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6578 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
6579 GetLastError() == OSS_DATA_ERROR /* Win9x */),
6580 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %x\n",
6582 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6583 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6584 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6585 ok(ret || broken(GetLastError() == OSS_DATA_ERROR),
6586 "CryptDecodeObjectEx failed: %x\n", GetLastError());
6589 info = (CMSG_SIGNER_INFO *)buf;
6590 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6592 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6593 "Unexpected size %d\n", info->Issuer.cbData);
6594 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6595 info->Issuer.cbData), "Unexpected value\n");
6596 ok(info->SerialNumber.cbData == sizeof(serialNum),
6597 "Unexpected size %d\n", info->SerialNumber.cbData);
6598 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6599 "Unexpected value\n");
6602 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6603 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6604 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6607 info = (CMSG_SIGNER_INFO *)buf;
6608 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6610 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6611 "Unexpected size %d\n", info->Issuer.cbData);
6612 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6613 info->Issuer.cbData), "Unexpected value\n");
6614 ok(info->SerialNumber.cbData == sizeof(serialNum),
6615 "Unexpected size %d\n", info->SerialNumber.cbData);
6616 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6617 "Unexpected value\n");
6618 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6619 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6622 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6623 PKCSSignerWithHashAndEncryptionAlgo,
6624 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
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);
6645 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6646 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6647 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6650 info = (CMSG_SIGNER_INFO *)buf;
6651 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6653 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6654 "Unexpected size %d\n", info->Issuer.cbData);
6655 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6656 info->Issuer.cbData), "Unexpected value\n");
6657 ok(info->SerialNumber.cbData == sizeof(serialNum),
6658 "Unexpected size %d\n", info->SerialNumber.cbData);
6659 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6660 "Unexpected value\n");
6661 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6662 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6663 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6664 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6665 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6666 info->EncryptedHash.cbData);
6667 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6668 "Unexpected value\n");
6671 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6672 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
6673 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6676 info = (CMSG_SIGNER_INFO *)buf;
6677 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n",
6678 info->AuthAttrs.cAttr);
6679 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
6680 "Expected %s, got %s\n", szOID_COMMON_NAME,
6681 info->AuthAttrs.rgAttr[0].pszObjId);
6682 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
6683 info->AuthAttrs.rgAttr[0].cValue);
6684 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
6685 sizeof(encodedCommonName), "Unexpected size %d\n",
6686 info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
6687 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
6688 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
6693 static const BYTE CMSSignerWithKeyId[] = {
6694 0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,
6695 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6697 static void test_encodeCMSSignerInfo(DWORD dwEncoding)
6702 CMSG_CMS_SIGNER_INFO info = { 0 };
6703 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6705 SetLastError(0xdeadbeef);
6706 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6707 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6708 ok(!ret, "Expected failure, got %d\n", ret);
6709 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6711 skip("no CMS_SIGNER_INFO encode support\n");
6714 ok(GetLastError() == E_INVALIDARG,
6715 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6716 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6717 SetLastError(0xdeadbeef);
6718 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6719 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6720 ok(!ret, "Expected failure, got %d\n", ret);
6721 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6723 skip("no CMS_SIGNER_INFO encode support\n");
6726 ok(GetLastError() == E_INVALIDARG,
6727 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6728 /* To be encoded, a signer must have a valid cert ID, where a valid ID may
6729 * be a key id or a issuer serial number with at least the issuer set, and
6730 * the encoding must include PKCS_7_ASN_ENCODING.
6731 * (That isn't enough to be decoded, see decoding tests.)
6733 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6734 sizeof(encodedCommonNameNoNull);
6735 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6736 SetLastError(0xdeadbeef);
6737 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6738 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6739 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6740 ok(!ret && GetLastError() == E_INVALIDARG,
6741 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6744 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6747 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6748 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6752 U(info.SignerId).IssuerSerialNumber.SerialNumber.cbData = sizeof(serialNum);
6753 U(info.SignerId).IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
6754 SetLastError(0xdeadbeef);
6755 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6756 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6757 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6758 ok(!ret && GetLastError() == E_INVALIDARG,
6759 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6762 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6765 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6767 ok(!memcmp(buf, PKCSSignerWithSerial, size), "Unexpected value\n");
6771 info.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
6772 U(info.SignerId).KeyId.cbData = sizeof(serialNum);
6773 U(info.SignerId).KeyId.pbData = (BYTE *)serialNum;
6774 SetLastError(0xdeadbeef);
6775 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6776 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6777 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6778 ok(!ret && GetLastError() == E_INVALIDARG,
6779 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6782 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6785 ok(size == sizeof(CMSSignerWithKeyId), "Unexpected size %d\n",
6787 ok(!memcmp(buf, CMSSignerWithKeyId, size), "Unexpected value\n");
6791 /* While a CERT_ID can have a hash type, that's not allowed in CMS, where
6792 * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed
6793 * (see RFC 3852, section 5.3.)
6795 info.SignerId.dwIdChoice = CERT_ID_SHA1_HASH;
6796 U(info.SignerId).HashId.cbData = sizeof(hash);
6797 U(info.SignerId).HashId.pbData = (BYTE *)hash;
6798 SetLastError(0xdeadbeef);
6799 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6800 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6801 ok(!ret && GetLastError() == E_INVALIDARG,
6802 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6803 /* Now with a hash algo */
6804 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6805 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6806 sizeof(encodedCommonNameNoNull);
6807 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6808 info.HashAlgorithm.pszObjId = oid1;
6809 SetLastError(0xdeadbeef);
6810 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6811 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6812 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6813 ok(!ret && GetLastError() == E_INVALIDARG,
6814 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6817 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6820 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6822 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6823 "Unexpected value\n");
6827 info.HashEncryptionAlgorithm.pszObjId = oid2;
6828 SetLastError(0xdeadbeef);
6829 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6830 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6831 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6832 ok(!ret && GetLastError() == E_INVALIDARG,
6833 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6836 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6839 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6840 "Unexpected size %d\n", size);
6841 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6842 "Unexpected value\n");
6846 info.EncryptedHash.cbData = sizeof(hash);
6847 info.EncryptedHash.pbData = (BYTE *)hash;
6848 SetLastError(0xdeadbeef);
6849 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6850 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6851 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6852 ok(!ret && GetLastError() == E_INVALIDARG,
6853 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6856 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6859 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6861 ok(!memcmp(buf, PKCSSignerWithHash, size), "Unexpected value\n");
6867 static void test_decodeCMSSignerInfo(DWORD dwEncoding)
6872 CMSG_CMS_SIGNER_INFO *info;
6873 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6875 /* A CMS signer can't be decoded without a serial number. */
6876 SetLastError(0xdeadbeef);
6877 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6878 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6879 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6880 ok(!ret, "expected failure\n");
6881 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6883 skip("no CMS_SIGNER_INFO decode support\n");
6886 ok(GetLastError() == CRYPT_E_ASN1_CORRUPT,
6887 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
6888 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6889 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6890 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6891 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6894 info = (CMSG_CMS_SIGNER_INFO *)buf;
6895 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6897 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6898 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6899 info->SignerId.dwIdChoice);
6900 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6901 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6902 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6903 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6904 encodedCommonNameNoNull,
6905 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6906 "Unexpected value\n");
6907 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6908 sizeof(serialNum), "Unexpected size %d\n",
6909 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6910 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6911 serialNum, sizeof(serialNum)), "Unexpected value\n");
6914 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6915 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6916 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6917 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6920 info = (CMSG_CMS_SIGNER_INFO *)buf;
6921 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6923 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6924 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6925 info->SignerId.dwIdChoice);
6926 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6927 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6928 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6929 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6930 encodedCommonNameNoNull,
6931 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6932 "Unexpected value\n");
6933 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6934 sizeof(serialNum), "Unexpected size %d\n",
6935 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6936 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6937 serialNum, sizeof(serialNum)), "Unexpected value\n");
6938 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6939 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6942 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6943 PKCSSignerWithHashAndEncryptionAlgo,
6944 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6946 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6949 info = (CMSG_CMS_SIGNER_INFO *)buf;
6950 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6952 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6953 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6954 info->SignerId.dwIdChoice);
6955 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6956 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6957 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6958 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6959 encodedCommonNameNoNull,
6960 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6961 "Unexpected value\n");
6962 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6963 sizeof(serialNum), "Unexpected size %d\n",
6964 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6965 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6966 serialNum, sizeof(serialNum)), "Unexpected value\n");
6967 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6968 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6969 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6970 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6973 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6974 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6975 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6976 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6979 info = (CMSG_CMS_SIGNER_INFO *)buf;
6980 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6982 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6983 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6984 info->SignerId.dwIdChoice);
6985 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6986 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6987 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6988 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6989 encodedCommonNameNoNull,
6990 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6991 "Unexpected value\n");
6992 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6993 sizeof(serialNum), "Unexpected size %d\n",
6994 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6995 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6996 serialNum, sizeof(serialNum)), "Unexpected value\n");
6997 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6998 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6999 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
7000 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
7001 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
7002 info->EncryptedHash.cbData);
7003 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
7004 "Unexpected value\n");
7007 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
7008 CMSSignerWithKeyId, sizeof(CMSSignerWithKeyId),
7009 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
7010 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
7013 info = (CMSG_CMS_SIGNER_INFO *)buf;
7014 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
7016 ok(info->SignerId.dwIdChoice == CERT_ID_KEY_IDENTIFIER,
7017 "Expected CERT_ID_KEY_IDENTIFIER, got %d\n",
7018 info->SignerId.dwIdChoice);
7019 ok(U(info->SignerId).KeyId.cbData == sizeof(serialNum),
7020 "Unexpected size %d\n", U(info->SignerId).KeyId.cbData);
7021 ok(!memcmp(U(info->SignerId).KeyId.pbData, serialNum, sizeof(serialNum)),
7022 "Unexpected value\n");
7027 static BYTE emptyDNSPermittedConstraints[] = {
7028 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
7029 static BYTE emptyDNSExcludedConstraints[] = {
7030 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
7031 static BYTE DNSExcludedConstraints[] = {
7032 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
7033 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7034 static BYTE permittedAndExcludedConstraints[] = {
7035 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7036 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
7037 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7038 static BYTE permittedAndExcludedWithMinConstraints[] = {
7039 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7040 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
7041 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7042 static BYTE permittedAndExcludedWithMinMaxConstraints[] = {
7043 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7044 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
7045 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7047 static void test_encodeNameConstraints(DWORD dwEncoding)
7050 CERT_NAME_CONSTRAINTS_INFO constraints = { 0 };
7051 CERT_GENERAL_SUBTREE permitted = { { 0 } };
7052 CERT_GENERAL_SUBTREE excluded = { { 0 } };
7056 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7057 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7058 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7060 skip("no X509_NAME_CONSTRAINTS encode support\n");
7063 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7066 ok(size == sizeof(emptySequence), "Unexpected size\n");
7067 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
7070 constraints.cPermittedSubtree = 1;
7071 constraints.rgPermittedSubtree = &permitted;
7072 SetLastError(0xdeadbeef);
7073 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7074 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7075 ok(!ret && GetLastError() == E_INVALIDARG,
7076 "Expected E_INVALIDARG, got %08x\n", GetLastError());
7077 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
7078 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7079 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7080 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7083 ok(size == sizeof(emptyDNSPermittedConstraints), "Unexpected size\n");
7084 ok(!memcmp(buf, emptyDNSPermittedConstraints, size),
7085 "Unexpected value\n");
7088 constraints.cPermittedSubtree = 0;
7089 constraints.cExcludedSubtree = 1;
7090 constraints.rgExcludedSubtree = &excluded;
7091 excluded.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
7092 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7093 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7094 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7097 ok(size == sizeof(emptyDNSExcludedConstraints), "Unexpected size\n");
7098 ok(!memcmp(buf, emptyDNSExcludedConstraints, size),
7099 "Unexpected value\n");
7102 U(excluded.Base).pwszURL = (LPWSTR)url;
7103 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7104 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7105 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7108 ok(size == sizeof(DNSExcludedConstraints), "Unexpected size\n");
7109 ok(!memcmp(buf, DNSExcludedConstraints, size),
7110 "Unexpected value\n");
7113 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
7114 U(permitted.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7115 U(permitted.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7116 constraints.cPermittedSubtree = 1;
7117 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7118 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7119 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7122 ok(size == sizeof(permittedAndExcludedConstraints),
7123 "Unexpected size\n");
7124 ok(!memcmp(buf, permittedAndExcludedConstraints, size),
7125 "Unexpected value\n");
7128 permitted.dwMinimum = 5;
7129 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7130 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7131 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7134 ok(size == sizeof(permittedAndExcludedWithMinConstraints),
7135 "Unexpected size\n");
7136 ok(!memcmp(buf, permittedAndExcludedWithMinConstraints, size),
7137 "Unexpected value\n");
7140 permitted.fMaximum = TRUE;
7141 permitted.dwMaximum = 3;
7142 SetLastError(0xdeadbeef);
7143 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7144 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7145 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7148 ok(size == sizeof(permittedAndExcludedWithMinMaxConstraints),
7149 "Unexpected size\n");
7150 ok(!memcmp(buf, permittedAndExcludedWithMinMaxConstraints, size),
7151 "Unexpected value\n");
7156 struct EncodedNameConstraints
7158 CRYPT_DATA_BLOB encoded;
7159 CERT_NAME_CONSTRAINTS_INFO constraints;
7162 static CERT_GENERAL_SUBTREE emptyDNSSubtree = {
7163 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
7164 static CERT_GENERAL_SUBTREE DNSSubtree = {
7165 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
7166 static CERT_GENERAL_SUBTREE IPAddressSubtree = {
7167 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 0 };
7168 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree = {
7169 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, 0 };
7170 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree = {
7171 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, TRUE, 3 };
7173 struct EncodedNameConstraints encodedNameConstraints[] = {
7174 { { sizeof(emptySequence), (LPBYTE)emptySequence }, { 0 } },
7175 { { sizeof(emptyDNSPermittedConstraints), emptyDNSPermittedConstraints },
7176 { 1, &emptyDNSSubtree, 0, NULL } },
7177 { { sizeof(emptyDNSExcludedConstraints), emptyDNSExcludedConstraints },
7178 { 0, NULL, 1, &emptyDNSSubtree } },
7179 { { sizeof(DNSExcludedConstraints), DNSExcludedConstraints },
7180 { 0, NULL, 1, &DNSSubtree } },
7181 { { sizeof(permittedAndExcludedConstraints), permittedAndExcludedConstraints },
7182 { 1, &IPAddressSubtree, 1, &DNSSubtree } },
7183 { { sizeof(permittedAndExcludedWithMinConstraints),
7184 permittedAndExcludedWithMinConstraints },
7185 { 1, &IPAddressWithMinSubtree, 1, &DNSSubtree } },
7186 { { sizeof(permittedAndExcludedWithMinMaxConstraints),
7187 permittedAndExcludedWithMinMaxConstraints },
7188 { 1, &IPAddressWithMinMaxSubtree, 1, &DNSSubtree } },
7191 static void test_decodeNameConstraints(DWORD dwEncoding)
7195 CERT_NAME_CONSTRAINTS_INFO *constraints;
7197 U(DNSSubtree.Base).pwszURL = (LPWSTR)url;
7198 U(IPAddressSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7199 U(IPAddressSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7200 U(IPAddressWithMinSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7201 U(IPAddressWithMinSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7202 U(IPAddressWithMinMaxSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7203 U(IPAddressWithMinMaxSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7205 i < sizeof(encodedNameConstraints) / sizeof(encodedNameConstraints[0]);
7210 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS,
7211 encodedNameConstraints[i].encoded.pbData,
7212 encodedNameConstraints[i].encoded.cbData,
7213 CRYPT_DECODE_ALLOC_FLAG, NULL, &constraints, &size);
7214 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7216 skip("no X509_NAME_CONSTRAINTS decode support\n");
7219 ok(ret, "%d: CryptDecodeObjectEx failed: %08x\n", i, GetLastError());
7224 if (constraints->cPermittedSubtree !=
7225 encodedNameConstraints[i].constraints.cPermittedSubtree)
7226 fprintf(stderr, "%d: expected %d permitted, got %d\n", i,
7227 encodedNameConstraints[i].constraints.cPermittedSubtree,
7228 constraints->cPermittedSubtree);
7229 if (constraints->cPermittedSubtree ==
7230 encodedNameConstraints[i].constraints.cPermittedSubtree)
7232 for (j = 0; j < constraints->cPermittedSubtree; j++)
7234 compareAltNameEntry(&constraints->rgPermittedSubtree[j].Base,
7235 &encodedNameConstraints[i].constraints.rgPermittedSubtree[j].Base);
7238 if (constraints->cExcludedSubtree !=
7239 encodedNameConstraints[i].constraints.cExcludedSubtree)
7240 fprintf(stderr, "%d: expected %d excluded, got %d\n", i,
7241 encodedNameConstraints[i].constraints.cExcludedSubtree,
7242 constraints->cExcludedSubtree);
7243 if (constraints->cExcludedSubtree ==
7244 encodedNameConstraints[i].constraints.cExcludedSubtree)
7246 for (j = 0; j < constraints->cExcludedSubtree; j++)
7248 compareAltNameEntry(&constraints->rgExcludedSubtree[j].Base,
7249 &encodedNameConstraints[i].constraints.rgExcludedSubtree[j].Base);
7252 LocalFree(constraints);
7257 static WCHAR noticeText[] = { 'T','h','i','s',' ','i','s',' ','a',' ',
7258 'n','o','t','i','c','e',0 };
7259 static const BYTE noticeWithDisplayText[] = {
7260 0x30,0x22,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,0x00,
7261 0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,0x74,
7262 0x00,0x69,0x00,0x63,0x00,0x65
7264 static char org[] = "Wine";
7265 static int noticeNumbers[] = { 2,3 };
7266 static BYTE noticeWithReference[] = {
7267 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7268 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7269 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7270 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7273 static void test_encodePolicyQualifierUserNotice(DWORD dwEncoding)
7278 CERT_POLICY_QUALIFIER_USER_NOTICE notice;
7279 CERT_POLICY_QUALIFIER_NOTICE_REFERENCE reference;
7281 memset(¬ice, 0, sizeof(notice));
7282 ret = pCryptEncodeObjectEx(dwEncoding,
7283 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, ¬ice, CRYPT_ENCODE_ALLOC_FLAG,
7285 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7287 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE encode support\n");
7290 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7293 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size);
7294 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
7297 notice.pszDisplayText = noticeText;
7298 ret = pCryptEncodeObjectEx(dwEncoding,
7299 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, ¬ice, CRYPT_ENCODE_ALLOC_FLAG,
7301 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7304 ok(sizeof(noticeWithDisplayText) == size, "unexpected size %d\n", size);
7305 ok(!memcmp(buf, noticeWithDisplayText, size), "unexpected value\n");
7308 reference.pszOrganization = org;
7309 reference.cNoticeNumbers = 2;
7310 reference.rgNoticeNumbers = noticeNumbers;
7311 notice.pNoticeReference = &reference;
7312 ret = pCryptEncodeObjectEx(dwEncoding,
7313 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, ¬ice, CRYPT_ENCODE_ALLOC_FLAG,
7315 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7318 ok(sizeof(noticeWithReference) == size, "unexpected size %d\n", size);
7319 ok(!memcmp(buf, noticeWithReference, size), "unexpected value\n");
7324 static void test_decodePolicyQualifierUserNotice(DWORD dwEncoding)
7327 CERT_POLICY_QUALIFIER_USER_NOTICE *notice;
7330 ret = pCryptDecodeObjectEx(dwEncoding,
7331 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7332 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7334 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7336 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE decode support\n");
7339 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7342 ok(notice->pszDisplayText == NULL, "unexpected display text\n");
7343 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7346 ret = pCryptDecodeObjectEx(dwEncoding,
7347 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7348 noticeWithDisplayText, sizeof(noticeWithDisplayText),
7349 CRYPT_DECODE_ALLOC_FLAG, NULL, ¬ice, &size);
7350 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7353 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7354 "unexpected display text\n");
7355 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7358 ret = pCryptDecodeObjectEx(dwEncoding,
7359 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7360 noticeWithReference, sizeof(noticeWithReference),
7361 CRYPT_DECODE_ALLOC_FLAG, NULL, ¬ice, &size);
7362 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7365 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7366 "unexpected display text\n");
7367 ok(notice->pNoticeReference != NULL, "expected a notice reference\n");
7368 if (notice->pNoticeReference)
7370 ok(!strcmp(notice->pNoticeReference->pszOrganization, org),
7371 "unexpected organization %s\n",
7372 notice->pNoticeReference->pszOrganization);
7373 ok(notice->pNoticeReference->cNoticeNumbers == 2,
7374 "expected 2 notice numbers, got %d\n",
7375 notice->pNoticeReference->cNoticeNumbers);
7376 ok(notice->pNoticeReference->rgNoticeNumbers[0] == noticeNumbers[0],
7377 "unexpected notice number %d\n",
7378 notice->pNoticeReference->rgNoticeNumbers[0]);
7379 ok(notice->pNoticeReference->rgNoticeNumbers[1] == noticeNumbers[1],
7380 "unexpected notice number %d\n",
7381 notice->pNoticeReference->rgNoticeNumbers[1]);
7387 static char oid_any_policy[] = "2.5.29.32.0";
7388 static const BYTE policiesWithAnyPolicy[] = {
7389 0x30,0x08,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00
7391 static char oid1[] = "1.2.3";
7392 static char oid_user_notice[] = "1.3.6.1.5.5.7.2.2";
7393 static const BYTE twoPolicies[] = {
7394 0x30,0x50,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00,0x30,0x46,0x06,0x02,0x2a,
7395 0x03,0x30,0x40,0x30,0x3e,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x02,
7396 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7397 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7398 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7399 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7402 static void test_encodeCertPolicies(DWORD dwEncoding)
7405 CERT_POLICIES_INFO info;
7406 CERT_POLICY_INFO policy[2];
7407 CERT_POLICY_QUALIFIER_INFO qualifier;
7411 memset(&info, 0, sizeof(info));
7412 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7413 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7414 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7417 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size);
7418 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
7421 memset(policy, 0, sizeof(policy));
7422 info.cPolicyInfo = 1;
7423 info.rgPolicyInfo = policy;
7424 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7425 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7426 ok(!ret && (GetLastError() == E_INVALIDARG ||
7427 GetLastError() == OSS_LIMITED /* Win9x/NT4 */),
7428 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
7429 policy[0].pszPolicyIdentifier = oid_any_policy;
7430 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7431 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7432 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7435 ok(sizeof(policiesWithAnyPolicy) == size, "unexpected size %d\n", size);
7436 ok(!memcmp(buf, policiesWithAnyPolicy, size), "unexpected value\n");
7439 policy[1].pszPolicyIdentifier = oid1;
7440 memset(&qualifier, 0, sizeof(qualifier));
7441 qualifier.pszPolicyQualifierId = oid_user_notice;
7442 qualifier.Qualifier.cbData = sizeof(noticeWithReference);
7443 qualifier.Qualifier.pbData = noticeWithReference;
7444 policy[1].cPolicyQualifier = 1;
7445 policy[1].rgPolicyQualifier = &qualifier;
7446 info.cPolicyInfo = 2;
7447 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7448 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7449 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7452 ok(sizeof(twoPolicies) == size, "unexpected size %d\n", size);
7453 ok(!memcmp(buf, twoPolicies, size), "unexpected value\n");
7458 static void test_decodeCertPolicies(DWORD dwEncoding)
7461 CERT_POLICIES_INFO *info;
7464 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7465 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7467 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7470 ok(info->cPolicyInfo == 0, "unexpected policy info %d\n",
7474 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7475 policiesWithAnyPolicy, sizeof(policiesWithAnyPolicy),
7476 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7477 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7480 ok(info->cPolicyInfo == 1, "unexpected policy info %d\n",
7482 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy),
7483 "unexpected policy id %s\n",
7484 info->rgPolicyInfo[0].pszPolicyIdentifier);
7485 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0,
7486 "unexpected policy qualifier count %d\n",
7487 info->rgPolicyInfo[0].cPolicyQualifier);
7490 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7491 twoPolicies, sizeof(twoPolicies),
7492 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7493 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7496 ok(info->cPolicyInfo == 2, "unexpected policy info %d\n",
7498 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy),
7499 "unexpected policy id %s\n",
7500 info->rgPolicyInfo[0].pszPolicyIdentifier);
7501 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0,
7502 "unexpected policy qualifier count %d\n",
7503 info->rgPolicyInfo[0].cPolicyQualifier);
7504 ok(!strcmp(info->rgPolicyInfo[1].pszPolicyIdentifier, oid1),
7505 "unexpected policy id %s\n",
7506 info->rgPolicyInfo[1].pszPolicyIdentifier);
7507 ok(info->rgPolicyInfo[1].cPolicyQualifier == 1,
7508 "unexpected policy qualifier count %d\n",
7509 info->rgPolicyInfo[1].cPolicyQualifier);
7511 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId,
7512 oid_user_notice), "unexpected policy qualifier id %s\n",
7513 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId);
7514 ok(info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData ==
7515 sizeof(noticeWithReference), "unexpected qualifier size %d\n",
7516 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData);
7518 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.pbData,
7519 noticeWithReference, sizeof(noticeWithReference)),
7520 "unexpected qualifier value\n");
7525 static const BYTE policyMappingWithOneMapping[] = {
7526 0x30,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04 };
7527 static const BYTE policyMappingWithTwoMappings[] = {
7528 0x30,0x14,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04,0x30,0x08,0x06,
7529 0x02,0x2b,0x04,0x06,0x02,0x55,0x06 };
7530 static const LPCSTR mappingOids[] = { X509_POLICY_MAPPINGS,
7531 szOID_POLICY_MAPPINGS, szOID_LEGACY_POLICY_MAPPINGS };
7533 static void test_encodeCertPolicyMappings(DWORD dwEncoding)
7535 static char oid2[] = "2.3.4";
7536 static char oid3[] = "1.3.4";
7537 static char oid4[] = "2.5.6";
7539 CERT_POLICY_MAPPINGS_INFO info = { 0 };
7540 CERT_POLICY_MAPPING mapping[2];
7544 /* Each of the mapping OIDs is equivalent, so check with all of them */
7545 for (i = 0; i < sizeof(mappingOids) / sizeof(mappingOids[0]); i++)
7547 memset(&info, 0, sizeof(info));
7548 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7549 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7550 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
7551 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7552 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7554 win_skip("no policy mappings support\n");
7559 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
7560 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
7561 "unexpected value\n");
7564 mapping[0].pszIssuerDomainPolicy = NULL;
7565 mapping[0].pszSubjectDomainPolicy = NULL;
7566 info.cPolicyMapping = 1;
7567 info.rgPolicyMapping = mapping;
7568 SetLastError(0xdeadbeef);
7569 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7570 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7571 ok(!ret && GetLastError() == E_INVALIDARG,
7572 "expected E_INVALIDARG, got %08x\n", GetLastError());
7573 mapping[0].pszIssuerDomainPolicy = oid1;
7574 mapping[0].pszSubjectDomainPolicy = oid2;
7575 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7576 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7577 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7580 ok(size == sizeof(policyMappingWithOneMapping),
7581 "unexpected size %d\n", size);
7582 ok(!memcmp(buf, policyMappingWithOneMapping, size),
7583 "unexpected value\n");
7586 mapping[1].pszIssuerDomainPolicy = oid3;
7587 mapping[1].pszSubjectDomainPolicy = oid4;
7588 info.cPolicyMapping = 2;
7589 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7590 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7591 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7594 ok(size == sizeof(policyMappingWithTwoMappings),
7595 "unexpected size %d\n", size);
7596 ok(!memcmp(buf, policyMappingWithTwoMappings, size),
7597 "unexpected value\n");
7603 static void test_decodeCertPolicyMappings(DWORD dwEncoding)
7606 CERT_POLICY_MAPPINGS_INFO *info;
7609 /* Each of the mapping OIDs is equivalent, so check with all of them */
7610 for (i = 0; i < sizeof(mappingOids) / sizeof(mappingOids[0]); i++)
7612 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7613 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7615 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
7616 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7617 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7619 win_skip("no policy mappings support\n");
7624 ok(info->cPolicyMapping == 0,
7625 "expected 0 policy mappings, got %d\n", info->cPolicyMapping);
7628 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7629 policyMappingWithOneMapping, sizeof(policyMappingWithOneMapping),
7630 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7631 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7634 ok(info->cPolicyMapping == 1,
7635 "expected 1 policy mappings, got %d\n", info->cPolicyMapping);
7636 ok(!strcmp(info->rgPolicyMapping[0].pszIssuerDomainPolicy, "1.2.3"),
7637 "unexpected issuer policy %s\n",
7638 info->rgPolicyMapping[0].pszIssuerDomainPolicy);
7639 ok(!strcmp(info->rgPolicyMapping[0].pszSubjectDomainPolicy,
7640 "2.3.4"), "unexpected subject policy %s\n",
7641 info->rgPolicyMapping[0].pszSubjectDomainPolicy);
7644 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7645 policyMappingWithTwoMappings, sizeof(policyMappingWithTwoMappings),
7646 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7647 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7650 ok(info->cPolicyMapping == 2,
7651 "expected 2 policy mappings, got %d\n", info->cPolicyMapping);
7652 ok(!strcmp(info->rgPolicyMapping[0].pszIssuerDomainPolicy, "1.2.3"),
7653 "unexpected issuer policy %s\n",
7654 info->rgPolicyMapping[0].pszIssuerDomainPolicy);
7655 ok(!strcmp(info->rgPolicyMapping[0].pszSubjectDomainPolicy,
7656 "2.3.4"), "unexpected subject policy %s\n",
7657 info->rgPolicyMapping[0].pszSubjectDomainPolicy);
7658 ok(!strcmp(info->rgPolicyMapping[1].pszIssuerDomainPolicy, "1.3.4"),
7659 "unexpected issuer policy %s\n",
7660 info->rgPolicyMapping[1].pszIssuerDomainPolicy);
7661 ok(!strcmp(info->rgPolicyMapping[1].pszSubjectDomainPolicy,
7662 "2.5.6"), "unexpected subject policy %s\n",
7663 info->rgPolicyMapping[1].pszSubjectDomainPolicy);
7669 static const BYTE policyConstraintsWithRequireExplicit[] = {
7670 0x30,0x03,0x80,0x01,0x00 };
7671 static const BYTE policyConstraintsWithInhibitMapping[] = {
7672 0x30,0x03,0x81,0x01,0x01 };
7673 static const BYTE policyConstraintsWithBoth[] = {
7674 0x30,0x06,0x80,0x01,0x01,0x81,0x01,0x01 };
7676 static void test_encodeCertPolicyConstraints(DWORD dwEncoding)
7678 CERT_POLICY_CONSTRAINTS_INFO info = { 0 };
7683 /* Even though RFC 5280 explicitly states CAs must not issue empty
7684 * policy constraints (section 4.2.1.11), the API doesn't prevent it.
7686 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7687 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7688 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
7689 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7690 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7692 win_skip("no policy constraints support\n");
7697 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
7698 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
7699 "unexpected value\n");
7702 /* If fRequireExplicitPolicy is set but dwRequireExplicitPolicySkipCerts
7703 * is not, then a skip of 0 is encoded.
7705 info.fRequireExplicitPolicy = TRUE;
7706 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7707 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7708 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7711 ok(size == sizeof(policyConstraintsWithRequireExplicit),
7712 "unexpected size %d\n", size);
7713 ok(!memcmp(buf, policyConstraintsWithRequireExplicit,
7714 sizeof(policyConstraintsWithRequireExplicit)), "unexpected value\n");
7717 /* With inhibit policy mapping */
7718 info.fRequireExplicitPolicy = FALSE;
7719 info.dwRequireExplicitPolicySkipCerts = 0;
7720 info.fInhibitPolicyMapping = TRUE;
7721 info.dwInhibitPolicyMappingSkipCerts = 1;
7722 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7723 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7724 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7727 ok(size == sizeof(policyConstraintsWithInhibitMapping),
7728 "unexpected size %d\n", size);
7729 ok(!memcmp(buf, policyConstraintsWithInhibitMapping,
7730 sizeof(policyConstraintsWithInhibitMapping)), "unexpected value\n");
7734 info.fRequireExplicitPolicy = TRUE;
7735 info.dwRequireExplicitPolicySkipCerts = 1;
7736 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7737 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7738 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7741 ok(size == sizeof(policyConstraintsWithBoth), "unexpected size %d\n",
7743 ok(!memcmp(buf, policyConstraintsWithBoth,
7744 sizeof(policyConstraintsWithBoth)), "unexpected value\n");
7749 static void test_decodeCertPolicyConstraints(DWORD dwEncoding)
7751 CERT_POLICY_CONSTRAINTS_INFO *info;
7755 /* Again, even though CAs must not issue such constraints, they can be
7758 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7759 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7761 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
7762 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7763 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7765 win_skip("no policy mappings support\n");
7770 ok(!info->fRequireExplicitPolicy,
7771 "expected require explicit = FALSE\n");
7772 ok(!info->fInhibitPolicyMapping,
7773 "expected implicit mapping = FALSE\n");
7776 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7777 policyConstraintsWithRequireExplicit,
7778 sizeof(policyConstraintsWithRequireExplicit), CRYPT_DECODE_ALLOC_FLAG,
7779 NULL, &info, &size);
7780 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7783 ok(info->fRequireExplicitPolicy,
7784 "expected require explicit = TRUE\n");
7785 ok(info->dwRequireExplicitPolicySkipCerts == 0, "expected 0, got %d\n",
7786 info->dwRequireExplicitPolicySkipCerts);
7787 ok(!info->fInhibitPolicyMapping,
7788 "expected implicit mapping = FALSE\n");
7791 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7792 policyConstraintsWithInhibitMapping,
7793 sizeof(policyConstraintsWithInhibitMapping), CRYPT_DECODE_ALLOC_FLAG,
7794 NULL, &info, &size);
7795 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7798 ok(!info->fRequireExplicitPolicy,
7799 "expected require explicit = FALSE\n");
7800 ok(info->fInhibitPolicyMapping,
7801 "expected implicit mapping = TRUE\n");
7802 ok(info->dwInhibitPolicyMappingSkipCerts == 1, "expected 1, got %d\n",
7803 info->dwInhibitPolicyMappingSkipCerts);
7806 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7807 policyConstraintsWithBoth, sizeof(policyConstraintsWithBoth),
7808 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7809 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7812 ok(info->fRequireExplicitPolicy,
7813 "expected require explicit = TRUE\n");
7814 ok(info->dwRequireExplicitPolicySkipCerts == 1, "expected 1, got %d\n",
7815 info->dwRequireExplicitPolicySkipCerts);
7816 ok(info->fInhibitPolicyMapping,
7817 "expected implicit mapping = TRUE\n");
7818 ok(info->dwInhibitPolicyMappingSkipCerts == 1, "expected 1, got %d\n",
7819 info->dwInhibitPolicyMappingSkipCerts);
7824 /* Free *pInfo with HeapFree */
7825 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
7832 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
7834 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size);
7835 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7836 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7837 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL,
7839 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7840 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7841 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL,
7843 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7844 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7845 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7846 0, NULL, NULL, &size);
7847 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7848 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7849 /* Test with no key */
7850 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7851 0, NULL, NULL, &size);
7852 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n",
7854 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
7855 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
7858 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
7859 NULL, 0, NULL, NULL, &size);
7860 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
7861 *pInfo = HeapAlloc(GetProcessHeap(), 0, size);
7864 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
7865 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size);
7866 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n",
7870 /* By default (we passed NULL as the OID) the OID is
7873 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA),
7874 "Expected %s, got %s\n", szOID_RSA_RSA,
7875 (*pInfo)->Algorithm.pszObjId);
7879 CryptDestroyKey(key);
7882 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
7883 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
7884 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
7885 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7886 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7887 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7888 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
7889 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
7890 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7891 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7892 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7893 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
7894 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
7895 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
7896 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
7897 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
7898 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
7899 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
7900 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
7901 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
7902 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
7903 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
7904 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
7905 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
7906 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
7908 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info)
7912 PCCERT_CONTEXT context;
7917 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
7918 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
7919 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
7920 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7923 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key);
7924 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7925 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7926 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key);
7927 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7928 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7929 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL,
7931 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7932 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7934 /* Export key with standard algorithm (CALG_RSA_KEYX) */
7935 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7937 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7939 dwSize = sizeof(ai);
7940 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7941 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7944 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7945 ok(ai == CALG_RSA_KEYX, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai);
7948 CryptDestroyKey(key);
7950 /* Repeat with forced algorithm */
7951 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, CALG_RSA_SIGN, 0, NULL,
7953 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7955 dwSize = sizeof(ai);
7956 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7957 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7960 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7961 ok(ai == CALG_RSA_SIGN, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai);
7964 CryptDestroyKey(key);
7966 /* Test importing a public key from a certificate context */
7967 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert,
7968 sizeof(expiredCert));
7969 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
7973 ok(!strcmp(szOID_RSA_RSA,
7974 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId),
7975 "Expected %s, got %s\n", szOID_RSA_RSA,
7976 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
7977 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING,
7978 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
7979 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7980 CryptDestroyKey(key);
7981 CertFreeCertificateContext(context);
7985 static const char cspName[] = "WineCryptTemp";
7987 static void testPortPublicKeyInfo(void)
7991 PCERT_PUBLIC_KEY_INFO info = NULL;
7993 /* Just in case a previous run failed, delete this thing */
7994 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7995 CRYPT_DELETEKEYSET);
7996 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7999 testExportPublicKey(csp, &info);
8000 testImportPublicKey(csp, info);
8002 HeapFree(GetProcessHeap(), 0, info);
8003 CryptReleaseContext(csp, 0);
8004 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
8005 CRYPT_DELETEKEYSET);
8010 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
8011 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING };
8015 hCrypt32 = GetModuleHandleA("crypt32.dll");
8016 pCryptDecodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptDecodeObjectEx");
8017 pCryptEncodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptEncodeObjectEx");
8018 if (!pCryptDecodeObjectEx || !pCryptEncodeObjectEx)
8020 win_skip("CryptDecodeObjectEx() is not available\n");
8024 for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++)
8026 test_encodeInt(encodings[i]);
8027 test_decodeInt(encodings[i]);
8028 test_encodeEnumerated(encodings[i]);
8029 test_decodeEnumerated(encodings[i]);
8030 test_encodeFiletime(encodings[i]);
8031 test_decodeFiletime(encodings[i]);
8032 test_encodeName(encodings[i]);
8033 test_decodeName(encodings[i]);
8034 test_encodeUnicodeName(encodings[i]);
8035 test_decodeUnicodeName(encodings[i]);
8036 test_encodeNameValue(encodings[i]);
8037 test_decodeNameValue(encodings[i]);
8038 test_encodeUnicodeNameValue(encodings[i]);
8039 test_decodeUnicodeNameValue(encodings[i]);
8040 test_encodeAltName(encodings[i]);
8041 test_decodeAltName(encodings[i]);
8042 test_encodeOctets(encodings[i]);
8043 test_decodeOctets(encodings[i]);
8044 test_encodeBits(encodings[i]);
8045 test_decodeBits(encodings[i]);
8046 test_encodeBasicConstraints(encodings[i]);
8047 test_decodeBasicConstraints(encodings[i]);
8048 test_encodeRsaPublicKey(encodings[i]);
8049 test_decodeRsaPublicKey(encodings[i]);
8050 test_encodeSequenceOfAny(encodings[i]);
8051 test_decodeSequenceOfAny(encodings[i]);
8052 test_encodeExtensions(encodings[i]);
8053 test_decodeExtensions(encodings[i]);
8054 test_encodePublicKeyInfo(encodings[i]);
8055 test_decodePublicKeyInfo(encodings[i]);
8056 test_encodeCertToBeSigned(encodings[i]);
8057 test_decodeCertToBeSigned(encodings[i]);
8058 test_encodeCert(encodings[i]);
8059 test_decodeCert(encodings[i]);
8060 test_encodeCRLDistPoints(encodings[i]);
8061 test_decodeCRLDistPoints(encodings[i]);
8062 test_encodeCRLIssuingDistPoint(encodings[i]);
8063 test_decodeCRLIssuingDistPoint(encodings[i]);
8064 test_encodeCRLToBeSigned(encodings[i]);
8065 test_decodeCRLToBeSigned(encodings[i]);
8066 test_encodeEnhancedKeyUsage(encodings[i]);
8067 test_decodeEnhancedKeyUsage(encodings[i]);
8068 test_encodeAuthorityKeyId(encodings[i]);
8069 test_decodeAuthorityKeyId(encodings[i]);
8070 test_encodeAuthorityKeyId2(encodings[i]);
8071 test_decodeAuthorityKeyId2(encodings[i]);
8072 test_encodeAuthorityInfoAccess(encodings[i]);
8073 test_decodeAuthorityInfoAccess(encodings[i]);
8074 test_encodeCTL(encodings[i]);
8075 test_decodeCTL(encodings[i]);
8076 test_encodePKCSContentInfo(encodings[i]);
8077 test_decodePKCSContentInfo(encodings[i]);
8078 test_encodePKCSAttribute(encodings[i]);
8079 test_decodePKCSAttribute(encodings[i]);
8080 test_encodePKCSAttributes(encodings[i]);
8081 test_decodePKCSAttributes(encodings[i]);
8082 test_encodePKCSSMimeCapabilities(encodings[i]);
8083 test_decodePKCSSMimeCapabilities(encodings[i]);
8084 test_encodePKCSSignerInfo(encodings[i]);
8085 test_decodePKCSSignerInfo(encodings[i]);
8086 test_encodeCMSSignerInfo(encodings[i]);
8087 test_decodeCMSSignerInfo(encodings[i]);
8088 test_encodeNameConstraints(encodings[i]);
8089 test_decodeNameConstraints(encodings[i]);
8090 test_encodePolicyQualifierUserNotice(encodings[i]);
8091 test_decodePolicyQualifierUserNotice(encodings[i]);
8092 test_encodeCertPolicies(encodings[i]);
8093 test_decodeCertPolicies(encodings[i]);
8094 test_encodeCertPolicyMappings(encodings[i]);
8095 test_decodeCertPolicyMappings(encodings[i]);
8096 test_encodeCertPolicyConstraints(encodings[i]);
8097 test_decodeCertPolicyConstraints(encodings[i]);
8099 testPortPublicKeyInfo();