push 8742e928a3d078c1d2cecb5ceee0ffde3118cbb7
[wine/hacks.git] / dlls / crypt32 / tests / encode.c
blobe08a7ce6f9ca08d937632500fed90f1c207d7ecf
1 /*
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
20 #include <stdio.h>
21 #include <stdarg.h>
22 #include <windef.h>
23 #include <winbase.h>
24 #include <winerror.h>
25 #include <wincrypt.h>
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*);
33 struct encodedInt
35 int val;
36 const BYTE *encoded;
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[] = {
48 { 1, bin1 },
49 { 127, bin2 },
50 { 128, bin3 },
51 { 256, bin4 },
52 { -128, bin5 },
53 { -129, bin6 },
54 { 0xbaddf00d, bin7 },
57 struct encodedBigInt
59 const BYTE *val;
60 const BYTE *encoded;
61 const BYTE *decoded;
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)
90 DWORD bufSize = 0;
91 int i;
92 BOOL ret;
93 CRYPT_INTEGER_BLOB blob;
94 BYTE *buf = NULL;
96 /* CryptEncodeObjectEx with NULL bufSize crashes..
97 ret = pCryptEncodeObjectEx(3, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
98 NULL);
100 /* check bogus encoding */
101 ret = pCryptEncodeObjectEx(0, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
102 &bufSize);
103 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
104 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
105 if (0)
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,
111 &bufSize);
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());
124 if (buf)
126 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
127 buf[0]);
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);
132 LocalFree(buf);
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());
143 if (buf)
145 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
146 buf[0]);
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);
151 LocalFree(buf);
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());
167 if (buf)
169 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
170 buf[0]);
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");
176 LocalFree(buf);
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());
190 if (buf)
192 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
193 buf[0]);
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");
199 LocalFree(buf);
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 };
211 BYTE *buf = NULL;
212 DWORD bufSize = 0;
213 int i;
214 BOOL ret;
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,
227 &bufSize);
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, (BYTE *)&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, (BYTE *)&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",
243 GetLastError());
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,
250 &bufSize);
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, (BYTE *)&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");
259 if (buf)
261 ok(!memcmp(buf, &ints[i].val, bufSize), "Expected %d, got %d\n",
262 ints[i].val, *(int *)buf);
263 LocalFree(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,
270 &bufSize);
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, (BYTE *)&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");
279 if (buf)
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),
285 blob->cbData);
286 ok(!memcmp(blob->pbData, bigInts[i].decoded, blob->cbData),
287 "Unexpected value\n");
288 LocalFree(buf);
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,
295 &bufSize);
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, (BYTE *)&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");
304 if (buf)
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),
310 blob->cbData);
311 ok(!memcmp(blob->pbData, bigUInts[i].val, blob->cbData),
312 "Unexpected value\n");
313 LocalFree(buf);
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, (BYTE *)&buf, &bufSize);
319 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
320 if (buf)
322 ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf);
323 LocalFree(buf);
325 /* check with extra bytes at the end */
326 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, extraBytes,
327 sizeof(extraBytes), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
328 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
329 if (buf)
331 ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf);
332 LocalFree(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, (BYTE *)&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
346 * caught.
348 if (0)
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, (BYTE *)&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
362 * particular value
364 static const struct encodedInt enums[] = {
365 { 1, bin18 },
366 { -128, bin19 },
369 /* X509_CRL_REASON_CODE is also an enumerated type, but it's #defined to
370 * X509_ENUMERATED.
372 static const LPCSTR enumeratedTypes[] = { X509_ENUMERATED,
373 szOID_CRL_REASON_CODE };
375 static void test_encodeEnumerated(DWORD dwEncoding)
377 DWORD i, j;
379 for (i = 0; i < sizeof(enumeratedTypes) / sizeof(enumeratedTypes[0]); i++)
381 for (j = 0; j < sizeof(enums) / sizeof(enums[0]); j++)
383 BOOL ret;
384 BYTE *buf = NULL;
385 DWORD bufSize = 0;
387 ret = pCryptEncodeObjectEx(dwEncoding, enumeratedTypes[i],
388 &enums[j].val, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
389 &bufSize);
390 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
391 if (buf)
393 ok(buf[0] == 0xa,
394 "Got unexpected type %d for enumerated (expected 0xa)\n",
395 buf[0]);
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",
401 enums[j].val);
402 LocalFree(buf);
408 static void test_decodeEnumerated(DWORD dwEncoding)
410 DWORD i, j;
412 for (i = 0; i < sizeof(enumeratedTypes) / sizeof(enumeratedTypes[0]); i++)
414 for (j = 0; j < sizeof(enums) / sizeof(enums[0]); j++)
416 BOOL ret;
417 DWORD bufSize = sizeof(int);
418 int val;
420 ret = pCryptDecodeObjectEx(dwEncoding, enumeratedTypes[i],
421 enums[j].encoded, enums[j].encoded[1] + 2, 0, NULL,
422 (BYTE *)&val, &bufSize);
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",
427 val, enums[j].val);
432 struct encodedFiletime
434 SYSTEMTIME sysTime;
435 const BYTE *encodedTime;
438 static void testTimeEncoding(DWORD dwEncoding, LPCSTR structType,
439 const struct encodedFiletime *time)
441 FILETIME ft = { 0 };
442 BYTE *buf = NULL;
443 DWORD bufSize = 0;
444 BOOL ret;
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, (BYTE *)&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(),
457 GetLastError());
458 ok(buf != NULL, "Expected an allocated buffer\n");
459 if (buf)
461 ok(buf[0] == time->encodedTime[0],
462 "Expected type 0x%02x, got 0x%02x\n", time->encodedTime[0],
463 buf[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");
468 LocalFree(buf);
471 else
472 ok((!ret && GetLastError() == CRYPT_E_BAD_ENCODE) || broken(ret),
473 "Expected CRYPT_E_BAD_ENCODE, got 0x%08x\n", GetLastError());
476 static const char *printSystemTime(const SYSTEMTIME *st)
478 static char buf[25];
480 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st->wMonth, st->wDay,
481 st->wYear, st->wHour, st->wMinute, st->wSecond, st->wMilliseconds);
482 return buf;
485 static const char *printFileTime(const FILETIME *ft)
487 static char buf[25];
488 SYSTEMTIME st;
490 FileTimeToSystemTime(ft, &st);
491 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st.wMonth, st.wDay,
492 st.wYear, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
493 return buf;
496 static void compareTime(const SYSTEMTIME *expected, const FILETIME *got)
498 SYSTEMTIME st;
500 FileTimeToSystemTime(got, &st);
501 ok(expected->wYear == st.wYear &&
502 expected->wMonth == st.wMonth &&
503 expected->wDay == st.wDay &&
504 expected->wHour == st.wHour &&
505 expected->wMinute == st.wMinute &&
506 expected->wSecond == st.wSecond &&
507 abs(expected->wMilliseconds - st.wMilliseconds) <= 1,
508 "Got unexpected value for time decoding:\nexpected %s, got %s\n",
509 printSystemTime(expected), printFileTime(got));
512 static void testTimeDecoding(DWORD dwEncoding, LPCSTR structType,
513 const struct encodedFiletime *time)
515 FILETIME ft = { 0 };
516 DWORD size = sizeof(ft);
517 BOOL ret;
519 ret = pCryptDecodeObjectEx(dwEncoding, structType, time->encodedTime,
520 time->encodedTime[1] + 2, 0, NULL, &ft, &size);
521 /* years other than 1950-2050 are not allowed for encodings other than
522 * X509_CHOICE_OF_TIME.
524 if (structType == X509_CHOICE_OF_TIME ||
525 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050))
527 ok(ret, "CryptDecodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
528 GetLastError());
529 if (ret)
530 compareTime(&time->sysTime, &ft);
532 else
533 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
534 GetLastError() == OSS_PDU_MISMATCH /* Win9x */ ),
535 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %08x\n",
536 GetLastError());
539 static const BYTE bin20[] = {
540 0x17,0x0d,'0','5','0','6','0','6','1','6','1','0','0','0','Z'};
541 static const BYTE bin21[] = {
542 0x18,0x0f,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
543 static const BYTE bin22[] = {
544 0x18,0x0f,'2','1','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
546 static const struct encodedFiletime times[] = {
547 { { 2005, 6, 1, 6, 16, 10, 0, 0 }, bin20 },
548 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin21 },
549 { { 2145, 6, 1, 6, 16, 10, 0, 0 }, bin22 },
552 static void test_encodeFiletime(DWORD dwEncoding)
554 DWORD i;
556 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
558 testTimeEncoding(dwEncoding, X509_CHOICE_OF_TIME, &times[i]);
559 testTimeEncoding(dwEncoding, PKCS_UTC_TIME, &times[i]);
560 testTimeEncoding(dwEncoding, szOID_RSA_signingTime, &times[i]);
564 static const BYTE bin23[] = {
565 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','0','0','0','Z'};
566 static const BYTE bin24[] = {
567 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','9','9','9','Z'};
568 static const BYTE bin25[] = {
569 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','+','0','1','0','0'};
570 static const BYTE bin26[] = {
571 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','0','0'};
572 static const BYTE bin27[] = {
573 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','1','5'};
574 static const BYTE bin28[] = {
575 0x18,0x0a,'2','1','4','5','0','6','0','6','1','6'};
576 static const BYTE bin29[] = {
577 0x17,0x0a,'4','5','0','6','0','6','1','6','1','0'};
578 static const BYTE bin30[] = {
579 0x17,0x0b,'4','5','0','6','0','6','1','6','1','0','Z'};
580 static const BYTE bin31[] = {
581 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','+','0','1'};
582 static const BYTE bin32[] = {
583 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','-','0','1'};
584 static const BYTE bin33[] = {
585 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','+','0','1','0','0'};
586 static const BYTE bin34[] = {
587 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','-','0','1','0','0'};
588 static const BYTE bin35[] = {
589 0x17,0x08, '4','5','0','6','0','6','1','6'};
590 static const BYTE bin36[] = {
591 0x18,0x0f, 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','Z'};
592 static const BYTE bin37[] = {
593 0x18,0x04, '2','1','4','5'};
594 static const BYTE bin38[] = {
595 0x18,0x08, '2','1','4','5','0','6','0','6'};
597 static void test_decodeFiletime(DWORD dwEncoding)
599 static const struct encodedFiletime otherTimes[] = {
600 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin23 },
601 { { 1945, 6, 1, 6, 16, 10, 0, 999 }, bin24 },
602 { { 1945, 6, 1, 6, 17, 10, 0, 0 }, bin25 },
603 { { 1945, 6, 1, 6, 15, 10, 0, 0 }, bin26 },
604 { { 1945, 6, 1, 6, 14, 55, 0, 0 }, bin27 },
605 { { 2145, 6, 1, 6, 16, 0, 0, 0 }, bin28 },
606 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin29 },
607 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin30 },
608 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin31 },
609 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin32 },
610 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin33 },
611 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin34 },
613 /* An oddball case that succeeds in Windows, but doesn't seem correct
614 { { 2145, 6, 1, 2, 11, 31, 0, 0 }, "\x18" "\x13" "21450606161000-9999" },
616 static const unsigned char *bogusTimes[] = {
617 /* oddly, this succeeds on Windows, with year 2765
618 "\x18" "\x0f" "21r50606161000Z",
620 bin35,
621 bin36,
622 bin37,
623 bin38,
625 DWORD i, size;
626 FILETIME ft1 = { 0 }, ft2 = { 0 };
627 BOOL ret;
629 /* Check bogus length with non-NULL buffer */
630 ret = SystemTimeToFileTime(&times[0].sysTime, &ft1);
631 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
632 size = 1;
633 ret = pCryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
634 times[0].encodedTime, times[0].encodedTime[1] + 2, 0, NULL, &ft2, &size);
635 ok(!ret && GetLastError() == ERROR_MORE_DATA,
636 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
637 /* Normal tests */
638 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
640 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &times[i]);
641 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &times[i]);
642 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &times[i]);
644 for (i = 0; i < sizeof(otherTimes) / sizeof(otherTimes[0]); i++)
646 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &otherTimes[i]);
647 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &otherTimes[i]);
648 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &otherTimes[i]);
650 for (i = 0; i < sizeof(bogusTimes) / sizeof(bogusTimes[0]); i++)
652 size = sizeof(ft1);
653 ret = pCryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
654 bogusTimes[i], bogusTimes[i][1] + 2, 0, NULL, &ft1, &size);
655 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
656 GetLastError() == OSS_DATA_ERROR /* Win9x */),
657 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
658 GetLastError());
662 static const char commonName[] = "Juan Lang";
663 static const char surName[] = "Lang";
665 static const BYTE emptySequence[] = { 0x30, 0 };
666 static const BYTE emptyRDNs[] = { 0x30, 0x02, 0x31, 0 };
667 static const BYTE twoRDNs[] = {
668 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
669 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
670 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0};
671 static const BYTE encodedTwoRDNs[] = {
672 0x30,0x2e,0x31,0x2c,0x30,0x2a,0x06,0x03,0x55,0x04,0x03,0x30,0x23,0x31,0x21,
673 0x30,0x0c,0x06,0x03,0x55,0x04,0x04,0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,
674 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
675 0x6e,0x67,0x00,
678 static const BYTE us[] = { 0x55, 0x53 };
679 static const BYTE minnesota[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x73, 0x6f,
680 0x74, 0x61 };
681 static const BYTE minneapolis[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x61, 0x70,
682 0x6f, 0x6c, 0x69, 0x73 };
683 static const BYTE codeweavers[] = { 0x43, 0x6f, 0x64, 0x65, 0x57, 0x65, 0x61,
684 0x76, 0x65, 0x72, 0x73 };
685 static const BYTE wine[] = { 0x57, 0x69, 0x6e, 0x65, 0x20, 0x44, 0x65, 0x76,
686 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74 };
687 static const BYTE localhostAttr[] = { 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
688 0x73, 0x74 };
689 static const BYTE aric[] = { 0x61, 0x72, 0x69, 0x63, 0x40, 0x63, 0x6f, 0x64,
690 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d };
692 #define RDNA(arr) oid_ ## arr, CERT_RDN_PRINTABLE_STRING, { sizeof(arr), (LPBYTE)arr }
693 #define RDNIA5(arr) oid_ ## arr, CERT_RDN_IA5_STRING, { sizeof(arr), (LPBYTE)arr }
695 static CHAR oid_us[] = "2.5.4.6",
696 oid_minnesota[] = "2.5.4.8",
697 oid_minneapolis[] = "2.5.4.7",
698 oid_codeweavers[] = "2.5.4.10",
699 oid_wine[] = "2.5.4.11",
700 oid_localhostAttr[] = "2.5.4.3",
701 oid_aric[] = "1.2.840.113549.1.9.1";
702 static CERT_RDN_ATTR rdnAttrs[] = { { RDNA(us) },
703 { RDNA(minnesota) },
704 { RDNA(minneapolis) },
705 { RDNA(codeweavers) },
706 { RDNA(wine) },
707 { RDNA(localhostAttr) },
708 { RDNIA5(aric) } };
709 static CERT_RDN_ATTR decodedRdnAttrs[] = { { RDNA(us) },
710 { RDNA(localhostAttr) },
711 { RDNA(minnesota) },
712 { RDNA(minneapolis) },
713 { RDNA(codeweavers) },
714 { RDNA(wine) },
715 { RDNIA5(aric) } };
717 #undef RDNIA5
718 #undef RDNA
720 static const BYTE encodedRDNAttrs[] = {
721 0x30,0x81,0x96,0x31,0x81,0x93,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
722 0x53,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x68,
723 0x6f,0x73,0x74,0x30,0x10,0x06,0x03,0x55,0x04,0x08,0x13,0x09,0x4d,0x69,0x6e,0x6e,
724 0x65,0x73,0x6f,0x74,0x61,0x30,0x12,0x06,0x03,0x55,0x04,0x07,0x13,0x0b,0x4d,0x69,
725 0x6e,0x6e,0x65,0x61,0x70,0x6f,0x6c,0x69,0x73,0x30,0x12,0x06,0x03,0x55,0x04,0x0a,
726 0x13,0x0b,0x43,0x6f,0x64,0x65,0x57,0x65,0x61,0x76,0x65,0x72,0x73,0x30,0x17,0x06,
727 0x03,0x55,0x04,0x0b,0x13,0x10,0x57,0x69,0x6e,0x65,0x20,0x44,0x65,0x76,0x65,0x6c,
728 0x6f,0x70,0x6d,0x65,0x6e,0x74,0x30,0x21,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
729 0x01,0x09,0x01,0x16,0x14,0x61,0x72,0x69,0x63,0x40,0x63,0x6f,0x64,0x65,0x77,0x65,
730 0x61,0x76,0x65,0x72,0x73,0x2e,0x63,0x6f,0x6d
733 static void test_encodeName(DWORD dwEncoding)
735 CERT_RDN_ATTR attrs[2];
736 CERT_RDN rdn;
737 CERT_NAME_INFO info;
738 static CHAR oid_common_name[] = szOID_COMMON_NAME,
739 oid_sur_name[] = szOID_SUR_NAME;
740 BYTE *buf = NULL;
741 DWORD size = 0;
742 BOOL ret;
744 if (0)
746 /* Test with NULL pvStructInfo (crashes on win9x) */
747 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, NULL,
748 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
749 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
750 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
752 /* Test with empty CERT_NAME_INFO */
753 info.cRDN = 0;
754 info.rgRDN = NULL;
755 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
756 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
757 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
758 if (buf)
760 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
761 "Got unexpected encoding for empty name\n");
762 LocalFree(buf);
764 if (0)
766 /* Test with bogus CERT_RDN (crashes on win9x) */
767 info.cRDN = 1;
768 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
769 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
770 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
771 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
773 /* Test with empty CERT_RDN */
774 rdn.cRDNAttr = 0;
775 rdn.rgRDNAttr = NULL;
776 info.cRDN = 1;
777 info.rgRDN = &rdn;
778 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
779 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
780 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
781 if (buf)
783 ok(!memcmp(buf, emptyRDNs, sizeof(emptyRDNs)),
784 "Got unexpected encoding for empty RDN array\n");
785 LocalFree(buf);
787 if (0)
789 /* Test with bogus attr array (crashes on win9x) */
790 rdn.cRDNAttr = 1;
791 rdn.rgRDNAttr = NULL;
792 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
793 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
794 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
795 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
797 /* oddly, a bogus OID is accepted by Windows XP; not testing.
798 attrs[0].pszObjId = "bogus";
799 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
800 attrs[0].Value.cbData = sizeof(commonName);
801 attrs[0].Value.pbData = (BYTE *)commonName;
802 rdn.cRDNAttr = 1;
803 rdn.rgRDNAttr = attrs;
804 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
805 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
806 ok(!ret, "Expected failure, got success\n");
808 /* Check with two CERT_RDN_ATTRs. Note DER encoding forces the order of
809 * the encoded attributes to be swapped.
811 attrs[0].pszObjId = oid_common_name;
812 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
813 attrs[0].Value.cbData = sizeof(commonName);
814 attrs[0].Value.pbData = (BYTE *)commonName;
815 attrs[1].pszObjId = oid_sur_name;
816 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
817 attrs[1].Value.cbData = sizeof(surName);
818 attrs[1].Value.pbData = (BYTE *)surName;
819 rdn.cRDNAttr = 2;
820 rdn.rgRDNAttr = attrs;
821 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
822 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
823 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
824 if (buf)
826 ok(!memcmp(buf, twoRDNs, sizeof(twoRDNs)),
827 "Got unexpected encoding for two RDN array\n");
828 LocalFree(buf);
830 /* A name can be "encoded" with previously encoded RDN attrs. */
831 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
832 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
833 attrs[0].Value.cbData = sizeof(twoRDNs);
834 rdn.cRDNAttr = 1;
835 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
836 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
837 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
838 if (buf)
840 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
841 ok(!memcmp(buf, encodedTwoRDNs, size),
842 "Unexpected value for re-endoded two RDN array\n");
843 LocalFree(buf);
845 /* CERT_RDN_ANY_TYPE is too vague for X509_NAMEs, check the return */
846 rdn.cRDNAttr = 1;
847 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
848 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
849 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
850 ok(!ret && GetLastError() == E_INVALIDARG,
851 "Expected E_INVALIDARG, got %08x\n", GetLastError());
852 /* Test a more complex name */
853 rdn.cRDNAttr = sizeof(rdnAttrs) / sizeof(rdnAttrs[0]);
854 rdn.rgRDNAttr = (PCERT_RDN_ATTR)rdnAttrs;
855 info.cRDN = 1;
856 info.rgRDN = &rdn;
857 buf = NULL;
858 size = 0;
859 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, X509_NAME, &info,
860 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
861 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
862 if (ret)
864 ok(size == sizeof(encodedRDNAttrs), "Wrong size %d\n", size);
865 ok(!memcmp(buf, encodedRDNAttrs, size), "Unexpected value\n");
866 LocalFree(buf);
870 static WCHAR commonNameW[] = { 'J','u','a','n',' ','L','a','n','g',0 };
871 static WCHAR surNameW[] = { 'L','a','n','g',0 };
873 static const BYTE twoRDNsNoNull[] = {
874 0x30,0x21,0x31,0x1f,0x30,0x0b,0x06,0x03,0x55,0x04,0x04,0x13,0x04,0x4c,0x61,
875 0x6e,0x67,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,
876 0x20,0x4c,0x61,0x6e,0x67 };
877 static const BYTE anyType[] = {
878 0x30,0x2f,0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x1e,0x24,0x23,0x30,
879 0x21,0x31,0x0c,0x30,0x03,0x06,0x04,0x55,0x13,0x04,0x4c,0x05,0x6e,0x61,0x00,
880 0x67,0x11,0x30,0x03,0x06,0x04,0x55,0x13,0x03,0x4a,0x0a,0x61,0x75,0x20,0x6e,
881 0x61,0x4c,0x67,0x6e };
883 static void test_encodeUnicodeName(DWORD dwEncoding)
885 CERT_RDN_ATTR attrs[2];
886 CERT_RDN rdn;
887 CERT_NAME_INFO info;
888 static CHAR oid_common_name[] = szOID_COMMON_NAME,
889 oid_sur_name[] = szOID_SUR_NAME;
890 BYTE *buf = NULL;
891 DWORD size = 0;
892 BOOL ret;
894 if (0)
896 /* Test with NULL pvStructInfo (crashes on win9x) */
897 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, NULL,
898 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
899 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
900 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
902 /* Test with empty CERT_NAME_INFO */
903 info.cRDN = 0;
904 info.rgRDN = NULL;
905 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
906 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
907 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
908 if (buf)
910 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
911 "Got unexpected encoding for empty name\n");
912 LocalFree(buf);
914 /* Check with one CERT_RDN_ATTR, that has an invalid character for the
915 * encoding (the NULL).
917 attrs[0].pszObjId = oid_common_name;
918 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
919 attrs[0].Value.cbData = sizeof(commonNameW);
920 attrs[0].Value.pbData = (BYTE *)commonNameW;
921 rdn.cRDNAttr = 1;
922 rdn.rgRDNAttr = attrs;
923 info.cRDN = 1;
924 info.rgRDN = &rdn;
925 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
926 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
927 ok(!ret && GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING,
928 "Expected CRYPT_E_INVALID_PRINTABLE_STRING, got %08x\n", GetLastError());
929 ok(size == 9, "Unexpected error index %08x\n", size);
930 /* Check with two NULL-terminated CERT_RDN_ATTRs. Note DER encoding
931 * forces the order of the encoded attributes to be swapped.
933 attrs[0].pszObjId = oid_common_name;
934 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
935 attrs[0].Value.cbData = 0;
936 attrs[0].Value.pbData = (BYTE *)commonNameW;
937 attrs[1].pszObjId = oid_sur_name;
938 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
939 attrs[1].Value.cbData = 0;
940 attrs[1].Value.pbData = (BYTE *)surNameW;
941 rdn.cRDNAttr = 2;
942 rdn.rgRDNAttr = attrs;
943 info.cRDN = 1;
944 info.rgRDN = &rdn;
945 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
946 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
947 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
948 if (buf)
950 ok(!memcmp(buf, twoRDNsNoNull, sizeof(twoRDNsNoNull)),
951 "Got unexpected encoding for two RDN array\n");
952 LocalFree(buf);
954 /* A name can be "encoded" with previously encoded RDN attrs. */
955 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
956 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
957 attrs[0].Value.cbData = sizeof(twoRDNs);
958 rdn.cRDNAttr = 1;
959 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
960 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
961 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
962 if (buf)
964 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
965 ok(!memcmp(buf, encodedTwoRDNs, size),
966 "Unexpected value for re-endoded two RDN array\n");
967 LocalFree(buf);
969 /* Unicode names infer the type for CERT_RDN_ANY_TYPE */
970 rdn.cRDNAttr = 1;
971 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
972 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
973 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
974 todo_wine ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
975 if (buf)
977 ok(size == sizeof(anyType), "Unexpected size %d\n", size);
978 ok(!memcmp(buf, anyType, size), "Unexpected value\n");
979 LocalFree(buf);
983 static void compareNameValues(const CERT_NAME_VALUE *expected,
984 const CERT_NAME_VALUE *got)
986 ok(got->dwValueType == expected->dwValueType,
987 "Expected string type %d, got %d\n", expected->dwValueType,
988 got->dwValueType);
989 ok(got->Value.cbData == expected->Value.cbData,
990 "String type %d: unexpected data size, got %d, expected %d\n",
991 expected->dwValueType, got->Value.cbData, expected->Value.cbData);
992 if (got->Value.cbData && got->Value.pbData)
993 ok(!memcmp(got->Value.pbData, expected->Value.pbData,
994 min(got->Value.cbData, expected->Value.cbData)),
995 "String type %d: unexpected value\n", expected->dwValueType);
998 static void compareRDNAttrs(const CERT_RDN_ATTR *expected,
999 const CERT_RDN_ATTR *got)
1001 if (expected->pszObjId && strlen(expected->pszObjId))
1003 ok(got->pszObjId != NULL, "Expected OID %s, got NULL\n",
1004 expected->pszObjId);
1005 if (got->pszObjId)
1007 ok(!strcmp(got->pszObjId, expected->pszObjId),
1008 "Got unexpected OID %s, expected %s\n", got->pszObjId,
1009 expected->pszObjId);
1012 compareNameValues((const CERT_NAME_VALUE *)&expected->dwValueType,
1013 (const CERT_NAME_VALUE *)&got->dwValueType);
1016 static void compareRDNs(const CERT_RDN *expected, const CERT_RDN *got)
1018 ok(got->cRDNAttr == expected->cRDNAttr,
1019 "Expected %d RDN attrs, got %d\n", expected->cRDNAttr, got->cRDNAttr);
1020 if (got->cRDNAttr)
1022 DWORD i;
1024 for (i = 0; i < got->cRDNAttr; i++)
1025 compareRDNAttrs(&expected->rgRDNAttr[i], &got->rgRDNAttr[i]);
1029 static void compareNames(const CERT_NAME_INFO *expected,
1030 const CERT_NAME_INFO *got)
1032 ok(got->cRDN == expected->cRDN, "Expected %d RDNs, got %d\n",
1033 expected->cRDN, got->cRDN);
1034 if (got->cRDN)
1036 DWORD i;
1038 for (i = 0; i < got->cRDN; i++)
1039 compareRDNs(&expected->rgRDN[i], &got->rgRDN[i]);
1043 static const BYTE emptyIndefiniteSequence[] = { 0x30,0x80,0x00,0x00 };
1044 static const BYTE twoRDNsExtraBytes[] = {
1045 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
1046 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1047 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0,0,0,0,0,0};
1049 static void test_decodeName(DWORD dwEncoding)
1051 BYTE *buf = NULL;
1052 DWORD bufSize = 0;
1053 BOOL ret;
1054 CERT_RDN rdn;
1055 CERT_NAME_INFO info = { 1, &rdn };
1057 /* test empty name */
1058 bufSize = 0;
1059 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptySequence,
1060 emptySequence[1] + 2,
1061 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1062 (BYTE *)&buf, &bufSize);
1063 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1064 /* Interestingly, in Windows, if cRDN is 0, rgRGN may not be NULL. My
1065 * decoder works the same way, so only test the count.
1067 if (buf)
1069 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1070 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1071 "Expected 0 RDNs in empty info, got %d\n",
1072 ((CERT_NAME_INFO *)buf)->cRDN);
1073 LocalFree(buf);
1075 /* test empty name with indefinite-length encoding */
1076 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyIndefiniteSequence,
1077 sizeof(emptyIndefiniteSequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
1078 (BYTE *)&buf, &bufSize);
1079 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1080 if (ret)
1082 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1083 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1084 "Expected 0 RDNs in empty info, got %d\n",
1085 ((CERT_NAME_INFO *)buf)->cRDN);
1086 LocalFree(buf);
1088 /* test empty RDN */
1089 bufSize = 0;
1090 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyRDNs,
1091 emptyRDNs[1] + 2,
1092 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1093 (BYTE *)&buf, &bufSize);
1094 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1095 if (buf)
1097 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1099 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1100 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1101 "Got unexpected value for empty RDN\n");
1102 LocalFree(buf);
1104 /* test two RDN attrs */
1105 bufSize = 0;
1106 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNs,
1107 twoRDNs[1] + 2,
1108 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1109 (BYTE *)&buf, &bufSize);
1110 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1111 if (buf)
1113 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1114 oid_common_name[] = szOID_COMMON_NAME;
1116 CERT_RDN_ATTR attrs[] = {
1117 { oid_sur_name, CERT_RDN_PRINTABLE_STRING, { sizeof(surName),
1118 (BYTE *)surName } },
1119 { oid_common_name, CERT_RDN_PRINTABLE_STRING, { sizeof(commonName),
1120 (BYTE *)commonName } },
1123 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1124 rdn.rgRDNAttr = attrs;
1125 compareNames(&info, (CERT_NAME_INFO *)buf);
1126 LocalFree(buf);
1128 /* test that two RDN attrs with extra bytes succeeds */
1129 bufSize = 0;
1130 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNsExtraBytes,
1131 sizeof(twoRDNsExtraBytes), 0, NULL, NULL, &bufSize);
1132 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1133 /* And, a slightly more complicated name */
1134 buf = NULL;
1135 bufSize = 0;
1136 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME, encodedRDNAttrs,
1137 sizeof(encodedRDNAttrs), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1138 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1139 if (ret)
1141 rdn.cRDNAttr = sizeof(decodedRdnAttrs) / sizeof(decodedRdnAttrs[0]);
1142 rdn.rgRDNAttr = (PCERT_RDN_ATTR)decodedRdnAttrs;
1143 compareNames(&info, (CERT_NAME_INFO *)buf);
1144 LocalFree(buf);
1148 static void test_decodeUnicodeName(DWORD dwEncoding)
1150 BYTE *buf = NULL;
1151 DWORD bufSize = 0;
1152 BOOL ret;
1153 CERT_RDN rdn;
1154 CERT_NAME_INFO info = { 1, &rdn };
1156 /* test empty name */
1157 bufSize = 0;
1158 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptySequence,
1159 emptySequence[1] + 2,
1160 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1161 (BYTE *)&buf, &bufSize);
1162 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1163 if (buf)
1165 ok(bufSize == sizeof(CERT_NAME_INFO),
1166 "Got wrong bufSize %d\n", bufSize);
1167 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1168 "Expected 0 RDNs in empty info, got %d\n",
1169 ((CERT_NAME_INFO *)buf)->cRDN);
1170 LocalFree(buf);
1172 /* test empty RDN */
1173 bufSize = 0;
1174 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptyRDNs,
1175 emptyRDNs[1] + 2,
1176 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1177 (BYTE *)&buf, &bufSize);
1178 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1179 if (buf)
1181 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1183 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1184 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1185 "Got unexpected value for empty RDN\n");
1186 LocalFree(buf);
1188 /* test two RDN attrs */
1189 bufSize = 0;
1190 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, twoRDNsNoNull,
1191 sizeof(twoRDNsNoNull),
1192 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1193 (BYTE *)&buf, &bufSize);
1194 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1195 if (buf)
1197 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1198 oid_common_name[] = szOID_COMMON_NAME;
1200 CERT_RDN_ATTR attrs[] = {
1201 { oid_sur_name, CERT_RDN_PRINTABLE_STRING,
1202 { lstrlenW(surNameW) * sizeof(WCHAR), (BYTE *)surNameW } },
1203 { oid_common_name, CERT_RDN_PRINTABLE_STRING,
1204 { lstrlenW(commonNameW) * sizeof(WCHAR), (BYTE *)commonNameW } },
1207 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1208 rdn.rgRDNAttr = attrs;
1209 compareNames(&info, (CERT_NAME_INFO *)buf);
1210 LocalFree(buf);
1214 struct EncodedNameValue
1216 CERT_NAME_VALUE value;
1217 const BYTE *encoded;
1218 DWORD encodedSize;
1221 static const char bogusIA5[] = "\x80";
1222 static const char bogusPrintable[] = "~";
1223 static const char bogusNumeric[] = "A";
1224 static const BYTE bin42[] = { 0x16,0x02,0x80,0x00 };
1225 static const BYTE bin43[] = { 0x13,0x02,0x7e,0x00 };
1226 static const BYTE bin44[] = { 0x12,0x02,0x41,0x00 };
1227 static BYTE octetCommonNameValue[] = {
1228 0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1229 static BYTE numericCommonNameValue[] = {
1230 0x12,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1231 static BYTE printableCommonNameValue[] = {
1232 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1233 static BYTE t61CommonNameValue[] = {
1234 0x14,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1235 static BYTE videotexCommonNameValue[] = {
1236 0x15,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1237 static BYTE ia5CommonNameValue[] = {
1238 0x16,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1239 static BYTE graphicCommonNameValue[] = {
1240 0x19,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1241 static BYTE visibleCommonNameValue[] = {
1242 0x1a,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1243 static BYTE generalCommonNameValue[] = {
1244 0x1b,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1245 static BYTE bmpCommonNameValue[] = {
1246 0x1e,0x14,0x00,0x4a,0x00,0x75,0x00,0x61,0x00,0x6e,0x00,0x20,0x00,0x4c,0x00,
1247 0x61,0x00,0x6e,0x00,0x67,0x00,0x00 };
1248 static BYTE utf8CommonNameValue[] = {
1249 0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1251 static struct EncodedNameValue nameValues[] = {
1252 { { CERT_RDN_OCTET_STRING, { sizeof(commonName), (BYTE *)commonName } },
1253 octetCommonNameValue, sizeof(octetCommonNameValue) },
1254 { { CERT_RDN_NUMERIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1255 numericCommonNameValue, sizeof(numericCommonNameValue) },
1256 { { CERT_RDN_PRINTABLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1257 printableCommonNameValue, sizeof(printableCommonNameValue) },
1258 { { CERT_RDN_T61_STRING, { sizeof(commonName), (BYTE *)commonName } },
1259 t61CommonNameValue, sizeof(t61CommonNameValue) },
1260 { { CERT_RDN_VIDEOTEX_STRING, { sizeof(commonName), (BYTE *)commonName } },
1261 videotexCommonNameValue, sizeof(videotexCommonNameValue) },
1262 { { CERT_RDN_IA5_STRING, { sizeof(commonName), (BYTE *)commonName } },
1263 ia5CommonNameValue, sizeof(ia5CommonNameValue) },
1264 { { CERT_RDN_GRAPHIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1265 graphicCommonNameValue, sizeof(graphicCommonNameValue) },
1266 { { CERT_RDN_VISIBLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1267 visibleCommonNameValue, sizeof(visibleCommonNameValue) },
1268 { { CERT_RDN_GENERAL_STRING, { sizeof(commonName), (BYTE *)commonName } },
1269 generalCommonNameValue, sizeof(generalCommonNameValue) },
1270 { { CERT_RDN_BMP_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1271 bmpCommonNameValue, sizeof(bmpCommonNameValue) },
1272 { { CERT_RDN_UTF8_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1273 utf8CommonNameValue, sizeof(utf8CommonNameValue) },
1274 /* The following tests succeed under Windows, but really should fail,
1275 * they contain characters that are illegal for the encoding. I'm
1276 * including them to justify my lazy encoding.
1278 { { CERT_RDN_IA5_STRING, { sizeof(bogusIA5), (BYTE *)bogusIA5 } }, bin42,
1279 sizeof(bin42) },
1280 { { CERT_RDN_PRINTABLE_STRING, { sizeof(bogusPrintable),
1281 (BYTE *)bogusPrintable } }, bin43, sizeof(bin43) },
1282 { { CERT_RDN_NUMERIC_STRING, { sizeof(bogusNumeric), (BYTE *)bogusNumeric } },
1283 bin44, sizeof(bin44) },
1286 static void test_encodeNameValue(DWORD dwEncoding)
1288 BYTE *buf = NULL;
1289 DWORD size = 0, i;
1290 BOOL ret;
1291 CERT_NAME_VALUE value = { 0, { 0, NULL } };
1293 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1294 value.Value.pbData = printableCommonNameValue;
1295 value.Value.cbData = sizeof(printableCommonNameValue);
1296 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, &value,
1297 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1298 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1299 if (buf)
1301 ok(size == sizeof(printableCommonNameValue), "Unexpected size %d\n",
1302 size);
1303 ok(!memcmp(buf, printableCommonNameValue, size),
1304 "Unexpected encoding\n");
1305 LocalFree(buf);
1307 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1309 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE,
1310 &nameValues[i].value, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1311 &size);
1312 ok(ret, "Type %d: CryptEncodeObjectEx failed: %08x\n",
1313 nameValues[i].value.dwValueType, GetLastError());
1314 if (buf)
1316 ok(size == nameValues[i].encodedSize,
1317 "Expected size %d, got %d\n", nameValues[i].encodedSize, size);
1318 ok(!memcmp(buf, nameValues[i].encoded, size),
1319 "Got unexpected encoding\n");
1320 LocalFree(buf);
1325 static void test_decodeNameValue(DWORD dwEncoding)
1327 int i;
1328 BYTE *buf = NULL;
1329 DWORD bufSize = 0;
1330 BOOL ret;
1332 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1334 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE,
1335 nameValues[i].encoded, nameValues[i].encoded[1] + 2,
1336 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1337 (BYTE *)&buf, &bufSize);
1338 ok(ret, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
1339 nameValues[i].value.dwValueType, GetLastError());
1340 if (buf)
1342 compareNameValues(&nameValues[i].value,
1343 (const CERT_NAME_VALUE *)buf);
1344 LocalFree(buf);
1349 static const BYTE emptyURL[] = { 0x30, 0x02, 0x86, 0x00 };
1350 static const BYTE emptyURLExtraBytes[] = { 0x30, 0x02, 0x86, 0x00, 0, 0, 0 };
1351 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e',
1352 'h','q','.','o','r','g',0 };
1353 static const BYTE encodedURL[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74,
1354 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e,
1355 0x6f, 0x72, 0x67 };
1356 static const WCHAR nihongoURL[] = { 'h','t','t','p',':','/','/',0x226f,
1357 0x575b, 0 };
1358 static const WCHAR dnsName[] = { 'w','i','n','e','h','q','.','o','r','g',0 };
1359 static const BYTE encodedDnsName[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69,
1360 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
1361 static const BYTE localhost[] = { 127, 0, 0, 1 };
1362 static const BYTE encodedIPAddr[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00,
1363 0x01 };
1364 static const unsigned char encodedCommonName[] = {
1365 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0};
1366 static const BYTE encodedOidName[] = { 0x30,0x04,0x88,0x02,0x2a,0x03 };
1367 static const BYTE encodedDirectoryName[] = {
1368 0x30,0x19,0xa4,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1369 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1371 static void test_encodeAltName(DWORD dwEncoding)
1373 CERT_ALT_NAME_INFO info = { 0 };
1374 CERT_ALT_NAME_ENTRY entry = { 0 };
1375 BYTE *buf = NULL;
1376 DWORD size = 0;
1377 BOOL ret;
1378 char oid[] = "1.2.3";
1380 /* Test with empty info */
1381 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1382 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1383 if (buf)
1385 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
1386 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
1387 LocalFree(buf);
1389 /* Test with an empty entry */
1390 info.cAltEntry = 1;
1391 info.rgAltEntry = &entry;
1392 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1393 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1394 ok(!ret && GetLastError() == E_INVALIDARG,
1395 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1396 /* Test with an empty pointer */
1397 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
1398 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1399 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1400 if (buf)
1402 ok(size == sizeof(emptyURL), "Wrong size %d\n", size);
1403 ok(!memcmp(buf, emptyURL, size), "Unexpected value\n");
1404 LocalFree(buf);
1406 /* Test with a real URL */
1407 U(entry).pwszURL = (LPWSTR)url;
1408 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1409 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1410 if (buf)
1412 ok(size == sizeof(encodedURL), "Wrong size %d\n", size);
1413 ok(!memcmp(buf, encodedURL, size), "Unexpected value\n");
1414 LocalFree(buf);
1416 /* Now with the URL containing an invalid IA5 char */
1417 U(entry).pwszURL = (LPWSTR)nihongoURL;
1418 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1419 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1420 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
1421 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
1422 /* The first invalid character is at index 7 */
1423 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
1424 "Expected invalid char at index 7, got %d\n",
1425 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
1426 /* Now with the URL missing a scheme */
1427 U(entry).pwszURL = (LPWSTR)dnsName;
1428 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1429 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1430 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1431 if (buf)
1433 /* This succeeds, but it shouldn't, so don't worry about conforming */
1434 LocalFree(buf);
1436 /* Now with a DNS name */
1437 entry.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
1438 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1439 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1440 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1441 if (buf)
1443 ok(size == sizeof(encodedDnsName), "Wrong size %d\n", size);
1444 ok(!memcmp(buf, encodedDnsName, size), "Unexpected value\n");
1445 LocalFree(buf);
1447 /* Test with an IP address */
1448 entry.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
1449 U(entry).IPAddress.cbData = sizeof(localhost);
1450 U(entry).IPAddress.pbData = (LPBYTE)localhost;
1451 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1452 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1453 if (buf)
1455 ok(size == sizeof(encodedIPAddr), "Wrong size %d\n", size);
1456 ok(!memcmp(buf, encodedIPAddr, size), "Unexpected value\n");
1457 LocalFree(buf);
1459 /* Test with OID */
1460 entry.dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID;
1461 U(entry).pszRegisteredID = oid;
1462 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1463 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1464 if (buf)
1466 ok(size == sizeof(encodedOidName), "Wrong size %d\n", size);
1467 ok(!memcmp(buf, encodedOidName, size), "Unexpected value\n");
1468 LocalFree(buf);
1470 /* Test with directory name */
1471 entry.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
1472 U(entry).DirectoryName.cbData = sizeof(encodedCommonName);
1473 U(entry).DirectoryName.pbData = (LPBYTE)encodedCommonName;
1474 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1475 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1476 if (buf)
1478 ok(size == sizeof(encodedDirectoryName), "Wrong size %d\n", size);
1479 ok(!memcmp(buf, encodedDirectoryName, size), "Unexpected value\n");
1480 LocalFree(buf);
1484 static void test_decodeAltName(DWORD dwEncoding)
1486 static const BYTE unimplementedType[] = { 0x30, 0x06, 0x85, 0x04, 0x7f,
1487 0x00, 0x00, 0x01 };
1488 static const BYTE bogusType[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00,
1489 0x01 };
1490 BOOL ret;
1491 BYTE *buf = NULL;
1492 DWORD bufSize = 0;
1493 CERT_ALT_NAME_INFO *info;
1495 /* Test some bogus ones first */
1496 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1497 unimplementedType, sizeof(unimplementedType), CRYPT_DECODE_ALLOC_FLAG,
1498 NULL, (BYTE *)&buf, &bufSize);
1499 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
1500 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1501 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
1502 GetLastError());
1503 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1504 bogusType, sizeof(bogusType), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1505 &bufSize);
1506 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
1507 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1508 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
1509 GetLastError());
1510 /* Now expected cases */
1511 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptySequence,
1512 emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1513 &bufSize);
1514 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1515 if (buf)
1517 info = (CERT_ALT_NAME_INFO *)buf;
1519 ok(info->cAltEntry == 0, "Expected 0 entries, got %d\n",
1520 info->cAltEntry);
1521 LocalFree(buf);
1523 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptyURL,
1524 emptyURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1525 &bufSize);
1526 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1527 if (buf)
1529 info = (CERT_ALT_NAME_INFO *)buf;
1531 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1532 info->cAltEntry);
1533 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1534 "Expected CERT_ALT_NAME_URL, got %d\n",
1535 info->rgAltEntry[0].dwAltNameChoice);
1536 ok(U(info->rgAltEntry[0]).pwszURL == NULL || !*U(info->rgAltEntry[0]).pwszURL,
1537 "Expected empty URL\n");
1538 LocalFree(buf);
1540 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1541 emptyURLExtraBytes, sizeof(emptyURLExtraBytes), 0, NULL, NULL, &bufSize);
1542 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1543 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedURL,
1544 encodedURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1545 &bufSize);
1546 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1547 if (buf)
1549 info = (CERT_ALT_NAME_INFO *)buf;
1551 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1552 info->cAltEntry);
1553 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1554 "Expected CERT_ALT_NAME_URL, got %d\n",
1555 info->rgAltEntry[0].dwAltNameChoice);
1556 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszURL, url), "Unexpected URL\n");
1557 LocalFree(buf);
1559 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedDnsName,
1560 encodedDnsName[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1561 &bufSize);
1562 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1563 if (buf)
1565 info = (CERT_ALT_NAME_INFO *)buf;
1567 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1568 info->cAltEntry);
1569 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1570 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1571 info->rgAltEntry[0].dwAltNameChoice);
1572 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszDNSName, dnsName),
1573 "Unexpected DNS name\n");
1574 LocalFree(buf);
1576 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedIPAddr,
1577 encodedIPAddr[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1578 &bufSize);
1579 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1580 if (buf)
1582 info = (CERT_ALT_NAME_INFO *)buf;
1584 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1585 info->cAltEntry);
1586 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS,
1587 "Expected CERT_ALT_NAME_IP_ADDRESS, got %d\n",
1588 info->rgAltEntry[0].dwAltNameChoice);
1589 ok(U(info->rgAltEntry[0]).IPAddress.cbData == sizeof(localhost),
1590 "Unexpected IP address length %d\n",
1591 U(info->rgAltEntry[0]).IPAddress.cbData);
1592 ok(!memcmp(U(info->rgAltEntry[0]).IPAddress.pbData, localhost,
1593 sizeof(localhost)), "Unexpected IP address value\n");
1594 LocalFree(buf);
1596 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedOidName,
1597 sizeof(encodedOidName), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1598 &bufSize);
1599 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1600 if (buf)
1602 info = (CERT_ALT_NAME_INFO *)buf;
1604 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1605 info->cAltEntry);
1606 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_REGISTERED_ID,
1607 "Expected CERT_ALT_NAME_REGISTERED_ID, got %d\n",
1608 info->rgAltEntry[0].dwAltNameChoice);
1609 ok(!strcmp(U(info->rgAltEntry[0]).pszRegisteredID, "1.2.3"),
1610 "Expected OID 1.2.3, got %s\n", U(info->rgAltEntry[0]).pszRegisteredID);
1611 LocalFree(buf);
1613 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1614 encodedDirectoryName, sizeof(encodedDirectoryName),
1615 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1616 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1617 if (buf)
1619 info = (CERT_ALT_NAME_INFO *)buf;
1621 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1622 info->cAltEntry);
1623 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME,
1624 "Expected CERT_ALT_NAME_DIRECTORY_NAME, got %d\n",
1625 info->rgAltEntry[0].dwAltNameChoice);
1626 ok(U(info->rgAltEntry[0]).DirectoryName.cbData ==
1627 sizeof(encodedCommonName), "Unexpected directory name length %d\n",
1628 U(info->rgAltEntry[0]).DirectoryName.cbData);
1629 ok(!memcmp(U(info->rgAltEntry[0]).DirectoryName.pbData,
1630 encodedCommonName, sizeof(encodedCommonName)),
1631 "Unexpected directory name value\n");
1632 LocalFree(buf);
1636 struct UnicodeExpectedError
1638 DWORD valueType;
1639 LPCWSTR str;
1640 DWORD errorIndex;
1641 DWORD error;
1644 static const WCHAR oneW[] = { '1',0 };
1645 static const WCHAR aW[] = { 'a',0 };
1646 static const WCHAR quoteW[] = { '"', 0 };
1648 static struct UnicodeExpectedError unicodeErrors[] = {
1649 { CERT_RDN_ANY_TYPE, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1650 { CERT_RDN_ENCODED_BLOB, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1651 { CERT_RDN_OCTET_STRING, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1652 { CERT_RDN_NUMERIC_STRING, aW, 0, CRYPT_E_INVALID_NUMERIC_STRING },
1653 { CERT_RDN_PRINTABLE_STRING, quoteW, 0, CRYPT_E_INVALID_PRINTABLE_STRING },
1654 { CERT_RDN_IA5_STRING, nihongoURL, 7, CRYPT_E_INVALID_IA5_STRING },
1657 struct UnicodeExpectedResult
1659 DWORD valueType;
1660 LPCWSTR str;
1661 CRYPT_DATA_BLOB encoded;
1664 static BYTE oneNumeric[] = { 0x12, 0x01, 0x31 };
1665 static BYTE onePrintable[] = { 0x13, 0x01, 0x31 };
1666 static BYTE oneTeletex[] = { 0x14, 0x01, 0x31 };
1667 static BYTE oneVideotex[] = { 0x15, 0x01, 0x31 };
1668 static BYTE oneIA5[] = { 0x16, 0x01, 0x31 };
1669 static BYTE oneGraphic[] = { 0x19, 0x01, 0x31 };
1670 static BYTE oneVisible[] = { 0x1a, 0x01, 0x31 };
1671 static BYTE oneUniversal[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 };
1672 static BYTE oneGeneral[] = { 0x1b, 0x01, 0x31 };
1673 static BYTE oneBMP[] = { 0x1e, 0x02, 0x00, 0x31 };
1674 static BYTE oneUTF8[] = { 0x0c, 0x01, 0x31 };
1675 static BYTE nihongoT61[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,
1676 0x5b };
1677 static BYTE nihongoGeneral[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1678 0x6f,0x5b };
1679 static BYTE nihongoBMP[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,
1680 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
1681 static BYTE nihongoUTF8[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1682 0xe2,0x89,0xaf,0xe5,0x9d,0x9b };
1684 static struct UnicodeExpectedResult unicodeResults[] = {
1685 { CERT_RDN_NUMERIC_STRING, oneW, { sizeof(oneNumeric), oneNumeric } },
1686 { CERT_RDN_PRINTABLE_STRING, oneW, { sizeof(onePrintable), onePrintable } },
1687 { CERT_RDN_TELETEX_STRING, oneW, { sizeof(oneTeletex), oneTeletex } },
1688 { CERT_RDN_VIDEOTEX_STRING, oneW, { sizeof(oneVideotex), oneVideotex } },
1689 { CERT_RDN_IA5_STRING, oneW, { sizeof(oneIA5), oneIA5 } },
1690 { CERT_RDN_GRAPHIC_STRING, oneW, { sizeof(oneGraphic), oneGraphic } },
1691 { CERT_RDN_VISIBLE_STRING, oneW, { sizeof(oneVisible), oneVisible } },
1692 { CERT_RDN_UNIVERSAL_STRING, oneW, { sizeof(oneUniversal), oneUniversal } },
1693 { CERT_RDN_GENERAL_STRING, oneW, { sizeof(oneGeneral), oneGeneral } },
1694 { CERT_RDN_BMP_STRING, oneW, { sizeof(oneBMP), oneBMP } },
1695 { CERT_RDN_UTF8_STRING, oneW, { sizeof(oneUTF8), oneUTF8 } },
1696 { CERT_RDN_BMP_STRING, nihongoURL, { sizeof(nihongoBMP), nihongoBMP } },
1697 { CERT_RDN_UTF8_STRING, nihongoURL, { sizeof(nihongoUTF8), nihongoUTF8 } },
1700 static struct UnicodeExpectedResult unicodeWeirdness[] = {
1701 { CERT_RDN_TELETEX_STRING, nihongoURL, { sizeof(nihongoT61), nihongoT61 } },
1702 { CERT_RDN_GENERAL_STRING, nihongoURL, { sizeof(nihongoGeneral), nihongoGeneral } },
1705 static void test_encodeUnicodeNameValue(DWORD dwEncoding)
1707 BYTE *buf = NULL;
1708 DWORD size = 0, i;
1709 BOOL ret;
1710 CERT_NAME_VALUE value;
1712 if (0)
1714 /* Crashes on win9x */
1715 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, NULL,
1716 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1717 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1718 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1720 /* Have to have a string of some sort */
1721 value.dwValueType = 0; /* aka CERT_RDN_ANY_TYPE */
1722 value.Value.pbData = NULL;
1723 value.Value.cbData = 0;
1724 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1725 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1726 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1727 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1728 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1729 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1730 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1731 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1732 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1733 value.dwValueType = CERT_RDN_ANY_TYPE;
1734 value.Value.pbData = (LPBYTE)oneW;
1735 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1736 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1737 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1738 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1739 value.Value.cbData = sizeof(oneW);
1740 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1741 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1742 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1743 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1744 /* An encoded string with specified length isn't good enough either */
1745 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1746 value.Value.pbData = oneUniversal;
1747 value.Value.cbData = sizeof(oneUniversal);
1748 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1749 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1750 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1751 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1752 /* More failure checking */
1753 value.Value.cbData = 0;
1754 for (i = 0; i < sizeof(unicodeErrors) / sizeof(unicodeErrors[0]); i++)
1756 value.Value.pbData = (LPBYTE)unicodeErrors[i].str;
1757 value.dwValueType = unicodeErrors[i].valueType;
1758 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1759 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1760 ok(!ret && GetLastError() == unicodeErrors[i].error,
1761 "Value type %d: expected %08x, got %08x\n", value.dwValueType,
1762 unicodeErrors[i].error, GetLastError());
1763 ok(size == unicodeErrors[i].errorIndex,
1764 "Expected error index %d, got %d\n", unicodeErrors[i].errorIndex,
1765 size);
1767 /* cbData can be zero if the string is NULL-terminated */
1768 value.Value.cbData = 0;
1769 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1771 value.Value.pbData = (LPBYTE)unicodeResults[i].str;
1772 value.dwValueType = unicodeResults[i].valueType;
1773 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1774 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1775 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
1776 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1777 if (buf)
1779 ok(size == unicodeResults[i].encoded.cbData,
1780 "Value type %d: expected size %d, got %d\n",
1781 value.dwValueType, unicodeResults[i].encoded.cbData, size);
1782 ok(!memcmp(unicodeResults[i].encoded.pbData, buf, size),
1783 "Value type %d: unexpected value\n", value.dwValueType);
1784 LocalFree(buf);
1787 /* These "encode," but they do so by truncating each unicode character
1788 * rather than properly encoding it. Kept separate from the proper results,
1789 * because the encoded forms won't decode to their original strings.
1791 for (i = 0; i < sizeof(unicodeWeirdness) / sizeof(unicodeWeirdness[0]); i++)
1793 value.Value.pbData = (LPBYTE)unicodeWeirdness[i].str;
1794 value.dwValueType = unicodeWeirdness[i].valueType;
1795 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1796 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1797 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1798 if (buf)
1800 ok(size == unicodeWeirdness[i].encoded.cbData,
1801 "Value type %d: expected size %d, got %d\n",
1802 value.dwValueType, unicodeWeirdness[i].encoded.cbData, size);
1803 ok(!memcmp(unicodeWeirdness[i].encoded.pbData, buf, size),
1804 "Value type %d: unexpected value\n", value.dwValueType);
1805 LocalFree(buf);
1810 static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
1812 if (n <= 0) return 0;
1813 while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
1814 return *str1 - *str2;
1817 static void test_decodeUnicodeNameValue(DWORD dwEncoding)
1819 DWORD i;
1821 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1823 BYTE *buf = NULL;
1824 BOOL ret;
1825 DWORD size = 0;
1827 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE,
1828 unicodeResults[i].encoded.pbData, unicodeResults[i].encoded.cbData,
1829 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1830 ok(ret || broken(GetLastError() == CRYPT_E_NOT_CHAR_STRING /* Win9x */),
1831 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1832 if (ret && buf)
1834 PCERT_NAME_VALUE value = (PCERT_NAME_VALUE)buf;
1836 ok(value->dwValueType == unicodeResults[i].valueType,
1837 "Expected value type %d, got %d\n", unicodeResults[i].valueType,
1838 value->dwValueType);
1839 ok(!strncmpW((LPWSTR)value->Value.pbData, unicodeResults[i].str,
1840 value->Value.cbData / sizeof(WCHAR)),
1841 "Unexpected decoded value for index %d (value type %d)\n", i,
1842 unicodeResults[i].valueType);
1843 LocalFree(buf);
1848 struct encodedOctets
1850 const BYTE *val;
1851 const BYTE *encoded;
1854 static const unsigned char bin46[] = { 'h','i',0 };
1855 static const unsigned char bin47[] = { 0x04,0x02,'h','i',0 };
1856 static const unsigned char bin48[] = {
1857 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1858 static const unsigned char bin49[] = {
1859 0x04,0x0f,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1860 static const unsigned char bin50[] = { 0 };
1861 static const unsigned char bin51[] = { 0x04,0x00,0 };
1863 static const struct encodedOctets octets[] = {
1864 { bin46, bin47 },
1865 { bin48, bin49 },
1866 { bin50, bin51 },
1869 static void test_encodeOctets(DWORD dwEncoding)
1871 CRYPT_DATA_BLOB blob;
1872 DWORD i;
1874 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1876 BYTE *buf = NULL;
1877 BOOL ret;
1878 DWORD bufSize = 0;
1880 blob.cbData = strlen((const char*)octets[i].val);
1881 blob.pbData = (BYTE*)octets[i].val;
1882 ret = pCryptEncodeObjectEx(dwEncoding, X509_OCTET_STRING, &blob,
1883 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1884 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
1885 if (buf)
1887 ok(buf[0] == 4,
1888 "Got unexpected type %d for octet string (expected 4)\n", buf[0]);
1889 ok(buf[1] == octets[i].encoded[1], "Got length %d, expected %d\n",
1890 buf[1], octets[i].encoded[1]);
1891 ok(!memcmp(buf + 1, octets[i].encoded + 1,
1892 octets[i].encoded[1] + 1), "Got unexpected value\n");
1893 LocalFree(buf);
1898 static void test_decodeOctets(DWORD dwEncoding)
1900 DWORD i;
1902 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1904 BYTE *buf = NULL;
1905 BOOL ret;
1906 DWORD bufSize = 0;
1908 ret = pCryptDecodeObjectEx(dwEncoding, X509_OCTET_STRING,
1909 (BYTE *)octets[i].encoded, octets[i].encoded[1] + 2,
1910 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1911 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1912 ok(bufSize >= sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1],
1913 "Expected size >= %d, got %d\n",
1914 (int)sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1], bufSize);
1915 ok(buf != NULL, "Expected allocated buffer\n");
1916 if (buf)
1918 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)buf;
1920 if (blob->cbData)
1921 ok(!memcmp(blob->pbData, octets[i].val, blob->cbData),
1922 "Unexpected value\n");
1923 LocalFree(buf);
1928 static const BYTE bytesToEncode[] = { 0xff, 0xff };
1930 struct encodedBits
1932 DWORD cUnusedBits;
1933 const BYTE *encoded;
1934 DWORD cbDecoded;
1935 const BYTE *decoded;
1938 static const unsigned char bin52[] = { 0x03,0x03,0x00,0xff,0xff };
1939 static const unsigned char bin53[] = { 0xff,0xff };
1940 static const unsigned char bin54[] = { 0x03,0x03,0x01,0xff,0xfe };
1941 static const unsigned char bin55[] = { 0xff,0xfe };
1942 static const unsigned char bin56[] = { 0x03,0x02,0x01,0xfe };
1943 static const unsigned char bin57[] = { 0xfe };
1944 static const unsigned char bin58[] = { 0x03,0x01,0x00 };
1946 static const struct encodedBits bits[] = {
1947 /* normal test cases */
1948 { 0, bin52, 2, bin53 },
1949 { 1, bin54, 2, bin55 },
1950 /* strange test case, showing cUnusedBits >= 8 is allowed */
1951 { 9, bin56, 1, bin57 },
1952 /* even stranger test case, showing cUnusedBits > cbData * 8 is allowed */
1953 { 17, bin58, 0, NULL },
1956 static void test_encodeBits(DWORD dwEncoding)
1958 DWORD i;
1960 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
1962 CRYPT_BIT_BLOB blob;
1963 BOOL ret;
1964 BYTE *buf = NULL;
1965 DWORD bufSize = 0;
1967 blob.cbData = sizeof(bytesToEncode);
1968 blob.pbData = (BYTE *)bytesToEncode;
1969 blob.cUnusedBits = bits[i].cUnusedBits;
1970 ret = pCryptEncodeObjectEx(dwEncoding, X509_BITS, &blob,
1971 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1972 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1973 if (buf)
1975 ok(bufSize == bits[i].encoded[1] + 2,
1976 "Got unexpected size %d, expected %d\n", bufSize,
1977 bits[i].encoded[1] + 2);
1978 ok(!memcmp(buf, bits[i].encoded, bits[i].encoded[1] + 2),
1979 "Unexpected value\n");
1980 LocalFree(buf);
1985 static void test_decodeBits(DWORD dwEncoding)
1987 static const BYTE ber[] = "\x03\x02\x01\xff";
1988 static const BYTE berDecoded = 0xfe;
1989 DWORD i;
1990 BOOL ret;
1991 BYTE *buf = NULL;
1992 DWORD bufSize = 0;
1994 /* normal cases */
1995 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
1997 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, bits[i].encoded,
1998 bits[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1999 &bufSize);
2000 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2001 if (buf)
2003 CRYPT_BIT_BLOB *blob;
2005 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + bits[i].cbDecoded,
2006 "Got unexpected size %d\n", bufSize);
2007 blob = (CRYPT_BIT_BLOB *)buf;
2008 ok(blob->cbData == bits[i].cbDecoded,
2009 "Got unexpected length %d, expected %d\n", blob->cbData,
2010 bits[i].cbDecoded);
2011 if (blob->cbData && bits[i].cbDecoded)
2012 ok(!memcmp(blob->pbData, bits[i].decoded, bits[i].cbDecoded),
2013 "Unexpected value\n");
2014 LocalFree(buf);
2017 /* special case: check that something that's valid in BER but not in DER
2018 * decodes successfully
2020 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, ber, ber[1] + 2,
2021 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2022 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2023 if (buf)
2025 CRYPT_BIT_BLOB *blob;
2027 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + sizeof(berDecoded),
2028 "Got unexpected size %d\n", bufSize);
2029 blob = (CRYPT_BIT_BLOB *)buf;
2030 ok(blob->cbData == sizeof(berDecoded),
2031 "Got unexpected length %d\n", blob->cbData);
2032 if (blob->cbData)
2033 ok(*blob->pbData == berDecoded, "Unexpected value\n");
2034 LocalFree(buf);
2038 struct Constraints2
2040 CERT_BASIC_CONSTRAINTS2_INFO info;
2041 const BYTE *encoded;
2044 static const unsigned char bin59[] = { 0x30,0x00 };
2045 static const unsigned char bin60[] = { 0x30,0x03,0x01,0x01,0xff };
2046 static const unsigned char bin61[] = { 0x30,0x03,0x02,0x01,0x00 };
2047 static const unsigned char bin62[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2048 static const struct Constraints2 constraints2[] = {
2049 /* empty constraints */
2050 { { FALSE, FALSE, 0}, bin59 },
2051 /* can be a CA */
2052 { { TRUE, FALSE, 0}, bin60 },
2053 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well,
2054 * but that's not the case
2056 { { FALSE, TRUE, 0}, bin61 },
2057 /* can be a CA and has path length constraints set */
2058 { { TRUE, TRUE, 1}, bin62 },
2061 static const BYTE emptyConstraint[] = { 0x30, 0x03, 0x03, 0x01, 0x00 };
2062 static const BYTE encodedDomainName[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11,
2063 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
2064 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
2065 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2066 static const BYTE constraintWithDomainName[] = { 0x30, 0x32, 0x03, 0x01, 0x00,
2067 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
2068 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30,
2069 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
2070 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2072 static void test_encodeBasicConstraints(DWORD dwEncoding)
2074 DWORD i, bufSize = 0;
2075 CERT_BASIC_CONSTRAINTS_INFO info = { { 0 } };
2076 CERT_NAME_BLOB nameBlob = { sizeof(encodedDomainName),
2077 (LPBYTE)encodedDomainName };
2078 BOOL ret;
2079 BYTE *buf = NULL;
2081 /* First test with the simpler info2 */
2082 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2084 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2085 &constraints2[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2086 &bufSize);
2087 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2088 if (buf)
2090 ok(bufSize == constraints2[i].encoded[1] + 2,
2091 "Expected %d bytes, got %d\n", constraints2[i].encoded[1] + 2,
2092 bufSize);
2093 ok(!memcmp(buf, constraints2[i].encoded,
2094 constraints2[i].encoded[1] + 2), "Unexpected value\n");
2095 LocalFree(buf);
2098 /* Now test with more complex basic constraints */
2099 info.SubjectType.cbData = 0;
2100 info.fPathLenConstraint = FALSE;
2101 info.cSubtreesConstraint = 0;
2102 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2103 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2104 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2105 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2106 if (buf)
2108 ok(bufSize == sizeof(emptyConstraint), "Wrong size %d\n", bufSize);
2109 ok(!memcmp(buf, emptyConstraint, sizeof(emptyConstraint)),
2110 "Unexpected value\n");
2111 LocalFree(buf);
2113 /* None of the certs I examined had any subtree constraint, but I test one
2114 * anyway just in case.
2116 info.cSubtreesConstraint = 1;
2117 info.rgSubtreesConstraint = &nameBlob;
2118 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2119 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2120 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2121 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2122 if (buf)
2124 ok(bufSize == sizeof(constraintWithDomainName), "Wrong size %d\n", bufSize);
2125 ok(!memcmp(buf, constraintWithDomainName,
2126 sizeof(constraintWithDomainName)), "Unexpected value\n");
2127 LocalFree(buf);
2129 /* FIXME: test encoding with subject type. */
2132 static const unsigned char bin63[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 };
2134 static void test_decodeBasicConstraints(DWORD dwEncoding)
2136 static const BYTE inverted[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01,
2137 0xff };
2138 static const struct Constraints2 badBool = { { TRUE, TRUE, 1 }, bin63 };
2139 DWORD i;
2140 BOOL ret;
2141 BYTE *buf = NULL;
2142 DWORD bufSize = 0;
2144 /* First test with simpler info2 */
2145 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2147 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2148 constraints2[i].encoded, constraints2[i].encoded[1] + 2,
2149 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2150 ok(ret, "CryptDecodeObjectEx failed for item %d: %08x\n", i,
2151 GetLastError());
2152 if (buf)
2154 CERT_BASIC_CONSTRAINTS2_INFO *info =
2155 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2157 ok(!memcmp(info, &constraints2[i].info, sizeof(*info)),
2158 "Unexpected value for item %d\n", i);
2159 LocalFree(buf);
2162 /* Check with the order of encoded elements inverted */
2163 buf = (PBYTE)1;
2164 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2165 inverted, inverted[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2166 &bufSize);
2167 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2168 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2169 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2170 GetLastError());
2171 ok(!buf, "Expected buf to be set to NULL\n");
2172 /* Check with a non-DER bool */
2173 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2174 badBool.encoded, badBool.encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2175 (BYTE *)&buf, &bufSize);
2176 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2177 if (buf)
2179 CERT_BASIC_CONSTRAINTS2_INFO *info =
2180 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2182 ok(!memcmp(info, &badBool.info, sizeof(*info)), "Unexpected value\n");
2183 LocalFree(buf);
2185 /* Check with a non-basic constraints value */
2186 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2187 (LPBYTE)encodedCommonName, encodedCommonName[1] + 2,
2188 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2189 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2190 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2191 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2192 GetLastError());
2193 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */
2194 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2195 emptyConstraint, sizeof(emptyConstraint), CRYPT_DECODE_ALLOC_FLAG, NULL,
2196 (BYTE *)&buf, &bufSize);
2197 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2198 if (buf)
2200 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2202 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2203 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2204 ok(info->cSubtreesConstraint == 0, "Expected no subtree constraints\n");
2205 LocalFree(buf);
2207 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2208 constraintWithDomainName, sizeof(constraintWithDomainName),
2209 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2210 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2211 if (buf)
2213 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2215 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2216 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2217 ok(info->cSubtreesConstraint == 1, "Expected a subtree constraint\n");
2218 if (info->cSubtreesConstraint && info->rgSubtreesConstraint)
2220 ok(info->rgSubtreesConstraint[0].cbData ==
2221 sizeof(encodedDomainName), "Wrong size %d\n",
2222 info->rgSubtreesConstraint[0].cbData);
2223 ok(!memcmp(info->rgSubtreesConstraint[0].pbData, encodedDomainName,
2224 sizeof(encodedDomainName)), "Unexpected value\n");
2226 LocalFree(buf);
2230 /* These are terrible public keys of course, I'm just testing encoding */
2231 static const BYTE modulus1[] = { 0,0,0,1,1,1,1,1 };
2232 static const BYTE modulus2[] = { 1,1,1,1,1,0,0,0 };
2233 static const BYTE modulus3[] = { 0x80,1,1,1,1,0,0,0 };
2234 static const BYTE modulus4[] = { 1,1,1,1,1,0,0,0x80 };
2235 static const BYTE mod1_encoded[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 };
2236 static const BYTE mod2_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2237 static const BYTE mod3_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 };
2238 static const BYTE mod4_encoded[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2240 struct EncodedRSAPubKey
2242 const BYTE *modulus;
2243 size_t modulusLen;
2244 const BYTE *encoded;
2245 size_t decodedModulusLen;
2248 struct EncodedRSAPubKey rsaPubKeys[] = {
2249 { modulus1, sizeof(modulus1), mod1_encoded, sizeof(modulus1) },
2250 { modulus2, sizeof(modulus2), mod2_encoded, 5 },
2251 { modulus3, sizeof(modulus3), mod3_encoded, 5 },
2252 { modulus4, sizeof(modulus4), mod4_encoded, 8 },
2255 static void test_encodeRsaPublicKey(DWORD dwEncoding)
2257 BYTE toEncode[sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + sizeof(modulus1)];
2258 BLOBHEADER *hdr = (BLOBHEADER *)toEncode;
2259 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(toEncode + sizeof(BLOBHEADER));
2260 BOOL ret;
2261 BYTE *buf = NULL;
2262 DWORD bufSize = 0, i;
2264 /* Try with a bogus blob type */
2265 hdr->bType = 2;
2266 hdr->bVersion = CUR_BLOB_VERSION;
2267 hdr->reserved = 0;
2268 hdr->aiKeyAlg = CALG_RSA_KEYX;
2269 rsaPubKey->magic = 0x31415352;
2270 rsaPubKey->bitlen = sizeof(modulus1) * 8;
2271 rsaPubKey->pubexp = 65537;
2272 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), modulus1,
2273 sizeof(modulus1));
2275 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2276 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2277 &bufSize);
2278 ok(!ret && GetLastError() == E_INVALIDARG,
2279 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2280 /* Now with a bogus reserved field */
2281 hdr->bType = PUBLICKEYBLOB;
2282 hdr->reserved = 1;
2283 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2284 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2285 &bufSize);
2286 if (buf)
2288 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2289 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2290 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2291 LocalFree(buf);
2293 /* Now with a bogus blob version */
2294 hdr->reserved = 0;
2295 hdr->bVersion = 0;
2296 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2297 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2298 &bufSize);
2299 if (buf)
2301 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2302 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2303 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2304 LocalFree(buf);
2306 /* And with a bogus alg ID */
2307 hdr->bVersion = CUR_BLOB_VERSION;
2308 hdr->aiKeyAlg = CALG_DES;
2309 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2310 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2311 &bufSize);
2312 if (buf)
2314 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2315 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2316 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2317 LocalFree(buf);
2319 /* Check a couple of RSA-related OIDs */
2320 hdr->aiKeyAlg = CALG_RSA_KEYX;
2321 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_RSA,
2322 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2323 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2324 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2325 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2326 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2327 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2328 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2329 /* Finally, all valid */
2330 hdr->aiKeyAlg = CALG_RSA_KEYX;
2331 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2333 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2334 rsaPubKeys[i].modulus, rsaPubKeys[i].modulusLen);
2335 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2336 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2337 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2338 if (buf)
2340 ok(bufSize == rsaPubKeys[i].encoded[1] + 2,
2341 "Expected size %d, got %d\n", rsaPubKeys[i].encoded[1] + 2,
2342 bufSize);
2343 ok(!memcmp(buf, rsaPubKeys[i].encoded, bufSize),
2344 "Unexpected value\n");
2345 LocalFree(buf);
2350 static void test_decodeRsaPublicKey(DWORD dwEncoding)
2352 DWORD i;
2353 LPBYTE buf = NULL;
2354 DWORD bufSize = 0;
2355 BOOL ret;
2357 /* Try with a bad length */
2358 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2359 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1],
2360 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2361 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2362 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2363 /* Try with a couple of RSA-related OIDs */
2364 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_RSA,
2365 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2366 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2367 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2368 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2369 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2370 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2371 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2372 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2373 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2374 /* Now try success cases */
2375 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2377 bufSize = 0;
2378 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2379 rsaPubKeys[i].encoded, rsaPubKeys[i].encoded[1] + 2,
2380 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2381 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2382 if (buf)
2384 BLOBHEADER *hdr = (BLOBHEADER *)buf;
2385 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER));
2387 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2388 rsaPubKeys[i].decodedModulusLen,
2389 "Wrong size %d\n", bufSize);
2390 ok(hdr->bType == PUBLICKEYBLOB,
2391 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB,
2392 hdr->bType);
2393 ok(hdr->bVersion == CUR_BLOB_VERSION,
2394 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
2395 CUR_BLOB_VERSION, hdr->bVersion);
2396 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n",
2397 hdr->reserved);
2398 ok(hdr->aiKeyAlg == CALG_RSA_KEYX,
2399 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg);
2400 ok(rsaPubKey->magic == 0x31415352,
2401 "Expected magic RSA1, got %08x\n", rsaPubKey->magic);
2402 ok(rsaPubKey->bitlen == rsaPubKeys[i].decodedModulusLen * 8,
2403 "Wrong bit len %d\n", rsaPubKey->bitlen);
2404 ok(rsaPubKey->pubexp == 65537, "Expected pubexp 65537, got %d\n",
2405 rsaPubKey->pubexp);
2406 ok(!memcmp(buf + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2407 rsaPubKeys[i].modulus, rsaPubKeys[i].decodedModulusLen),
2408 "Unexpected modulus\n");
2409 LocalFree(buf);
2414 static const BYTE intSequence[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01,
2415 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02,
2416 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2418 static const BYTE mixedSequence[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
2419 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f,
2420 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02,
2421 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2423 static void test_encodeSequenceOfAny(DWORD dwEncoding)
2425 CRYPT_DER_BLOB blobs[sizeof(ints) / sizeof(ints[0])];
2426 CRYPT_SEQUENCE_OF_ANY seq;
2427 DWORD i;
2428 BOOL ret;
2429 BYTE *buf = NULL;
2430 DWORD bufSize = 0;
2432 /* Encode a homogeneous sequence */
2433 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
2435 blobs[i].cbData = ints[i].encoded[1] + 2;
2436 blobs[i].pbData = (BYTE *)ints[i].encoded;
2438 seq.cValue = sizeof(ints) / sizeof(ints[0]);
2439 seq.rgValue = blobs;
2441 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2442 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2443 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2444 if (buf)
2446 ok(bufSize == sizeof(intSequence), "Wrong size %d\n", bufSize);
2447 ok(!memcmp(buf, intSequence, intSequence[1] + 2), "Unexpected value\n");
2448 LocalFree(buf);
2450 /* Change the type of the first element in the sequence, and give it
2451 * another go
2453 blobs[0].cbData = times[0].encodedTime[1] + 2;
2454 blobs[0].pbData = (BYTE *)times[0].encodedTime;
2455 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2456 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2457 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2458 if (buf)
2460 ok(bufSize == sizeof(mixedSequence), "Wrong size %d\n", bufSize);
2461 ok(!memcmp(buf, mixedSequence, mixedSequence[1] + 2),
2462 "Unexpected value\n");
2463 LocalFree(buf);
2467 static void test_decodeSequenceOfAny(DWORD dwEncoding)
2469 BOOL ret;
2470 BYTE *buf = NULL;
2471 DWORD bufSize = 0;
2473 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, intSequence,
2474 intSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2475 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2476 if (buf)
2478 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2479 DWORD i;
2481 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2482 "Wrong elements %d\n", seq->cValue);
2483 for (i = 0; i < min(seq->cValue, sizeof(ints) / sizeof(ints[0])); i++)
2485 ok(seq->rgValue[i].cbData == ints[i].encoded[1] + 2,
2486 "Expected %d bytes, got %d\n", ints[i].encoded[1] + 2,
2487 seq->rgValue[i].cbData);
2488 ok(!memcmp(seq->rgValue[i].pbData, ints[i].encoded,
2489 ints[i].encoded[1] + 2), "Unexpected value\n");
2491 LocalFree(buf);
2493 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, mixedSequence,
2494 mixedSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2495 &bufSize);
2496 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2497 if (buf)
2499 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2501 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2502 "Wrong elements %d\n", seq->cValue);
2503 /* Just check the first element since it's all that changed */
2504 ok(seq->rgValue[0].cbData == times[0].encodedTime[1] + 2,
2505 "Expected %d bytes, got %d\n", times[0].encodedTime[1] + 2,
2506 seq->rgValue[0].cbData);
2507 ok(!memcmp(seq->rgValue[0].pbData, times[0].encodedTime,
2508 times[0].encodedTime[1] + 2), "Unexpected value\n");
2509 LocalFree(buf);
2513 struct encodedExtensions
2515 CERT_EXTENSIONS exts;
2516 const BYTE *encoded;
2519 static BYTE crit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2520 static BYTE noncrit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2521 static CHAR oid_basic_constraints2[] = szOID_BASIC_CONSTRAINTS2;
2522 static CERT_EXTENSION criticalExt =
2523 { oid_basic_constraints2, TRUE, { 8, crit_ext_data } };
2524 static CERT_EXTENSION nonCriticalExt =
2525 { oid_basic_constraints2, FALSE, { 8, noncrit_ext_data } };
2527 static const BYTE ext0[] = { 0x30,0x00 };
2528 static const BYTE ext1[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2529 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2530 static const BYTE ext2[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2531 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2533 static const struct encodedExtensions exts[] = {
2534 { { 0, NULL }, ext0 },
2535 { { 1, &criticalExt }, ext1 },
2536 { { 1, &nonCriticalExt }, ext2 },
2539 static void test_encodeExtensions(DWORD dwEncoding)
2541 DWORD i;
2543 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2545 BOOL ret;
2546 BYTE *buf = NULL;
2547 DWORD bufSize = 0;
2549 ret = pCryptEncodeObjectEx(dwEncoding, X509_EXTENSIONS, &exts[i].exts,
2550 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2551 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2552 if (buf)
2554 ok(bufSize == exts[i].encoded[1] + 2,
2555 "Expected %d bytes, got %d\n", exts[i].encoded[1] + 2, bufSize);
2556 ok(!memcmp(buf, exts[i].encoded, exts[i].encoded[1] + 2),
2557 "Unexpected value\n");
2558 LocalFree(buf);
2563 static void test_decodeExtensions(DWORD dwEncoding)
2565 DWORD i;
2567 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2569 BOOL ret;
2570 BYTE *buf = NULL;
2571 DWORD bufSize = 0;
2573 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS,
2574 exts[i].encoded, exts[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2575 NULL, (BYTE *)&buf, &bufSize);
2576 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2577 if (buf)
2579 CERT_EXTENSIONS *ext = (CERT_EXTENSIONS *)buf;
2580 DWORD j;
2582 ok(ext->cExtension == exts[i].exts.cExtension,
2583 "Expected %d extensions, see %d\n", exts[i].exts.cExtension,
2584 ext->cExtension);
2585 for (j = 0; j < min(ext->cExtension, exts[i].exts.cExtension); j++)
2587 ok(!strcmp(ext->rgExtension[j].pszObjId,
2588 exts[i].exts.rgExtension[j].pszObjId),
2589 "Expected OID %s, got %s\n",
2590 exts[i].exts.rgExtension[j].pszObjId,
2591 ext->rgExtension[j].pszObjId);
2592 ok(!memcmp(ext->rgExtension[j].Value.pbData,
2593 exts[i].exts.rgExtension[j].Value.pbData,
2594 exts[i].exts.rgExtension[j].Value.cbData),
2595 "Unexpected value\n");
2597 LocalFree(buf);
2602 /* MS encodes public key info with a NULL if the algorithm identifier's
2603 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2604 * it encodes them by omitting the algorithm parameters. This latter approach
2605 * seems more correct, so accept either form.
2607 struct encodedPublicKey
2609 CERT_PUBLIC_KEY_INFO info;
2610 const BYTE *encoded;
2611 const BYTE *encodedNoNull;
2612 CERT_PUBLIC_KEY_INFO decoded;
2615 static const BYTE aKey[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2616 0xe, 0xf };
2617 static const BYTE params[] = { 0x02, 0x01, 0x01 };
2619 static const unsigned char bin64[] = {
2620 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2621 static const unsigned char bin65[] = {
2622 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2623 static const unsigned char bin66[] = {
2624 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2625 static const unsigned char bin67[] = {
2626 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2627 static const unsigned char bin68[] = {
2628 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01,
2629 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2630 static const unsigned char bin69[] = {
2631 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2632 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2633 static const unsigned char bin70[] = {
2634 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2635 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2636 0x0f};
2637 static const unsigned char bin71[] = {
2638 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2639 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2640 0x0f};
2641 static unsigned char bin72[] = { 0x05,0x00};
2643 static CHAR oid_bogus[] = "1.2.3",
2644 oid_rsa[] = szOID_RSA;
2646 static const struct encodedPublicKey pubKeys[] = {
2647 /* with a bogus OID */
2648 { { { oid_bogus, { 0, NULL } }, { 0, NULL, 0 } },
2649 bin64, bin65,
2650 { { oid_bogus, { 2, bin72 } }, { 0, NULL, 0 } } },
2651 /* some normal keys */
2652 { { { oid_rsa, { 0, NULL } }, { 0, NULL, 0} },
2653 bin66, bin67,
2654 { { oid_rsa, { 2, bin72 } }, { 0, NULL, 0 } } },
2655 { { { oid_rsa, { 0, NULL } }, { sizeof(aKey), (BYTE *)aKey, 0} },
2656 bin68, bin69,
2657 { { oid_rsa, { 2, bin72 } }, { sizeof(aKey), (BYTE *)aKey, 0} } },
2658 /* with add'l parameters--note they must be DER-encoded */
2659 { { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2660 (BYTE *)aKey, 0 } },
2661 bin70, bin71,
2662 { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2663 (BYTE *)aKey, 0 } } },
2666 static void test_encodePublicKeyInfo(DWORD dwEncoding)
2668 DWORD i;
2670 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2672 BOOL ret;
2673 BYTE *buf = NULL;
2674 DWORD bufSize = 0;
2676 ret = pCryptEncodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2677 &pubKeys[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2678 &bufSize);
2679 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2680 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2681 if (buf)
2683 ok(bufSize == pubKeys[i].encoded[1] + 2 ||
2684 bufSize == pubKeys[i].encodedNoNull[1] + 2,
2685 "Expected %d or %d bytes, got %d\n", pubKeys[i].encoded[1] + 2,
2686 pubKeys[i].encodedNoNull[1] + 2, bufSize);
2687 if (bufSize == pubKeys[i].encoded[1] + 2)
2688 ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2),
2689 "Unexpected value\n");
2690 else if (bufSize == pubKeys[i].encodedNoNull[1] + 2)
2691 ok(!memcmp(buf, pubKeys[i].encodedNoNull,
2692 pubKeys[i].encodedNoNull[1] + 2), "Unexpected value\n");
2693 LocalFree(buf);
2698 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO *expected,
2699 const CERT_PUBLIC_KEY_INFO *got)
2701 ok(!strcmp(expected->Algorithm.pszObjId, got->Algorithm.pszObjId),
2702 "Expected OID %s, got %s\n", expected->Algorithm.pszObjId,
2703 got->Algorithm.pszObjId);
2704 ok(expected->Algorithm.Parameters.cbData ==
2705 got->Algorithm.Parameters.cbData,
2706 "Expected parameters of %d bytes, got %d\n",
2707 expected->Algorithm.Parameters.cbData, got->Algorithm.Parameters.cbData);
2708 if (expected->Algorithm.Parameters.cbData)
2709 ok(!memcmp(expected->Algorithm.Parameters.pbData,
2710 got->Algorithm.Parameters.pbData, got->Algorithm.Parameters.cbData),
2711 "Unexpected algorithm parameters\n");
2712 ok(expected->PublicKey.cbData == got->PublicKey.cbData,
2713 "Expected public key of %d bytes, got %d\n",
2714 expected->PublicKey.cbData, got->PublicKey.cbData);
2715 if (expected->PublicKey.cbData)
2716 ok(!memcmp(expected->PublicKey.pbData, got->PublicKey.pbData,
2717 got->PublicKey.cbData), "Unexpected public key value\n");
2720 static void test_decodePublicKeyInfo(DWORD dwEncoding)
2722 static const BYTE bogusPubKeyInfo[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
2723 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
2724 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
2725 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2726 DWORD i;
2727 BOOL ret;
2728 BYTE *buf = NULL;
2729 DWORD bufSize = 0;
2731 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2733 /* The NULL form decodes to the decoded member */
2734 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2735 pubKeys[i].encoded, pubKeys[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2736 NULL, (BYTE *)&buf, &bufSize);
2737 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2738 if (buf)
2740 comparePublicKeyInfo(&pubKeys[i].decoded,
2741 (CERT_PUBLIC_KEY_INFO *)buf);
2742 LocalFree(buf);
2744 /* The non-NULL form decodes to the original */
2745 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2746 pubKeys[i].encodedNoNull, pubKeys[i].encodedNoNull[1] + 2,
2747 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2748 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2749 if (buf)
2751 comparePublicKeyInfo(&pubKeys[i].info, (CERT_PUBLIC_KEY_INFO *)buf);
2752 LocalFree(buf);
2755 /* Test with bogus (not valid DER) parameters */
2756 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2757 bogusPubKeyInfo, bogusPubKeyInfo[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2758 NULL, (BYTE *)&buf, &bufSize);
2759 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2760 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2761 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2762 GetLastError());
2765 static const BYTE v1Cert[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
2766 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2767 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
2768 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
2769 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2770 static const BYTE v2Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02,
2771 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2772 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2773 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2774 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2775 static const BYTE v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2776 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2777 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2778 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2779 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2780 static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
2781 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2782 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2783 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2784 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2785 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2786 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2787 static const BYTE v1CertWithSerial[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
2788 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2789 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2790 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2791 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2792 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2793 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2794 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2795 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
2796 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
2797 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
2798 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
2799 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
2800 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
2801 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
2802 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
2803 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2804 static const BYTE v1CertWithPubKey[] = {
2805 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2806 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2807 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2808 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2809 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2810 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2811 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2812 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2813 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
2814 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
2815 0x01,0x01 };
2816 static const BYTE v1CertWithPubKeyNoNull[] = {
2817 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2818 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2819 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2820 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2821 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2822 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2823 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2824 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2825 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
2826 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2827 static const BYTE v1CertWithSubjectKeyId[] = {
2828 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2829 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2830 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2831 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2832 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2833 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2834 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
2835 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2836 0x4c,0x61,0x6e,0x67,0x00 };
2838 static const BYTE serialNum[] = { 0x01 };
2840 static void test_encodeCertToBeSigned(DWORD dwEncoding)
2842 BOOL ret;
2843 BYTE *buf = NULL;
2844 DWORD size = 0;
2845 CERT_INFO info = { 0 };
2846 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2847 static char oid_subject_key_identifier[] = szOID_SUBJECT_KEY_IDENTIFIER;
2848 CERT_EXTENSION ext;
2850 if (0)
2852 /* Test with NULL pvStructInfo (crashes on win9x) */
2853 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL,
2854 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2855 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2856 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2858 /* Test with a V1 cert */
2859 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2860 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2861 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2862 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2863 if (buf)
2865 ok(size == v1Cert[1] + 2, "Expected size %d, got %d\n",
2866 v1Cert[1] + 2, size);
2867 ok(!memcmp(buf, v1Cert, size), "Got unexpected value\n");
2868 LocalFree(buf);
2870 /* Test v2 cert */
2871 info.dwVersion = CERT_V2;
2872 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2873 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2874 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2875 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2876 if (buf)
2878 ok(size == sizeof(v2Cert), "Wrong size %d\n", size);
2879 ok(!memcmp(buf, v2Cert, size), "Got unexpected value\n");
2880 LocalFree(buf);
2882 /* Test v3 cert */
2883 info.dwVersion = CERT_V3;
2884 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2885 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2886 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2887 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2888 if (buf)
2890 ok(size == sizeof(v3Cert), "Wrong size %d\n", size);
2891 ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n");
2892 LocalFree(buf);
2894 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
2895 * API doesn't prevent it)
2897 info.dwVersion = CERT_V1;
2898 info.cExtension = 1;
2899 info.rgExtension = &criticalExt;
2900 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2901 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2902 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2903 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2904 if (buf)
2906 ok(size == sizeof(v1CertWithConstraints), "Wrong size %d\n", size);
2907 ok(!memcmp(buf, v1CertWithConstraints, size), "Got unexpected value\n");
2908 LocalFree(buf);
2910 /* test v1 cert with a serial number */
2911 info.SerialNumber.cbData = sizeof(serialNum);
2912 info.SerialNumber.pbData = (BYTE *)serialNum;
2913 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2914 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2915 if (buf)
2917 ok(size == sizeof(v1CertWithSerial), "Wrong size %d\n", size);
2918 ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n");
2919 LocalFree(buf);
2921 /* Test v1 cert with an issuer name, a subject name, and a serial number */
2922 info.Issuer.cbData = sizeof(encodedCommonName);
2923 info.Issuer.pbData = (BYTE *)encodedCommonName;
2924 info.Subject.cbData = sizeof(encodedCommonName);
2925 info.Subject.pbData = (BYTE *)encodedCommonName;
2926 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2927 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2928 if (buf)
2930 ok(size == sizeof(bigCert), "Wrong size %d\n", size);
2931 ok(!memcmp(buf, bigCert, size), "Got unexpected value\n");
2932 LocalFree(buf);
2934 /* Add a public key */
2935 info.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2936 info.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2937 info.SubjectPublicKeyInfo.PublicKey.pbData = (LPBYTE)aKey;
2938 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2939 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2940 if (buf)
2942 ok(size == sizeof(v1CertWithPubKey) ||
2943 size == sizeof(v1CertWithPubKeyNoNull), "Wrong size %d\n", size);
2944 if (size == sizeof(v1CertWithPubKey))
2945 ok(!memcmp(buf, v1CertWithPubKey, size), "Got unexpected value\n");
2946 else if (size == sizeof(v1CertWithPubKeyNoNull))
2947 ok(!memcmp(buf, v1CertWithPubKeyNoNull, size),
2948 "Got unexpected value\n");
2949 LocalFree(buf);
2951 /* Remove the public key, and add a subject key identifier extension */
2952 info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2953 info.SubjectPublicKeyInfo.PublicKey.cbData = 0;
2954 info.SubjectPublicKeyInfo.PublicKey.pbData = NULL;
2955 ext.pszObjId = oid_subject_key_identifier;
2956 ext.fCritical = FALSE;
2957 ext.Value.cbData = sizeof(octetCommonNameValue);
2958 ext.Value.pbData = (BYTE *)octetCommonNameValue;
2959 info.cExtension = 1;
2960 info.rgExtension = &ext;
2961 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2962 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2963 if (buf)
2965 ok(size == sizeof(v1CertWithSubjectKeyId), "Wrong size %d\n", size);
2966 ok(!memcmp(buf, v1CertWithSubjectKeyId, size), "Unexpected value\n");
2967 LocalFree(buf);
2971 static void test_decodeCertToBeSigned(DWORD dwEncoding)
2973 static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert,
2974 v1CertWithConstraints, v1CertWithSerial };
2975 BOOL ret;
2976 BYTE *buf = NULL;
2977 DWORD size = 0, i;
2979 /* Test with NULL pbEncoded */
2980 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 0,
2981 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2982 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
2983 GetLastError() == OSS_BAD_ARG /* Win9x */),
2984 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
2985 if (0)
2987 /* Crashes on win9x */
2988 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 1,
2989 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2990 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2991 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2993 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT, because at a
2994 * minimum a cert must have a non-zero serial number, an issuer, and a
2995 * subject.
2997 for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++)
2999 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3000 corruptCerts[i], corruptCerts[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3001 (BYTE *)&buf, &size);
3002 ok(!ret, "Expected failure\n");
3004 /* Now check with serial number, subject and issuer specified */
3005 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert,
3006 sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3007 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3008 if (buf)
3010 CERT_INFO *info = (CERT_INFO *)buf;
3012 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3013 ok(info->SerialNumber.cbData == 1,
3014 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3015 ok(*info->SerialNumber.pbData == *serialNum,
3016 "Expected serial number %d, got %d\n", *serialNum,
3017 *info->SerialNumber.pbData);
3018 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3019 "Wrong size %d\n", info->Issuer.cbData);
3020 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3021 "Unexpected issuer\n");
3022 ok(info->Subject.cbData == sizeof(encodedCommonName),
3023 "Wrong size %d\n", info->Subject.cbData);
3024 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3025 info->Subject.cbData), "Unexpected subject\n");
3026 LocalFree(buf);
3028 /* Check again with pub key specified */
3029 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3030 v1CertWithPubKey, sizeof(v1CertWithPubKey), CRYPT_DECODE_ALLOC_FLAG, NULL,
3031 (BYTE *)&buf, &size);
3032 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3033 if (buf)
3035 CERT_INFO *info = (CERT_INFO *)buf;
3037 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3038 ok(info->SerialNumber.cbData == 1,
3039 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3040 ok(*info->SerialNumber.pbData == *serialNum,
3041 "Expected serial number %d, got %d\n", *serialNum,
3042 *info->SerialNumber.pbData);
3043 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3044 "Wrong size %d\n", info->Issuer.cbData);
3045 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3046 "Unexpected issuer\n");
3047 ok(info->Subject.cbData == sizeof(encodedCommonName),
3048 "Wrong size %d\n", info->Subject.cbData);
3049 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3050 info->Subject.cbData), "Unexpected subject\n");
3051 ok(!strcmp(info->SubjectPublicKeyInfo.Algorithm.pszObjId,
3052 szOID_RSA_RSA), "Expected szOID_RSA_RSA, got %s\n",
3053 info->SubjectPublicKeyInfo.Algorithm.pszObjId);
3054 ok(info->SubjectPublicKeyInfo.PublicKey.cbData == sizeof(aKey),
3055 "Wrong size %d\n", info->SubjectPublicKeyInfo.PublicKey.cbData);
3056 ok(!memcmp(info->SubjectPublicKeyInfo.PublicKey.pbData, aKey,
3057 sizeof(aKey)), "Unexpected public key\n");
3058 LocalFree(buf);
3062 static const BYTE hash[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
3063 0xe, 0xf };
3065 static const BYTE signedBigCert[] = {
3066 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
3067 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
3068 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
3069 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3070 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
3071 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
3072 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
3073 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
3074 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
3075 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3076 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
3077 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
3079 static void test_encodeCert(DWORD dwEncoding)
3081 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
3082 * also that bigCert is a NULL-terminated string, so don't count its
3083 * last byte (otherwise the signed cert won't decode.)
3085 CERT_SIGNED_CONTENT_INFO info = { { sizeof(bigCert), (BYTE *)bigCert },
3086 { NULL, { 0, NULL } }, { sizeof(hash), (BYTE *)hash, 0 } };
3087 BOOL ret;
3088 BYTE *buf = NULL;
3089 DWORD bufSize = 0;
3091 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT, &info,
3092 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
3093 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3094 if (buf)
3096 ok(bufSize == sizeof(signedBigCert), "Wrong size %d\n", bufSize);
3097 ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n");
3098 LocalFree(buf);
3102 static void test_decodeCert(DWORD dwEncoding)
3104 BOOL ret;
3105 BYTE *buf = NULL;
3106 DWORD size = 0;
3108 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert,
3109 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3110 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3111 if (buf)
3113 CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf;
3115 ok(info->ToBeSigned.cbData == sizeof(bigCert),
3116 "Wrong cert size %d\n", info->ToBeSigned.cbData);
3117 ok(!memcmp(info->ToBeSigned.pbData, bigCert, info->ToBeSigned.cbData),
3118 "Unexpected cert\n");
3119 ok(info->Signature.cbData == sizeof(hash),
3120 "Wrong signature size %d\n", info->Signature.cbData);
3121 ok(!memcmp(info->Signature.pbData, hash, info->Signature.cbData),
3122 "Unexpected signature\n");
3123 LocalFree(buf);
3125 /* A signed cert decodes as a CERT_INFO too */
3126 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCert,
3127 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3128 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3129 if (buf)
3131 CERT_INFO *info = (CERT_INFO *)buf;
3133 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3134 ok(info->SerialNumber.cbData == 1,
3135 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3136 ok(*info->SerialNumber.pbData == *serialNum,
3137 "Expected serial number %d, got %d\n", *serialNum,
3138 *info->SerialNumber.pbData);
3139 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3140 "Wrong size %d\n", info->Issuer.cbData);
3141 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3142 "Unexpected issuer\n");
3143 ok(info->Subject.cbData == sizeof(encodedCommonName),
3144 "Wrong size %d\n", info->Subject.cbData);
3145 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3146 info->Subject.cbData), "Unexpected subject\n");
3147 LocalFree(buf);
3151 static const BYTE emptyDistPoint[] = { 0x30, 0x02, 0x30, 0x00 };
3152 static const BYTE distPointWithUrl[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3153 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3154 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3155 static const BYTE distPointWithReason[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3156 0x00, 0x03 };
3157 static const BYTE distPointWithIssuer[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3158 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3159 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3160 static const BYTE distPointWithUrlAndIssuer[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3161 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3162 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3163 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3164 0x2e, 0x6f, 0x72, 0x67 };
3165 static const BYTE crlReason = CRL_REASON_KEY_COMPROMISE |
3166 CRL_REASON_AFFILIATION_CHANGED;
3168 static void test_encodeCRLDistPoints(DWORD dwEncoding)
3170 CRL_DIST_POINTS_INFO info = { 0 };
3171 CRL_DIST_POINT point = { { 0 } };
3172 CERT_ALT_NAME_ENTRY entry = { 0 };
3173 BOOL ret;
3174 BYTE *buf = NULL;
3175 DWORD size = 0;
3177 /* Test with an empty info */
3178 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3179 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3180 ok(!ret && GetLastError() == E_INVALIDARG,
3181 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3182 /* Test with one empty dist point */
3183 info.cDistPoint = 1;
3184 info.rgDistPoint = &point;
3185 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3186 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3187 if (buf)
3189 ok(size == sizeof(emptyDistPoint), "Wrong size %d\n", size);
3190 ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n");
3191 LocalFree(buf);
3193 /* A dist point with an invalid name */
3194 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3195 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3196 U(entry).pwszURL = (LPWSTR)nihongoURL;
3197 U(point.DistPointName).FullName.cAltEntry = 1;
3198 U(point.DistPointName).FullName.rgAltEntry = &entry;
3199 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3200 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3201 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
3202 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
3203 /* The first invalid character is at index 7 */
3204 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
3205 "Expected invalid char at index 7, got %d\n",
3206 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
3207 /* A dist point with (just) a valid name */
3208 U(entry).pwszURL = (LPWSTR)url;
3209 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3210 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3211 if (buf)
3213 ok(size == sizeof(distPointWithUrl), "Wrong size %d\n", size);
3214 ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n");
3215 LocalFree(buf);
3217 /* A dist point with (just) reason flags */
3218 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3219 point.ReasonFlags.cbData = sizeof(crlReason);
3220 point.ReasonFlags.pbData = (LPBYTE)&crlReason;
3221 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3222 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3223 if (buf)
3225 ok(size == sizeof(distPointWithReason), "Wrong size %d\n", size);
3226 ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n");
3227 LocalFree(buf);
3229 /* A dist point with just an issuer */
3230 point.ReasonFlags.cbData = 0;
3231 point.CRLIssuer.cAltEntry = 1;
3232 point.CRLIssuer.rgAltEntry = &entry;
3233 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3234 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3235 if (buf)
3237 ok(size == sizeof(distPointWithIssuer), "Wrong size %d\n", size);
3238 ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n");
3239 LocalFree(buf);
3241 /* A dist point with both a name and an issuer */
3242 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3243 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3244 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3245 if (buf)
3247 ok(size == sizeof(distPointWithUrlAndIssuer),
3248 "Wrong size %d\n", size);
3249 ok(!memcmp(buf, distPointWithUrlAndIssuer, size), "Unexpected value\n");
3250 LocalFree(buf);
3254 static void test_decodeCRLDistPoints(DWORD dwEncoding)
3256 BOOL ret;
3257 BYTE *buf = NULL;
3258 DWORD size = 0;
3259 PCRL_DIST_POINTS_INFO info;
3260 PCRL_DIST_POINT point;
3261 PCERT_ALT_NAME_ENTRY entry;
3263 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3264 emptyDistPoint, emptyDistPoint[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3265 (BYTE *)&buf, &size);
3266 if (ret)
3268 info = (PCRL_DIST_POINTS_INFO)buf;
3269 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3270 "Wrong size %d\n", size);
3271 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3272 info->cDistPoint);
3273 point = info->rgDistPoint;
3274 ok(point->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_NO_NAME,
3275 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3276 point->DistPointName.dwDistPointNameChoice);
3277 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3278 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3279 LocalFree(buf);
3281 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3282 distPointWithUrl, distPointWithUrl[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3283 (BYTE *)&buf, &size);
3284 if (ret)
3286 info = (PCRL_DIST_POINTS_INFO)buf;
3287 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3288 "Wrong size %d\n", size);
3289 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3290 info->cDistPoint);
3291 point = info->rgDistPoint;
3292 ok(point->DistPointName.dwDistPointNameChoice ==
3293 CRL_DIST_POINT_FULL_NAME,
3294 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3295 point->DistPointName.dwDistPointNameChoice);
3296 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3297 "Expected 1 name entry, got %d\n",
3298 U(point->DistPointName).FullName.cAltEntry);
3299 entry = U(point->DistPointName).FullName.rgAltEntry;
3300 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3301 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3302 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3303 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3304 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3305 LocalFree(buf);
3307 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3308 distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
3309 NULL, (BYTE *)&buf, &size);
3310 if (ret)
3312 info = (PCRL_DIST_POINTS_INFO)buf;
3313 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3314 "Wrong size %d\n", size);
3315 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3316 info->cDistPoint);
3317 point = info->rgDistPoint;
3318 ok(point->DistPointName.dwDistPointNameChoice ==
3319 CRL_DIST_POINT_NO_NAME,
3320 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3321 point->DistPointName.dwDistPointNameChoice);
3322 ok(point->ReasonFlags.cbData == sizeof(crlReason),
3323 "Expected reason length\n");
3324 ok(!memcmp(point->ReasonFlags.pbData, &crlReason, sizeof(crlReason)),
3325 "Unexpected reason\n");
3326 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3327 LocalFree(buf);
3329 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3330 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2,
3331 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3332 if (ret)
3334 info = (PCRL_DIST_POINTS_INFO)buf;
3335 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3336 "Wrong size %d\n", size);
3337 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3338 info->cDistPoint);
3339 point = info->rgDistPoint;
3340 ok(point->DistPointName.dwDistPointNameChoice ==
3341 CRL_DIST_POINT_FULL_NAME,
3342 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3343 point->DistPointName.dwDistPointNameChoice);
3344 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3345 "Expected 1 name entry, got %d\n",
3346 U(point->DistPointName).FullName.cAltEntry);
3347 entry = U(point->DistPointName).FullName.rgAltEntry;
3348 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3349 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3350 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3351 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3352 ok(point->CRLIssuer.cAltEntry == 1,
3353 "Expected 1 issuer entry, got %d\n", point->CRLIssuer.cAltEntry);
3354 entry = point->CRLIssuer.rgAltEntry;
3355 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3356 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3357 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3358 LocalFree(buf);
3362 static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3363 static const BYTE emptyNameIDP[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3364 static const BYTE urlIDP[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3365 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3366 0x67 };
3368 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding)
3370 BOOL ret;
3371 BYTE *buf = NULL;
3372 DWORD size = 0;
3373 CRL_ISSUING_DIST_POINT point = { { 0 } };
3374 CERT_ALT_NAME_ENTRY entry;
3376 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, NULL,
3377 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3378 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3380 skip("no X509_ISSUING_DIST_POINT encode support\n");
3381 return;
3383 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3384 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3385 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3386 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3387 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3388 if (buf)
3390 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
3391 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
3392 LocalFree(buf);
3394 /* nonsensical flags */
3395 point.fOnlyContainsUserCerts = TRUE;
3396 point.fOnlyContainsCACerts = TRUE;
3397 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3398 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3399 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3400 if (buf)
3402 ok(size == sizeof(badFlagsIDP), "Unexpected size %d\n", size);
3403 ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n");
3404 LocalFree(buf);
3406 /* unimplemented name type */
3407 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3408 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_ISSUER_RDN_NAME;
3409 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3410 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3411 ok(!ret && GetLastError() == E_INVALIDARG,
3412 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3413 /* empty name */
3414 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3415 U(point.DistPointName).FullName.cAltEntry = 0;
3416 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3417 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3418 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3419 if (buf)
3421 ok(size == sizeof(emptyNameIDP), "Unexpected size %d\n", size);
3422 ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n");
3423 LocalFree(buf);
3425 /* name with URL entry */
3426 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3427 U(entry).pwszURL = (LPWSTR)url;
3428 U(point.DistPointName).FullName.cAltEntry = 1;
3429 U(point.DistPointName).FullName.rgAltEntry = &entry;
3430 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3431 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3432 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3433 if (buf)
3435 ok(size == sizeof(urlIDP), "Unexpected size %d\n", size);
3436 ok(!memcmp(buf, urlIDP, size), "Unexpected value\n");
3437 LocalFree(buf);
3441 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY *expected,
3442 const CERT_ALT_NAME_ENTRY *got)
3444 ok(expected->dwAltNameChoice == got->dwAltNameChoice,
3445 "Expected name choice %d, got %d\n", expected->dwAltNameChoice,
3446 got->dwAltNameChoice);
3447 if (expected->dwAltNameChoice == got->dwAltNameChoice)
3449 switch (got->dwAltNameChoice)
3451 case CERT_ALT_NAME_RFC822_NAME:
3452 case CERT_ALT_NAME_DNS_NAME:
3453 case CERT_ALT_NAME_EDI_PARTY_NAME:
3454 case CERT_ALT_NAME_URL:
3455 case CERT_ALT_NAME_REGISTERED_ID:
3456 ok((!U(*expected).pwszURL && !U(*got).pwszURL) ||
3457 (!U(*expected).pwszURL && !lstrlenW(U(*got).pwszURL)) ||
3458 (!U(*got).pwszURL && !lstrlenW(U(*expected).pwszURL)) ||
3459 !lstrcmpW(U(*expected).pwszURL, U(*got).pwszURL),
3460 "Unexpected name\n");
3461 break;
3462 case CERT_ALT_NAME_X400_ADDRESS:
3463 case CERT_ALT_NAME_DIRECTORY_NAME:
3464 case CERT_ALT_NAME_IP_ADDRESS:
3465 ok(U(*got).IPAddress.cbData == U(*expected).IPAddress.cbData,
3466 "Unexpected IP address length %d\n", U(*got).IPAddress.cbData);
3467 ok(!memcmp(U(*got).IPAddress.pbData, U(*got).IPAddress.pbData,
3468 U(*got).IPAddress.cbData), "Unexpected value\n");
3469 break;
3474 static void compareAltNameInfo(const CERT_ALT_NAME_INFO *expected,
3475 const CERT_ALT_NAME_INFO *got)
3477 DWORD i;
3479 ok(expected->cAltEntry == got->cAltEntry, "Expected %d entries, got %d\n",
3480 expected->cAltEntry, got->cAltEntry);
3481 for (i = 0; i < min(expected->cAltEntry, got->cAltEntry); i++)
3482 compareAltNameEntry(&expected->rgAltEntry[i], &got->rgAltEntry[i]);
3485 static void compareDistPointName(const CRL_DIST_POINT_NAME *expected,
3486 const CRL_DIST_POINT_NAME *got)
3488 ok(got->dwDistPointNameChoice == expected->dwDistPointNameChoice,
3489 "Unexpected name choice %d\n", got->dwDistPointNameChoice);
3490 if (got->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME)
3491 compareAltNameInfo(&(U(*expected).FullName), &(U(*got).FullName));
3494 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT *expected,
3495 const CRL_ISSUING_DIST_POINT *got)
3497 compareDistPointName(&expected->DistPointName, &got->DistPointName);
3498 ok(got->fOnlyContainsUserCerts == expected->fOnlyContainsUserCerts,
3499 "Unexpected fOnlyContainsUserCerts\n");
3500 ok(got->fOnlyContainsCACerts == expected->fOnlyContainsCACerts,
3501 "Unexpected fOnlyContainsCACerts\n");
3502 ok(got->OnlySomeReasonFlags.cbData == expected->OnlySomeReasonFlags.cbData,
3503 "Unexpected reason flags\n");
3504 ok(got->fIndirectCRL == expected->fIndirectCRL,
3505 "Unexpected fIndirectCRL\n");
3508 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding)
3510 BOOL ret;
3511 BYTE *buf = NULL;
3512 DWORD size = 0;
3513 CRL_ISSUING_DIST_POINT point = { { 0 } };
3515 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3516 emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3517 (BYTE *)&buf, &size);
3518 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3520 skip("no X509_ISSUING_DIST_POINT decode support\n");
3521 return;
3523 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3524 if (ret)
3526 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3527 LocalFree(buf);
3529 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3530 badFlagsIDP, badFlagsIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3531 (BYTE *)&buf, &size);
3532 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3533 if (ret)
3535 point.fOnlyContainsUserCerts = point.fOnlyContainsCACerts = TRUE;
3536 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3537 LocalFree(buf);
3539 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3540 emptyNameIDP, emptyNameIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3541 (BYTE *)&buf, &size);
3542 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3543 if (ret)
3545 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3546 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3547 U(point.DistPointName).FullName.cAltEntry = 0;
3548 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3549 LocalFree(buf);
3551 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3552 urlIDP, urlIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3553 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3554 if (ret)
3556 CERT_ALT_NAME_ENTRY entry;
3558 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3559 U(entry).pwszURL = (LPWSTR)url;
3560 U(point.DistPointName).FullName.cAltEntry = 1;
3561 U(point.DistPointName).FullName.rgAltEntry = &entry;
3562 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3563 LocalFree(buf);
3567 static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3568 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3569 0x30, 0x5a };
3570 static const BYTE v2CRL[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3571 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3572 0x30, 0x30, 0x30, 0x30, 0x5a };
3573 static const BYTE v1CRLWithIssuer[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3574 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3575 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3576 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3577 0x5a };
3578 static const BYTE v1CRLWithIssuerAndEmptyEntry[] = { 0x30, 0x43, 0x30, 0x02,
3579 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3580 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3581 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3582 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3583 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3584 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3585 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3586 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3587 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3588 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3589 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3590 static const BYTE v1CRLWithEntryExt[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3591 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3592 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3593 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3594 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3595 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3596 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3597 static const BYTE v1CRLWithExt[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3598 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3599 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3600 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
3601 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3602 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
3603 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3604 static const BYTE v2CRLWithExt[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
3605 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
3606 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
3607 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
3608 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
3609 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
3610 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3611 static const BYTE v2CRLWithIssuingDistPoint[] = { 0x30,0x5c,0x02,0x01,0x01,
3612 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
3613 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
3614 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
3615 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3616 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
3617 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3619 static void test_encodeCRLToBeSigned(DWORD dwEncoding)
3621 BOOL ret;
3622 BYTE *buf = NULL;
3623 static CHAR oid_issuing_dist_point[] = szOID_ISSUING_DIST_POINT;
3624 DWORD size = 0;
3625 CRL_INFO info = { 0 };
3626 CRL_ENTRY entry = { { 0 }, { 0 }, 0, 0 };
3627 CERT_EXTENSION ext;
3629 /* Test with a V1 CRL */
3630 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3631 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3632 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3633 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3634 if (buf)
3636 ok(size == sizeof(v1CRL), "Wrong size %d\n", size);
3637 ok(!memcmp(buf, v1CRL, size), "Got unexpected value\n");
3638 LocalFree(buf);
3640 /* Test v2 CRL */
3641 info.dwVersion = CRL_V2;
3642 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3643 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3644 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3645 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3646 if (buf)
3648 ok(size == v2CRL[1] + 2, "Expected size %d, got %d\n",
3649 v2CRL[1] + 2, size);
3650 ok(!memcmp(buf, v2CRL, size), "Got unexpected value\n");
3651 LocalFree(buf);
3653 /* v1 CRL with a name */
3654 info.dwVersion = CRL_V1;
3655 info.Issuer.cbData = sizeof(encodedCommonName);
3656 info.Issuer.pbData = (BYTE *)encodedCommonName;
3657 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3658 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3659 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3660 if (buf)
3662 ok(size == sizeof(v1CRLWithIssuer), "Wrong size %d\n", size);
3663 ok(!memcmp(buf, v1CRLWithIssuer, size), "Got unexpected value\n");
3664 LocalFree(buf);
3666 if (0)
3668 /* v1 CRL with a name and a NULL entry pointer (crashes on win9x) */
3669 info.cCRLEntry = 1;
3670 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3671 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3672 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3673 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3675 /* now set an empty entry */
3676 info.cCRLEntry = 1;
3677 info.rgCRLEntry = &entry;
3678 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3679 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3680 if (buf)
3682 ok(size == sizeof(v1CRLWithIssuerAndEmptyEntry),
3683 "Wrong size %d\n", size);
3684 ok(!memcmp(buf, v1CRLWithIssuerAndEmptyEntry, size),
3685 "Got unexpected value\n");
3686 LocalFree(buf);
3688 /* an entry with a serial number */
3689 entry.SerialNumber.cbData = sizeof(serialNum);
3690 entry.SerialNumber.pbData = (BYTE *)serialNum;
3691 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3692 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3693 if (buf)
3695 ok(size == sizeof(v1CRLWithIssuerAndEntry),
3696 "Wrong size %d\n", size);
3697 ok(!memcmp(buf, v1CRLWithIssuerAndEntry, size),
3698 "Got unexpected value\n");
3699 LocalFree(buf);
3701 /* an entry with an extension */
3702 entry.cExtension = 1;
3703 entry.rgExtension = &criticalExt;
3704 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3705 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3706 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3707 if (buf)
3709 ok(size == sizeof(v1CRLWithEntryExt), "Wrong size %d\n", size);
3710 ok(!memcmp(buf, v1CRLWithEntryExt, size), "Got unexpected value\n");
3711 LocalFree(buf);
3713 /* a CRL with an extension */
3714 entry.cExtension = 0;
3715 info.cExtension = 1;
3716 info.rgExtension = &criticalExt;
3717 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3718 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3719 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3720 if (buf)
3722 ok(size == sizeof(v1CRLWithExt), "Wrong size %d\n", size);
3723 ok(!memcmp(buf, v1CRLWithExt, size), "Got unexpected value\n");
3724 LocalFree(buf);
3726 /* a v2 CRL with an extension, this time non-critical */
3727 info.dwVersion = CRL_V2;
3728 info.rgExtension = &nonCriticalExt;
3729 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3730 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3731 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3732 if (buf)
3734 ok(size == sizeof(v2CRLWithExt), "Wrong size %d\n", size);
3735 ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n");
3736 LocalFree(buf);
3738 /* a v2 CRL with an issuing dist point extension */
3739 ext.pszObjId = oid_issuing_dist_point;
3740 ext.fCritical = TRUE;
3741 ext.Value.cbData = sizeof(urlIDP);
3742 ext.Value.pbData = (LPBYTE)urlIDP;
3743 entry.rgExtension = &ext;
3744 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3745 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3746 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3747 if (buf)
3749 ok(size == sizeof(v2CRLWithIssuingDistPoint), "Wrong size %d\n", size);
3750 ok(!memcmp(buf, v2CRLWithIssuingDistPoint, size), "Unexpected value\n");
3751 LocalFree(buf);
3755 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
3756 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
3757 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
3758 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
3759 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
3760 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
3761 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
3762 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
3763 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
3764 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
3765 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
3766 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
3767 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
3768 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
3769 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
3770 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
3771 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
3772 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
3773 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
3774 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
3775 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
3776 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
3777 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
3778 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
3779 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
3780 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
3781 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
3782 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
3783 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
3784 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
3785 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
3786 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
3787 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
3788 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
3789 0xcd };
3790 static const BYTE verisignCRLWithLotsOfEntries[] = {
3791 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
3792 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
3793 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
3794 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
3795 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
3796 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
3797 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
3798 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
3799 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
3800 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
3801 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
3802 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
3803 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
3804 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
3805 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
3806 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
3807 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3808 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
3809 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
3810 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3811 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
3812 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
3813 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
3814 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
3815 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
3816 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
3817 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
3818 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
3819 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
3820 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
3821 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3822 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
3823 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
3824 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3825 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
3826 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
3827 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
3828 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
3829 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
3830 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
3831 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
3832 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
3833 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
3834 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
3835 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
3836 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
3837 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
3838 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
3839 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
3840 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
3841 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
3842 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
3843 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
3844 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
3845 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3846 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
3847 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
3848 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
3849 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
3850 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
3851 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
3852 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
3853 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
3854 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
3855 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
3856 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
3857 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
3858 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
3859 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
3860 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
3861 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
3862 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
3863 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
3864 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
3865 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
3866 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
3867 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
3868 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
3869 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
3870 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
3871 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
3872 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
3873 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3874 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
3875 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
3876 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
3877 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
3878 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
3879 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
3880 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
3881 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
3882 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
3883 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
3884 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
3885 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
3886 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
3887 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
3888 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
3889 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
3890 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
3891 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
3892 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
3893 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
3894 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
3895 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
3896 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
3897 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
3898 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
3899 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
3900 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
3901 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3902 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
3903 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
3904 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
3905 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
3906 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
3907 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
3908 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
3909 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
3910 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
3911 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
3912 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
3913 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
3914 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
3915 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3916 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
3917 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
3918 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
3919 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
3920 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
3921 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
3922 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
3923 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
3924 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
3925 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
3926 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
3927 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
3928 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
3929 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
3930 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
3931 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
3932 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
3933 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
3934 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
3935 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
3936 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
3937 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
3938 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
3939 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
3940 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
3941 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
3942 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
3943 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
3944 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
3945 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
3946 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
3947 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
3948 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
3949 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
3950 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
3951 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
3952 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
3953 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
3954 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
3955 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
3956 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
3957 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
3958 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
3959 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
3960 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
3961 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
3962 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
3963 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
3964 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
3965 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
3966 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
3967 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
3968 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
3969 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
3970 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
3971 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
3972 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
3973 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
3974 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
3975 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
3976 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
3977 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
3978 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
3979 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
3980 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
3981 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
3982 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
3983 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
3984 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
3985 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
3986 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
3987 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
3988 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
3989 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
3990 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
3991 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
3992 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
3993 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
3994 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
3995 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
3996 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
3997 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
3998 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
3999 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
4000 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
4001 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
4002 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
4003 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
4004 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
4005 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
4006 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
4007 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
4008 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
4009 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
4010 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
4011 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
4012 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
4013 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
4014 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
4015 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
4016 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
4017 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
4018 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
4019 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
4020 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
4021 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
4022 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
4023 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
4024 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
4025 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
4026 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
4027 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
4028 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
4029 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
4030 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
4031 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
4032 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
4033 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
4034 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
4035 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
4036 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
4037 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
4038 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
4039 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
4040 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
4041 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
4042 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
4043 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
4044 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
4045 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
4046 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
4047 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
4048 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
4049 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
4050 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
4051 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
4052 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
4053 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
4054 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
4055 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
4056 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
4057 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
4058 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
4059 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
4060 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
4061 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
4062 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
4063 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
4064 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
4065 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
4066 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
4067 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
4068 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
4069 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
4070 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
4071 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
4072 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
4073 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
4074 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
4075 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
4076 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
4077 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
4078 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
4079 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
4080 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
4081 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
4082 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
4083 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
4084 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
4085 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
4086 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
4087 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
4088 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
4089 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
4090 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
4091 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
4092 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
4093 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
4094 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4095 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4096 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4097 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4098 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4099 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4100 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4101 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4102 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4103 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4104 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4105 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4106 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4107 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4108 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4109 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4110 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4111 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4112 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4113 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4114 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4115 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4116 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4117 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4118 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4119 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4120 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4121 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4122 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4123 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4124 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4125 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4126 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4127 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4128 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4129 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4130 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4131 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4132 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4133 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4134 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4135 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4136 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4137 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4138 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4139 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4140 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4141 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4142 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4143 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4144 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4145 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4146 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4147 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4148 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4149 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4150 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4151 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4152 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4153 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4154 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4155 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4156 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4157 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4158 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4159 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4160 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4161 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4162 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4163 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4164 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4165 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4166 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4167 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4168 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4169 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4170 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4171 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4172 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4173 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4174 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4175 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4176 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4177 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4178 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4179 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4180 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4181 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4182 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4183 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4184 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4185 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4186 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4187 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4188 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4189 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4190 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4191 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4192 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4193 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4194 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4195 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4196 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4197 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4198 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4199 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4200 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4201 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4202 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4203 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4204 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4205 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4206 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4207 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4208 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4209 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4210 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4211 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4212 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4213 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4214 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4215 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4216 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4217 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4218 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4219 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4220 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4221 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4222 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4223 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4224 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4225 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4226 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4227 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4228 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4229 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4230 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4231 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4232 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4233 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4234 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4235 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4236 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4237 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4238 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4239 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4240 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4241 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4242 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4243 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4244 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4245 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4246 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4247 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4248 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4249 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4250 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4251 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4252 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4253 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4254 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4255 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4256 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4257 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4258 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4259 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4260 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4261 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4262 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4263 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4264 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4265 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4266 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4267 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4268 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4269 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4270 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4271 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4272 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4273 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4274 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4275 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4276 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4277 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4278 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4279 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4280 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4281 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4282 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4283 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4284 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4285 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4286 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4287 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4288 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4289 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4290 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4291 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4292 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4293 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4294 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4295 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4296 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4297 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4298 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4300 static void test_decodeCRLToBeSigned(DWORD dwEncoding)
4302 static const BYTE *corruptCRLs[] = { v1CRL, v2CRL };
4303 BOOL ret;
4304 BYTE *buf = NULL;
4305 DWORD size = 0, i;
4307 for (i = 0; i < sizeof(corruptCRLs) / sizeof(corruptCRLs[0]); i++)
4309 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4310 corruptCRLs[i], corruptCRLs[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4311 (BYTE *)&buf, &size);
4312 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4313 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4314 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4315 GetLastError());
4317 /* at a minimum, a CRL must contain an issuer: */
4318 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4319 v1CRLWithIssuer, v1CRLWithIssuer[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4320 (BYTE *)&buf, &size);
4321 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4322 if (buf)
4324 CRL_INFO *info = (CRL_INFO *)buf;
4326 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4327 ok(info->cCRLEntry == 0, "Expected 0 CRL entries, got %d\n",
4328 info->cCRLEntry);
4329 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4330 "Wrong issuer size %d\n", info->Issuer.cbData);
4331 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4332 "Unexpected issuer\n");
4333 LocalFree(buf);
4335 /* check decoding with an empty CRL entry */
4336 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4337 v1CRLWithIssuerAndEmptyEntry, v1CRLWithIssuerAndEmptyEntry[1] + 2,
4338 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4339 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4340 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4341 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4342 GetLastError());
4343 /* with a real CRL entry */
4344 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4345 v1CRLWithIssuerAndEntry, v1CRLWithIssuerAndEntry[1] + 2,
4346 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4347 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4348 if (buf)
4350 CRL_INFO *info = (CRL_INFO *)buf;
4351 CRL_ENTRY *entry;
4353 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4354 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4355 info->cCRLEntry);
4356 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4357 entry = info->rgCRLEntry;
4358 ok(entry->SerialNumber.cbData == 1,
4359 "Expected serial number size 1, got %d\n",
4360 entry->SerialNumber.cbData);
4361 ok(*entry->SerialNumber.pbData == *serialNum,
4362 "Expected serial number %d, got %d\n", *serialNum,
4363 *entry->SerialNumber.pbData);
4364 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4365 "Wrong issuer size %d\n", info->Issuer.cbData);
4366 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4367 "Unexpected issuer\n");
4368 LocalFree(buf);
4370 /* a real CRL from verisign that has extensions */
4371 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4372 verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG,
4373 NULL, (BYTE *)&buf, &size);
4374 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4375 if (buf)
4377 CRL_INFO *info = (CRL_INFO *)buf;
4378 CRL_ENTRY *entry;
4380 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4381 ok(info->cCRLEntry == 3, "Expected 3 CRL entries, got %d\n",
4382 info->cCRLEntry);
4383 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4384 entry = info->rgCRLEntry;
4385 ok(info->cExtension == 2, "Expected 2 extensions, got %d\n",
4386 info->cExtension);
4387 LocalFree(buf);
4389 /* another real CRL from verisign that has lots of entries */
4390 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4391 verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries),
4392 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4393 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4394 if (buf)
4396 CRL_INFO *info = (CRL_INFO *)buf;
4398 ok(size >= sizeof(CRL_INFO), "Got size %d\n", size);
4399 ok(info->cCRLEntry == 209, "Expected 209 CRL entries, got %d\n",
4400 info->cCRLEntry);
4401 ok(info->cExtension == 0, "Expected 0 extensions, got %d\n",
4402 info->cExtension);
4403 LocalFree(buf);
4405 /* and finally, with an extension */
4406 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4407 v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4408 NULL, (BYTE *)&buf, &size);
4409 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4410 if (buf)
4412 CRL_INFO *info = (CRL_INFO *)buf;
4413 CRL_ENTRY *entry;
4415 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4416 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4417 info->cCRLEntry);
4418 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4419 entry = info->rgCRLEntry;
4420 ok(entry->SerialNumber.cbData == 1,
4421 "Expected serial number size 1, got %d\n",
4422 entry->SerialNumber.cbData);
4423 ok(*entry->SerialNumber.pbData == *serialNum,
4424 "Expected serial number %d, got %d\n", *serialNum,
4425 *entry->SerialNumber.pbData);
4426 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4427 "Wrong issuer size %d\n", info->Issuer.cbData);
4428 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4429 "Unexpected issuer\n");
4430 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4431 info->cExtension);
4432 LocalFree(buf);
4434 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4435 v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4436 NULL, (BYTE *)&buf, &size);
4437 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4438 if (buf)
4440 CRL_INFO *info = (CRL_INFO *)buf;
4442 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4443 info->cExtension);
4444 LocalFree(buf);
4446 /* And again, with an issuing dist point */
4447 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4448 v2CRLWithIssuingDistPoint, sizeof(v2CRLWithIssuingDistPoint),
4449 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4450 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4451 if (buf)
4453 CRL_INFO *info = (CRL_INFO *)buf;
4455 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4456 info->cExtension);
4457 LocalFree(buf);
4461 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
4462 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
4463 static const BYTE encodedUsage[] = {
4464 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4465 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4466 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4468 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding)
4470 BOOL ret;
4471 BYTE *buf = NULL;
4472 DWORD size = 0;
4473 CERT_ENHKEY_USAGE usage;
4475 /* Test with empty usage */
4476 usage.cUsageIdentifier = 0;
4477 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4478 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4479 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4480 if (buf)
4482 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
4483 ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n");
4484 LocalFree(buf);
4486 /* Test with a few usages */
4487 usage.cUsageIdentifier = sizeof(keyUsages) / sizeof(keyUsages[0]);
4488 usage.rgpszUsageIdentifier = (LPSTR *)keyUsages;
4489 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4490 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4491 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4492 if (buf)
4494 ok(size == sizeof(encodedUsage), "Wrong size %d\n", size);
4495 ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n");
4496 LocalFree(buf);
4500 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding)
4502 BOOL ret;
4503 LPBYTE buf = NULL;
4504 DWORD size = 0;
4506 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4507 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4508 (BYTE *)&buf, &size);
4509 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4510 if (buf)
4512 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4514 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4515 "Wrong size %d\n", size);
4516 ok(usage->cUsageIdentifier == 0, "Expected 0 CRL entries, got %d\n",
4517 usage->cUsageIdentifier);
4518 LocalFree(buf);
4520 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4521 encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL,
4522 (BYTE *)&buf, &size);
4523 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4524 if (buf)
4526 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4527 DWORD i;
4529 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4530 "Wrong size %d\n", size);
4531 ok(usage->cUsageIdentifier == sizeof(keyUsages) / sizeof(keyUsages[0]),
4532 "Wrong CRL entries count %d\n", usage->cUsageIdentifier);
4533 for (i = 0; i < usage->cUsageIdentifier; i++)
4534 ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]),
4535 "Expected OID %s, got %s\n", keyUsages[i],
4536 usage->rgpszUsageIdentifier[i]);
4537 LocalFree(buf);
4541 static BYTE keyId[] = { 1,2,3,4 };
4542 static const BYTE authorityKeyIdWithId[] = {
4543 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4544 static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4545 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4546 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4547 static const BYTE authorityKeyIdWithSerial[] = { 0x30,0x03,0x82,0x01,0x01 };
4549 static void test_encodeAuthorityKeyId(DWORD dwEncoding)
4551 CERT_AUTHORITY_KEY_ID_INFO info = { { 0 } };
4552 BOOL ret;
4553 BYTE *buf = NULL;
4554 DWORD size = 0;
4556 /* Test with empty id */
4557 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4558 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4559 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4560 if (buf)
4562 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4563 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4564 LocalFree(buf);
4566 /* With just a key id */
4567 info.KeyId.cbData = sizeof(keyId);
4568 info.KeyId.pbData = keyId;
4569 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4570 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4571 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4572 if (buf)
4574 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", size);
4575 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4576 LocalFree(buf);
4578 /* With just an issuer */
4579 info.KeyId.cbData = 0;
4580 info.CertIssuer.cbData = sizeof(encodedCommonName);
4581 info.CertIssuer.pbData = (BYTE *)encodedCommonName;
4582 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4583 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4584 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4585 if (buf)
4587 ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %d\n",
4588 size);
4589 ok(!memcmp(buf, authorityKeyIdWithIssuer, size), "Unexpected value\n");
4590 LocalFree(buf);
4592 /* With just a serial number */
4593 info.CertIssuer.cbData = 0;
4594 info.CertSerialNumber.cbData = sizeof(serialNum);
4595 info.CertSerialNumber.pbData = (BYTE *)serialNum;
4596 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4597 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4598 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4599 if (buf)
4601 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4602 size);
4603 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4604 LocalFree(buf);
4608 static void test_decodeAuthorityKeyId(DWORD dwEncoding)
4610 BOOL ret;
4611 LPBYTE buf = NULL;
4612 DWORD size = 0;
4614 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4615 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4616 (BYTE *)&buf, &size);
4617 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4618 if (buf)
4620 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4622 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4623 size);
4624 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4625 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4626 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4627 LocalFree(buf);
4629 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4630 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4631 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4632 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4633 if (buf)
4635 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4637 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4638 size);
4639 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4640 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4641 "Unexpected key id\n");
4642 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4643 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4644 LocalFree(buf);
4646 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4647 authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer),
4648 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4649 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4650 if (buf)
4652 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4654 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4655 size);
4656 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4657 ok(info->CertIssuer.cbData == sizeof(encodedCommonName),
4658 "Unexpected issuer len\n");
4659 ok(!memcmp(info->CertIssuer.pbData, encodedCommonName,
4660 sizeof(encodedCommonName)), "Unexpected issuer\n");
4661 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4662 LocalFree(buf);
4664 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4665 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4666 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4667 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4668 if (buf)
4670 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4672 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4673 size);
4674 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4675 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4676 ok(info->CertSerialNumber.cbData == sizeof(serialNum),
4677 "Unexpected serial number len\n");
4678 ok(!memcmp(info->CertSerialNumber.pbData, serialNum, sizeof(serialNum)),
4679 "Unexpected serial number\n");
4680 LocalFree(buf);
4684 static const BYTE authorityKeyIdWithIssuerUrl[] = { 0x30,0x15,0xa1,0x13,0x86,
4685 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
4686 0x6f,0x72,0x67 };
4688 static void test_encodeAuthorityKeyId2(DWORD dwEncoding)
4690 CERT_AUTHORITY_KEY_ID2_INFO info = { { 0 } };
4691 CERT_ALT_NAME_ENTRY entry = { 0 };
4692 BOOL ret;
4693 BYTE *buf = NULL;
4694 DWORD size = 0;
4696 /* Test with empty id */
4697 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4698 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4699 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4700 if (buf)
4702 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4703 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4704 LocalFree(buf);
4706 /* With just a key id */
4707 info.KeyId.cbData = sizeof(keyId);
4708 info.KeyId.pbData = keyId;
4709 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4710 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4711 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4712 if (buf)
4714 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n",
4715 size);
4716 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4717 LocalFree(buf);
4719 /* With a bogus issuer name */
4720 info.KeyId.cbData = 0;
4721 info.AuthorityCertIssuer.cAltEntry = 1;
4722 info.AuthorityCertIssuer.rgAltEntry = &entry;
4723 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4724 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4725 ok(!ret && GetLastError() == E_INVALIDARG,
4726 "Expected E_INVALIDARG, got %08x\n", GetLastError());
4727 /* With an issuer name */
4728 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
4729 U(entry).pwszURL = (LPWSTR)url;
4730 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4731 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4732 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4733 if (buf)
4735 ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %d\n",
4736 size);
4737 ok(!memcmp(buf, authorityKeyIdWithIssuerUrl, size),
4738 "Unexpected value\n");
4739 LocalFree(buf);
4741 /* With just a serial number */
4742 info.AuthorityCertIssuer.cAltEntry = 0;
4743 info.AuthorityCertSerialNumber.cbData = sizeof(serialNum);
4744 info.AuthorityCertSerialNumber.pbData = (BYTE *)serialNum;
4745 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4746 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4747 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4748 if (buf)
4750 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4751 size);
4752 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4753 LocalFree(buf);
4757 static void test_decodeAuthorityKeyId2(DWORD dwEncoding)
4759 BOOL ret;
4760 LPBYTE buf = NULL;
4761 DWORD size = 0;
4763 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4764 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4765 (BYTE *)&buf, &size);
4766 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4767 if (buf)
4769 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4771 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4772 size);
4773 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4774 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4775 "Expected no issuer name entries\n");
4776 ok(info->AuthorityCertSerialNumber.cbData == 0,
4777 "Expected no serial number\n");
4778 LocalFree(buf);
4780 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4781 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4782 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4783 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4784 if (buf)
4786 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4788 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4789 size);
4790 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4791 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4792 "Unexpected key id\n");
4793 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4794 "Expected no issuer name entries\n");
4795 ok(info->AuthorityCertSerialNumber.cbData == 0,
4796 "Expected no serial number\n");
4797 LocalFree(buf);
4799 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4800 authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl),
4801 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4802 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4803 if (buf)
4805 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4807 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4808 size);
4809 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4810 ok(info->AuthorityCertIssuer.cAltEntry == 1,
4811 "Expected 1 issuer entry, got %d\n",
4812 info->AuthorityCertIssuer.cAltEntry);
4813 ok(info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice ==
4814 CERT_ALT_NAME_URL, "Expected CERT_ALT_NAME_URL, got %d\n",
4815 info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice);
4816 ok(!lstrcmpW(U(info->AuthorityCertIssuer.rgAltEntry[0]).pwszURL,
4817 url), "Unexpected URL\n");
4818 ok(info->AuthorityCertSerialNumber.cbData == 0,
4819 "Expected no serial number\n");
4820 LocalFree(buf);
4822 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4823 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4824 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4825 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4826 if (buf)
4828 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4830 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4831 size);
4832 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4833 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4834 "Expected no issuer name entries\n");
4835 ok(info->AuthorityCertSerialNumber.cbData == sizeof(serialNum),
4836 "Unexpected serial number len\n");
4837 ok(!memcmp(info->AuthorityCertSerialNumber.pbData, serialNum,
4838 sizeof(serialNum)), "Unexpected serial number\n");
4839 LocalFree(buf);
4843 static const BYTE authorityInfoAccessWithUrl[] = {
4844 0x30,0x19,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
4845 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
4846 static const BYTE authorityInfoAccessWithUrlAndIPAddr[] = {
4847 0x30,0x29,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
4848 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x0e,0x06,
4849 0x02,0x2d,0x06,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
4851 static void test_encodeAuthorityInfoAccess(DWORD dwEncoding)
4853 static char oid1[] = "1.2.3";
4854 static char oid2[] = "1.5.6";
4855 BOOL ret;
4856 BYTE *buf = NULL;
4857 DWORD size = 0;
4858 CERT_ACCESS_DESCRIPTION accessDescription[2];
4859 CERT_AUTHORITY_INFO_ACCESS aia;
4861 memset(accessDescription, 0, sizeof(accessDescription));
4862 aia.cAccDescr = 0;
4863 aia.rgAccDescr = NULL;
4864 /* Having no access descriptions is allowed */
4865 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4866 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4867 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4868 if (buf)
4870 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
4871 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
4872 LocalFree(buf);
4873 buf = NULL;
4875 /* It can't have an empty access method */
4876 aia.cAccDescr = 1;
4877 aia.rgAccDescr = accessDescription;
4878 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4879 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4880 ok(!ret && (GetLastError() == E_INVALIDARG ||
4881 GetLastError() == OSS_LIMITED /* Win9x */),
4882 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
4883 /* It can't have an empty location */
4884 accessDescription[0].pszAccessMethod = oid1;
4885 SetLastError(0xdeadbeef);
4886 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4887 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4888 ok(!ret && GetLastError() == E_INVALIDARG,
4889 "expected E_INVALIDARG, got %08x\n", GetLastError());
4890 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
4891 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
4892 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4893 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4894 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4895 if (buf)
4897 ok(size == sizeof(authorityInfoAccessWithUrl), "unexpected size %d\n",
4898 size);
4899 ok(!memcmp(buf, authorityInfoAccessWithUrl, size),
4900 "unexpected value\n");
4901 LocalFree(buf);
4902 buf = NULL;
4904 accessDescription[1].pszAccessMethod = oid2;
4905 accessDescription[1].AccessLocation.dwAltNameChoice =
4906 CERT_ALT_NAME_IP_ADDRESS;
4907 U(accessDescription[1].AccessLocation).IPAddress.cbData =
4908 sizeof(encodedIPAddr);
4909 U(accessDescription[1].AccessLocation).IPAddress.pbData =
4910 (LPBYTE)encodedIPAddr;
4911 aia.cAccDescr = 2;
4912 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4913 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4914 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4915 if (buf)
4917 ok(size == sizeof(authorityInfoAccessWithUrlAndIPAddr),
4918 "unexpected size %d\n", size);
4919 ok(!memcmp(buf, authorityInfoAccessWithUrlAndIPAddr, size),
4920 "unexpected value\n");
4921 LocalFree(buf);
4922 buf = NULL;
4926 static void compareAuthorityInfoAccess(LPCSTR header,
4927 const CERT_AUTHORITY_INFO_ACCESS *expected,
4928 const CERT_AUTHORITY_INFO_ACCESS *got)
4930 DWORD i;
4932 ok(expected->cAccDescr == got->cAccDescr,
4933 "%s: expected %d access descriptions, got %d\n", header,
4934 expected->cAccDescr, got->cAccDescr);
4935 for (i = 0; i < expected->cAccDescr; i++)
4937 ok(!strcmp(expected->rgAccDescr[i].pszAccessMethod,
4938 got->rgAccDescr[i].pszAccessMethod), "%s[%d]: expected %s, got %s\n",
4939 header, i, expected->rgAccDescr[i].pszAccessMethod,
4940 got->rgAccDescr[i].pszAccessMethod);
4941 compareAltNameEntry(&expected->rgAccDescr[i].AccessLocation,
4942 &got->rgAccDescr[i].AccessLocation);
4946 static void test_decodeAuthorityInfoAccess(DWORD dwEncoding)
4948 static char oid1[] = "1.2.3";
4949 static char oid2[] = "1.5.6";
4950 BOOL ret;
4951 LPBYTE buf = NULL;
4952 DWORD size = 0;
4954 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
4955 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4956 (BYTE *)&buf, &size);
4957 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4958 if (buf)
4960 CERT_AUTHORITY_INFO_ACCESS aia = { 0, NULL };
4962 compareAuthorityInfoAccess("empty AIA", &aia,
4963 (CERT_AUTHORITY_INFO_ACCESS *)buf);
4964 LocalFree(buf);
4965 buf = NULL;
4967 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
4968 authorityInfoAccessWithUrl, sizeof(authorityInfoAccessWithUrl),
4969 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4970 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4971 if (buf)
4973 CERT_ACCESS_DESCRIPTION accessDescription;
4974 CERT_AUTHORITY_INFO_ACCESS aia;
4976 accessDescription.pszAccessMethod = oid1;
4977 accessDescription.AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
4978 U(accessDescription.AccessLocation).pwszURL = (LPWSTR)url;
4979 aia.cAccDescr = 1;
4980 aia.rgAccDescr = &accessDescription;
4981 compareAuthorityInfoAccess("AIA with URL", &aia,
4982 (CERT_AUTHORITY_INFO_ACCESS *)buf);
4983 LocalFree(buf);
4984 buf = NULL;
4986 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
4987 authorityInfoAccessWithUrlAndIPAddr,
4988 sizeof(authorityInfoAccessWithUrlAndIPAddr), CRYPT_DECODE_ALLOC_FLAG,
4989 NULL, (BYTE *)&buf, &size);
4990 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4991 if (buf)
4993 CERT_ACCESS_DESCRIPTION accessDescription[2];
4994 CERT_AUTHORITY_INFO_ACCESS aia;
4996 accessDescription[0].pszAccessMethod = oid1;
4997 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
4998 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
4999 accessDescription[1].pszAccessMethod = oid2;
5000 accessDescription[1].AccessLocation.dwAltNameChoice =
5001 CERT_ALT_NAME_IP_ADDRESS;
5002 U(accessDescription[1].AccessLocation).IPAddress.cbData =
5003 sizeof(encodedIPAddr);
5004 U(accessDescription[1].AccessLocation).IPAddress.pbData =
5005 (LPBYTE)encodedIPAddr;
5006 aia.cAccDescr = 2;
5007 aia.rgAccDescr = accessDescription;
5008 compareAuthorityInfoAccess("AIA with URL and IP addr", &aia,
5009 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5010 LocalFree(buf);
5011 buf = NULL;
5015 static const BYTE emptyCTL[] = {
5016 0x30,0x17,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5017 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5018 static const BYTE emptyCTLWithVersion1[] = {
5019 0x30,0x1a,0x02,0x01,0x01,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5020 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5021 static const BYTE ctlWithUsageIdentifier[] = {
5022 0x30,0x1b,0x30,0x04,0x06,0x02,0x2a,0x03,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
5023 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5024 static const BYTE ctlWithListIdentifier[] = {
5025 0x30,0x1a,0x30,0x00,0x04,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5026 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5027 static const BYTE ctlWithSequenceNumber[] = {
5028 0x30,0x1a,0x30,0x00,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5029 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5030 static const BYTE ctlWithThisUpdate[] = {
5031 0x30,0x15,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5032 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5033 static const BYTE ctlWithThisAndNextUpdate[] = {
5034 0x30,0x24,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5035 0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5036 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5037 static const BYTE ctlWithAlgId[] = {
5038 0x30,0x1b,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5039 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5040 static const BYTE ctlWithBogusEntry[] = {
5041 0x30,0x29,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5042 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x10,0x30,0x0e,0x04,
5043 0x01,0x01,0x31,0x09,0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,0x01 };
5044 static const BYTE ctlWithOneEntry[] = {
5045 0x30,0x2a,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5046 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x11,0x30,0x0f,0x04,
5047 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00 };
5048 static const BYTE ctlWithTwoEntries[] = {
5049 0x30,0x41,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5050 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x28,0x30,0x0f,0x04,
5051 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00,0x30,
5052 0x15,0x04,0x01,0x01,0x31,0x10,0x30,0x0e,0x06,0x02,0x2d,0x06,0x31,0x08,0x30,
5053 0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5055 static void test_encodeCTL(DWORD dwEncoding)
5057 static char oid1[] = "1.2.3";
5058 static char oid2[] = "1.5.6";
5059 char *pOid1 = oid1;
5060 BOOL ret;
5061 BYTE *buf = NULL;
5062 DWORD size = 0;
5063 CTL_INFO info;
5064 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5065 CTL_ENTRY ctlEntry[2];
5066 CRYPT_ATTRIBUTE attr1, attr2;
5067 CRYPT_ATTR_BLOB value1, value2;
5069 memset(&info, 0, sizeof(info));
5070 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5071 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5072 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5073 if (buf)
5075 ok(size == sizeof(emptyCTL), "unexpected size %d\n", size);
5076 ok(!memcmp(buf, emptyCTL, size), "unexpected value\n");
5077 LocalFree(buf);
5078 buf = NULL;
5080 info.dwVersion = 1;
5081 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5082 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5083 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5084 if (buf)
5086 ok(size == sizeof(emptyCTLWithVersion1), "unexpected size %d\n", size);
5087 ok(!memcmp(buf, emptyCTLWithVersion1, size), "unexpected value\n");
5088 LocalFree(buf);
5089 buf = NULL;
5091 info.dwVersion = 0;
5092 info.SubjectUsage.cUsageIdentifier = 1;
5093 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5094 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5095 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5096 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5097 if (buf)
5099 ok(size == sizeof(ctlWithUsageIdentifier), "unexpected size %d\n",
5100 size);
5101 ok(!memcmp(buf, ctlWithUsageIdentifier, size), "unexpected value\n");
5102 LocalFree(buf);
5103 buf = NULL;
5105 info.SubjectUsage.cUsageIdentifier = 0;
5106 info.ListIdentifier.cbData = sizeof(serialNum);
5107 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5108 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5109 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5110 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5111 if (buf)
5113 ok(size == sizeof(ctlWithListIdentifier), "unexpected size %d\n", size);
5114 ok(!memcmp(buf, ctlWithListIdentifier, size), "unexpected value\n");
5115 LocalFree(buf);
5116 buf = NULL;
5118 info.ListIdentifier.cbData = 0;
5119 info.SequenceNumber.cbData = sizeof(serialNum);
5120 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5121 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5122 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5123 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5124 if (buf)
5126 ok(size == sizeof(ctlWithSequenceNumber), "unexpected size %d\n",
5127 size);
5128 ok(!memcmp(buf, ctlWithSequenceNumber, size), "unexpected value\n");
5129 LocalFree(buf);
5130 buf = NULL;
5132 info.SequenceNumber.cbData = 0;
5133 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5134 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5135 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5136 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5137 if (buf)
5139 ok(size == sizeof(ctlWithThisUpdate), "unexpected size %d\n", size);
5140 ok(!memcmp(buf, ctlWithThisUpdate, size), "unexpected value\n");
5141 LocalFree(buf);
5142 buf = NULL;
5144 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5145 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5146 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5147 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5148 if (buf)
5150 ok(size == sizeof(ctlWithThisAndNextUpdate), "unexpected size %d\n",
5151 size);
5152 ok(!memcmp(buf, ctlWithThisAndNextUpdate, size), "unexpected value\n");
5153 LocalFree(buf);
5154 buf = NULL;
5156 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5157 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5158 info.SubjectAlgorithm.pszObjId = oid2;
5159 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5160 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5161 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5162 if (buf)
5164 ok(size == sizeof(ctlWithAlgId), "unexpected size %d\n", size);
5165 ok(!memcmp(buf, ctlWithAlgId, size), "unexpected value\n");
5166 LocalFree(buf);
5167 buf = NULL;
5169 /* The value is supposed to be asn.1 encoded, so this'll fail to decode
5170 * (see tests below) but it'll encode fine.
5172 info.SubjectAlgorithm.pszObjId = NULL;
5173 value1.cbData = sizeof(serialNum);
5174 value1.pbData = (LPBYTE)serialNum;
5175 attr1.pszObjId = oid1;
5176 attr1.cValue = 1;
5177 attr1.rgValue = &value1;
5178 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5179 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5180 ctlEntry[0].cAttribute = 1;
5181 ctlEntry[0].rgAttribute = &attr1;
5182 info.cCTLEntry = 1;
5183 info.rgCTLEntry = ctlEntry;
5184 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5185 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5186 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5187 if (buf)
5189 ok(size == sizeof(ctlWithBogusEntry), "unexpected size %d\n", size);
5190 ok(!memcmp(buf, ctlWithBogusEntry, size), "unexpected value\n");
5191 LocalFree(buf);
5192 buf = NULL;
5194 value1.cbData = sizeof(emptySequence);
5195 value1.pbData = (LPBYTE)emptySequence;
5196 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5197 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5198 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5199 if (buf)
5201 ok(size == sizeof(ctlWithOneEntry), "unexpected size %d\n", size);
5202 ok(!memcmp(buf, ctlWithOneEntry, size), "unexpected value\n");
5203 LocalFree(buf);
5204 buf = NULL;
5206 value2.cbData = sizeof(encodedIPAddr);
5207 value2.pbData = (LPBYTE)encodedIPAddr;
5208 attr2.pszObjId = oid2;
5209 attr2.cValue = 1;
5210 attr2.rgValue = &value2;
5211 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5212 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5213 ctlEntry[1].cAttribute = 1;
5214 ctlEntry[1].rgAttribute = &attr2;
5215 info.cCTLEntry = 2;
5216 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5217 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5218 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5219 if (buf)
5221 ok(size == sizeof(ctlWithTwoEntries), "unexpected size %d\n", size);
5222 ok(!memcmp(buf, ctlWithTwoEntries, size), "unexpected value\n");
5223 LocalFree(buf);
5224 buf = NULL;
5228 static void compareCTLInfo(LPCSTR header, const CTL_INFO *expected,
5229 const CTL_INFO *got)
5231 DWORD i, j, k;
5233 ok(expected->dwVersion == got->dwVersion,
5234 "%s: expected version %d, got %d\n", header, expected->dwVersion,
5235 got->dwVersion);
5236 ok(expected->SubjectUsage.cUsageIdentifier ==
5237 got->SubjectUsage.cUsageIdentifier,
5238 "%s: expected %d usage identifiers, got %d\n", header,
5239 expected->SubjectUsage.cUsageIdentifier,
5240 got->SubjectUsage.cUsageIdentifier);
5241 for (i = 0; i < expected->SubjectUsage.cUsageIdentifier; i++)
5242 ok(!strcmp(expected->SubjectUsage.rgpszUsageIdentifier[i],
5243 got->SubjectUsage.rgpszUsageIdentifier[i]),
5244 "%s[%d]: expected %s, got %s\n", header, i,
5245 expected->SubjectUsage.rgpszUsageIdentifier[i],
5246 got->SubjectUsage.rgpszUsageIdentifier[i]);
5247 ok(expected->ListIdentifier.cbData == got->ListIdentifier.cbData,
5248 "%s: expected list identifier of %d bytes, got %d\n", header,
5249 expected->ListIdentifier.cbData, got->ListIdentifier.cbData);
5250 if (expected->ListIdentifier.cbData)
5251 ok(!memcmp(expected->ListIdentifier.pbData, got->ListIdentifier.pbData,
5252 expected->ListIdentifier.cbData),
5253 "%s: unexpected list identifier value\n", header);
5254 ok(expected->SequenceNumber.cbData == got->SequenceNumber.cbData,
5255 "%s: expected sequence number of %d bytes, got %d\n", header,
5256 expected->SequenceNumber.cbData, got->SequenceNumber.cbData);
5257 if (expected->SequenceNumber.cbData)
5258 ok(!memcmp(expected->SequenceNumber.pbData, got->SequenceNumber.pbData,
5259 expected->SequenceNumber.cbData),
5260 "%s: unexpected sequence number value\n", header);
5261 ok(!memcmp(&expected->ThisUpdate, &got->ThisUpdate, sizeof(FILETIME)),
5262 "%s: expected this update = (%d, %d), got (%d, %d)\n", header,
5263 expected->ThisUpdate.dwLowDateTime, expected->ThisUpdate.dwHighDateTime,
5264 got->ThisUpdate.dwLowDateTime, got->ThisUpdate.dwHighDateTime);
5265 ok(!memcmp(&expected->NextUpdate, &got->NextUpdate, sizeof(FILETIME)),
5266 "%s: expected next update = (%d, %d), got (%d, %d)\n", header,
5267 expected->NextUpdate.dwLowDateTime, expected->NextUpdate.dwHighDateTime,
5268 got->NextUpdate.dwLowDateTime, got->NextUpdate.dwHighDateTime);
5269 if (expected->SubjectAlgorithm.pszObjId &&
5270 *expected->SubjectAlgorithm.pszObjId && !got->SubjectAlgorithm.pszObjId)
5271 ok(0, "%s: expected subject algorithm %s, got NULL\n", header,
5272 expected->SubjectAlgorithm.pszObjId);
5273 if (expected->SubjectAlgorithm.pszObjId && got->SubjectAlgorithm.pszObjId)
5274 ok(!strcmp(expected->SubjectAlgorithm.pszObjId,
5275 got->SubjectAlgorithm.pszObjId),
5276 "%s: expected subject algorithm %s, got %s\n", header,
5277 expected->SubjectAlgorithm.pszObjId, got->SubjectAlgorithm.pszObjId);
5278 ok(expected->SubjectAlgorithm.Parameters.cbData ==
5279 got->SubjectAlgorithm.Parameters.cbData,
5280 "%s: expected subject algorithm parameters of %d bytes, got %d\n", header,
5281 expected->SubjectAlgorithm.Parameters.cbData,
5282 got->SubjectAlgorithm.Parameters.cbData);
5283 if (expected->SubjectAlgorithm.Parameters.cbData)
5284 ok(!memcmp(expected->SubjectAlgorithm.Parameters.pbData,
5285 got->SubjectAlgorithm.Parameters.pbData,
5286 expected->SubjectAlgorithm.Parameters.cbData),
5287 "%s: unexpected subject algorithm parameter value\n", header);
5288 ok(expected->cCTLEntry == got->cCTLEntry,
5289 "%s: expected %d CTL entries, got %d\n", header, expected->cCTLEntry,
5290 got->cCTLEntry);
5291 for (i = 0; i < expected->cCTLEntry; i++)
5293 ok(expected->rgCTLEntry[i].SubjectIdentifier.cbData ==
5294 got->rgCTLEntry[i].SubjectIdentifier.cbData,
5295 "%s[%d]: expected subject identifier of %d bytes, got %d\n",
5296 header, i, expected->rgCTLEntry[i].SubjectIdentifier.cbData,
5297 got->rgCTLEntry[i].SubjectIdentifier.cbData);
5298 if (expected->rgCTLEntry[i].SubjectIdentifier.cbData)
5299 ok(!memcmp(expected->rgCTLEntry[i].SubjectIdentifier.pbData,
5300 got->rgCTLEntry[i].SubjectIdentifier.pbData,
5301 expected->rgCTLEntry[i].SubjectIdentifier.cbData),
5302 "%s[%d]: unexpected subject identifier value\n",
5303 header, i);
5304 for (j = 0; j < expected->rgCTLEntry[i].cAttribute; j++)
5306 ok(!strcmp(expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5307 got->rgCTLEntry[i].rgAttribute[j].pszObjId),
5308 "%s[%d][%d]: expected attribute OID %s, got %s\n", header, i, j,
5309 expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5310 got->rgCTLEntry[i].rgAttribute[j].pszObjId);
5311 for (k = 0; k < expected->rgCTLEntry[i].rgAttribute[j].cValue; k++)
5313 ok(expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData ==
5314 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5315 "%s[%d][%d][%d]: expected value of %d bytes, got %d\n",
5316 header, i, j, k,
5317 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5318 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData);
5319 if (expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData)
5320 ok(!memcmp(
5321 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5322 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5323 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData),
5324 "%s[%d][%d][%d]: unexpected value\n",
5325 header, i, j, k);
5329 ok(expected->cExtension == got->cExtension,
5330 "%s: expected %d extensions, got %d\n", header, expected->cExtension,
5331 got->cExtension);
5332 for (i = 0; i < expected->cExtension; i++)
5334 ok(!strcmp(expected->rgExtension[i].pszObjId,
5335 got->rgExtension[i].pszObjId), "%s[%d]: expected %s, got %s\n",
5336 header, i, expected->rgExtension[i].pszObjId,
5337 got->rgExtension[i].pszObjId);
5338 ok(expected->rgExtension[i].fCritical == got->rgExtension[i].fCritical,
5339 "%s[%d]: expected fCritical = %d, got %d\n", header, i,
5340 expected->rgExtension[i].fCritical, got->rgExtension[i].fCritical);
5341 ok(expected->rgExtension[i].Value.cbData ==
5342 got->rgExtension[i].Value.cbData,
5343 "%s[%d]: expected extension value to have %d bytes, got %d\n",
5344 header, i, expected->rgExtension[i].Value.cbData,
5345 got->rgExtension[i].Value.cbData);
5346 if (expected->rgExtension[i].Value.cbData)
5347 ok(!memcmp(expected->rgExtension[i].Value.pbData,
5348 got->rgExtension[i].Value.pbData,
5349 expected->rgExtension[i].Value.cbData),
5350 "%s[%d]: unexpected extension value\n", header, i);
5354 static const BYTE signedCTL[] = {
5355 0x30,0x81,0xc7,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
5356 0x81,0xb9,0x30,0x81,0xb6,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
5357 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x28,0x06,0x09,0x2a,0x86,
5358 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x1b,0x04,0x19,0x30,0x17,0x30,0x00,
5359 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5360 0x30,0x5a,0x30,0x02,0x06,0x00,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
5361 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
5362 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
5363 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5364 0x00,0x04,0x40,0xca,0xd8,0x32,0xd1,0xbd,0x97,0x61,0x54,0xd6,0x80,0xcf,0x0d,
5365 0xbd,0xa2,0x42,0xc7,0xca,0x37,0x91,0x7d,0x9d,0xac,0x8c,0xdf,0x05,0x8a,0x39,
5366 0xc6,0x07,0xc1,0x37,0xe6,0xb9,0xd1,0x0d,0x26,0xec,0xa5,0xb0,0x8a,0x51,0x26,
5367 0x2b,0x4f,0x73,0x44,0x86,0x83,0x5e,0x2b,0x6e,0xcc,0xf8,0x1b,0x85,0x53,0xe9,
5368 0x7a,0x80,0x8f,0x6b,0x42,0x19,0x93 };
5369 static const BYTE signedCTLWithCTLInnerContent[] = {
5370 0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
5371 0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
5372 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
5373 0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
5374 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5375 0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
5376 0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
5377 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
5378 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
5379 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
5380 0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
5381 0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
5382 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
5383 0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5384 0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
5385 0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
5386 0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
5387 0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
5388 0x57,0x6c,0x0b,0x47,0xb8 };
5390 static void test_decodeCTL(DWORD dwEncoding)
5392 static char oid1[] = "1.2.3";
5393 static char oid2[] = "1.5.6";
5394 static BYTE nullData[] = { 5,0 };
5395 char *pOid1 = oid1;
5396 BOOL ret;
5397 BYTE *buf = NULL;
5398 DWORD size = 0;
5399 CTL_INFO info;
5400 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5401 CTL_ENTRY ctlEntry[2];
5402 CRYPT_ATTRIBUTE attr1, attr2;
5403 CRYPT_ATTR_BLOB value1, value2;
5405 memset(&info, 0, sizeof(info));
5406 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTL, sizeof(emptyCTL),
5407 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5408 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5409 if (buf)
5411 compareCTLInfo("empty CTL", &info, (CTL_INFO *)buf);
5412 LocalFree(buf);
5413 buf = NULL;
5415 info.dwVersion = 1;
5416 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTLWithVersion1,
5417 sizeof(emptyCTLWithVersion1), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
5418 &size);
5419 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5420 if (buf)
5422 compareCTLInfo("v1 CTL", &info, (CTL_INFO *)buf);
5423 LocalFree(buf);
5424 buf = NULL;
5426 info.dwVersion = 0;
5427 info.SubjectUsage.cUsageIdentifier = 1;
5428 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5429 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithUsageIdentifier,
5430 sizeof(ctlWithUsageIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5431 (BYTE *)&buf, &size);
5432 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5433 if (buf)
5435 compareCTLInfo("CTL with usage identifier", &info, (CTL_INFO *)buf);
5436 LocalFree(buf);
5437 buf = NULL;
5439 info.SubjectUsage.cUsageIdentifier = 0;
5440 info.ListIdentifier.cbData = sizeof(serialNum);
5441 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5442 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithListIdentifier,
5443 sizeof(ctlWithListIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5444 (BYTE *)&buf, &size);
5445 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5446 if (buf)
5448 compareCTLInfo("CTL with list identifier", &info, (CTL_INFO *)buf);
5449 LocalFree(buf);
5450 buf = NULL;
5452 info.ListIdentifier.cbData = 0;
5453 info.SequenceNumber.cbData = sizeof(serialNum);
5454 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5455 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithSequenceNumber,
5456 sizeof(ctlWithSequenceNumber), CRYPT_DECODE_ALLOC_FLAG, NULL,
5457 (BYTE *)&buf, &size);
5458 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5459 if (buf)
5461 compareCTLInfo("CTL with sequence number", &info, (CTL_INFO *)buf);
5462 LocalFree(buf);
5463 buf = NULL;
5465 info.SequenceNumber.cbData = 0;
5466 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5467 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisUpdate,
5468 sizeof(ctlWithThisUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5469 (BYTE *)&buf, &size);
5470 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5471 if (buf)
5473 compareCTLInfo("CTL with this update", &info, (CTL_INFO *)buf);
5474 LocalFree(buf);
5475 buf = NULL;
5477 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5478 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisAndNextUpdate,
5479 sizeof(ctlWithThisAndNextUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5480 (BYTE *)&buf, &size);
5481 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5482 if (buf)
5484 compareCTLInfo("CTL with this and next update", &info, (CTL_INFO *)buf);
5485 LocalFree(buf);
5486 buf = NULL;
5488 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5489 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5490 info.SubjectAlgorithm.pszObjId = oid2;
5491 info.SubjectAlgorithm.Parameters.cbData = sizeof(nullData);
5492 info.SubjectAlgorithm.Parameters.pbData = nullData;
5493 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithAlgId,
5494 sizeof(ctlWithAlgId), CRYPT_DECODE_ALLOC_FLAG, NULL,
5495 (BYTE *)&buf, &size);
5496 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5497 if (buf)
5499 compareCTLInfo("CTL with algorithm identifier", &info, (CTL_INFO *)buf);
5500 LocalFree(buf);
5501 buf = NULL;
5503 SetLastError(0xdeadbeef);
5504 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithBogusEntry,
5505 sizeof(ctlWithBogusEntry), CRYPT_DECODE_ALLOC_FLAG, NULL,
5506 (BYTE *)&buf, &size);
5507 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD || CRYPT_E_ASN1_CORRUPT),
5508 "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n",
5509 GetLastError());
5510 info.SubjectAlgorithm.Parameters.cbData = 0;
5511 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5512 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5513 info.SubjectAlgorithm.pszObjId = oid2;
5514 info.SubjectAlgorithm.pszObjId = NULL;
5515 value1.cbData = sizeof(emptySequence);
5516 value1.pbData = (LPBYTE)emptySequence;
5517 attr1.pszObjId = oid1;
5518 attr1.cValue = 1;
5519 attr1.rgValue = &value1;
5520 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5521 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5522 ctlEntry[0].cAttribute = 1;
5523 ctlEntry[0].rgAttribute = &attr1;
5524 info.cCTLEntry = 1;
5525 info.rgCTLEntry = ctlEntry;
5526 SetLastError(0xdeadbeef);
5527 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithOneEntry,
5528 sizeof(ctlWithOneEntry), CRYPT_DECODE_ALLOC_FLAG, NULL,
5529 (BYTE *)&buf, &size);
5530 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5531 if (buf)
5533 compareCTLInfo("CTL with one entry", &info, (CTL_INFO *)buf);
5534 LocalFree(buf);
5535 buf = NULL;
5537 value2.cbData = sizeof(encodedIPAddr);
5538 value2.pbData = (LPBYTE)encodedIPAddr;
5539 attr2.pszObjId = oid2;
5540 attr2.cValue = 1;
5541 attr2.rgValue = &value2;
5542 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5543 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5544 ctlEntry[1].cAttribute = 1;
5545 ctlEntry[1].rgAttribute = &attr2;
5546 info.cCTLEntry = 2;
5547 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithTwoEntries,
5548 sizeof(ctlWithTwoEntries), CRYPT_DECODE_ALLOC_FLAG, NULL,
5549 (BYTE *)&buf, &size);
5550 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5551 if (buf)
5553 compareCTLInfo("CTL with two entries", &info, (CTL_INFO *)buf);
5554 LocalFree(buf);
5555 buf = NULL;
5557 /* A signed CTL isn't decodable, even if the inner content is a CTL */
5558 SetLastError(0xdeadbeef);
5559 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, signedCTL,
5560 sizeof(signedCTL), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5561 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5562 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5563 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5564 GetLastError());
5565 SetLastError(0xdeadbeef);
5566 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL,
5567 signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent),
5568 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5569 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5570 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5571 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5572 GetLastError());
5575 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
5576 static const BYTE emptyPKCSContentInfoExtraBytes[] = { 0x30,0x04,0x06,0x02,0x2a,
5577 0x03,0,0,0,0,0,0 };
5578 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
5579 0xa0,0x01,0x01 };
5580 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
5581 0x03,0x02,0x01,0x01 };
5582 static BYTE bogusDER[] = { 1 };
5584 static void test_encodePKCSContentInfo(DWORD dwEncoding)
5586 BOOL ret;
5587 BYTE *buf = NULL;
5588 DWORD size = 0;
5589 CRYPT_CONTENT_INFO info = { 0 };
5590 char oid1[] = "1.2.3";
5592 if (0)
5594 /* Crashes on win9x */
5595 SetLastError(0xdeadbeef);
5596 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL,
5597 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5598 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5599 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5601 SetLastError(0xdeadbeef);
5602 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5603 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5604 ok(!ret && (GetLastError() == E_INVALIDARG ||
5605 GetLastError() == OSS_LIMITED /* Win9x */),
5606 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5607 info.pszObjId = oid1;
5608 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5609 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5610 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5611 if (buf)
5613 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size);
5614 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n");
5615 LocalFree(buf);
5617 info.Content.pbData = bogusDER;
5618 info.Content.cbData = sizeof(bogusDER);
5619 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5620 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5621 ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError());
5622 if (buf)
5624 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size);
5625 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n");
5626 LocalFree(buf);
5628 info.Content.pbData = (BYTE *)ints[0].encoded;
5629 info.Content.cbData = ints[0].encoded[1] + 2;
5630 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5631 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5632 if (buf)
5634 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size);
5635 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n");
5636 LocalFree(buf);
5640 static const BYTE indefiniteSignedPKCSContent[] = {
5641 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
5642 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
5643 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
5644 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
5645 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
5646 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
5647 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5648 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5649 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
5650 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5651 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5652 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
5653 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
5654 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
5655 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
5656 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
5657 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
5658 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
5659 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
5660 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5661 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5662 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
5663 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
5664 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
5665 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
5666 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
5667 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
5668 0x00,0x00,0x00,0x00,0x00,0x00 };
5670 static void test_decodePKCSContentInfo(DWORD dwEncoding)
5672 BOOL ret;
5673 LPBYTE buf = NULL;
5674 DWORD size = 0;
5675 CRYPT_CONTENT_INFO *info;
5677 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5678 emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo),
5679 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5680 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5681 if (buf)
5683 info = (CRYPT_CONTENT_INFO *)buf;
5685 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5686 info->pszObjId);
5687 ok(info->Content.cbData == 0, "Expected no data, got %d\n",
5688 info->Content.cbData);
5689 LocalFree(buf);
5691 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5692 emptyPKCSContentInfoExtraBytes, sizeof(emptyPKCSContentInfoExtraBytes),
5693 0, NULL, NULL, &size);
5694 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5695 SetLastError(0xdeadbeef);
5696 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5697 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo),
5698 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5699 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5700 * I doubt an app depends on that.
5702 ok((!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5703 GetLastError() == CRYPT_E_ASN1_CORRUPT)) || broken(ret),
5704 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5705 GetLastError());
5706 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5707 intPKCSContentInfo, sizeof(intPKCSContentInfo),
5708 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5709 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5710 if (buf)
5712 info = (CRYPT_CONTENT_INFO *)buf;
5714 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5715 info->pszObjId);
5716 ok(info->Content.cbData == ints[0].encoded[1] + 2,
5717 "Unexpected size %d\n", info->Content.cbData);
5718 ok(!memcmp(info->Content.pbData, ints[0].encoded,
5719 info->Content.cbData), "Unexpected value\n");
5720 LocalFree(buf);
5722 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5723 indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent),
5724 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5725 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5726 if (buf)
5728 info = (CRYPT_CONTENT_INFO *)buf;
5730 ok(!strcmp(info->pszObjId, szOID_RSA_signedData),
5731 "Expected %s, got %s\n", szOID_RSA_signedData, info->pszObjId);
5732 ok(info->Content.cbData == 392, "Expected 392, got %d\n",
5733 info->Content.cbData);
5734 LocalFree(buf);
5738 static const BYTE emptyPKCSAttr[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
5739 0x00 };
5740 static const BYTE bogusPKCSAttr[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
5741 0x01 };
5742 static const BYTE intPKCSAttr[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
5743 0x02,0x01,0x01 };
5745 static void test_encodePKCSAttribute(DWORD dwEncoding)
5747 CRYPT_ATTRIBUTE attr = { 0 };
5748 BOOL ret;
5749 LPBYTE buf = NULL;
5750 DWORD size = 0;
5751 CRYPT_ATTR_BLOB blob;
5752 char oid[] = "1.2.3";
5754 if (0)
5756 /* Crashes on win9x */
5757 SetLastError(0xdeadbeef);
5758 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, NULL,
5759 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5760 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5761 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5763 SetLastError(0xdeadbeef);
5764 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5765 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5766 ok(!ret && (GetLastError() == E_INVALIDARG ||
5767 GetLastError() == OSS_LIMITED /* Win9x */),
5768 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5769 attr.pszObjId = oid;
5770 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5771 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5772 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5773 if (buf)
5775 ok(size == sizeof(emptyPKCSAttr), "Unexpected size %d\n", size);
5776 ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n");
5777 LocalFree(buf);
5779 blob.cbData = sizeof(bogusDER);
5780 blob.pbData = bogusDER;
5781 attr.cValue = 1;
5782 attr.rgValue = &blob;
5783 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5784 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5785 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5786 if (buf)
5788 ok(size == sizeof(bogusPKCSAttr), "Unexpected size %d\n", size);
5789 ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n");
5790 LocalFree(buf);
5792 blob.pbData = (BYTE *)ints[0].encoded;
5793 blob.cbData = ints[0].encoded[1] + 2;
5794 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5795 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5796 if (buf)
5798 ok(size == sizeof(intPKCSAttr), "Unexpected size %d\n", size);
5799 ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n");
5800 LocalFree(buf);
5804 static void test_decodePKCSAttribute(DWORD dwEncoding)
5806 BOOL ret;
5807 LPBYTE buf = NULL;
5808 DWORD size = 0;
5809 CRYPT_ATTRIBUTE *attr;
5811 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5812 emptyPKCSAttr, sizeof(emptyPKCSAttr),
5813 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5814 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5815 if (buf)
5817 attr = (CRYPT_ATTRIBUTE *)buf;
5819 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5820 attr->pszObjId);
5821 ok(attr->cValue == 0, "Expected no value, got %d\n", attr->cValue);
5822 LocalFree(buf);
5824 SetLastError(0xdeadbeef);
5825 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5826 bogusPKCSAttr, sizeof(bogusPKCSAttr),
5827 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5828 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5829 * I doubt an app depends on that.
5831 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5832 GetLastError() == CRYPT_E_ASN1_CORRUPT || OSS_MORE_INPUT /* Win9x */),
5833 "Expected CRYPT_E_ASN1_EOD, CRYPT_E_ASN1_CORRUPT, or OSS_MORE_INPUT, got %x\n",
5834 GetLastError());
5835 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5836 intPKCSAttr, sizeof(intPKCSAttr),
5837 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5838 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5839 if (buf)
5841 attr = (CRYPT_ATTRIBUTE *)buf;
5843 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5844 attr->pszObjId);
5845 ok(attr->cValue == 1, "Expected 1 value, got %d\n", attr->cValue);
5846 ok(attr->rgValue[0].cbData == ints[0].encoded[1] + 2,
5847 "Unexpected size %d\n", attr->rgValue[0].cbData);
5848 ok(!memcmp(attr->rgValue[0].pbData, ints[0].encoded,
5849 attr->rgValue[0].cbData), "Unexpected value\n");
5850 LocalFree(buf);
5854 static const BYTE emptyPKCSAttributes[] = { 0x31,0x00 };
5855 static const BYTE singlePKCSAttributes[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
5856 0x2a,0x03,0x31,0x00 };
5857 static const BYTE doublePKCSAttributes[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
5858 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
5860 static void test_encodePKCSAttributes(DWORD dwEncoding)
5862 CRYPT_ATTRIBUTES attributes = { 0 };
5863 CRYPT_ATTRIBUTE attr[2] = { { 0 } };
5864 CRYPT_ATTR_BLOB blob;
5865 BOOL ret;
5866 LPBYTE buf = NULL;
5867 DWORD size = 0;
5868 char oid1[] = "1.2.3", oid2[] = "1.5.6";
5870 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5871 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5872 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5873 if (buf)
5875 ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %d\n", size);
5876 ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n");
5877 LocalFree(buf);
5879 attributes.cAttr = 1;
5880 attributes.rgAttr = attr;
5881 SetLastError(0xdeadbeef);
5882 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5883 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5884 ok(!ret && (GetLastError() == E_INVALIDARG ||
5885 GetLastError() == OSS_LIMITED /* Win9x */),
5886 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
5887 attr[0].pszObjId = oid1;
5888 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5889 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5890 if (buf)
5892 ok(size == sizeof(singlePKCSAttributes), "Unexpected size %d\n", size);
5893 ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n");
5894 LocalFree(buf);
5896 attr[1].pszObjId = oid2;
5897 attr[1].cValue = 1;
5898 attr[1].rgValue = &blob;
5899 blob.pbData = (BYTE *)ints[0].encoded;
5900 blob.cbData = ints[0].encoded[1] + 2;
5901 attributes.cAttr = 2;
5902 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5903 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5904 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5905 if (buf)
5907 ok(size == sizeof(doublePKCSAttributes), "Unexpected size %d\n", size);
5908 ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n");
5909 LocalFree(buf);
5913 static void test_decodePKCSAttributes(DWORD dwEncoding)
5915 BOOL ret;
5916 LPBYTE buf = NULL;
5917 DWORD size = 0;
5918 CRYPT_ATTRIBUTES *attributes;
5920 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5921 emptyPKCSAttributes, sizeof(emptyPKCSAttributes),
5922 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5923 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5924 if (buf)
5926 attributes = (CRYPT_ATTRIBUTES *)buf;
5927 ok(attributes->cAttr == 0, "Expected no attributes, got %d\n",
5928 attributes->cAttr);
5929 LocalFree(buf);
5931 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5932 singlePKCSAttributes, sizeof(singlePKCSAttributes),
5933 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5934 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5935 if (buf)
5937 attributes = (CRYPT_ATTRIBUTES *)buf;
5938 ok(attributes->cAttr == 1, "Expected 1 attribute, got %d\n",
5939 attributes->cAttr);
5940 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5941 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5942 ok(attributes->rgAttr[0].cValue == 0,
5943 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5944 LocalFree(buf);
5946 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5947 doublePKCSAttributes, sizeof(doublePKCSAttributes),
5948 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5949 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5950 if (buf)
5952 attributes = (CRYPT_ATTRIBUTES *)buf;
5953 ok(attributes->cAttr == 2, "Expected 2 attributes, got %d\n",
5954 attributes->cAttr);
5955 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5956 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5957 ok(attributes->rgAttr[0].cValue == 0,
5958 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5959 ok(!strcmp(attributes->rgAttr[1].pszObjId, "1.5.6"),
5960 "Expected 1.5.6, got %s\n", attributes->rgAttr[1].pszObjId);
5961 ok(attributes->rgAttr[1].cValue == 1,
5962 "Expected 1 attribute, got %d\n", attributes->rgAttr[1].cValue);
5963 ok(attributes->rgAttr[1].rgValue[0].cbData == ints[0].encoded[1] + 2,
5964 "Unexpected size %d\n", attributes->rgAttr[1].rgValue[0].cbData);
5965 ok(!memcmp(attributes->rgAttr[1].rgValue[0].pbData, ints[0].encoded,
5966 attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n");
5967 LocalFree(buf);
5971 static const BYTE singleCapability[] = {
5972 0x30,0x06,0x30,0x04,0x06,0x02,0x2d,0x06 };
5973 static const BYTE twoCapabilities[] = {
5974 0x30,0x0c,0x30,0x04,0x06,0x02,0x2d,0x06,0x30,0x04,0x06,0x02,0x2a,0x03 };
5975 static const BYTE singleCapabilitywithNULL[] = {
5976 0x30,0x08,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5978 static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding)
5980 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
5981 BOOL ret;
5982 LPBYTE buf = NULL;
5983 DWORD size = 0;
5984 CRYPT_SMIME_CAPABILITY capability[2];
5985 CRYPT_SMIME_CAPABILITIES capabilities;
5987 /* An empty capabilities is allowed */
5988 capabilities.cCapability = 0;
5989 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
5990 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5991 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5992 if (buf)
5994 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
5995 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
5996 LocalFree(buf);
5998 /* A non-empty capabilities with an empty capability (lacking an OID) is
5999 * not allowed
6001 capability[0].pszObjId = NULL;
6002 capability[0].Parameters.cbData = 0;
6003 capabilities.cCapability = 1;
6004 capabilities.rgCapability = capability;
6005 SetLastError(0xdeadbeef);
6006 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6007 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6008 ok(!ret && (GetLastError() == E_INVALIDARG ||
6009 GetLastError() == OSS_LIMITED /* Win9x */),
6010 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6011 capability[0].pszObjId = oid1;
6012 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6013 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6014 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6015 if (buf)
6017 ok(size == sizeof(singleCapability), "unexpected size %d\n", size);
6018 ok(!memcmp(buf, singleCapability, size), "unexpected value\n");
6019 LocalFree(buf);
6021 capability[1].pszObjId = oid2;
6022 capability[1].Parameters.cbData = 0;
6023 capabilities.cCapability = 2;
6024 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6025 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6026 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6027 if (buf)
6029 ok(size == sizeof(twoCapabilities), "unexpected size %d\n", size);
6030 ok(!memcmp(buf, twoCapabilities, size), "unexpected value\n");
6031 LocalFree(buf);
6035 static void compareSMimeCapabilities(LPCSTR header,
6036 const CRYPT_SMIME_CAPABILITIES *expected, const CRYPT_SMIME_CAPABILITIES *got)
6038 DWORD i;
6040 ok(got->cCapability == expected->cCapability,
6041 "%s: expected %d capabilities, got %d\n", header, expected->cCapability,
6042 got->cCapability);
6043 for (i = 0; i < expected->cCapability; i++)
6045 ok(!strcmp(expected->rgCapability[i].pszObjId,
6046 got->rgCapability[i].pszObjId), "%s[%d]: expected %s, got %s\n",
6047 header, i, expected->rgCapability[i].pszObjId,
6048 got->rgCapability[i].pszObjId);
6049 ok(expected->rgCapability[i].Parameters.cbData ==
6050 got->rgCapability[i].Parameters.cbData,
6051 "%s[%d]: expected %d bytes, got %d\n", header, i,
6052 expected->rgCapability[i].Parameters.cbData,
6053 got->rgCapability[i].Parameters.cbData);
6054 if (expected->rgCapability[i].Parameters.cbData)
6055 ok(!memcmp(expected->rgCapability[i].Parameters.pbData,
6056 got->rgCapability[i].Parameters.pbData,
6057 expected->rgCapability[i].Parameters.cbData),
6058 "%s[%d]: unexpected value\n", header, i);
6062 static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding)
6064 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6065 BOOL ret;
6066 DWORD size = 0;
6067 CRYPT_SMIME_CAPABILITY capability[2];
6068 CRYPT_SMIME_CAPABILITIES capabilities, *ptr;
6070 SetLastError(0xdeadbeef);
6071 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6072 emptySequence, sizeof(emptySequence),
6073 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&ptr, &size);
6074 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6075 if (ret)
6077 capabilities.cCapability = 0;
6078 compareSMimeCapabilities("empty capabilities", &capabilities, ptr);
6079 LocalFree(ptr);
6081 SetLastError(0xdeadbeef);
6082 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6083 singleCapability, sizeof(singleCapability), CRYPT_DECODE_ALLOC_FLAG, NULL,
6084 (BYTE *)&ptr, &size);
6085 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6086 if (ret)
6088 capability[0].pszObjId = oid1;
6089 capability[0].Parameters.cbData = 0;
6090 capabilities.cCapability = 1;
6091 capabilities.rgCapability = capability;
6092 compareSMimeCapabilities("single capability", &capabilities, ptr);
6093 LocalFree(ptr);
6095 SetLastError(0xdeadbeef);
6096 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6097 singleCapabilitywithNULL, sizeof(singleCapabilitywithNULL),
6098 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&ptr, &size);
6099 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6100 if (ret)
6102 BYTE NULLparam[] = {0x05, 0x00};
6103 capability[0].pszObjId = oid1;
6104 capability[0].Parameters.cbData = 2;
6105 capability[0].Parameters.pbData = NULLparam;
6106 capabilities.cCapability = 1;
6107 capabilities.rgCapability = capability;
6108 compareSMimeCapabilities("single capability with NULL", &capabilities,
6109 ptr);
6110 LocalFree(ptr);
6112 SetLastError(0xdeadbeef);
6113 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6114 twoCapabilities, sizeof(twoCapabilities), CRYPT_DECODE_ALLOC_FLAG, NULL,
6115 (BYTE *)&ptr, &size);
6116 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6117 if (ret)
6119 capability[0].Parameters.cbData = 0;
6120 capability[1].pszObjId = oid2;
6121 capability[1].Parameters.cbData = 0;
6122 capabilities.cCapability = 2;
6123 compareSMimeCapabilities("two capabilities", &capabilities, ptr);
6124 LocalFree(ptr);
6128 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
6129 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
6130 0x67 };
6131 static const BYTE minimalPKCSSigner[] = {
6132 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6133 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6134 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6135 static const BYTE PKCSSignerWithSerial[] = {
6136 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6137 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6138 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
6139 0x00 };
6140 static const BYTE PKCSSignerWithHashAlgo[] = {
6141 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6142 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6143 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
6144 0x00,0x04,0x00 };
6145 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = {
6146 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6147 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6148 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6149 0x06,0x05,0x00,0x04,0x00 };
6150 static const BYTE PKCSSignerWithHash[] = {
6151 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6152 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6153 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6154 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
6155 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6156 static const BYTE PKCSSignerWithAuthAttr[] = {
6157 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6158 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6159 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
6160 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
6161 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
6162 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
6163 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6165 static void test_encodePKCSSignerInfo(DWORD dwEncoding)
6167 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6168 BOOL ret;
6169 LPBYTE buf = NULL;
6170 DWORD size = 0;
6171 CMSG_SIGNER_INFO info = { 0 };
6172 char oid_common_name[] = szOID_COMMON_NAME;
6173 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
6174 (LPBYTE)encodedCommonName };
6175 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
6177 SetLastError(0xdeadbeef);
6178 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6179 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6180 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6182 skip("no PKCS7_SIGNER_INFO encode support\n");
6183 return;
6185 ok(!ret && (GetLastError() == E_INVALIDARG ||
6186 GetLastError() == OSS_LIMITED /* Win9x */),
6187 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6188 /* To be encoded, a signer must have an issuer at least, and the encoding
6189 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
6190 * see decoding tests.)
6192 info.Issuer.cbData = sizeof(encodedCommonNameNoNull);
6193 info.Issuer.pbData = encodedCommonNameNoNull;
6194 SetLastError(0xdeadbeef);
6195 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6196 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6197 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6198 ok(!ret && GetLastError() == E_INVALIDARG,
6199 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6200 else
6202 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6203 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6204 if (buf)
6206 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6207 if (size == sizeof(minimalPKCSSigner))
6208 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6209 else
6210 ok(0, "Unexpected value\n");
6211 LocalFree(buf);
6214 info.SerialNumber.cbData = sizeof(serialNum);
6215 info.SerialNumber.pbData = (BYTE *)serialNum;
6216 SetLastError(0xdeadbeef);
6217 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6218 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6219 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6220 ok(!ret && GetLastError() == E_INVALIDARG,
6221 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6222 else
6224 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6225 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6226 if (buf)
6228 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6229 size);
6230 if (size == sizeof(PKCSSignerWithSerial))
6231 ok(!memcmp(buf, PKCSSignerWithSerial, size),
6232 "Unexpected value\n");
6233 else
6234 ok(0, "Unexpected value\n");
6235 LocalFree(buf);
6238 info.HashAlgorithm.pszObjId = oid1;
6239 SetLastError(0xdeadbeef);
6240 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6241 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6242 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6243 ok(!ret && GetLastError() == E_INVALIDARG,
6244 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6245 else
6247 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6248 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6249 if (buf)
6251 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6252 size);
6253 if (size == sizeof(PKCSSignerWithHashAlgo))
6254 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6255 "Unexpected value\n");
6256 else
6257 ok(0, "Unexpected value\n");
6258 LocalFree(buf);
6261 info.HashEncryptionAlgorithm.pszObjId = oid2;
6262 SetLastError(0xdeadbeef);
6263 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6264 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6265 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6266 ok(!ret && GetLastError() == E_INVALIDARG,
6267 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6268 else
6270 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6271 if (buf)
6273 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6274 "Unexpected size %d\n", size);
6275 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo))
6276 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6277 "Unexpected value\n");
6278 else
6279 ok(0, "Unexpected value\n");
6280 LocalFree(buf);
6283 info.EncryptedHash.cbData = sizeof(hash);
6284 info.EncryptedHash.pbData = (BYTE *)hash;
6285 SetLastError(0xdeadbeef);
6286 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6287 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6288 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6289 ok(!ret && GetLastError() == E_INVALIDARG,
6290 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6291 else
6293 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6294 if (buf)
6296 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6297 size);
6298 if (size == sizeof(PKCSSignerWithHash))
6299 ok(!memcmp(buf, PKCSSignerWithHash, size),
6300 "Unexpected value\n");
6301 else
6302 ok(0, "Unexpected value\n");
6303 LocalFree(buf);
6306 info.AuthAttrs.cAttr = 1;
6307 info.AuthAttrs.rgAttr = &attr;
6308 SetLastError(0xdeadbeef);
6309 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6310 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6311 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6312 ok(!ret && GetLastError() == E_INVALIDARG,
6313 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6314 else
6316 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6317 if (buf)
6319 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
6320 size);
6321 if (size == sizeof(PKCSSignerWithAuthAttr))
6322 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
6323 "Unexpected value\n");
6324 else
6325 ok(0, "Unexpected value\n");
6326 LocalFree(buf);
6331 static void test_decodePKCSSignerInfo(DWORD dwEncoding)
6333 BOOL ret;
6334 LPBYTE buf = NULL;
6335 DWORD size = 0;
6336 CMSG_SIGNER_INFO *info;
6338 /* A PKCS signer can't be decoded without a serial number. */
6339 SetLastError(0xdeadbeef);
6340 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6341 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6342 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6343 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
6344 GetLastError() == OSS_DATA_ERROR /* Win9x */),
6345 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %x\n",
6346 GetLastError());
6347 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6348 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6349 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6350 ok(ret || broken(GetLastError() == OSS_DATA_ERROR),
6351 "CryptDecodeObjectEx failed: %x\n", GetLastError());
6352 if (buf)
6354 info = (CMSG_SIGNER_INFO *)buf;
6355 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6356 info->dwVersion);
6357 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6358 "Unexpected size %d\n", info->Issuer.cbData);
6359 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6360 info->Issuer.cbData), "Unexpected value\n");
6361 ok(info->SerialNumber.cbData == sizeof(serialNum),
6362 "Unexpected size %d\n", info->SerialNumber.cbData);
6363 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6364 "Unexpected value\n");
6365 LocalFree(buf);
6367 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6368 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6369 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6370 if (buf)
6372 info = (CMSG_SIGNER_INFO *)buf;
6373 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6374 info->dwVersion);
6375 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6376 "Unexpected size %d\n", info->Issuer.cbData);
6377 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6378 info->Issuer.cbData), "Unexpected value\n");
6379 ok(info->SerialNumber.cbData == sizeof(serialNum),
6380 "Unexpected size %d\n", info->SerialNumber.cbData);
6381 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6382 "Unexpected value\n");
6383 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6384 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6385 LocalFree(buf);
6387 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6388 PKCSSignerWithHashAndEncryptionAlgo,
6389 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6390 NULL, (BYTE *)&buf, &size);
6391 if (buf)
6393 info = (CMSG_SIGNER_INFO *)buf;
6394 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6395 info->dwVersion);
6396 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6397 "Unexpected size %d\n", info->Issuer.cbData);
6398 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6399 info->Issuer.cbData), "Unexpected value\n");
6400 ok(info->SerialNumber.cbData == sizeof(serialNum),
6401 "Unexpected size %d\n", info->SerialNumber.cbData);
6402 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6403 "Unexpected value\n");
6404 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6405 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6406 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6407 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6408 LocalFree(buf);
6410 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6411 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6412 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6413 if (buf)
6415 info = (CMSG_SIGNER_INFO *)buf;
6416 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6417 info->dwVersion);
6418 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6419 "Unexpected size %d\n", info->Issuer.cbData);
6420 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6421 info->Issuer.cbData), "Unexpected value\n");
6422 ok(info->SerialNumber.cbData == sizeof(serialNum),
6423 "Unexpected size %d\n", info->SerialNumber.cbData);
6424 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6425 "Unexpected value\n");
6426 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6427 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6428 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6429 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6430 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6431 info->EncryptedHash.cbData);
6432 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6433 "Unexpected value\n");
6434 LocalFree(buf);
6436 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6437 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
6438 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6439 if (buf)
6441 info = (CMSG_SIGNER_INFO *)buf;
6442 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n",
6443 info->AuthAttrs.cAttr);
6444 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
6445 "Expected %s, got %s\n", szOID_COMMON_NAME,
6446 info->AuthAttrs.rgAttr[0].pszObjId);
6447 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
6448 info->AuthAttrs.rgAttr[0].cValue);
6449 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
6450 sizeof(encodedCommonName), "Unexpected size %d\n",
6451 info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
6452 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
6453 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
6454 LocalFree(buf);
6458 static const BYTE CMSSignerWithKeyId[] = {
6459 0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,
6460 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6462 static void test_encodeCMSSignerInfo(DWORD dwEncoding)
6464 BOOL ret;
6465 LPBYTE buf = NULL;
6466 DWORD size = 0;
6467 CMSG_CMS_SIGNER_INFO info = { 0 };
6468 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6470 SetLastError(0xdeadbeef);
6471 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6472 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6473 ok(!ret, "Expected failure, got %d\n", ret);
6474 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6476 skip("no CMS_SIGNER_INFO encode support\n");
6477 return;
6479 ok(GetLastError() == E_INVALIDARG,
6480 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6481 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6482 SetLastError(0xdeadbeef);
6483 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6484 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6485 ok(!ret, "Expected failure, got %d\n", ret);
6486 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6488 skip("no CMS_SIGNER_INFO encode support\n");
6489 return;
6491 ok(GetLastError() == E_INVALIDARG,
6492 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6493 /* To be encoded, a signer must have a valid cert ID, where a valid ID may
6494 * be a key id or a issuer serial number with at least the issuer set, and
6495 * the encoding must include PKCS_7_ASN_ENCODING.
6496 * (That isn't enough to be decoded, see decoding tests.)
6498 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6499 sizeof(encodedCommonNameNoNull);
6500 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6501 SetLastError(0xdeadbeef);
6502 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6503 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6504 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6505 ok(!ret && GetLastError() == E_INVALIDARG,
6506 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6507 else
6509 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6510 if (buf)
6512 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6513 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6514 LocalFree(buf);
6517 U(info.SignerId).IssuerSerialNumber.SerialNumber.cbData = sizeof(serialNum);
6518 U(info.SignerId).IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
6519 SetLastError(0xdeadbeef);
6520 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6521 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6522 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6523 ok(!ret && GetLastError() == E_INVALIDARG,
6524 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6525 else
6527 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6528 if (buf)
6530 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6531 size);
6532 ok(!memcmp(buf, PKCSSignerWithSerial, size), "Unexpected value\n");
6533 LocalFree(buf);
6536 info.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
6537 U(info.SignerId).KeyId.cbData = sizeof(serialNum);
6538 U(info.SignerId).KeyId.pbData = (BYTE *)serialNum;
6539 SetLastError(0xdeadbeef);
6540 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6541 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6542 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6543 ok(!ret && GetLastError() == E_INVALIDARG,
6544 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6545 else
6547 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6548 if (buf)
6550 ok(size == sizeof(CMSSignerWithKeyId), "Unexpected size %d\n",
6551 size);
6552 ok(!memcmp(buf, CMSSignerWithKeyId, size), "Unexpected value\n");
6553 LocalFree(buf);
6556 /* While a CERT_ID can have a hash type, that's not allowed in CMS, where
6557 * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed
6558 * (see RFC 3852, section 5.3.)
6560 info.SignerId.dwIdChoice = CERT_ID_SHA1_HASH;
6561 U(info.SignerId).HashId.cbData = sizeof(hash);
6562 U(info.SignerId).HashId.pbData = (BYTE *)hash;
6563 SetLastError(0xdeadbeef);
6564 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6565 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6566 ok(!ret && GetLastError() == E_INVALIDARG,
6567 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6568 /* Now with a hash algo */
6569 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6570 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6571 sizeof(encodedCommonNameNoNull);
6572 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6573 info.HashAlgorithm.pszObjId = oid1;
6574 SetLastError(0xdeadbeef);
6575 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6576 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6577 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6578 ok(!ret && GetLastError() == E_INVALIDARG,
6579 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6580 else
6582 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6583 if (buf)
6585 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6586 size);
6587 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6588 "Unexpected value\n");
6589 LocalFree(buf);
6592 info.HashEncryptionAlgorithm.pszObjId = oid2;
6593 SetLastError(0xdeadbeef);
6594 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6595 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6596 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6597 ok(!ret && GetLastError() == E_INVALIDARG,
6598 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6599 else
6601 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6602 if (buf)
6604 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6605 "Unexpected size %d\n", size);
6606 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6607 "Unexpected value\n");
6608 LocalFree(buf);
6611 info.EncryptedHash.cbData = sizeof(hash);
6612 info.EncryptedHash.pbData = (BYTE *)hash;
6613 SetLastError(0xdeadbeef);
6614 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6615 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6616 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6617 ok(!ret && GetLastError() == E_INVALIDARG,
6618 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6619 else
6621 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6622 if (buf)
6624 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6625 size);
6626 ok(!memcmp(buf, PKCSSignerWithHash, size), "Unexpected value\n");
6627 LocalFree(buf);
6632 static void test_decodeCMSSignerInfo(DWORD dwEncoding)
6634 BOOL ret;
6635 LPBYTE buf = NULL;
6636 DWORD size = 0;
6637 CMSG_CMS_SIGNER_INFO *info;
6638 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6640 /* A CMS signer can't be decoded without a serial number. */
6641 SetLastError(0xdeadbeef);
6642 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6643 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6644 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6645 ok(!ret, "expected failure\n");
6646 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6648 skip("no CMS_SIGNER_INFO decode support\n");
6649 return;
6651 ok(GetLastError() == CRYPT_E_ASN1_CORRUPT,
6652 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
6653 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6654 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6655 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6656 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6657 if (buf)
6659 info = (CMSG_CMS_SIGNER_INFO *)buf;
6660 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6661 info->dwVersion);
6662 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6663 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6664 info->SignerId.dwIdChoice);
6665 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6666 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6667 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6668 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6669 encodedCommonNameNoNull,
6670 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6671 "Unexpected value\n");
6672 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6673 sizeof(serialNum), "Unexpected size %d\n",
6674 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6675 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6676 serialNum, sizeof(serialNum)), "Unexpected value\n");
6677 LocalFree(buf);
6679 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6680 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6681 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6682 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6683 if (buf)
6685 info = (CMSG_CMS_SIGNER_INFO *)buf;
6686 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6687 info->dwVersion);
6688 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6689 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6690 info->SignerId.dwIdChoice);
6691 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6692 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6693 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6694 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6695 encodedCommonNameNoNull,
6696 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6697 "Unexpected value\n");
6698 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6699 sizeof(serialNum), "Unexpected size %d\n",
6700 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6701 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6702 serialNum, sizeof(serialNum)), "Unexpected value\n");
6703 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6704 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6705 LocalFree(buf);
6707 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6708 PKCSSignerWithHashAndEncryptionAlgo,
6709 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6710 NULL, (BYTE *)&buf, &size);
6711 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6712 if (buf)
6714 info = (CMSG_CMS_SIGNER_INFO *)buf;
6715 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6716 info->dwVersion);
6717 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6718 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6719 info->SignerId.dwIdChoice);
6720 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6721 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6722 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6723 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6724 encodedCommonNameNoNull,
6725 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6726 "Unexpected value\n");
6727 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6728 sizeof(serialNum), "Unexpected size %d\n",
6729 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6730 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6731 serialNum, sizeof(serialNum)), "Unexpected value\n");
6732 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6733 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6734 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6735 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6736 LocalFree(buf);
6738 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6739 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6740 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6741 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6742 if (buf)
6744 info = (CMSG_CMS_SIGNER_INFO *)buf;
6745 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6746 info->dwVersion);
6747 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6748 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6749 info->SignerId.dwIdChoice);
6750 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6751 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6752 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6753 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6754 encodedCommonNameNoNull,
6755 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6756 "Unexpected value\n");
6757 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6758 sizeof(serialNum), "Unexpected size %d\n",
6759 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6760 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6761 serialNum, sizeof(serialNum)), "Unexpected value\n");
6762 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6763 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6764 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6765 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6766 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6767 info->EncryptedHash.cbData);
6768 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6769 "Unexpected value\n");
6770 LocalFree(buf);
6772 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6773 CMSSignerWithKeyId, sizeof(CMSSignerWithKeyId),
6774 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6775 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6776 if (buf)
6778 info = (CMSG_CMS_SIGNER_INFO *)buf;
6779 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6780 info->dwVersion);
6781 ok(info->SignerId.dwIdChoice == CERT_ID_KEY_IDENTIFIER,
6782 "Expected CERT_ID_KEY_IDENTIFIER, got %d\n",
6783 info->SignerId.dwIdChoice);
6784 ok(U(info->SignerId).KeyId.cbData == sizeof(serialNum),
6785 "Unexpected size %d\n", U(info->SignerId).KeyId.cbData);
6786 ok(!memcmp(U(info->SignerId).KeyId.pbData, serialNum, sizeof(serialNum)),
6787 "Unexpected value\n");
6788 LocalFree(buf);
6792 static BYTE emptyDNSPermittedConstraints[] = {
6793 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
6794 static BYTE emptyDNSExcludedConstraints[] = {
6795 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
6796 static BYTE DNSExcludedConstraints[] = {
6797 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
6798 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6799 static BYTE permittedAndExcludedConstraints[] = {
6800 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6801 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
6802 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6803 static BYTE permittedAndExcludedWithMinConstraints[] = {
6804 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6805 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
6806 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6807 static BYTE permittedAndExcludedWithMinMaxConstraints[] = {
6808 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6809 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
6810 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6812 static void test_encodeNameConstraints(DWORD dwEncoding)
6814 BOOL ret;
6815 CERT_NAME_CONSTRAINTS_INFO constraints = { 0 };
6816 CERT_GENERAL_SUBTREE permitted = { { 0 } };
6817 CERT_GENERAL_SUBTREE excluded = { { 0 } };
6818 LPBYTE buf;
6819 DWORD size;
6821 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6822 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6823 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6825 skip("no X509_NAME_CONSTRAINTS encode support\n");
6826 return;
6828 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6829 if (ret)
6831 ok(size == sizeof(emptySequence), "Unexpected size\n");
6832 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
6833 LocalFree(buf);
6835 constraints.cPermittedSubtree = 1;
6836 constraints.rgPermittedSubtree = &permitted;
6837 SetLastError(0xdeadbeef);
6838 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6839 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6840 ok(!ret && GetLastError() == E_INVALIDARG,
6841 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6842 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
6843 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6844 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6845 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6846 if (ret)
6848 ok(size == sizeof(emptyDNSPermittedConstraints), "Unexpected size\n");
6849 ok(!memcmp(buf, emptyDNSPermittedConstraints, size),
6850 "Unexpected value\n");
6851 LocalFree(buf);
6853 constraints.cPermittedSubtree = 0;
6854 constraints.cExcludedSubtree = 1;
6855 constraints.rgExcludedSubtree = &excluded;
6856 excluded.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
6857 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6858 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6859 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6860 if (ret)
6862 ok(size == sizeof(emptyDNSExcludedConstraints), "Unexpected size\n");
6863 ok(!memcmp(buf, emptyDNSExcludedConstraints, size),
6864 "Unexpected value\n");
6865 LocalFree(buf);
6867 U(excluded.Base).pwszURL = (LPWSTR)url;
6868 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6869 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6870 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6871 if (ret)
6873 ok(size == sizeof(DNSExcludedConstraints), "Unexpected size\n");
6874 ok(!memcmp(buf, DNSExcludedConstraints, size),
6875 "Unexpected value\n");
6876 LocalFree(buf);
6878 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
6879 U(permitted.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6880 U(permitted.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6881 constraints.cPermittedSubtree = 1;
6882 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6883 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6884 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6885 if (ret)
6887 ok(size == sizeof(permittedAndExcludedConstraints),
6888 "Unexpected size\n");
6889 ok(!memcmp(buf, permittedAndExcludedConstraints, size),
6890 "Unexpected value\n");
6891 LocalFree(buf);
6893 permitted.dwMinimum = 5;
6894 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6895 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6896 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6897 if (ret)
6899 ok(size == sizeof(permittedAndExcludedWithMinConstraints),
6900 "Unexpected size\n");
6901 ok(!memcmp(buf, permittedAndExcludedWithMinConstraints, size),
6902 "Unexpected value\n");
6903 LocalFree(buf);
6905 permitted.fMaximum = TRUE;
6906 permitted.dwMaximum = 3;
6907 SetLastError(0xdeadbeef);
6908 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6909 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6910 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6911 if (ret)
6913 ok(size == sizeof(permittedAndExcludedWithMinMaxConstraints),
6914 "Unexpected size\n");
6915 ok(!memcmp(buf, permittedAndExcludedWithMinMaxConstraints, size),
6916 "Unexpected value\n");
6917 LocalFree(buf);
6921 struct EncodedNameConstraints
6923 CRYPT_DATA_BLOB encoded;
6924 CERT_NAME_CONSTRAINTS_INFO constraints;
6927 static CERT_GENERAL_SUBTREE emptyDNSSubtree = {
6928 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
6929 static CERT_GENERAL_SUBTREE DNSSubtree = {
6930 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
6931 static CERT_GENERAL_SUBTREE IPAddressSubtree = {
6932 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 0 };
6933 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree = {
6934 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, 0 };
6935 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree = {
6936 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, TRUE, 3 };
6938 struct EncodedNameConstraints encodedNameConstraints[] = {
6939 { { sizeof(emptySequence), (LPBYTE)emptySequence }, { 0 } },
6940 { { sizeof(emptyDNSPermittedConstraints), emptyDNSPermittedConstraints },
6941 { 1, &emptyDNSSubtree, 0, NULL } },
6942 { { sizeof(emptyDNSExcludedConstraints), emptyDNSExcludedConstraints },
6943 { 0, NULL, 1, &emptyDNSSubtree } },
6944 { { sizeof(DNSExcludedConstraints), DNSExcludedConstraints },
6945 { 0, NULL, 1, &DNSSubtree } },
6946 { { sizeof(permittedAndExcludedConstraints), permittedAndExcludedConstraints },
6947 { 1, &IPAddressSubtree, 1, &DNSSubtree } },
6948 { { sizeof(permittedAndExcludedWithMinConstraints),
6949 permittedAndExcludedWithMinConstraints },
6950 { 1, &IPAddressWithMinSubtree, 1, &DNSSubtree } },
6951 { { sizeof(permittedAndExcludedWithMinMaxConstraints),
6952 permittedAndExcludedWithMinMaxConstraints },
6953 { 1, &IPAddressWithMinMaxSubtree, 1, &DNSSubtree } },
6956 static void test_decodeNameConstraints(DWORD dwEncoding)
6958 BOOL ret;
6959 DWORD i;
6960 CERT_NAME_CONSTRAINTS_INFO *constraints;
6962 U(DNSSubtree.Base).pwszURL = (LPWSTR)url;
6963 U(IPAddressSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6964 U(IPAddressSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6965 U(IPAddressWithMinSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6966 U(IPAddressWithMinSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6967 U(IPAddressWithMinMaxSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6968 U(IPAddressWithMinMaxSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6969 for (i = 0;
6970 i < sizeof(encodedNameConstraints) / sizeof(encodedNameConstraints[0]);
6971 i++)
6973 DWORD size;
6975 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS,
6976 encodedNameConstraints[i].encoded.pbData,
6977 encodedNameConstraints[i].encoded.cbData,
6978 CRYPT_DECODE_ALLOC_FLAG, NULL, &constraints, &size);
6979 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6981 skip("no X509_NAME_CONSTRAINTS decode support\n");
6982 return;
6984 ok(ret, "%d: CryptDecodeObjectEx failed: %08x\n", i, GetLastError());
6985 if (ret)
6987 DWORD j;
6989 if (constraints->cPermittedSubtree !=
6990 encodedNameConstraints[i].constraints.cPermittedSubtree)
6991 fprintf(stderr, "%d: expected %d permitted, got %d\n", i,
6992 encodedNameConstraints[i].constraints.cPermittedSubtree,
6993 constraints->cPermittedSubtree);
6994 if (constraints->cPermittedSubtree ==
6995 encodedNameConstraints[i].constraints.cPermittedSubtree)
6997 for (j = 0; j < constraints->cPermittedSubtree; j++)
6999 compareAltNameEntry(&constraints->rgPermittedSubtree[j].Base,
7000 &encodedNameConstraints[i].constraints.rgPermittedSubtree[j].Base);
7003 if (constraints->cExcludedSubtree !=
7004 encodedNameConstraints[i].constraints.cExcludedSubtree)
7005 fprintf(stderr, "%d: expected %d excluded, got %d\n", i,
7006 encodedNameConstraints[i].constraints.cExcludedSubtree,
7007 constraints->cExcludedSubtree);
7008 if (constraints->cExcludedSubtree ==
7009 encodedNameConstraints[i].constraints.cExcludedSubtree)
7011 for (j = 0; j < constraints->cExcludedSubtree; j++)
7013 compareAltNameEntry(&constraints->rgExcludedSubtree[j].Base,
7014 &encodedNameConstraints[i].constraints.rgExcludedSubtree[j].Base);
7017 LocalFree(constraints);
7022 /* Free *pInfo with HeapFree */
7023 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
7025 BOOL ret;
7026 DWORD size = 0;
7027 HCRYPTKEY key;
7029 /* This crashes
7030 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
7032 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size);
7033 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7034 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7035 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL,
7036 &size);
7037 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7038 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7039 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL,
7040 NULL, &size);
7041 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7042 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7043 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7044 0, NULL, NULL, &size);
7045 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7046 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7047 /* Test with no key */
7048 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7049 0, NULL, NULL, &size);
7050 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n",
7051 GetLastError());
7052 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
7053 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
7054 if (ret)
7056 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
7057 NULL, 0, NULL, NULL, &size);
7058 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
7059 *pInfo = HeapAlloc(GetProcessHeap(), 0, size);
7060 if (*pInfo)
7062 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
7063 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size);
7064 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n",
7065 GetLastError());
7066 if (ret)
7068 /* By default (we passed NULL as the OID) the OID is
7069 * szOID_RSA_RSA.
7071 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA),
7072 "Expected %s, got %s\n", szOID_RSA_RSA,
7073 (*pInfo)->Algorithm.pszObjId);
7077 CryptDestroyKey(key);
7080 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
7081 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
7082 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
7083 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7084 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7085 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7086 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
7087 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
7088 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7089 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7090 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7091 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
7092 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
7093 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
7094 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
7095 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
7096 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
7097 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
7098 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
7099 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
7100 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
7101 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
7102 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
7103 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
7104 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
7106 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info)
7108 BOOL ret;
7109 HCRYPTKEY key;
7110 PCCERT_CONTEXT context;
7111 DWORD dwSize;
7112 ALG_ID ai;
7114 /* These crash
7115 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
7116 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
7117 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
7118 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7119 NULL);
7121 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key);
7122 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7123 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7124 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key);
7125 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7126 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7127 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL,
7128 &key);
7129 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7130 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7132 /* Export key with standard algorithm (CALG_RSA_KEYX) */
7133 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7134 &key);
7135 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7137 dwSize = sizeof(ai);
7138 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7139 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7140 if(ret)
7142 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7143 ok(ai == CALG_RSA_KEYX, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai);
7146 CryptDestroyKey(key);
7148 /* Repeat with forced algorithm */
7149 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, CALG_RSA_SIGN, 0, NULL,
7150 &key);
7151 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7153 dwSize = sizeof(ai);
7154 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7155 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7156 if(ret)
7158 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7159 ok(ai == CALG_RSA_SIGN, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai);
7162 CryptDestroyKey(key);
7164 /* Test importing a public key from a certificate context */
7165 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert,
7166 sizeof(expiredCert));
7167 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
7168 GetLastError());
7169 if (context)
7171 ok(!strcmp(szOID_RSA_RSA,
7172 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId),
7173 "Expected %s, got %s\n", szOID_RSA_RSA,
7174 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
7175 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING,
7176 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
7177 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7178 CryptDestroyKey(key);
7179 CertFreeCertificateContext(context);
7183 static const char cspName[] = "WineCryptTemp";
7185 static void testPortPublicKeyInfo(void)
7187 HCRYPTPROV csp;
7188 BOOL ret;
7189 PCERT_PUBLIC_KEY_INFO info = NULL;
7191 /* Just in case a previous run failed, delete this thing */
7192 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7193 CRYPT_DELETEKEYSET);
7194 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7195 CRYPT_NEWKEYSET);
7197 testExportPublicKey(csp, &info);
7198 testImportPublicKey(csp, info);
7200 HeapFree(GetProcessHeap(), 0, info);
7201 CryptReleaseContext(csp, 0);
7202 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7203 CRYPT_DELETEKEYSET);
7206 START_TEST(encode)
7208 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
7209 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING };
7210 HMODULE hCrypt32;
7211 DWORD i;
7213 hCrypt32 = GetModuleHandleA("crypt32.dll");
7214 pCryptDecodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptDecodeObjectEx");
7215 pCryptEncodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptEncodeObjectEx");
7216 if (!pCryptDecodeObjectEx || !pCryptEncodeObjectEx)
7218 skip("CryptDecodeObjectEx() is not available\n");
7219 return;
7222 for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++)
7224 test_encodeInt(encodings[i]);
7225 test_decodeInt(encodings[i]);
7226 test_encodeEnumerated(encodings[i]);
7227 test_decodeEnumerated(encodings[i]);
7228 test_encodeFiletime(encodings[i]);
7229 test_decodeFiletime(encodings[i]);
7230 test_encodeName(encodings[i]);
7231 test_decodeName(encodings[i]);
7232 test_encodeUnicodeName(encodings[i]);
7233 test_decodeUnicodeName(encodings[i]);
7234 test_encodeNameValue(encodings[i]);
7235 test_decodeNameValue(encodings[i]);
7236 test_encodeUnicodeNameValue(encodings[i]);
7237 test_decodeUnicodeNameValue(encodings[i]);
7238 test_encodeAltName(encodings[i]);
7239 test_decodeAltName(encodings[i]);
7240 test_encodeOctets(encodings[i]);
7241 test_decodeOctets(encodings[i]);
7242 test_encodeBits(encodings[i]);
7243 test_decodeBits(encodings[i]);
7244 test_encodeBasicConstraints(encodings[i]);
7245 test_decodeBasicConstraints(encodings[i]);
7246 test_encodeRsaPublicKey(encodings[i]);
7247 test_decodeRsaPublicKey(encodings[i]);
7248 test_encodeSequenceOfAny(encodings[i]);
7249 test_decodeSequenceOfAny(encodings[i]);
7250 test_encodeExtensions(encodings[i]);
7251 test_decodeExtensions(encodings[i]);
7252 test_encodePublicKeyInfo(encodings[i]);
7253 test_decodePublicKeyInfo(encodings[i]);
7254 test_encodeCertToBeSigned(encodings[i]);
7255 test_decodeCertToBeSigned(encodings[i]);
7256 test_encodeCert(encodings[i]);
7257 test_decodeCert(encodings[i]);
7258 test_encodeCRLDistPoints(encodings[i]);
7259 test_decodeCRLDistPoints(encodings[i]);
7260 test_encodeCRLIssuingDistPoint(encodings[i]);
7261 test_decodeCRLIssuingDistPoint(encodings[i]);
7262 test_encodeCRLToBeSigned(encodings[i]);
7263 test_decodeCRLToBeSigned(encodings[i]);
7264 test_encodeEnhancedKeyUsage(encodings[i]);
7265 test_decodeEnhancedKeyUsage(encodings[i]);
7266 test_encodeAuthorityKeyId(encodings[i]);
7267 test_decodeAuthorityKeyId(encodings[i]);
7268 test_encodeAuthorityKeyId2(encodings[i]);
7269 test_decodeAuthorityKeyId2(encodings[i]);
7270 test_encodeAuthorityInfoAccess(encodings[i]);
7271 test_decodeAuthorityInfoAccess(encodings[i]);
7272 test_encodeCTL(encodings[i]);
7273 test_decodeCTL(encodings[i]);
7274 test_encodePKCSContentInfo(encodings[i]);
7275 test_decodePKCSContentInfo(encodings[i]);
7276 test_encodePKCSAttribute(encodings[i]);
7277 test_decodePKCSAttribute(encodings[i]);
7278 test_encodePKCSAttributes(encodings[i]);
7279 test_decodePKCSAttributes(encodings[i]);
7280 test_encodePKCSSMimeCapabilities(encodings[i]);
7281 test_decodePKCSSMimeCapabilities(encodings[i]);
7282 test_encodePKCSSignerInfo(encodings[i]);
7283 test_decodePKCSSignerInfo(encodings[i]);
7284 test_encodeCMSSignerInfo(encodings[i]);
7285 test_decodeCMSSignerInfo(encodings[i]);
7286 test_encodeNameConstraints(encodings[i]);
7287 test_decodeNameConstraints(encodings[i]);
7289 testPortPublicKeyInfo();