push 9e645869891abdc47a8701768b7a401b196a1e38
[wine/hacks.git] / dlls / crypt32 / tests / encode.c
blob60c387c9f26bfd35f4356abbc8445def8b179b72
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) ||
473 broken(GetLastError() == ERROR_SUCCESS),
474 "Expected CRYPT_E_BAD_ENCODE, got 0x%08x\n", GetLastError());
477 static const char *printSystemTime(const SYSTEMTIME *st)
479 static char buf[25];
481 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st->wMonth, st->wDay,
482 st->wYear, st->wHour, st->wMinute, st->wSecond, st->wMilliseconds);
483 return buf;
486 static const char *printFileTime(const FILETIME *ft)
488 static char buf[25];
489 SYSTEMTIME st;
491 FileTimeToSystemTime(ft, &st);
492 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st.wMonth, st.wDay,
493 st.wYear, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
494 return buf;
497 static void compareTime(const SYSTEMTIME *expected, const FILETIME *got)
499 SYSTEMTIME st;
501 FileTimeToSystemTime(got, &st);
502 ok((expected->wYear == st.wYear &&
503 expected->wMonth == st.wMonth &&
504 expected->wDay == st.wDay &&
505 expected->wHour == st.wHour &&
506 expected->wMinute == st.wMinute &&
507 expected->wSecond == st.wSecond &&
508 abs(expected->wMilliseconds - st.wMilliseconds) <= 1) ||
509 /* Some Windows systems only seem to be accurate in their time decoding to
510 * within about an hour.
512 broken(expected->wYear == st.wYear &&
513 expected->wMonth == st.wMonth &&
514 expected->wDay == st.wDay &&
515 abs(expected->wHour - st.wHour) <= 1),
516 "Got unexpected value for time decoding:\nexpected %s, got %s\n",
517 printSystemTime(expected), printFileTime(got));
520 static void testTimeDecoding(DWORD dwEncoding, LPCSTR structType,
521 const struct encodedFiletime *time)
523 FILETIME ft = { 0 };
524 DWORD size = sizeof(ft);
525 BOOL ret;
527 ret = pCryptDecodeObjectEx(dwEncoding, structType, time->encodedTime,
528 time->encodedTime[1] + 2, 0, NULL, &ft, &size);
529 /* years other than 1950-2050 are not allowed for encodings other than
530 * X509_CHOICE_OF_TIME.
532 if (structType == X509_CHOICE_OF_TIME ||
533 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050))
535 ok(ret || broken(GetLastError() == OSS_DATA_ERROR),
536 "CryptDecodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
537 GetLastError());
538 if (ret)
539 compareTime(&time->sysTime, &ft);
541 else
542 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
543 GetLastError() == OSS_PDU_MISMATCH /* Win9x */ ),
544 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %08x\n",
545 GetLastError());
548 static const BYTE bin20[] = {
549 0x17,0x0d,'0','5','0','6','0','6','1','6','1','0','0','0','Z'};
550 static const BYTE bin21[] = {
551 0x18,0x0f,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
552 static const BYTE bin22[] = {
553 0x18,0x0f,'2','1','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
555 static const struct encodedFiletime times[] = {
556 { { 2005, 6, 1, 6, 16, 10, 0, 0 }, bin20 },
557 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin21 },
558 { { 2145, 6, 1, 6, 16, 10, 0, 0 }, bin22 },
561 static void test_encodeFiletime(DWORD dwEncoding)
563 DWORD i;
565 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
567 testTimeEncoding(dwEncoding, X509_CHOICE_OF_TIME, &times[i]);
568 testTimeEncoding(dwEncoding, PKCS_UTC_TIME, &times[i]);
569 testTimeEncoding(dwEncoding, szOID_RSA_signingTime, &times[i]);
573 static const BYTE bin23[] = {
574 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','0','0','0','Z'};
575 static const BYTE bin24[] = {
576 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','9','9','9','Z'};
577 static const BYTE bin25[] = {
578 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','+','0','1','0','0'};
579 static const BYTE bin26[] = {
580 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','0','0'};
581 static const BYTE bin27[] = {
582 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','1','5'};
583 static const BYTE bin28[] = {
584 0x18,0x0a,'2','1','4','5','0','6','0','6','1','6'};
585 static const BYTE bin29[] = {
586 0x17,0x0a,'4','5','0','6','0','6','1','6','1','0'};
587 static const BYTE bin30[] = {
588 0x17,0x0b,'4','5','0','6','0','6','1','6','1','0','Z'};
589 static const BYTE bin31[] = {
590 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','+','0','1'};
591 static const BYTE bin32[] = {
592 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','-','0','1'};
593 static const BYTE bin33[] = {
594 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','+','0','1','0','0'};
595 static const BYTE bin34[] = {
596 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','-','0','1','0','0'};
597 static const BYTE bin35[] = {
598 0x17,0x08, '4','5','0','6','0','6','1','6'};
599 static const BYTE bin36[] = {
600 0x18,0x0f, 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','Z'};
601 static const BYTE bin37[] = {
602 0x18,0x04, '2','1','4','5'};
603 static const BYTE bin38[] = {
604 0x18,0x08, '2','1','4','5','0','6','0','6'};
606 static void test_decodeFiletime(DWORD dwEncoding)
608 static const struct encodedFiletime otherTimes[] = {
609 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin23 },
610 { { 1945, 6, 1, 6, 16, 10, 0, 999 }, bin24 },
611 { { 1945, 6, 1, 6, 17, 10, 0, 0 }, bin25 },
612 { { 1945, 6, 1, 6, 15, 10, 0, 0 }, bin26 },
613 { { 1945, 6, 1, 6, 14, 55, 0, 0 }, bin27 },
614 { { 2145, 6, 1, 6, 16, 0, 0, 0 }, bin28 },
615 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin29 },
616 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin30 },
617 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin31 },
618 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin32 },
619 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin33 },
620 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin34 },
622 /* An oddball case that succeeds in Windows, but doesn't seem correct
623 { { 2145, 6, 1, 2, 11, 31, 0, 0 }, "\x18" "\x13" "21450606161000-9999" },
625 static const unsigned char *bogusTimes[] = {
626 /* oddly, this succeeds on Windows, with year 2765
627 "\x18" "\x0f" "21r50606161000Z",
629 bin35,
630 bin36,
631 bin37,
632 bin38,
634 DWORD i, size;
635 FILETIME ft1 = { 0 }, ft2 = { 0 };
636 BOOL ret;
638 /* Check bogus length with non-NULL buffer */
639 ret = SystemTimeToFileTime(&times[0].sysTime, &ft1);
640 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
641 size = 1;
642 ret = pCryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
643 times[0].encodedTime, times[0].encodedTime[1] + 2, 0, NULL, &ft2, &size);
644 ok(!ret && GetLastError() == ERROR_MORE_DATA,
645 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
646 /* Normal tests */
647 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
649 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &times[i]);
650 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &times[i]);
651 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &times[i]);
653 for (i = 0; i < sizeof(otherTimes) / sizeof(otherTimes[0]); i++)
655 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &otherTimes[i]);
656 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &otherTimes[i]);
657 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &otherTimes[i]);
659 for (i = 0; i < sizeof(bogusTimes) / sizeof(bogusTimes[0]); i++)
661 size = sizeof(ft1);
662 ret = pCryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
663 bogusTimes[i], bogusTimes[i][1] + 2, 0, NULL, &ft1, &size);
664 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
665 GetLastError() == OSS_DATA_ERROR /* Win9x */),
666 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
667 GetLastError());
671 static const char commonName[] = "Juan Lang";
672 static const char surName[] = "Lang";
674 static const BYTE emptySequence[] = { 0x30, 0 };
675 static const BYTE emptyRDNs[] = { 0x30, 0x02, 0x31, 0 };
676 static const BYTE twoRDNs[] = {
677 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
678 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
679 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0};
680 static const BYTE encodedTwoRDNs[] = {
681 0x30,0x2e,0x31,0x2c,0x30,0x2a,0x06,0x03,0x55,0x04,0x03,0x30,0x23,0x31,0x21,
682 0x30,0x0c,0x06,0x03,0x55,0x04,0x04,0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,
683 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
684 0x6e,0x67,0x00,
687 static const BYTE us[] = { 0x55, 0x53 };
688 static const BYTE minnesota[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x73, 0x6f,
689 0x74, 0x61 };
690 static const BYTE minneapolis[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x61, 0x70,
691 0x6f, 0x6c, 0x69, 0x73 };
692 static const BYTE codeweavers[] = { 0x43, 0x6f, 0x64, 0x65, 0x57, 0x65, 0x61,
693 0x76, 0x65, 0x72, 0x73 };
694 static const BYTE wine[] = { 0x57, 0x69, 0x6e, 0x65, 0x20, 0x44, 0x65, 0x76,
695 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74 };
696 static const BYTE localhostAttr[] = { 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
697 0x73, 0x74 };
698 static const BYTE aric[] = { 0x61, 0x72, 0x69, 0x63, 0x40, 0x63, 0x6f, 0x64,
699 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d };
701 #define RDNA(arr) oid_ ## arr, CERT_RDN_PRINTABLE_STRING, { sizeof(arr), (LPBYTE)arr }
702 #define RDNIA5(arr) oid_ ## arr, CERT_RDN_IA5_STRING, { sizeof(arr), (LPBYTE)arr }
704 static CHAR oid_us[] = "2.5.4.6",
705 oid_minnesota[] = "2.5.4.8",
706 oid_minneapolis[] = "2.5.4.7",
707 oid_codeweavers[] = "2.5.4.10",
708 oid_wine[] = "2.5.4.11",
709 oid_localhostAttr[] = "2.5.4.3",
710 oid_aric[] = "1.2.840.113549.1.9.1";
711 static CERT_RDN_ATTR rdnAttrs[] = { { RDNA(us) },
712 { RDNA(minnesota) },
713 { RDNA(minneapolis) },
714 { RDNA(codeweavers) },
715 { RDNA(wine) },
716 { RDNA(localhostAttr) },
717 { RDNIA5(aric) } };
718 static CERT_RDN_ATTR decodedRdnAttrs[] = { { RDNA(us) },
719 { RDNA(localhostAttr) },
720 { RDNA(minnesota) },
721 { RDNA(minneapolis) },
722 { RDNA(codeweavers) },
723 { RDNA(wine) },
724 { RDNIA5(aric) } };
726 #undef RDNIA5
727 #undef RDNA
729 static const BYTE encodedRDNAttrs[] = {
730 0x30,0x81,0x96,0x31,0x81,0x93,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
731 0x53,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x68,
732 0x6f,0x73,0x74,0x30,0x10,0x06,0x03,0x55,0x04,0x08,0x13,0x09,0x4d,0x69,0x6e,0x6e,
733 0x65,0x73,0x6f,0x74,0x61,0x30,0x12,0x06,0x03,0x55,0x04,0x07,0x13,0x0b,0x4d,0x69,
734 0x6e,0x6e,0x65,0x61,0x70,0x6f,0x6c,0x69,0x73,0x30,0x12,0x06,0x03,0x55,0x04,0x0a,
735 0x13,0x0b,0x43,0x6f,0x64,0x65,0x57,0x65,0x61,0x76,0x65,0x72,0x73,0x30,0x17,0x06,
736 0x03,0x55,0x04,0x0b,0x13,0x10,0x57,0x69,0x6e,0x65,0x20,0x44,0x65,0x76,0x65,0x6c,
737 0x6f,0x70,0x6d,0x65,0x6e,0x74,0x30,0x21,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
738 0x01,0x09,0x01,0x16,0x14,0x61,0x72,0x69,0x63,0x40,0x63,0x6f,0x64,0x65,0x77,0x65,
739 0x61,0x76,0x65,0x72,0x73,0x2e,0x63,0x6f,0x6d
742 static void test_encodeName(DWORD dwEncoding)
744 CERT_RDN_ATTR attrs[2];
745 CERT_RDN rdn;
746 CERT_NAME_INFO info;
747 static CHAR oid_common_name[] = szOID_COMMON_NAME,
748 oid_sur_name[] = szOID_SUR_NAME;
749 BYTE *buf = NULL;
750 DWORD size = 0;
751 BOOL ret;
753 if (0)
755 /* Test with NULL pvStructInfo (crashes on win9x) */
756 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, NULL,
757 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
758 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
759 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
761 /* Test with empty CERT_NAME_INFO */
762 info.cRDN = 0;
763 info.rgRDN = NULL;
764 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
765 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
766 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
767 if (buf)
769 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
770 "Got unexpected encoding for empty name\n");
771 LocalFree(buf);
773 if (0)
775 /* Test with bogus CERT_RDN (crashes on win9x) */
776 info.cRDN = 1;
777 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
778 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
779 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
780 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
782 /* Test with empty CERT_RDN */
783 rdn.cRDNAttr = 0;
784 rdn.rgRDNAttr = NULL;
785 info.cRDN = 1;
786 info.rgRDN = &rdn;
787 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
788 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
789 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
790 if (buf)
792 ok(!memcmp(buf, emptyRDNs, sizeof(emptyRDNs)),
793 "Got unexpected encoding for empty RDN array\n");
794 LocalFree(buf);
796 if (0)
798 /* Test with bogus attr array (crashes on win9x) */
799 rdn.cRDNAttr = 1;
800 rdn.rgRDNAttr = NULL;
801 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
802 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
803 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
804 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
806 /* oddly, a bogus OID is accepted by Windows XP; not testing.
807 attrs[0].pszObjId = "bogus";
808 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
809 attrs[0].Value.cbData = sizeof(commonName);
810 attrs[0].Value.pbData = (BYTE *)commonName;
811 rdn.cRDNAttr = 1;
812 rdn.rgRDNAttr = attrs;
813 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
814 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
815 ok(!ret, "Expected failure, got success\n");
817 /* Check with two CERT_RDN_ATTRs. Note DER encoding forces the order of
818 * the encoded attributes to be swapped.
820 attrs[0].pszObjId = oid_common_name;
821 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
822 attrs[0].Value.cbData = sizeof(commonName);
823 attrs[0].Value.pbData = (BYTE *)commonName;
824 attrs[1].pszObjId = oid_sur_name;
825 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
826 attrs[1].Value.cbData = sizeof(surName);
827 attrs[1].Value.pbData = (BYTE *)surName;
828 rdn.cRDNAttr = 2;
829 rdn.rgRDNAttr = attrs;
830 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
831 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
832 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
833 if (buf)
835 ok(!memcmp(buf, twoRDNs, sizeof(twoRDNs)),
836 "Got unexpected encoding for two RDN array\n");
837 LocalFree(buf);
839 /* A name can be "encoded" with previously encoded RDN attrs. */
840 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
841 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
842 attrs[0].Value.cbData = sizeof(twoRDNs);
843 rdn.cRDNAttr = 1;
844 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
845 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
846 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
847 if (buf)
849 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
850 ok(!memcmp(buf, encodedTwoRDNs, size),
851 "Unexpected value for re-endoded two RDN array\n");
852 LocalFree(buf);
854 /* CERT_RDN_ANY_TYPE is too vague for X509_NAMEs, check the return */
855 rdn.cRDNAttr = 1;
856 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
857 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
858 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
859 ok(!ret && GetLastError() == E_INVALIDARG,
860 "Expected E_INVALIDARG, got %08x\n", GetLastError());
861 /* Test a more complex name */
862 rdn.cRDNAttr = sizeof(rdnAttrs) / sizeof(rdnAttrs[0]);
863 rdn.rgRDNAttr = (PCERT_RDN_ATTR)rdnAttrs;
864 info.cRDN = 1;
865 info.rgRDN = &rdn;
866 buf = NULL;
867 size = 0;
868 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, X509_NAME, &info,
869 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
870 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
871 if (ret)
873 ok(size == sizeof(encodedRDNAttrs), "Wrong size %d\n", size);
874 ok(!memcmp(buf, encodedRDNAttrs, size), "Unexpected value\n");
875 LocalFree(buf);
879 static WCHAR commonNameW[] = { 'J','u','a','n',' ','L','a','n','g',0 };
880 static WCHAR surNameW[] = { 'L','a','n','g',0 };
882 static const BYTE twoRDNsNoNull[] = {
883 0x30,0x21,0x31,0x1f,0x30,0x0b,0x06,0x03,0x55,0x04,0x04,0x13,0x04,0x4c,0x61,
884 0x6e,0x67,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,
885 0x20,0x4c,0x61,0x6e,0x67 };
886 static const BYTE anyType[] = {
887 0x30,0x2f,0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x1e,0x24,0x23,0x30,
888 0x21,0x31,0x0c,0x30,0x03,0x06,0x04,0x55,0x13,0x04,0x4c,0x05,0x6e,0x61,0x00,
889 0x67,0x11,0x30,0x03,0x06,0x04,0x55,0x13,0x03,0x4a,0x0a,0x61,0x75,0x20,0x6e,
890 0x61,0x4c,0x67,0x6e };
892 static void test_encodeUnicodeName(DWORD dwEncoding)
894 CERT_RDN_ATTR attrs[2];
895 CERT_RDN rdn;
896 CERT_NAME_INFO info;
897 static CHAR oid_common_name[] = szOID_COMMON_NAME,
898 oid_sur_name[] = szOID_SUR_NAME;
899 BYTE *buf = NULL;
900 DWORD size = 0;
901 BOOL ret;
903 if (0)
905 /* Test with NULL pvStructInfo (crashes on win9x) */
906 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, NULL,
907 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
908 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
909 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
911 /* Test with empty CERT_NAME_INFO */
912 info.cRDN = 0;
913 info.rgRDN = NULL;
914 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
915 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
916 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
917 if (buf)
919 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
920 "Got unexpected encoding for empty name\n");
921 LocalFree(buf);
923 /* Check with one CERT_RDN_ATTR, that has an invalid character for the
924 * encoding (the NULL).
926 attrs[0].pszObjId = oid_common_name;
927 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
928 attrs[0].Value.cbData = sizeof(commonNameW);
929 attrs[0].Value.pbData = (BYTE *)commonNameW;
930 rdn.cRDNAttr = 1;
931 rdn.rgRDNAttr = attrs;
932 info.cRDN = 1;
933 info.rgRDN = &rdn;
934 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
935 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
936 ok(!ret && GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING,
937 "Expected CRYPT_E_INVALID_PRINTABLE_STRING, got %08x\n", GetLastError());
938 ok(size == 9, "Unexpected error index %08x\n", size);
939 /* Check with two NULL-terminated CERT_RDN_ATTRs. Note DER encoding
940 * forces the order of the encoded attributes to be swapped.
942 attrs[0].pszObjId = oid_common_name;
943 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
944 attrs[0].Value.cbData = 0;
945 attrs[0].Value.pbData = (BYTE *)commonNameW;
946 attrs[1].pszObjId = oid_sur_name;
947 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
948 attrs[1].Value.cbData = 0;
949 attrs[1].Value.pbData = (BYTE *)surNameW;
950 rdn.cRDNAttr = 2;
951 rdn.rgRDNAttr = attrs;
952 info.cRDN = 1;
953 info.rgRDN = &rdn;
954 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
955 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
956 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
957 if (buf)
959 ok(!memcmp(buf, twoRDNsNoNull, sizeof(twoRDNsNoNull)),
960 "Got unexpected encoding for two RDN array\n");
961 LocalFree(buf);
963 /* A name can be "encoded" with previously encoded RDN attrs. */
964 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
965 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
966 attrs[0].Value.cbData = sizeof(twoRDNs);
967 rdn.cRDNAttr = 1;
968 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
969 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
970 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
971 if (buf)
973 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
974 ok(!memcmp(buf, encodedTwoRDNs, size),
975 "Unexpected value for re-endoded two RDN array\n");
976 LocalFree(buf);
978 /* Unicode names infer the type for CERT_RDN_ANY_TYPE */
979 rdn.cRDNAttr = 1;
980 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
981 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
982 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
983 todo_wine ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
984 if (buf)
986 ok(size == sizeof(anyType), "Unexpected size %d\n", size);
987 ok(!memcmp(buf, anyType, size), "Unexpected value\n");
988 LocalFree(buf);
992 static void compareNameValues(const CERT_NAME_VALUE *expected,
993 const CERT_NAME_VALUE *got)
995 ok(got->dwValueType == expected->dwValueType,
996 "Expected string type %d, got %d\n", expected->dwValueType,
997 got->dwValueType);
998 ok(got->Value.cbData == expected->Value.cbData,
999 "String type %d: unexpected data size, got %d, expected %d\n",
1000 expected->dwValueType, got->Value.cbData, expected->Value.cbData);
1001 if (got->Value.cbData && got->Value.pbData)
1002 ok(!memcmp(got->Value.pbData, expected->Value.pbData,
1003 min(got->Value.cbData, expected->Value.cbData)),
1004 "String type %d: unexpected value\n", expected->dwValueType);
1007 static void compareRDNAttrs(const CERT_RDN_ATTR *expected,
1008 const CERT_RDN_ATTR *got)
1010 if (expected->pszObjId && strlen(expected->pszObjId))
1012 ok(got->pszObjId != NULL, "Expected OID %s, got NULL\n",
1013 expected->pszObjId);
1014 if (got->pszObjId)
1016 ok(!strcmp(got->pszObjId, expected->pszObjId),
1017 "Got unexpected OID %s, expected %s\n", got->pszObjId,
1018 expected->pszObjId);
1021 compareNameValues((const CERT_NAME_VALUE *)&expected->dwValueType,
1022 (const CERT_NAME_VALUE *)&got->dwValueType);
1025 static void compareRDNs(const CERT_RDN *expected, const CERT_RDN *got)
1027 ok(got->cRDNAttr == expected->cRDNAttr,
1028 "Expected %d RDN attrs, got %d\n", expected->cRDNAttr, got->cRDNAttr);
1029 if (got->cRDNAttr)
1031 DWORD i;
1033 for (i = 0; i < got->cRDNAttr; i++)
1034 compareRDNAttrs(&expected->rgRDNAttr[i], &got->rgRDNAttr[i]);
1038 static void compareNames(const CERT_NAME_INFO *expected,
1039 const CERT_NAME_INFO *got)
1041 ok(got->cRDN == expected->cRDN, "Expected %d RDNs, got %d\n",
1042 expected->cRDN, got->cRDN);
1043 if (got->cRDN)
1045 DWORD i;
1047 for (i = 0; i < got->cRDN; i++)
1048 compareRDNs(&expected->rgRDN[i], &got->rgRDN[i]);
1052 static const BYTE emptyIndefiniteSequence[] = { 0x30,0x80,0x00,0x00 };
1053 static const BYTE twoRDNsExtraBytes[] = {
1054 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
1055 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1056 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0,0,0,0,0,0};
1058 static void test_decodeName(DWORD dwEncoding)
1060 BYTE *buf = NULL;
1061 DWORD bufSize = 0;
1062 BOOL ret;
1063 CERT_RDN rdn;
1064 CERT_NAME_INFO info = { 1, &rdn };
1066 /* test empty name */
1067 bufSize = 0;
1068 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptySequence,
1069 emptySequence[1] + 2,
1070 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1071 (BYTE *)&buf, &bufSize);
1072 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1073 /* Interestingly, in Windows, if cRDN is 0, rgRGN may not be NULL. My
1074 * decoder works the same way, so only test the count.
1076 if (buf)
1078 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1079 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1080 "Expected 0 RDNs in empty info, got %d\n",
1081 ((CERT_NAME_INFO *)buf)->cRDN);
1082 LocalFree(buf);
1084 /* test empty name with indefinite-length encoding */
1085 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyIndefiniteSequence,
1086 sizeof(emptyIndefiniteSequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
1087 (BYTE *)&buf, &bufSize);
1088 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1089 if (ret)
1091 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1092 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1093 "Expected 0 RDNs in empty info, got %d\n",
1094 ((CERT_NAME_INFO *)buf)->cRDN);
1095 LocalFree(buf);
1097 /* test empty RDN */
1098 bufSize = 0;
1099 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyRDNs,
1100 emptyRDNs[1] + 2,
1101 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1102 (BYTE *)&buf, &bufSize);
1103 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1104 if (buf)
1106 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1108 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1109 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1110 "Got unexpected value for empty RDN\n");
1111 LocalFree(buf);
1113 /* test two RDN attrs */
1114 bufSize = 0;
1115 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNs,
1116 twoRDNs[1] + 2,
1117 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1118 (BYTE *)&buf, &bufSize);
1119 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1120 if (buf)
1122 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1123 oid_common_name[] = szOID_COMMON_NAME;
1125 CERT_RDN_ATTR attrs[] = {
1126 { oid_sur_name, CERT_RDN_PRINTABLE_STRING, { sizeof(surName),
1127 (BYTE *)surName } },
1128 { oid_common_name, CERT_RDN_PRINTABLE_STRING, { sizeof(commonName),
1129 (BYTE *)commonName } },
1132 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1133 rdn.rgRDNAttr = attrs;
1134 compareNames(&info, (CERT_NAME_INFO *)buf);
1135 LocalFree(buf);
1137 /* test that two RDN attrs with extra bytes succeeds */
1138 bufSize = 0;
1139 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNsExtraBytes,
1140 sizeof(twoRDNsExtraBytes), 0, NULL, NULL, &bufSize);
1141 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1142 /* And, a slightly more complicated name */
1143 buf = NULL;
1144 bufSize = 0;
1145 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME, encodedRDNAttrs,
1146 sizeof(encodedRDNAttrs), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1147 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1148 if (ret)
1150 rdn.cRDNAttr = sizeof(decodedRdnAttrs) / sizeof(decodedRdnAttrs[0]);
1151 rdn.rgRDNAttr = (PCERT_RDN_ATTR)decodedRdnAttrs;
1152 compareNames(&info, (CERT_NAME_INFO *)buf);
1153 LocalFree(buf);
1157 static void test_decodeUnicodeName(DWORD dwEncoding)
1159 BYTE *buf = NULL;
1160 DWORD bufSize = 0;
1161 BOOL ret;
1162 CERT_RDN rdn;
1163 CERT_NAME_INFO info = { 1, &rdn };
1165 /* test empty name */
1166 bufSize = 0;
1167 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptySequence,
1168 emptySequence[1] + 2,
1169 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1170 (BYTE *)&buf, &bufSize);
1171 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1172 if (buf)
1174 ok(bufSize == sizeof(CERT_NAME_INFO),
1175 "Got wrong bufSize %d\n", bufSize);
1176 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1177 "Expected 0 RDNs in empty info, got %d\n",
1178 ((CERT_NAME_INFO *)buf)->cRDN);
1179 LocalFree(buf);
1181 /* test empty RDN */
1182 bufSize = 0;
1183 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptyRDNs,
1184 emptyRDNs[1] + 2,
1185 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1186 (BYTE *)&buf, &bufSize);
1187 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1188 if (buf)
1190 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1192 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1193 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1194 "Got unexpected value for empty RDN\n");
1195 LocalFree(buf);
1197 /* test two RDN attrs */
1198 bufSize = 0;
1199 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, twoRDNsNoNull,
1200 sizeof(twoRDNsNoNull),
1201 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1202 (BYTE *)&buf, &bufSize);
1203 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1204 if (buf)
1206 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1207 oid_common_name[] = szOID_COMMON_NAME;
1209 CERT_RDN_ATTR attrs[] = {
1210 { oid_sur_name, CERT_RDN_PRINTABLE_STRING,
1211 { lstrlenW(surNameW) * sizeof(WCHAR), (BYTE *)surNameW } },
1212 { oid_common_name, CERT_RDN_PRINTABLE_STRING,
1213 { lstrlenW(commonNameW) * sizeof(WCHAR), (BYTE *)commonNameW } },
1216 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1217 rdn.rgRDNAttr = attrs;
1218 compareNames(&info, (CERT_NAME_INFO *)buf);
1219 LocalFree(buf);
1223 struct EncodedNameValue
1225 CERT_NAME_VALUE value;
1226 const BYTE *encoded;
1227 DWORD encodedSize;
1230 static const char bogusIA5[] = "\x80";
1231 static const char bogusPrintable[] = "~";
1232 static const char bogusNumeric[] = "A";
1233 static const BYTE bin42[] = { 0x16,0x02,0x80,0x00 };
1234 static const BYTE bin43[] = { 0x13,0x02,0x7e,0x00 };
1235 static const BYTE bin44[] = { 0x12,0x02,0x41,0x00 };
1236 static BYTE octetCommonNameValue[] = {
1237 0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1238 static BYTE numericCommonNameValue[] = {
1239 0x12,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1240 static BYTE printableCommonNameValue[] = {
1241 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1242 static BYTE t61CommonNameValue[] = {
1243 0x14,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1244 static BYTE videotexCommonNameValue[] = {
1245 0x15,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1246 static BYTE ia5CommonNameValue[] = {
1247 0x16,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1248 static BYTE graphicCommonNameValue[] = {
1249 0x19,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1250 static BYTE visibleCommonNameValue[] = {
1251 0x1a,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1252 static BYTE generalCommonNameValue[] = {
1253 0x1b,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1254 static BYTE bmpCommonNameValue[] = {
1255 0x1e,0x14,0x00,0x4a,0x00,0x75,0x00,0x61,0x00,0x6e,0x00,0x20,0x00,0x4c,0x00,
1256 0x61,0x00,0x6e,0x00,0x67,0x00,0x00 };
1257 static BYTE utf8CommonNameValue[] = {
1258 0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1260 static struct EncodedNameValue nameValues[] = {
1261 { { CERT_RDN_OCTET_STRING, { sizeof(commonName), (BYTE *)commonName } },
1262 octetCommonNameValue, sizeof(octetCommonNameValue) },
1263 { { CERT_RDN_NUMERIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1264 numericCommonNameValue, sizeof(numericCommonNameValue) },
1265 { { CERT_RDN_PRINTABLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1266 printableCommonNameValue, sizeof(printableCommonNameValue) },
1267 { { CERT_RDN_T61_STRING, { sizeof(commonName), (BYTE *)commonName } },
1268 t61CommonNameValue, sizeof(t61CommonNameValue) },
1269 { { CERT_RDN_VIDEOTEX_STRING, { sizeof(commonName), (BYTE *)commonName } },
1270 videotexCommonNameValue, sizeof(videotexCommonNameValue) },
1271 { { CERT_RDN_IA5_STRING, { sizeof(commonName), (BYTE *)commonName } },
1272 ia5CommonNameValue, sizeof(ia5CommonNameValue) },
1273 { { CERT_RDN_GRAPHIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1274 graphicCommonNameValue, sizeof(graphicCommonNameValue) },
1275 { { CERT_RDN_VISIBLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1276 visibleCommonNameValue, sizeof(visibleCommonNameValue) },
1277 { { CERT_RDN_GENERAL_STRING, { sizeof(commonName), (BYTE *)commonName } },
1278 generalCommonNameValue, sizeof(generalCommonNameValue) },
1279 { { CERT_RDN_BMP_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1280 bmpCommonNameValue, sizeof(bmpCommonNameValue) },
1281 { { CERT_RDN_UTF8_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1282 utf8CommonNameValue, sizeof(utf8CommonNameValue) },
1283 /* The following tests succeed under Windows, but really should fail,
1284 * they contain characters that are illegal for the encoding. I'm
1285 * including them to justify my lazy encoding.
1287 { { CERT_RDN_IA5_STRING, { sizeof(bogusIA5), (BYTE *)bogusIA5 } }, bin42,
1288 sizeof(bin42) },
1289 { { CERT_RDN_PRINTABLE_STRING, { sizeof(bogusPrintable),
1290 (BYTE *)bogusPrintable } }, bin43, sizeof(bin43) },
1291 { { CERT_RDN_NUMERIC_STRING, { sizeof(bogusNumeric), (BYTE *)bogusNumeric } },
1292 bin44, sizeof(bin44) },
1295 static void test_encodeNameValue(DWORD dwEncoding)
1297 BYTE *buf = NULL;
1298 DWORD size = 0, i;
1299 BOOL ret;
1300 CERT_NAME_VALUE value = { 0, { 0, NULL } };
1302 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1303 value.Value.pbData = printableCommonNameValue;
1304 value.Value.cbData = sizeof(printableCommonNameValue);
1305 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, &value,
1306 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1307 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1308 if (buf)
1310 ok(size == sizeof(printableCommonNameValue), "Unexpected size %d\n",
1311 size);
1312 ok(!memcmp(buf, printableCommonNameValue, size),
1313 "Unexpected encoding\n");
1314 LocalFree(buf);
1316 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1318 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE,
1319 &nameValues[i].value, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1320 &size);
1321 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH) /* NT4/Win9x */,
1322 "Type %d: CryptEncodeObjectEx failed: %08x\n",
1323 nameValues[i].value.dwValueType, GetLastError());
1324 if (ret)
1326 ok(size == nameValues[i].encodedSize,
1327 "Expected size %d, got %d\n", nameValues[i].encodedSize, size);
1328 ok(!memcmp(buf, nameValues[i].encoded, size),
1329 "Got unexpected encoding\n");
1330 LocalFree(buf);
1335 static void test_decodeNameValue(DWORD dwEncoding)
1337 int i;
1338 BYTE *buf = NULL;
1339 DWORD bufSize = 0;
1340 BOOL ret;
1342 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1344 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE,
1345 nameValues[i].encoded, nameValues[i].encoded[1] + 2,
1346 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1347 (BYTE *)&buf, &bufSize);
1348 ok(ret, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
1349 nameValues[i].value.dwValueType, GetLastError());
1350 if (ret)
1352 compareNameValues(&nameValues[i].value,
1353 (const CERT_NAME_VALUE *)buf);
1354 LocalFree(buf);
1359 static const BYTE emptyURL[] = { 0x30, 0x02, 0x86, 0x00 };
1360 static const BYTE emptyURLExtraBytes[] = { 0x30, 0x02, 0x86, 0x00, 0, 0, 0 };
1361 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e',
1362 'h','q','.','o','r','g',0 };
1363 static const BYTE encodedURL[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74,
1364 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e,
1365 0x6f, 0x72, 0x67 };
1366 static const WCHAR nihongoURL[] = { 'h','t','t','p',':','/','/',0x226f,
1367 0x575b, 0 };
1368 static const WCHAR dnsName[] = { 'w','i','n','e','h','q','.','o','r','g',0 };
1369 static const BYTE encodedDnsName[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69,
1370 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
1371 static const BYTE localhost[] = { 127, 0, 0, 1 };
1372 static const BYTE encodedIPAddr[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00,
1373 0x01 };
1374 static const unsigned char encodedCommonName[] = {
1375 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0};
1376 static const BYTE encodedOidName[] = { 0x30,0x04,0x88,0x02,0x2a,0x03 };
1377 static const BYTE encodedDirectoryName[] = {
1378 0x30,0x19,0xa4,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1379 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1381 static void test_encodeAltName(DWORD dwEncoding)
1383 CERT_ALT_NAME_INFO info = { 0 };
1384 CERT_ALT_NAME_ENTRY entry = { 0 };
1385 BYTE *buf = NULL;
1386 DWORD size = 0;
1387 BOOL ret;
1388 char oid[] = "1.2.3";
1390 /* Test with empty info */
1391 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1392 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1393 if (buf)
1395 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
1396 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
1397 LocalFree(buf);
1399 /* Test with an empty entry */
1400 info.cAltEntry = 1;
1401 info.rgAltEntry = &entry;
1402 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1403 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1404 ok(!ret && GetLastError() == E_INVALIDARG,
1405 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1406 /* Test with an empty pointer */
1407 entry.dwAltNameChoice = CERT_ALT_NAME_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(emptyURL), "Wrong size %d\n", size);
1413 ok(!memcmp(buf, emptyURL, size), "Unexpected value\n");
1414 LocalFree(buf);
1416 /* Test with a real URL */
1417 U(entry).pwszURL = (LPWSTR)url;
1418 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1419 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1420 if (buf)
1422 ok(size == sizeof(encodedURL), "Wrong size %d\n", size);
1423 ok(!memcmp(buf, encodedURL, size), "Unexpected value\n");
1424 LocalFree(buf);
1426 /* Now with the URL containing an invalid IA5 char */
1427 U(entry).pwszURL = (LPWSTR)nihongoURL;
1428 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1429 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1430 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
1431 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
1432 /* The first invalid character is at index 7 */
1433 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
1434 "Expected invalid char at index 7, got %d\n",
1435 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
1436 /* Now with the URL missing a scheme */
1437 U(entry).pwszURL = (LPWSTR)dnsName;
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 /* This succeeds, but it shouldn't, so don't worry about conforming */
1444 LocalFree(buf);
1446 /* Now with a DNS name */
1447 entry.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
1448 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1449 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1450 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1451 if (buf)
1453 ok(size == sizeof(encodedDnsName), "Wrong size %d\n", size);
1454 ok(!memcmp(buf, encodedDnsName, size), "Unexpected value\n");
1455 LocalFree(buf);
1457 /* Test with an IP address */
1458 entry.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
1459 U(entry).IPAddress.cbData = sizeof(localhost);
1460 U(entry).IPAddress.pbData = (LPBYTE)localhost;
1461 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1462 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1463 if (buf)
1465 ok(size == sizeof(encodedIPAddr), "Wrong size %d\n", size);
1466 ok(!memcmp(buf, encodedIPAddr, size), "Unexpected value\n");
1467 LocalFree(buf);
1469 /* Test with OID */
1470 entry.dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID;
1471 U(entry).pszRegisteredID = oid;
1472 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1473 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1474 if (buf)
1476 ok(size == sizeof(encodedOidName), "Wrong size %d\n", size);
1477 ok(!memcmp(buf, encodedOidName, size), "Unexpected value\n");
1478 LocalFree(buf);
1480 /* Test with directory name */
1481 entry.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
1482 U(entry).DirectoryName.cbData = sizeof(encodedCommonName);
1483 U(entry).DirectoryName.pbData = (LPBYTE)encodedCommonName;
1484 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1485 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1486 if (buf)
1488 ok(size == sizeof(encodedDirectoryName), "Wrong size %d\n", size);
1489 ok(!memcmp(buf, encodedDirectoryName, size), "Unexpected value\n");
1490 LocalFree(buf);
1494 static void test_decodeAltName(DWORD dwEncoding)
1496 static const BYTE unimplementedType[] = { 0x30, 0x06, 0x85, 0x04, 0x7f,
1497 0x00, 0x00, 0x01 };
1498 static const BYTE bogusType[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00,
1499 0x01 };
1500 BOOL ret;
1501 BYTE *buf = NULL;
1502 DWORD bufSize = 0;
1503 CERT_ALT_NAME_INFO *info;
1505 /* Test some bogus ones first */
1506 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1507 unimplementedType, sizeof(unimplementedType), CRYPT_DECODE_ALLOC_FLAG,
1508 NULL, (BYTE *)&buf, &bufSize);
1509 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
1510 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1511 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
1512 GetLastError());
1513 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1514 bogusType, sizeof(bogusType), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1515 &bufSize);
1516 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
1517 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1518 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
1519 GetLastError());
1520 /* Now expected cases */
1521 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptySequence,
1522 emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1523 &bufSize);
1524 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1525 if (buf)
1527 info = (CERT_ALT_NAME_INFO *)buf;
1529 ok(info->cAltEntry == 0, "Expected 0 entries, got %d\n",
1530 info->cAltEntry);
1531 LocalFree(buf);
1533 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptyURL,
1534 emptyURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1535 &bufSize);
1536 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1537 if (buf)
1539 info = (CERT_ALT_NAME_INFO *)buf;
1541 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1542 info->cAltEntry);
1543 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1544 "Expected CERT_ALT_NAME_URL, got %d\n",
1545 info->rgAltEntry[0].dwAltNameChoice);
1546 ok(U(info->rgAltEntry[0]).pwszURL == NULL || !*U(info->rgAltEntry[0]).pwszURL,
1547 "Expected empty URL\n");
1548 LocalFree(buf);
1550 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1551 emptyURLExtraBytes, sizeof(emptyURLExtraBytes), 0, NULL, NULL, &bufSize);
1552 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1553 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedURL,
1554 encodedURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1555 &bufSize);
1556 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1557 if (buf)
1559 info = (CERT_ALT_NAME_INFO *)buf;
1561 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1562 info->cAltEntry);
1563 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1564 "Expected CERT_ALT_NAME_URL, got %d\n",
1565 info->rgAltEntry[0].dwAltNameChoice);
1566 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszURL, url), "Unexpected URL\n");
1567 LocalFree(buf);
1569 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedDnsName,
1570 encodedDnsName[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1571 &bufSize);
1572 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1573 if (buf)
1575 info = (CERT_ALT_NAME_INFO *)buf;
1577 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1578 info->cAltEntry);
1579 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1580 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1581 info->rgAltEntry[0].dwAltNameChoice);
1582 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszDNSName, dnsName),
1583 "Unexpected DNS name\n");
1584 LocalFree(buf);
1586 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedIPAddr,
1587 encodedIPAddr[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1588 &bufSize);
1589 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1590 if (buf)
1592 info = (CERT_ALT_NAME_INFO *)buf;
1594 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1595 info->cAltEntry);
1596 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS,
1597 "Expected CERT_ALT_NAME_IP_ADDRESS, got %d\n",
1598 info->rgAltEntry[0].dwAltNameChoice);
1599 ok(U(info->rgAltEntry[0]).IPAddress.cbData == sizeof(localhost),
1600 "Unexpected IP address length %d\n",
1601 U(info->rgAltEntry[0]).IPAddress.cbData);
1602 ok(!memcmp(U(info->rgAltEntry[0]).IPAddress.pbData, localhost,
1603 sizeof(localhost)), "Unexpected IP address value\n");
1604 LocalFree(buf);
1606 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedOidName,
1607 sizeof(encodedOidName), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1608 &bufSize);
1609 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1610 if (buf)
1612 info = (CERT_ALT_NAME_INFO *)buf;
1614 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1615 info->cAltEntry);
1616 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_REGISTERED_ID,
1617 "Expected CERT_ALT_NAME_REGISTERED_ID, got %d\n",
1618 info->rgAltEntry[0].dwAltNameChoice);
1619 ok(!strcmp(U(info->rgAltEntry[0]).pszRegisteredID, "1.2.3"),
1620 "Expected OID 1.2.3, got %s\n", U(info->rgAltEntry[0]).pszRegisteredID);
1621 LocalFree(buf);
1623 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1624 encodedDirectoryName, sizeof(encodedDirectoryName),
1625 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1626 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1627 if (buf)
1629 info = (CERT_ALT_NAME_INFO *)buf;
1631 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1632 info->cAltEntry);
1633 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME,
1634 "Expected CERT_ALT_NAME_DIRECTORY_NAME, got %d\n",
1635 info->rgAltEntry[0].dwAltNameChoice);
1636 ok(U(info->rgAltEntry[0]).DirectoryName.cbData ==
1637 sizeof(encodedCommonName), "Unexpected directory name length %d\n",
1638 U(info->rgAltEntry[0]).DirectoryName.cbData);
1639 ok(!memcmp(U(info->rgAltEntry[0]).DirectoryName.pbData,
1640 encodedCommonName, sizeof(encodedCommonName)),
1641 "Unexpected directory name value\n");
1642 LocalFree(buf);
1646 struct UnicodeExpectedError
1648 DWORD valueType;
1649 LPCWSTR str;
1650 DWORD errorIndex;
1651 DWORD error;
1654 static const WCHAR oneW[] = { '1',0 };
1655 static const WCHAR aW[] = { 'a',0 };
1656 static const WCHAR quoteW[] = { '"', 0 };
1658 static struct UnicodeExpectedError unicodeErrors[] = {
1659 { CERT_RDN_ANY_TYPE, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1660 { CERT_RDN_ENCODED_BLOB, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1661 { CERT_RDN_OCTET_STRING, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1662 { CERT_RDN_NUMERIC_STRING, aW, 0, CRYPT_E_INVALID_NUMERIC_STRING },
1663 { CERT_RDN_PRINTABLE_STRING, quoteW, 0, CRYPT_E_INVALID_PRINTABLE_STRING },
1664 { CERT_RDN_IA5_STRING, nihongoURL, 7, CRYPT_E_INVALID_IA5_STRING },
1667 struct UnicodeExpectedResult
1669 DWORD valueType;
1670 LPCWSTR str;
1671 CRYPT_DATA_BLOB encoded;
1674 static BYTE oneNumeric[] = { 0x12, 0x01, 0x31 };
1675 static BYTE onePrintable[] = { 0x13, 0x01, 0x31 };
1676 static BYTE oneTeletex[] = { 0x14, 0x01, 0x31 };
1677 static BYTE oneVideotex[] = { 0x15, 0x01, 0x31 };
1678 static BYTE oneIA5[] = { 0x16, 0x01, 0x31 };
1679 static BYTE oneGraphic[] = { 0x19, 0x01, 0x31 };
1680 static BYTE oneVisible[] = { 0x1a, 0x01, 0x31 };
1681 static BYTE oneUniversal[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 };
1682 static BYTE oneGeneral[] = { 0x1b, 0x01, 0x31 };
1683 static BYTE oneBMP[] = { 0x1e, 0x02, 0x00, 0x31 };
1684 static BYTE oneUTF8[] = { 0x0c, 0x01, 0x31 };
1685 static BYTE nihongoT61[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,
1686 0x5b };
1687 static BYTE nihongoGeneral[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1688 0x6f,0x5b };
1689 static BYTE nihongoBMP[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,
1690 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
1691 static BYTE nihongoUTF8[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1692 0xe2,0x89,0xaf,0xe5,0x9d,0x9b };
1694 static struct UnicodeExpectedResult unicodeResults[] = {
1695 { CERT_RDN_NUMERIC_STRING, oneW, { sizeof(oneNumeric), oneNumeric } },
1696 { CERT_RDN_PRINTABLE_STRING, oneW, { sizeof(onePrintable), onePrintable } },
1697 { CERT_RDN_TELETEX_STRING, oneW, { sizeof(oneTeletex), oneTeletex } },
1698 { CERT_RDN_VIDEOTEX_STRING, oneW, { sizeof(oneVideotex), oneVideotex } },
1699 { CERT_RDN_IA5_STRING, oneW, { sizeof(oneIA5), oneIA5 } },
1700 { CERT_RDN_GRAPHIC_STRING, oneW, { sizeof(oneGraphic), oneGraphic } },
1701 { CERT_RDN_VISIBLE_STRING, oneW, { sizeof(oneVisible), oneVisible } },
1702 { CERT_RDN_UNIVERSAL_STRING, oneW, { sizeof(oneUniversal), oneUniversal } },
1703 { CERT_RDN_GENERAL_STRING, oneW, { sizeof(oneGeneral), oneGeneral } },
1704 { CERT_RDN_BMP_STRING, oneW, { sizeof(oneBMP), oneBMP } },
1705 { CERT_RDN_UTF8_STRING, oneW, { sizeof(oneUTF8), oneUTF8 } },
1706 { CERT_RDN_BMP_STRING, nihongoURL, { sizeof(nihongoBMP), nihongoBMP } },
1707 { CERT_RDN_UTF8_STRING, nihongoURL, { sizeof(nihongoUTF8), nihongoUTF8 } },
1710 static struct UnicodeExpectedResult unicodeWeirdness[] = {
1711 { CERT_RDN_TELETEX_STRING, nihongoURL, { sizeof(nihongoT61), nihongoT61 } },
1712 { CERT_RDN_GENERAL_STRING, nihongoURL, { sizeof(nihongoGeneral), nihongoGeneral } },
1715 static void test_encodeUnicodeNameValue(DWORD dwEncoding)
1717 BYTE *buf = NULL;
1718 DWORD size = 0, i;
1719 BOOL ret;
1720 CERT_NAME_VALUE value;
1722 if (0)
1724 /* Crashes on win9x */
1725 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, NULL,
1726 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1727 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1728 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1730 /* Have to have a string of some sort */
1731 value.dwValueType = 0; /* aka CERT_RDN_ANY_TYPE */
1732 value.Value.pbData = NULL;
1733 value.Value.cbData = 0;
1734 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1735 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1736 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1737 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1738 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1739 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1740 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1741 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1742 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1743 value.dwValueType = CERT_RDN_ANY_TYPE;
1744 value.Value.pbData = (LPBYTE)oneW;
1745 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1746 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1747 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1748 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1749 value.Value.cbData = sizeof(oneW);
1750 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1751 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1752 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1753 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1754 /* An encoded string with specified length isn't good enough either */
1755 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1756 value.Value.pbData = oneUniversal;
1757 value.Value.cbData = sizeof(oneUniversal);
1758 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1759 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1760 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1761 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1762 /* More failure checking */
1763 value.Value.cbData = 0;
1764 for (i = 0; i < sizeof(unicodeErrors) / sizeof(unicodeErrors[0]); i++)
1766 value.Value.pbData = (LPBYTE)unicodeErrors[i].str;
1767 value.dwValueType = unicodeErrors[i].valueType;
1768 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1769 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1770 ok(!ret && GetLastError() == unicodeErrors[i].error,
1771 "Value type %d: expected %08x, got %08x\n", value.dwValueType,
1772 unicodeErrors[i].error, GetLastError());
1773 ok(size == unicodeErrors[i].errorIndex,
1774 "Expected error index %d, got %d\n", unicodeErrors[i].errorIndex,
1775 size);
1777 /* cbData can be zero if the string is NULL-terminated */
1778 value.Value.cbData = 0;
1779 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1781 value.Value.pbData = (LPBYTE)unicodeResults[i].str;
1782 value.dwValueType = unicodeResults[i].valueType;
1783 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1784 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1785 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
1786 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1787 if (buf)
1789 ok(size == unicodeResults[i].encoded.cbData,
1790 "Value type %d: expected size %d, got %d\n",
1791 value.dwValueType, unicodeResults[i].encoded.cbData, size);
1792 ok(!memcmp(unicodeResults[i].encoded.pbData, buf, size),
1793 "Value type %d: unexpected value\n", value.dwValueType);
1794 LocalFree(buf);
1797 /* These "encode," but they do so by truncating each unicode character
1798 * rather than properly encoding it. Kept separate from the proper results,
1799 * because the encoded forms won't decode to their original strings.
1801 for (i = 0; i < sizeof(unicodeWeirdness) / sizeof(unicodeWeirdness[0]); i++)
1803 value.Value.pbData = (LPBYTE)unicodeWeirdness[i].str;
1804 value.dwValueType = unicodeWeirdness[i].valueType;
1805 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1806 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1807 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1808 if (buf)
1810 ok(size == unicodeWeirdness[i].encoded.cbData,
1811 "Value type %d: expected size %d, got %d\n",
1812 value.dwValueType, unicodeWeirdness[i].encoded.cbData, size);
1813 ok(!memcmp(unicodeWeirdness[i].encoded.pbData, buf, size),
1814 "Value type %d: unexpected value\n", value.dwValueType);
1815 LocalFree(buf);
1820 static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
1822 if (n <= 0) return 0;
1823 while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
1824 return *str1 - *str2;
1827 static void test_decodeUnicodeNameValue(DWORD dwEncoding)
1829 DWORD i;
1831 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1833 BYTE *buf = NULL;
1834 BOOL ret;
1835 DWORD size = 0;
1837 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE,
1838 unicodeResults[i].encoded.pbData, unicodeResults[i].encoded.cbData,
1839 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1840 ok(ret || broken(GetLastError() == CRYPT_E_NOT_CHAR_STRING /* Win9x */),
1841 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1842 if (ret && buf)
1844 PCERT_NAME_VALUE value = (PCERT_NAME_VALUE)buf;
1846 ok(value->dwValueType == unicodeResults[i].valueType,
1847 "Expected value type %d, got %d\n", unicodeResults[i].valueType,
1848 value->dwValueType);
1849 ok(!strncmpW((LPWSTR)value->Value.pbData, unicodeResults[i].str,
1850 value->Value.cbData / sizeof(WCHAR)),
1851 "Unexpected decoded value for index %d (value type %d)\n", i,
1852 unicodeResults[i].valueType);
1853 LocalFree(buf);
1858 struct encodedOctets
1860 const BYTE *val;
1861 const BYTE *encoded;
1864 static const unsigned char bin46[] = { 'h','i',0 };
1865 static const unsigned char bin47[] = { 0x04,0x02,'h','i',0 };
1866 static const unsigned char bin48[] = {
1867 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1868 static const unsigned char bin49[] = {
1869 0x04,0x0f,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1870 static const unsigned char bin50[] = { 0 };
1871 static const unsigned char bin51[] = { 0x04,0x00,0 };
1873 static const struct encodedOctets octets[] = {
1874 { bin46, bin47 },
1875 { bin48, bin49 },
1876 { bin50, bin51 },
1879 static void test_encodeOctets(DWORD dwEncoding)
1881 CRYPT_DATA_BLOB blob;
1882 DWORD i;
1884 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1886 BYTE *buf = NULL;
1887 BOOL ret;
1888 DWORD bufSize = 0;
1890 blob.cbData = strlen((const char*)octets[i].val);
1891 blob.pbData = (BYTE*)octets[i].val;
1892 ret = pCryptEncodeObjectEx(dwEncoding, X509_OCTET_STRING, &blob,
1893 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1894 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
1895 if (buf)
1897 ok(buf[0] == 4,
1898 "Got unexpected type %d for octet string (expected 4)\n", buf[0]);
1899 ok(buf[1] == octets[i].encoded[1], "Got length %d, expected %d\n",
1900 buf[1], octets[i].encoded[1]);
1901 ok(!memcmp(buf + 1, octets[i].encoded + 1,
1902 octets[i].encoded[1] + 1), "Got unexpected value\n");
1903 LocalFree(buf);
1908 static void test_decodeOctets(DWORD dwEncoding)
1910 DWORD i;
1912 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1914 BYTE *buf = NULL;
1915 BOOL ret;
1916 DWORD bufSize = 0;
1918 ret = pCryptDecodeObjectEx(dwEncoding, X509_OCTET_STRING,
1919 (BYTE *)octets[i].encoded, octets[i].encoded[1] + 2,
1920 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1921 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1922 ok(bufSize >= sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1],
1923 "Expected size >= %d, got %d\n",
1924 (int)sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1], bufSize);
1925 ok(buf != NULL, "Expected allocated buffer\n");
1926 if (buf)
1928 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)buf;
1930 if (blob->cbData)
1931 ok(!memcmp(blob->pbData, octets[i].val, blob->cbData),
1932 "Unexpected value\n");
1933 LocalFree(buf);
1938 static const BYTE bytesToEncode[] = { 0xff, 0xff };
1940 struct encodedBits
1942 DWORD cUnusedBits;
1943 const BYTE *encoded;
1944 DWORD cbDecoded;
1945 const BYTE *decoded;
1948 static const unsigned char bin52[] = { 0x03,0x03,0x00,0xff,0xff };
1949 static const unsigned char bin53[] = { 0xff,0xff };
1950 static const unsigned char bin54[] = { 0x03,0x03,0x01,0xff,0xfe };
1951 static const unsigned char bin55[] = { 0xff,0xfe };
1952 static const unsigned char bin56[] = { 0x03,0x02,0x01,0xfe };
1953 static const unsigned char bin57[] = { 0xfe };
1954 static const unsigned char bin58[] = { 0x03,0x01,0x00 };
1956 static const struct encodedBits bits[] = {
1957 /* normal test cases */
1958 { 0, bin52, 2, bin53 },
1959 { 1, bin54, 2, bin55 },
1960 /* strange test case, showing cUnusedBits >= 8 is allowed */
1961 { 9, bin56, 1, bin57 },
1962 /* even stranger test case, showing cUnusedBits > cbData * 8 is allowed */
1963 { 17, bin58, 0, NULL },
1966 static void test_encodeBits(DWORD dwEncoding)
1968 DWORD i;
1970 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
1972 CRYPT_BIT_BLOB blob;
1973 BOOL ret;
1974 BYTE *buf = NULL;
1975 DWORD bufSize = 0;
1977 blob.cbData = sizeof(bytesToEncode);
1978 blob.pbData = (BYTE *)bytesToEncode;
1979 blob.cUnusedBits = bits[i].cUnusedBits;
1980 ret = pCryptEncodeObjectEx(dwEncoding, X509_BITS, &blob,
1981 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1982 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1983 if (buf)
1985 ok(bufSize == bits[i].encoded[1] + 2,
1986 "Got unexpected size %d, expected %d\n", bufSize,
1987 bits[i].encoded[1] + 2);
1988 ok(!memcmp(buf, bits[i].encoded, bits[i].encoded[1] + 2),
1989 "Unexpected value\n");
1990 LocalFree(buf);
1995 static void test_decodeBits(DWORD dwEncoding)
1997 static const BYTE ber[] = "\x03\x02\x01\xff";
1998 static const BYTE berDecoded = 0xfe;
1999 DWORD i;
2000 BOOL ret;
2001 BYTE *buf = NULL;
2002 DWORD bufSize = 0;
2004 /* normal cases */
2005 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
2007 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, bits[i].encoded,
2008 bits[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2009 &bufSize);
2010 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2011 if (buf)
2013 CRYPT_BIT_BLOB *blob;
2015 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + bits[i].cbDecoded,
2016 "Got unexpected size %d\n", bufSize);
2017 blob = (CRYPT_BIT_BLOB *)buf;
2018 ok(blob->cbData == bits[i].cbDecoded,
2019 "Got unexpected length %d, expected %d\n", blob->cbData,
2020 bits[i].cbDecoded);
2021 if (blob->cbData && bits[i].cbDecoded)
2022 ok(!memcmp(blob->pbData, bits[i].decoded, bits[i].cbDecoded),
2023 "Unexpected value\n");
2024 LocalFree(buf);
2027 /* special case: check that something that's valid in BER but not in DER
2028 * decodes successfully
2030 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, ber, ber[1] + 2,
2031 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2032 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2033 if (buf)
2035 CRYPT_BIT_BLOB *blob;
2037 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + sizeof(berDecoded),
2038 "Got unexpected size %d\n", bufSize);
2039 blob = (CRYPT_BIT_BLOB *)buf;
2040 ok(blob->cbData == sizeof(berDecoded),
2041 "Got unexpected length %d\n", blob->cbData);
2042 if (blob->cbData)
2043 ok(*blob->pbData == berDecoded, "Unexpected value\n");
2044 LocalFree(buf);
2048 struct Constraints2
2050 CERT_BASIC_CONSTRAINTS2_INFO info;
2051 const BYTE *encoded;
2054 static const unsigned char bin59[] = { 0x30,0x00 };
2055 static const unsigned char bin60[] = { 0x30,0x03,0x01,0x01,0xff };
2056 static const unsigned char bin61[] = { 0x30,0x03,0x02,0x01,0x00 };
2057 static const unsigned char bin62[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2058 static const struct Constraints2 constraints2[] = {
2059 /* empty constraints */
2060 { { FALSE, FALSE, 0}, bin59 },
2061 /* can be a CA */
2062 { { TRUE, FALSE, 0}, bin60 },
2063 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well,
2064 * but that's not the case
2066 { { FALSE, TRUE, 0}, bin61 },
2067 /* can be a CA and has path length constraints set */
2068 { { TRUE, TRUE, 1}, bin62 },
2071 static const BYTE emptyConstraint[] = { 0x30, 0x03, 0x03, 0x01, 0x00 };
2072 static const BYTE encodedDomainName[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11,
2073 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
2074 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
2075 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2076 static const BYTE constraintWithDomainName[] = { 0x30, 0x32, 0x03, 0x01, 0x00,
2077 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
2078 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30,
2079 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
2080 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2082 static void test_encodeBasicConstraints(DWORD dwEncoding)
2084 DWORD i, bufSize = 0;
2085 CERT_BASIC_CONSTRAINTS_INFO info = { { 0 } };
2086 CERT_NAME_BLOB nameBlob = { sizeof(encodedDomainName),
2087 (LPBYTE)encodedDomainName };
2088 BOOL ret;
2089 BYTE *buf = NULL;
2091 /* First test with the simpler info2 */
2092 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2094 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2095 &constraints2[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2096 &bufSize);
2097 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2098 if (buf)
2100 ok(bufSize == constraints2[i].encoded[1] + 2,
2101 "Expected %d bytes, got %d\n", constraints2[i].encoded[1] + 2,
2102 bufSize);
2103 ok(!memcmp(buf, constraints2[i].encoded,
2104 constraints2[i].encoded[1] + 2), "Unexpected value\n");
2105 LocalFree(buf);
2108 /* Now test with more complex basic constraints */
2109 info.SubjectType.cbData = 0;
2110 info.fPathLenConstraint = FALSE;
2111 info.cSubtreesConstraint = 0;
2112 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2113 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2114 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2115 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2116 if (buf)
2118 ok(bufSize == sizeof(emptyConstraint), "Wrong size %d\n", bufSize);
2119 ok(!memcmp(buf, emptyConstraint, sizeof(emptyConstraint)),
2120 "Unexpected value\n");
2121 LocalFree(buf);
2123 /* None of the certs I examined had any subtree constraint, but I test one
2124 * anyway just in case.
2126 info.cSubtreesConstraint = 1;
2127 info.rgSubtreesConstraint = &nameBlob;
2128 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2129 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2130 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2131 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2132 if (buf)
2134 ok(bufSize == sizeof(constraintWithDomainName), "Wrong size %d\n", bufSize);
2135 ok(!memcmp(buf, constraintWithDomainName,
2136 sizeof(constraintWithDomainName)), "Unexpected value\n");
2137 LocalFree(buf);
2139 /* FIXME: test encoding with subject type. */
2142 static const unsigned char bin63[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 };
2144 static void test_decodeBasicConstraints(DWORD dwEncoding)
2146 static const BYTE inverted[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01,
2147 0xff };
2148 static const struct Constraints2 badBool = { { TRUE, TRUE, 1 }, bin63 };
2149 DWORD i;
2150 BOOL ret;
2151 BYTE *buf = NULL;
2152 DWORD bufSize = 0;
2154 /* First test with simpler info2 */
2155 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2157 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2158 constraints2[i].encoded, constraints2[i].encoded[1] + 2,
2159 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2160 ok(ret, "CryptDecodeObjectEx failed for item %d: %08x\n", i,
2161 GetLastError());
2162 if (buf)
2164 CERT_BASIC_CONSTRAINTS2_INFO *info =
2165 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2167 ok(!memcmp(info, &constraints2[i].info, sizeof(*info)),
2168 "Unexpected value for item %d\n", i);
2169 LocalFree(buf);
2172 /* Check with the order of encoded elements inverted */
2173 buf = (PBYTE)1;
2174 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2175 inverted, inverted[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2176 &bufSize);
2177 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2178 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2179 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2180 GetLastError());
2181 ok(!buf, "Expected buf to be set to NULL\n");
2182 /* Check with a non-DER bool */
2183 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2184 badBool.encoded, badBool.encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2185 (BYTE *)&buf, &bufSize);
2186 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2187 if (buf)
2189 CERT_BASIC_CONSTRAINTS2_INFO *info =
2190 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2192 ok(!memcmp(info, &badBool.info, sizeof(*info)), "Unexpected value\n");
2193 LocalFree(buf);
2195 /* Check with a non-basic constraints value */
2196 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2197 (LPBYTE)encodedCommonName, encodedCommonName[1] + 2,
2198 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2199 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2200 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2201 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2202 GetLastError());
2203 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */
2204 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2205 emptyConstraint, sizeof(emptyConstraint), CRYPT_DECODE_ALLOC_FLAG, NULL,
2206 (BYTE *)&buf, &bufSize);
2207 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2208 if (buf)
2210 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2212 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2213 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2214 ok(info->cSubtreesConstraint == 0, "Expected no subtree constraints\n");
2215 LocalFree(buf);
2217 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2218 constraintWithDomainName, sizeof(constraintWithDomainName),
2219 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2220 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2221 if (buf)
2223 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2225 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2226 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2227 ok(info->cSubtreesConstraint == 1, "Expected a subtree constraint\n");
2228 if (info->cSubtreesConstraint && info->rgSubtreesConstraint)
2230 ok(info->rgSubtreesConstraint[0].cbData ==
2231 sizeof(encodedDomainName), "Wrong size %d\n",
2232 info->rgSubtreesConstraint[0].cbData);
2233 ok(!memcmp(info->rgSubtreesConstraint[0].pbData, encodedDomainName,
2234 sizeof(encodedDomainName)), "Unexpected value\n");
2236 LocalFree(buf);
2240 /* These are terrible public keys of course, I'm just testing encoding */
2241 static const BYTE modulus1[] = { 0,0,0,1,1,1,1,1 };
2242 static const BYTE modulus2[] = { 1,1,1,1,1,0,0,0 };
2243 static const BYTE modulus3[] = { 0x80,1,1,1,1,0,0,0 };
2244 static const BYTE modulus4[] = { 1,1,1,1,1,0,0,0x80 };
2245 static const BYTE mod1_encoded[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 };
2246 static const BYTE mod2_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2247 static const BYTE mod3_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 };
2248 static const BYTE mod4_encoded[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2250 struct EncodedRSAPubKey
2252 const BYTE *modulus;
2253 size_t modulusLen;
2254 const BYTE *encoded;
2255 size_t decodedModulusLen;
2258 struct EncodedRSAPubKey rsaPubKeys[] = {
2259 { modulus1, sizeof(modulus1), mod1_encoded, sizeof(modulus1) },
2260 { modulus2, sizeof(modulus2), mod2_encoded, 5 },
2261 { modulus3, sizeof(modulus3), mod3_encoded, 5 },
2262 { modulus4, sizeof(modulus4), mod4_encoded, 8 },
2265 static void test_encodeRsaPublicKey(DWORD dwEncoding)
2267 BYTE toEncode[sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + sizeof(modulus1)];
2268 BLOBHEADER *hdr = (BLOBHEADER *)toEncode;
2269 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(toEncode + sizeof(BLOBHEADER));
2270 BOOL ret;
2271 BYTE *buf = NULL;
2272 DWORD bufSize = 0, i;
2274 /* Try with a bogus blob type */
2275 hdr->bType = 2;
2276 hdr->bVersion = CUR_BLOB_VERSION;
2277 hdr->reserved = 0;
2278 hdr->aiKeyAlg = CALG_RSA_KEYX;
2279 rsaPubKey->magic = 0x31415352;
2280 rsaPubKey->bitlen = sizeof(modulus1) * 8;
2281 rsaPubKey->pubexp = 65537;
2282 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), modulus1,
2283 sizeof(modulus1));
2285 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2286 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2287 &bufSize);
2288 ok(!ret && GetLastError() == E_INVALIDARG,
2289 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2290 /* Now with a bogus reserved field */
2291 hdr->bType = PUBLICKEYBLOB;
2292 hdr->reserved = 1;
2293 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2294 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2295 &bufSize);
2296 if (buf)
2298 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2299 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2300 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2301 LocalFree(buf);
2303 /* Now with a bogus blob version */
2304 hdr->reserved = 0;
2305 hdr->bVersion = 0;
2306 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2307 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2308 &bufSize);
2309 if (buf)
2311 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2312 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2313 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2314 LocalFree(buf);
2316 /* And with a bogus alg ID */
2317 hdr->bVersion = CUR_BLOB_VERSION;
2318 hdr->aiKeyAlg = CALG_DES;
2319 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2320 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2321 &bufSize);
2322 if (buf)
2324 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2325 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2326 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2327 LocalFree(buf);
2329 /* Check a couple of RSA-related OIDs */
2330 hdr->aiKeyAlg = CALG_RSA_KEYX;
2331 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_RSA,
2332 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2333 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2334 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2335 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2336 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2337 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2338 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2339 /* Finally, all valid */
2340 hdr->aiKeyAlg = CALG_RSA_KEYX;
2341 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2343 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2344 rsaPubKeys[i].modulus, rsaPubKeys[i].modulusLen);
2345 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2346 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2347 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2348 if (buf)
2350 ok(bufSize == rsaPubKeys[i].encoded[1] + 2,
2351 "Expected size %d, got %d\n", rsaPubKeys[i].encoded[1] + 2,
2352 bufSize);
2353 ok(!memcmp(buf, rsaPubKeys[i].encoded, bufSize),
2354 "Unexpected value\n");
2355 LocalFree(buf);
2360 static void test_decodeRsaPublicKey(DWORD dwEncoding)
2362 DWORD i;
2363 LPBYTE buf = NULL;
2364 DWORD bufSize = 0;
2365 BOOL ret;
2367 /* Try with a bad length */
2368 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2369 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1],
2370 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2371 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
2372 GetLastError() == OSS_MORE_INPUT /* Win9x/NT4 */),
2373 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n",
2374 GetLastError());
2375 /* Try with a couple of RSA-related OIDs */
2376 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_RSA,
2377 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2378 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2379 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2380 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2381 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2382 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2383 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2384 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2385 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2386 /* Now try success cases */
2387 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2389 bufSize = 0;
2390 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2391 rsaPubKeys[i].encoded, rsaPubKeys[i].encoded[1] + 2,
2392 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2393 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2394 if (buf)
2396 BLOBHEADER *hdr = (BLOBHEADER *)buf;
2397 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER));
2399 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2400 rsaPubKeys[i].decodedModulusLen,
2401 "Wrong size %d\n", bufSize);
2402 ok(hdr->bType == PUBLICKEYBLOB,
2403 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB,
2404 hdr->bType);
2405 ok(hdr->bVersion == CUR_BLOB_VERSION,
2406 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
2407 CUR_BLOB_VERSION, hdr->bVersion);
2408 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n",
2409 hdr->reserved);
2410 ok(hdr->aiKeyAlg == CALG_RSA_KEYX,
2411 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg);
2412 ok(rsaPubKey->magic == 0x31415352,
2413 "Expected magic RSA1, got %08x\n", rsaPubKey->magic);
2414 ok(rsaPubKey->bitlen == rsaPubKeys[i].decodedModulusLen * 8,
2415 "Wrong bit len %d\n", rsaPubKey->bitlen);
2416 ok(rsaPubKey->pubexp == 65537, "Expected pubexp 65537, got %d\n",
2417 rsaPubKey->pubexp);
2418 ok(!memcmp(buf + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2419 rsaPubKeys[i].modulus, rsaPubKeys[i].decodedModulusLen),
2420 "Unexpected modulus\n");
2421 LocalFree(buf);
2426 static const BYTE intSequence[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01,
2427 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02,
2428 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2430 static const BYTE mixedSequence[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
2431 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f,
2432 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02,
2433 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2435 static void test_encodeSequenceOfAny(DWORD dwEncoding)
2437 CRYPT_DER_BLOB blobs[sizeof(ints) / sizeof(ints[0])];
2438 CRYPT_SEQUENCE_OF_ANY seq;
2439 DWORD i;
2440 BOOL ret;
2441 BYTE *buf = NULL;
2442 DWORD bufSize = 0;
2444 /* Encode a homogeneous sequence */
2445 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
2447 blobs[i].cbData = ints[i].encoded[1] + 2;
2448 blobs[i].pbData = (BYTE *)ints[i].encoded;
2450 seq.cValue = sizeof(ints) / sizeof(ints[0]);
2451 seq.rgValue = blobs;
2453 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2454 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2455 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2456 if (buf)
2458 ok(bufSize == sizeof(intSequence), "Wrong size %d\n", bufSize);
2459 ok(!memcmp(buf, intSequence, intSequence[1] + 2), "Unexpected value\n");
2460 LocalFree(buf);
2462 /* Change the type of the first element in the sequence, and give it
2463 * another go
2465 blobs[0].cbData = times[0].encodedTime[1] + 2;
2466 blobs[0].pbData = (BYTE *)times[0].encodedTime;
2467 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2468 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2469 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2470 if (buf)
2472 ok(bufSize == sizeof(mixedSequence), "Wrong size %d\n", bufSize);
2473 ok(!memcmp(buf, mixedSequence, mixedSequence[1] + 2),
2474 "Unexpected value\n");
2475 LocalFree(buf);
2479 static void test_decodeSequenceOfAny(DWORD dwEncoding)
2481 BOOL ret;
2482 BYTE *buf = NULL;
2483 DWORD bufSize = 0;
2485 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, intSequence,
2486 intSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2487 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2488 if (buf)
2490 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2491 DWORD i;
2493 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2494 "Wrong elements %d\n", seq->cValue);
2495 for (i = 0; i < min(seq->cValue, sizeof(ints) / sizeof(ints[0])); i++)
2497 ok(seq->rgValue[i].cbData == ints[i].encoded[1] + 2,
2498 "Expected %d bytes, got %d\n", ints[i].encoded[1] + 2,
2499 seq->rgValue[i].cbData);
2500 ok(!memcmp(seq->rgValue[i].pbData, ints[i].encoded,
2501 ints[i].encoded[1] + 2), "Unexpected value\n");
2503 LocalFree(buf);
2505 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, mixedSequence,
2506 mixedSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2507 &bufSize);
2508 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2509 if (buf)
2511 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2513 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2514 "Wrong elements %d\n", seq->cValue);
2515 /* Just check the first element since it's all that changed */
2516 ok(seq->rgValue[0].cbData == times[0].encodedTime[1] + 2,
2517 "Expected %d bytes, got %d\n", times[0].encodedTime[1] + 2,
2518 seq->rgValue[0].cbData);
2519 ok(!memcmp(seq->rgValue[0].pbData, times[0].encodedTime,
2520 times[0].encodedTime[1] + 2), "Unexpected value\n");
2521 LocalFree(buf);
2525 struct encodedExtensions
2527 CERT_EXTENSIONS exts;
2528 const BYTE *encoded;
2531 static BYTE crit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2532 static BYTE noncrit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2533 static CHAR oid_basic_constraints2[] = szOID_BASIC_CONSTRAINTS2;
2534 static CERT_EXTENSION criticalExt =
2535 { oid_basic_constraints2, TRUE, { 8, crit_ext_data } };
2536 static CERT_EXTENSION nonCriticalExt =
2537 { oid_basic_constraints2, FALSE, { 8, noncrit_ext_data } };
2539 static const BYTE ext0[] = { 0x30,0x00 };
2540 static const BYTE ext1[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2541 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2542 static const BYTE ext2[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2543 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2545 static const struct encodedExtensions exts[] = {
2546 { { 0, NULL }, ext0 },
2547 { { 1, &criticalExt }, ext1 },
2548 { { 1, &nonCriticalExt }, ext2 },
2551 static void test_encodeExtensions(DWORD dwEncoding)
2553 DWORD i;
2555 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2557 BOOL ret;
2558 BYTE *buf = NULL;
2559 DWORD bufSize = 0;
2561 ret = pCryptEncodeObjectEx(dwEncoding, X509_EXTENSIONS, &exts[i].exts,
2562 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2563 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2564 if (buf)
2566 ok(bufSize == exts[i].encoded[1] + 2,
2567 "Expected %d bytes, got %d\n", exts[i].encoded[1] + 2, bufSize);
2568 ok(!memcmp(buf, exts[i].encoded, exts[i].encoded[1] + 2),
2569 "Unexpected value\n");
2570 LocalFree(buf);
2575 static void test_decodeExtensions(DWORD dwEncoding)
2577 DWORD i;
2579 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2581 BOOL ret;
2582 BYTE *buf = NULL;
2583 DWORD bufSize = 0;
2585 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS,
2586 exts[i].encoded, exts[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2587 NULL, (BYTE *)&buf, &bufSize);
2588 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2589 if (buf)
2591 CERT_EXTENSIONS *ext = (CERT_EXTENSIONS *)buf;
2592 DWORD j;
2594 ok(ext->cExtension == exts[i].exts.cExtension,
2595 "Expected %d extensions, see %d\n", exts[i].exts.cExtension,
2596 ext->cExtension);
2597 for (j = 0; j < min(ext->cExtension, exts[i].exts.cExtension); j++)
2599 ok(!strcmp(ext->rgExtension[j].pszObjId,
2600 exts[i].exts.rgExtension[j].pszObjId),
2601 "Expected OID %s, got %s\n",
2602 exts[i].exts.rgExtension[j].pszObjId,
2603 ext->rgExtension[j].pszObjId);
2604 ok(!memcmp(ext->rgExtension[j].Value.pbData,
2605 exts[i].exts.rgExtension[j].Value.pbData,
2606 exts[i].exts.rgExtension[j].Value.cbData),
2607 "Unexpected value\n");
2609 LocalFree(buf);
2614 /* MS encodes public key info with a NULL if the algorithm identifier's
2615 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2616 * it encodes them by omitting the algorithm parameters. This latter approach
2617 * seems more correct, so accept either form.
2619 struct encodedPublicKey
2621 CERT_PUBLIC_KEY_INFO info;
2622 const BYTE *encoded;
2623 const BYTE *encodedNoNull;
2624 CERT_PUBLIC_KEY_INFO decoded;
2627 static const BYTE aKey[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2628 0xe, 0xf };
2629 static const BYTE params[] = { 0x02, 0x01, 0x01 };
2631 static const unsigned char bin64[] = {
2632 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2633 static const unsigned char bin65[] = {
2634 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2635 static const unsigned char bin66[] = {
2636 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2637 static const unsigned char bin67[] = {
2638 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2639 static const unsigned char bin68[] = {
2640 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01,
2641 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2642 static const unsigned char bin69[] = {
2643 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2644 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2645 static const unsigned char bin70[] = {
2646 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2647 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2648 0x0f};
2649 static const unsigned char bin71[] = {
2650 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2651 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2652 0x0f};
2653 static unsigned char bin72[] = { 0x05,0x00};
2655 static CHAR oid_bogus[] = "1.2.3",
2656 oid_rsa[] = szOID_RSA;
2658 static const struct encodedPublicKey pubKeys[] = {
2659 /* with a bogus OID */
2660 { { { oid_bogus, { 0, NULL } }, { 0, NULL, 0 } },
2661 bin64, bin65,
2662 { { oid_bogus, { 2, bin72 } }, { 0, NULL, 0 } } },
2663 /* some normal keys */
2664 { { { oid_rsa, { 0, NULL } }, { 0, NULL, 0} },
2665 bin66, bin67,
2666 { { oid_rsa, { 2, bin72 } }, { 0, NULL, 0 } } },
2667 { { { oid_rsa, { 0, NULL } }, { sizeof(aKey), (BYTE *)aKey, 0} },
2668 bin68, bin69,
2669 { { oid_rsa, { 2, bin72 } }, { sizeof(aKey), (BYTE *)aKey, 0} } },
2670 /* with add'l parameters--note they must be DER-encoded */
2671 { { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2672 (BYTE *)aKey, 0 } },
2673 bin70, bin71,
2674 { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2675 (BYTE *)aKey, 0 } } },
2678 static void test_encodePublicKeyInfo(DWORD dwEncoding)
2680 DWORD i;
2682 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2684 BOOL ret;
2685 BYTE *buf = NULL;
2686 DWORD bufSize = 0;
2688 ret = pCryptEncodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2689 &pubKeys[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2690 &bufSize);
2691 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2692 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2693 if (buf)
2695 ok(bufSize == pubKeys[i].encoded[1] + 2 ||
2696 bufSize == pubKeys[i].encodedNoNull[1] + 2,
2697 "Expected %d or %d bytes, got %d\n", pubKeys[i].encoded[1] + 2,
2698 pubKeys[i].encodedNoNull[1] + 2, bufSize);
2699 if (bufSize == pubKeys[i].encoded[1] + 2)
2700 ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2),
2701 "Unexpected value\n");
2702 else if (bufSize == pubKeys[i].encodedNoNull[1] + 2)
2703 ok(!memcmp(buf, pubKeys[i].encodedNoNull,
2704 pubKeys[i].encodedNoNull[1] + 2), "Unexpected value\n");
2705 LocalFree(buf);
2710 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO *expected,
2711 const CERT_PUBLIC_KEY_INFO *got)
2713 ok(!strcmp(expected->Algorithm.pszObjId, got->Algorithm.pszObjId),
2714 "Expected OID %s, got %s\n", expected->Algorithm.pszObjId,
2715 got->Algorithm.pszObjId);
2716 ok(expected->Algorithm.Parameters.cbData ==
2717 got->Algorithm.Parameters.cbData,
2718 "Expected parameters of %d bytes, got %d\n",
2719 expected->Algorithm.Parameters.cbData, got->Algorithm.Parameters.cbData);
2720 if (expected->Algorithm.Parameters.cbData)
2721 ok(!memcmp(expected->Algorithm.Parameters.pbData,
2722 got->Algorithm.Parameters.pbData, got->Algorithm.Parameters.cbData),
2723 "Unexpected algorithm parameters\n");
2724 ok(expected->PublicKey.cbData == got->PublicKey.cbData,
2725 "Expected public key of %d bytes, got %d\n",
2726 expected->PublicKey.cbData, got->PublicKey.cbData);
2727 if (expected->PublicKey.cbData)
2728 ok(!memcmp(expected->PublicKey.pbData, got->PublicKey.pbData,
2729 got->PublicKey.cbData), "Unexpected public key value\n");
2732 static void test_decodePublicKeyInfo(DWORD dwEncoding)
2734 static const BYTE bogusPubKeyInfo[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
2735 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
2736 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
2737 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2738 DWORD i;
2739 BOOL ret;
2740 BYTE *buf = NULL;
2741 DWORD bufSize = 0;
2743 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2745 /* The NULL form decodes to the decoded member */
2746 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2747 pubKeys[i].encoded, pubKeys[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2748 NULL, (BYTE *)&buf, &bufSize);
2749 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2750 if (buf)
2752 comparePublicKeyInfo(&pubKeys[i].decoded,
2753 (CERT_PUBLIC_KEY_INFO *)buf);
2754 LocalFree(buf);
2756 /* The non-NULL form decodes to the original */
2757 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2758 pubKeys[i].encodedNoNull, pubKeys[i].encodedNoNull[1] + 2,
2759 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2760 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2761 if (buf)
2763 comparePublicKeyInfo(&pubKeys[i].info, (CERT_PUBLIC_KEY_INFO *)buf);
2764 LocalFree(buf);
2767 /* Test with bogus (not valid DER) parameters */
2768 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2769 bogusPubKeyInfo, bogusPubKeyInfo[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2770 NULL, (BYTE *)&buf, &bufSize);
2771 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2772 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2773 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2774 GetLastError());
2777 static const BYTE v1Cert[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
2778 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2779 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
2780 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
2781 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2782 static const BYTE v2Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02,
2783 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2784 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2785 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2786 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2787 static const BYTE v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2788 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2789 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2790 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2791 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2792 static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
2793 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2794 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2795 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2796 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2797 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2798 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2799 static const BYTE v1CertWithSerial[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
2800 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2801 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2802 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2803 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2804 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2805 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2806 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2807 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
2808 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
2809 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
2810 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
2811 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
2812 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
2813 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
2814 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
2815 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2816 static const BYTE v1CertWithPubKey[] = {
2817 0x30,0x81,0x95,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,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2824 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2825 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
2826 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
2827 0x01,0x01 };
2828 static const BYTE v1CertWithPubKeyNoNull[] = {
2829 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2830 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2831 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2832 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2833 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2834 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2835 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2836 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2837 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
2838 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2839 static const BYTE v1CertWithSubjectKeyId[] = {
2840 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2841 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2842 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2843 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2844 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2845 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2846 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
2847 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2848 0x4c,0x61,0x6e,0x67,0x00 };
2850 static const BYTE serialNum[] = { 0x01 };
2852 static void test_encodeCertToBeSigned(DWORD dwEncoding)
2854 BOOL ret;
2855 BYTE *buf = NULL;
2856 DWORD size = 0;
2857 CERT_INFO info = { 0 };
2858 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2859 static char oid_subject_key_identifier[] = szOID_SUBJECT_KEY_IDENTIFIER;
2860 CERT_EXTENSION ext;
2862 if (0)
2864 /* Test with NULL pvStructInfo (crashes on win9x) */
2865 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL,
2866 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2867 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2868 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2870 /* Test with a V1 cert */
2871 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2872 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2873 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2874 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2875 if (buf)
2877 ok(size == v1Cert[1] + 2, "Expected size %d, got %d\n",
2878 v1Cert[1] + 2, size);
2879 ok(!memcmp(buf, v1Cert, size), "Got unexpected value\n");
2880 LocalFree(buf);
2882 /* Test v2 cert */
2883 info.dwVersion = CERT_V2;
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(v2Cert), "Wrong size %d\n", size);
2891 ok(!memcmp(buf, v2Cert, size), "Got unexpected value\n");
2892 LocalFree(buf);
2894 /* Test v3 cert */
2895 info.dwVersion = CERT_V3;
2896 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2897 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2898 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2899 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2900 if (buf)
2902 ok(size == sizeof(v3Cert), "Wrong size %d\n", size);
2903 ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n");
2904 LocalFree(buf);
2906 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
2907 * API doesn't prevent it)
2909 info.dwVersion = CERT_V1;
2910 info.cExtension = 1;
2911 info.rgExtension = &criticalExt;
2912 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2913 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2914 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2915 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2916 if (buf)
2918 ok(size == sizeof(v1CertWithConstraints), "Wrong size %d\n", size);
2919 ok(!memcmp(buf, v1CertWithConstraints, size), "Got unexpected value\n");
2920 LocalFree(buf);
2922 /* test v1 cert with a serial number */
2923 info.SerialNumber.cbData = sizeof(serialNum);
2924 info.SerialNumber.pbData = (BYTE *)serialNum;
2925 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2926 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2927 if (buf)
2929 ok(size == sizeof(v1CertWithSerial), "Wrong size %d\n", size);
2930 ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n");
2931 LocalFree(buf);
2933 /* Test v1 cert with an issuer name, a subject name, and a serial number */
2934 info.Issuer.cbData = sizeof(encodedCommonName);
2935 info.Issuer.pbData = (BYTE *)encodedCommonName;
2936 info.Subject.cbData = sizeof(encodedCommonName);
2937 info.Subject.pbData = (BYTE *)encodedCommonName;
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(bigCert), "Wrong size %d\n", size);
2943 ok(!memcmp(buf, bigCert, size), "Got unexpected value\n");
2944 LocalFree(buf);
2946 /* Add a public key */
2947 info.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2948 info.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2949 info.SubjectPublicKeyInfo.PublicKey.pbData = (LPBYTE)aKey;
2950 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2951 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2952 if (buf)
2954 ok(size == sizeof(v1CertWithPubKey) ||
2955 size == sizeof(v1CertWithPubKeyNoNull), "Wrong size %d\n", size);
2956 if (size == sizeof(v1CertWithPubKey))
2957 ok(!memcmp(buf, v1CertWithPubKey, size), "Got unexpected value\n");
2958 else if (size == sizeof(v1CertWithPubKeyNoNull))
2959 ok(!memcmp(buf, v1CertWithPubKeyNoNull, size),
2960 "Got unexpected value\n");
2961 LocalFree(buf);
2963 /* Remove the public key, and add a subject key identifier extension */
2964 info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2965 info.SubjectPublicKeyInfo.PublicKey.cbData = 0;
2966 info.SubjectPublicKeyInfo.PublicKey.pbData = NULL;
2967 ext.pszObjId = oid_subject_key_identifier;
2968 ext.fCritical = FALSE;
2969 ext.Value.cbData = sizeof(octetCommonNameValue);
2970 ext.Value.pbData = (BYTE *)octetCommonNameValue;
2971 info.cExtension = 1;
2972 info.rgExtension = &ext;
2973 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2974 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2975 if (buf)
2977 ok(size == sizeof(v1CertWithSubjectKeyId), "Wrong size %d\n", size);
2978 ok(!memcmp(buf, v1CertWithSubjectKeyId, size), "Unexpected value\n");
2979 LocalFree(buf);
2983 static void test_decodeCertToBeSigned(DWORD dwEncoding)
2985 static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert,
2986 v1CertWithConstraints, v1CertWithSerial };
2987 BOOL ret;
2988 BYTE *buf = NULL;
2989 DWORD size = 0, i;
2991 /* Test with NULL pbEncoded */
2992 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 0,
2993 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2994 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
2995 GetLastError() == OSS_BAD_ARG /* Win9x */),
2996 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
2997 if (0)
2999 /* Crashes on win9x */
3000 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 1,
3001 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3002 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3003 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3005 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT, because at a
3006 * minimum a cert must have a non-zero serial number, an issuer, and a
3007 * subject.
3009 for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++)
3011 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3012 corruptCerts[i], corruptCerts[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3013 (BYTE *)&buf, &size);
3014 ok(!ret, "Expected failure\n");
3016 /* Now check with serial number, subject and issuer specified */
3017 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert,
3018 sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3019 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3020 if (buf)
3022 CERT_INFO *info = (CERT_INFO *)buf;
3024 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3025 ok(info->SerialNumber.cbData == 1,
3026 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3027 ok(*info->SerialNumber.pbData == *serialNum,
3028 "Expected serial number %d, got %d\n", *serialNum,
3029 *info->SerialNumber.pbData);
3030 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3031 "Wrong size %d\n", info->Issuer.cbData);
3032 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3033 "Unexpected issuer\n");
3034 ok(info->Subject.cbData == sizeof(encodedCommonName),
3035 "Wrong size %d\n", info->Subject.cbData);
3036 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3037 info->Subject.cbData), "Unexpected subject\n");
3038 LocalFree(buf);
3040 /* Check again with pub key specified */
3041 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3042 v1CertWithPubKey, sizeof(v1CertWithPubKey), CRYPT_DECODE_ALLOC_FLAG, NULL,
3043 (BYTE *)&buf, &size);
3044 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3045 if (buf)
3047 CERT_INFO *info = (CERT_INFO *)buf;
3049 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3050 ok(info->SerialNumber.cbData == 1,
3051 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3052 ok(*info->SerialNumber.pbData == *serialNum,
3053 "Expected serial number %d, got %d\n", *serialNum,
3054 *info->SerialNumber.pbData);
3055 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3056 "Wrong size %d\n", info->Issuer.cbData);
3057 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3058 "Unexpected issuer\n");
3059 ok(info->Subject.cbData == sizeof(encodedCommonName),
3060 "Wrong size %d\n", info->Subject.cbData);
3061 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3062 info->Subject.cbData), "Unexpected subject\n");
3063 ok(!strcmp(info->SubjectPublicKeyInfo.Algorithm.pszObjId,
3064 szOID_RSA_RSA), "Expected szOID_RSA_RSA, got %s\n",
3065 info->SubjectPublicKeyInfo.Algorithm.pszObjId);
3066 ok(info->SubjectPublicKeyInfo.PublicKey.cbData == sizeof(aKey),
3067 "Wrong size %d\n", info->SubjectPublicKeyInfo.PublicKey.cbData);
3068 ok(!memcmp(info->SubjectPublicKeyInfo.PublicKey.pbData, aKey,
3069 sizeof(aKey)), "Unexpected public key\n");
3070 LocalFree(buf);
3074 static const BYTE hash[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
3075 0xe, 0xf };
3077 static const BYTE signedBigCert[] = {
3078 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
3079 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
3080 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
3081 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3082 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
3083 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
3084 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
3085 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
3086 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
3087 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3088 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
3089 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
3091 static void test_encodeCert(DWORD dwEncoding)
3093 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
3094 * also that bigCert is a NULL-terminated string, so don't count its
3095 * last byte (otherwise the signed cert won't decode.)
3097 CERT_SIGNED_CONTENT_INFO info = { { sizeof(bigCert), (BYTE *)bigCert },
3098 { NULL, { 0, NULL } }, { sizeof(hash), (BYTE *)hash, 0 } };
3099 BOOL ret;
3100 BYTE *buf = NULL;
3101 DWORD bufSize = 0;
3103 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT, &info,
3104 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
3105 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3106 if (buf)
3108 ok(bufSize == sizeof(signedBigCert), "Wrong size %d\n", bufSize);
3109 ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n");
3110 LocalFree(buf);
3114 static void test_decodeCert(DWORD dwEncoding)
3116 BOOL ret;
3117 BYTE *buf = NULL;
3118 DWORD size = 0;
3120 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert,
3121 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3122 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3123 if (buf)
3125 CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf;
3127 ok(info->ToBeSigned.cbData == sizeof(bigCert),
3128 "Wrong cert size %d\n", info->ToBeSigned.cbData);
3129 ok(!memcmp(info->ToBeSigned.pbData, bigCert, info->ToBeSigned.cbData),
3130 "Unexpected cert\n");
3131 ok(info->Signature.cbData == sizeof(hash),
3132 "Wrong signature size %d\n", info->Signature.cbData);
3133 ok(!memcmp(info->Signature.pbData, hash, info->Signature.cbData),
3134 "Unexpected signature\n");
3135 LocalFree(buf);
3137 /* A signed cert decodes as a CERT_INFO too */
3138 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCert,
3139 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3140 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3141 if (buf)
3143 CERT_INFO *info = (CERT_INFO *)buf;
3145 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3146 ok(info->SerialNumber.cbData == 1,
3147 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3148 ok(*info->SerialNumber.pbData == *serialNum,
3149 "Expected serial number %d, got %d\n", *serialNum,
3150 *info->SerialNumber.pbData);
3151 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3152 "Wrong size %d\n", info->Issuer.cbData);
3153 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3154 "Unexpected issuer\n");
3155 ok(info->Subject.cbData == sizeof(encodedCommonName),
3156 "Wrong size %d\n", info->Subject.cbData);
3157 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3158 info->Subject.cbData), "Unexpected subject\n");
3159 LocalFree(buf);
3163 static const BYTE emptyDistPoint[] = { 0x30, 0x02, 0x30, 0x00 };
3164 static const BYTE distPointWithUrl[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3165 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3166 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3167 static const BYTE distPointWithReason[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3168 0x00, 0x03 };
3169 static const BYTE distPointWithIssuer[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3170 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3171 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3172 static const BYTE distPointWithUrlAndIssuer[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3173 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3174 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3175 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3176 0x2e, 0x6f, 0x72, 0x67 };
3177 static const BYTE crlReason = CRL_REASON_KEY_COMPROMISE |
3178 CRL_REASON_AFFILIATION_CHANGED;
3180 static void test_encodeCRLDistPoints(DWORD dwEncoding)
3182 CRL_DIST_POINTS_INFO info = { 0 };
3183 CRL_DIST_POINT point = { { 0 } };
3184 CERT_ALT_NAME_ENTRY entry = { 0 };
3185 BOOL ret;
3186 BYTE *buf = NULL;
3187 DWORD size = 0;
3189 /* Test with an empty info */
3190 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3191 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3192 ok(!ret && GetLastError() == E_INVALIDARG,
3193 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3194 /* Test with one empty dist point */
3195 info.cDistPoint = 1;
3196 info.rgDistPoint = &point;
3197 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3198 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3199 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3200 if (buf)
3202 ok(size == sizeof(emptyDistPoint), "Wrong size %d\n", size);
3203 ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n");
3204 LocalFree(buf);
3206 /* A dist point with an invalid name */
3207 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3208 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3209 U(entry).pwszURL = (LPWSTR)nihongoURL;
3210 U(point.DistPointName).FullName.cAltEntry = 1;
3211 U(point.DistPointName).FullName.rgAltEntry = &entry;
3212 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3213 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3214 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
3215 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
3216 /* The first invalid character is at index 7 */
3217 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
3218 "Expected invalid char at index 7, got %d\n",
3219 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
3220 /* A dist point with (just) a valid name */
3221 U(entry).pwszURL = (LPWSTR)url;
3222 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3223 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3224 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3225 if (buf)
3227 ok(size == sizeof(distPointWithUrl), "Wrong size %d\n", size);
3228 ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n");
3229 LocalFree(buf);
3231 /* A dist point with (just) reason flags */
3232 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3233 point.ReasonFlags.cbData = sizeof(crlReason);
3234 point.ReasonFlags.pbData = (LPBYTE)&crlReason;
3235 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3236 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3237 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3238 if (buf)
3240 ok(size == sizeof(distPointWithReason), "Wrong size %d\n", size);
3241 ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n");
3242 LocalFree(buf);
3244 /* A dist point with just an issuer */
3245 point.ReasonFlags.cbData = 0;
3246 point.CRLIssuer.cAltEntry = 1;
3247 point.CRLIssuer.rgAltEntry = &entry;
3248 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3249 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3250 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3251 if (buf)
3253 ok(size == sizeof(distPointWithIssuer), "Wrong size %d\n", size);
3254 ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n");
3255 LocalFree(buf);
3257 /* A dist point with both a name and an issuer */
3258 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3259 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3260 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3261 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3262 if (buf)
3264 ok(size == sizeof(distPointWithUrlAndIssuer),
3265 "Wrong size %d\n", size);
3266 ok(!memcmp(buf, distPointWithUrlAndIssuer, size), "Unexpected value\n");
3267 LocalFree(buf);
3271 static void test_decodeCRLDistPoints(DWORD dwEncoding)
3273 BOOL ret;
3274 BYTE *buf = NULL;
3275 DWORD size = 0;
3276 PCRL_DIST_POINTS_INFO info;
3277 PCRL_DIST_POINT point;
3278 PCERT_ALT_NAME_ENTRY entry;
3280 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3281 emptyDistPoint, emptyDistPoint[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3282 (BYTE *)&buf, &size);
3283 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
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 == CRL_DIST_POINT_NO_NAME,
3293 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3294 point->DistPointName.dwDistPointNameChoice);
3295 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3296 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3297 LocalFree(buf);
3299 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3300 distPointWithUrl, distPointWithUrl[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3301 (BYTE *)&buf, &size);
3302 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3303 if (ret)
3305 info = (PCRL_DIST_POINTS_INFO)buf;
3306 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3307 "Wrong size %d\n", size);
3308 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3309 info->cDistPoint);
3310 point = info->rgDistPoint;
3311 ok(point->DistPointName.dwDistPointNameChoice ==
3312 CRL_DIST_POINT_FULL_NAME,
3313 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3314 point->DistPointName.dwDistPointNameChoice);
3315 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3316 "Expected 1 name entry, got %d\n",
3317 U(point->DistPointName).FullName.cAltEntry);
3318 entry = U(point->DistPointName).FullName.rgAltEntry;
3319 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3320 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3321 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3322 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3323 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3324 LocalFree(buf);
3326 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3327 distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
3328 NULL, (BYTE *)&buf, &size);
3329 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3330 if (ret)
3332 info = (PCRL_DIST_POINTS_INFO)buf;
3333 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3334 "Wrong size %d\n", size);
3335 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3336 info->cDistPoint);
3337 point = info->rgDistPoint;
3338 ok(point->DistPointName.dwDistPointNameChoice ==
3339 CRL_DIST_POINT_NO_NAME,
3340 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3341 point->DistPointName.dwDistPointNameChoice);
3342 ok(point->ReasonFlags.cbData == sizeof(crlReason),
3343 "Expected reason length\n");
3344 ok(!memcmp(point->ReasonFlags.pbData, &crlReason, sizeof(crlReason)),
3345 "Unexpected reason\n");
3346 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3347 LocalFree(buf);
3349 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3350 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2,
3351 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3352 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3353 if (ret)
3355 info = (PCRL_DIST_POINTS_INFO)buf;
3356 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3357 "Wrong size %d\n", size);
3358 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3359 info->cDistPoint);
3360 point = info->rgDistPoint;
3361 ok(point->DistPointName.dwDistPointNameChoice ==
3362 CRL_DIST_POINT_FULL_NAME,
3363 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3364 point->DistPointName.dwDistPointNameChoice);
3365 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3366 "Expected 1 name entry, got %d\n",
3367 U(point->DistPointName).FullName.cAltEntry);
3368 entry = U(point->DistPointName).FullName.rgAltEntry;
3369 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3370 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3371 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3372 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3373 ok(point->CRLIssuer.cAltEntry == 1,
3374 "Expected 1 issuer entry, got %d\n", point->CRLIssuer.cAltEntry);
3375 entry = point->CRLIssuer.rgAltEntry;
3376 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3377 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3378 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3379 LocalFree(buf);
3383 static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3384 static const BYTE emptyNameIDP[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3385 static const BYTE urlIDP[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3386 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3387 0x67 };
3389 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding)
3391 BOOL ret;
3392 BYTE *buf = NULL;
3393 DWORD size = 0;
3394 CRL_ISSUING_DIST_POINT point = { { 0 } };
3395 CERT_ALT_NAME_ENTRY entry;
3397 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, NULL,
3398 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3399 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3401 skip("no X509_ISSUING_DIST_POINT encode support\n");
3402 return;
3404 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3405 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3406 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3407 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3408 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3409 if (buf)
3411 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
3412 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
3413 LocalFree(buf);
3415 /* nonsensical flags */
3416 point.fOnlyContainsUserCerts = TRUE;
3417 point.fOnlyContainsCACerts = TRUE;
3418 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3419 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3420 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3421 if (buf)
3423 ok(size == sizeof(badFlagsIDP), "Unexpected size %d\n", size);
3424 ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n");
3425 LocalFree(buf);
3427 /* unimplemented name type */
3428 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3429 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_ISSUER_RDN_NAME;
3430 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3431 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3432 ok(!ret && GetLastError() == E_INVALIDARG,
3433 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3434 /* empty name */
3435 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3436 U(point.DistPointName).FullName.cAltEntry = 0;
3437 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3438 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3439 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3440 if (buf)
3442 ok(size == sizeof(emptyNameIDP), "Unexpected size %d\n", size);
3443 ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n");
3444 LocalFree(buf);
3446 /* name with URL entry */
3447 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3448 U(entry).pwszURL = (LPWSTR)url;
3449 U(point.DistPointName).FullName.cAltEntry = 1;
3450 U(point.DistPointName).FullName.rgAltEntry = &entry;
3451 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3452 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3453 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3454 if (buf)
3456 ok(size == sizeof(urlIDP), "Unexpected size %d\n", size);
3457 ok(!memcmp(buf, urlIDP, size), "Unexpected value\n");
3458 LocalFree(buf);
3462 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY *expected,
3463 const CERT_ALT_NAME_ENTRY *got)
3465 ok(expected->dwAltNameChoice == got->dwAltNameChoice,
3466 "Expected name choice %d, got %d\n", expected->dwAltNameChoice,
3467 got->dwAltNameChoice);
3468 if (expected->dwAltNameChoice == got->dwAltNameChoice)
3470 switch (got->dwAltNameChoice)
3472 case CERT_ALT_NAME_RFC822_NAME:
3473 case CERT_ALT_NAME_DNS_NAME:
3474 case CERT_ALT_NAME_EDI_PARTY_NAME:
3475 case CERT_ALT_NAME_URL:
3476 case CERT_ALT_NAME_REGISTERED_ID:
3477 ok((!U(*expected).pwszURL && !U(*got).pwszURL) ||
3478 (!U(*expected).pwszURL && !lstrlenW(U(*got).pwszURL)) ||
3479 (!U(*got).pwszURL && !lstrlenW(U(*expected).pwszURL)) ||
3480 !lstrcmpW(U(*expected).pwszURL, U(*got).pwszURL),
3481 "Unexpected name\n");
3482 break;
3483 case CERT_ALT_NAME_X400_ADDRESS:
3484 case CERT_ALT_NAME_DIRECTORY_NAME:
3485 case CERT_ALT_NAME_IP_ADDRESS:
3486 ok(U(*got).IPAddress.cbData == U(*expected).IPAddress.cbData,
3487 "Unexpected IP address length %d\n", U(*got).IPAddress.cbData);
3488 ok(!memcmp(U(*got).IPAddress.pbData, U(*got).IPAddress.pbData,
3489 U(*got).IPAddress.cbData), "Unexpected value\n");
3490 break;
3495 static void compareAltNameInfo(const CERT_ALT_NAME_INFO *expected,
3496 const CERT_ALT_NAME_INFO *got)
3498 DWORD i;
3500 ok(expected->cAltEntry == got->cAltEntry, "Expected %d entries, got %d\n",
3501 expected->cAltEntry, got->cAltEntry);
3502 for (i = 0; i < min(expected->cAltEntry, got->cAltEntry); i++)
3503 compareAltNameEntry(&expected->rgAltEntry[i], &got->rgAltEntry[i]);
3506 static void compareDistPointName(const CRL_DIST_POINT_NAME *expected,
3507 const CRL_DIST_POINT_NAME *got)
3509 ok(got->dwDistPointNameChoice == expected->dwDistPointNameChoice,
3510 "Unexpected name choice %d\n", got->dwDistPointNameChoice);
3511 if (got->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME)
3512 compareAltNameInfo(&(U(*expected).FullName), &(U(*got).FullName));
3515 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT *expected,
3516 const CRL_ISSUING_DIST_POINT *got)
3518 compareDistPointName(&expected->DistPointName, &got->DistPointName);
3519 ok(got->fOnlyContainsUserCerts == expected->fOnlyContainsUserCerts,
3520 "Unexpected fOnlyContainsUserCerts\n");
3521 ok(got->fOnlyContainsCACerts == expected->fOnlyContainsCACerts,
3522 "Unexpected fOnlyContainsCACerts\n");
3523 ok(got->OnlySomeReasonFlags.cbData == expected->OnlySomeReasonFlags.cbData,
3524 "Unexpected reason flags\n");
3525 ok(got->fIndirectCRL == expected->fIndirectCRL,
3526 "Unexpected fIndirectCRL\n");
3529 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding)
3531 BOOL ret;
3532 BYTE *buf = NULL;
3533 DWORD size = 0;
3534 CRL_ISSUING_DIST_POINT point = { { 0 } };
3536 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3537 emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3538 (BYTE *)&buf, &size);
3539 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3541 skip("no X509_ISSUING_DIST_POINT decode support\n");
3542 return;
3544 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3545 if (ret)
3547 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3548 LocalFree(buf);
3550 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3551 badFlagsIDP, badFlagsIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3552 (BYTE *)&buf, &size);
3553 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3554 if (ret)
3556 point.fOnlyContainsUserCerts = point.fOnlyContainsCACerts = TRUE;
3557 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3558 LocalFree(buf);
3560 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3561 emptyNameIDP, emptyNameIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3562 (BYTE *)&buf, &size);
3563 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3564 if (ret)
3566 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3567 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3568 U(point.DistPointName).FullName.cAltEntry = 0;
3569 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3570 LocalFree(buf);
3572 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3573 urlIDP, urlIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3574 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3575 if (ret)
3577 CERT_ALT_NAME_ENTRY entry;
3579 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3580 U(entry).pwszURL = (LPWSTR)url;
3581 U(point.DistPointName).FullName.cAltEntry = 1;
3582 U(point.DistPointName).FullName.rgAltEntry = &entry;
3583 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3584 LocalFree(buf);
3588 static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3589 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3590 0x30, 0x5a };
3591 static const BYTE v2CRL[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3592 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3593 0x30, 0x30, 0x30, 0x30, 0x5a };
3594 static const BYTE v1CRLWithIssuer[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3595 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3596 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3597 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3598 0x5a };
3599 static const BYTE v1CRLWithIssuerAndEmptyEntry[] = { 0x30, 0x43, 0x30, 0x02,
3600 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3601 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3602 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3603 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3604 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3605 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3606 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3607 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3608 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3609 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3610 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3611 static const BYTE v1CRLWithEntryExt[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3612 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3613 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3614 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3615 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3616 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3617 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3618 static const BYTE v1CRLWithExt[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3619 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3620 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3621 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
3622 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3623 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
3624 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3625 static const BYTE v2CRLWithExt[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
3626 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
3627 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
3628 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
3629 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
3630 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
3631 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3632 static const BYTE v2CRLWithIssuingDistPoint[] = { 0x30,0x5c,0x02,0x01,0x01,
3633 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
3634 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
3635 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
3636 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3637 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
3638 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3640 static void test_encodeCRLToBeSigned(DWORD dwEncoding)
3642 BOOL ret;
3643 BYTE *buf = NULL;
3644 static CHAR oid_issuing_dist_point[] = szOID_ISSUING_DIST_POINT;
3645 DWORD size = 0;
3646 CRL_INFO info = { 0 };
3647 CRL_ENTRY entry = { { 0 }, { 0 }, 0, 0 };
3648 CERT_EXTENSION ext;
3650 /* Test with a V1 CRL */
3651 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3652 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3653 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3654 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3655 if (buf)
3657 ok(size == sizeof(v1CRL), "Wrong size %d\n", size);
3658 ok(!memcmp(buf, v1CRL, size), "Got unexpected value\n");
3659 LocalFree(buf);
3661 /* Test v2 CRL */
3662 info.dwVersion = CRL_V2;
3663 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3664 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3665 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3666 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3667 if (buf)
3669 ok(size == v2CRL[1] + 2, "Expected size %d, got %d\n",
3670 v2CRL[1] + 2, size);
3671 ok(!memcmp(buf, v2CRL, size), "Got unexpected value\n");
3672 LocalFree(buf);
3674 /* v1 CRL with a name */
3675 info.dwVersion = CRL_V1;
3676 info.Issuer.cbData = sizeof(encodedCommonName);
3677 info.Issuer.pbData = (BYTE *)encodedCommonName;
3678 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3679 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3680 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3681 if (buf)
3683 ok(size == sizeof(v1CRLWithIssuer), "Wrong size %d\n", size);
3684 ok(!memcmp(buf, v1CRLWithIssuer, size), "Got unexpected value\n");
3685 LocalFree(buf);
3687 if (0)
3689 /* v1 CRL with a name and a NULL entry pointer (crashes on win9x) */
3690 info.cCRLEntry = 1;
3691 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3692 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3693 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3694 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3696 /* now set an empty entry */
3697 info.cCRLEntry = 1;
3698 info.rgCRLEntry = &entry;
3699 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3700 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3701 if (buf)
3703 ok(size == sizeof(v1CRLWithIssuerAndEmptyEntry),
3704 "Wrong size %d\n", size);
3705 ok(!memcmp(buf, v1CRLWithIssuerAndEmptyEntry, size),
3706 "Got unexpected value\n");
3707 LocalFree(buf);
3709 /* an entry with a serial number */
3710 entry.SerialNumber.cbData = sizeof(serialNum);
3711 entry.SerialNumber.pbData = (BYTE *)serialNum;
3712 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3713 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3714 if (buf)
3716 ok(size == sizeof(v1CRLWithIssuerAndEntry),
3717 "Wrong size %d\n", size);
3718 ok(!memcmp(buf, v1CRLWithIssuerAndEntry, size),
3719 "Got unexpected value\n");
3720 LocalFree(buf);
3722 /* an entry with an extension */
3723 entry.cExtension = 1;
3724 entry.rgExtension = &criticalExt;
3725 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3726 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3727 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3728 if (buf)
3730 ok(size == sizeof(v1CRLWithEntryExt), "Wrong size %d\n", size);
3731 ok(!memcmp(buf, v1CRLWithEntryExt, size), "Got unexpected value\n");
3732 LocalFree(buf);
3734 /* a CRL with an extension */
3735 entry.cExtension = 0;
3736 info.cExtension = 1;
3737 info.rgExtension = &criticalExt;
3738 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3739 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3740 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3741 if (buf)
3743 ok(size == sizeof(v1CRLWithExt), "Wrong size %d\n", size);
3744 ok(!memcmp(buf, v1CRLWithExt, size), "Got unexpected value\n");
3745 LocalFree(buf);
3747 /* a v2 CRL with an extension, this time non-critical */
3748 info.dwVersion = CRL_V2;
3749 info.rgExtension = &nonCriticalExt;
3750 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3751 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3752 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3753 if (buf)
3755 ok(size == sizeof(v2CRLWithExt), "Wrong size %d\n", size);
3756 ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n");
3757 LocalFree(buf);
3759 /* a v2 CRL with an issuing dist point extension */
3760 ext.pszObjId = oid_issuing_dist_point;
3761 ext.fCritical = TRUE;
3762 ext.Value.cbData = sizeof(urlIDP);
3763 ext.Value.pbData = (LPBYTE)urlIDP;
3764 entry.rgExtension = &ext;
3765 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3766 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3767 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3768 if (buf)
3770 ok(size == sizeof(v2CRLWithIssuingDistPoint), "Wrong size %d\n", size);
3771 ok(!memcmp(buf, v2CRLWithIssuingDistPoint, size), "Unexpected value\n");
3772 LocalFree(buf);
3776 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
3777 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
3778 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
3779 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
3780 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
3781 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
3782 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
3783 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
3784 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
3785 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
3786 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
3787 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
3788 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
3789 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
3790 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
3791 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
3792 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
3793 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
3794 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
3795 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
3796 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
3797 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
3798 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
3799 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
3800 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
3801 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
3802 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
3803 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
3804 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
3805 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
3806 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
3807 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
3808 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
3809 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
3810 0xcd };
3811 static const BYTE verisignCRLWithLotsOfEntries[] = {
3812 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
3813 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
3814 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
3815 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
3816 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
3817 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
3818 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
3819 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
3820 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
3821 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
3822 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
3823 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
3824 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
3825 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
3826 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
3827 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
3828 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3829 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
3830 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
3831 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3832 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
3833 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
3834 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
3835 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
3836 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
3837 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
3838 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
3839 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
3840 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
3841 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
3842 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3843 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
3844 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
3845 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3846 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
3847 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
3848 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
3849 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
3850 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
3851 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
3852 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
3853 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
3854 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
3855 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
3856 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
3857 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
3858 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
3859 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
3860 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
3861 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
3862 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
3863 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
3864 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
3865 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
3866 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3867 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
3868 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
3869 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
3870 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
3871 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
3872 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
3873 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
3874 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
3875 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
3876 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
3877 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
3878 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
3879 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
3880 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
3881 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
3882 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
3883 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
3884 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
3885 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
3886 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
3887 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
3888 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
3889 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
3890 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
3891 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
3892 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
3893 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
3894 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3895 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
3896 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
3897 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
3898 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
3899 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
3900 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
3901 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
3902 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
3903 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
3904 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
3905 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
3906 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
3907 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
3908 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
3909 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
3910 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
3911 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
3912 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
3913 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
3914 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
3915 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
3916 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
3917 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
3918 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
3919 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
3920 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
3921 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
3922 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3923 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
3924 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
3925 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
3926 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
3927 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
3928 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
3929 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
3930 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
3931 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
3932 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
3933 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
3934 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
3935 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
3936 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3937 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
3938 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
3939 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
3940 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
3941 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
3942 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
3943 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
3944 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
3945 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
3946 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
3947 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
3948 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
3949 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
3950 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
3951 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
3952 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
3953 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
3954 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
3955 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
3956 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
3957 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
3958 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
3959 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
3960 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
3961 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
3962 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
3963 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
3964 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
3965 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
3966 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
3967 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
3968 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
3969 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
3970 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
3971 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
3972 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
3973 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
3974 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
3975 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
3976 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
3977 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
3978 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
3979 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
3980 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
3981 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
3982 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
3983 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
3984 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
3985 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
3986 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
3987 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
3988 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
3989 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
3990 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
3991 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
3992 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
3993 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
3994 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
3995 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
3996 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
3997 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
3998 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
3999 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
4000 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
4001 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
4002 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
4003 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
4004 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
4005 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
4006 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
4007 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
4008 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
4009 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
4010 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
4011 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
4012 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
4013 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
4014 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
4015 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
4016 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
4017 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
4018 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
4019 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
4020 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
4021 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
4022 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
4023 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
4024 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
4025 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
4026 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
4027 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
4028 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
4029 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
4030 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
4031 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
4032 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
4033 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
4034 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
4035 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
4036 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
4037 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
4038 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
4039 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
4040 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
4041 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
4042 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
4043 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
4044 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
4045 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
4046 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
4047 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
4048 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
4049 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
4050 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
4051 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
4052 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
4053 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
4054 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
4055 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
4056 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
4057 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
4058 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
4059 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
4060 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
4061 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
4062 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
4063 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
4064 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
4065 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
4066 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
4067 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
4068 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
4069 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
4070 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
4071 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
4072 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
4073 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
4074 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
4075 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
4076 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
4077 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
4078 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
4079 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
4080 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
4081 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
4082 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
4083 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
4084 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
4085 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
4086 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
4087 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
4088 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
4089 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
4090 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
4091 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
4092 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
4093 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
4094 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
4095 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
4096 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
4097 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
4098 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
4099 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
4100 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
4101 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
4102 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
4103 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
4104 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
4105 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
4106 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
4107 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
4108 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
4109 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
4110 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
4111 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
4112 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
4113 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
4114 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
4115 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4116 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4117 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4118 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4119 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4120 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4121 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4122 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4123 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4124 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4125 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4126 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4127 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4128 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4129 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4130 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4131 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4132 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4133 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4134 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4135 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4136 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4137 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4138 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4139 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4140 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4141 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4142 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4143 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4144 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4145 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4146 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4147 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4148 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4149 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4150 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4151 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4152 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4153 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4154 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4155 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4156 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4157 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4158 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4159 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4160 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4161 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4162 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4163 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4164 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4165 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4166 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4167 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4168 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4169 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4170 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4171 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4172 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4173 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4174 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4175 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4176 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4177 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4178 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4179 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4180 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4181 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4182 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4183 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4184 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4185 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4186 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4187 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4188 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4189 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4190 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4191 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4192 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4193 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4194 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4195 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4196 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4197 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4198 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4199 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4200 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4201 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4202 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4203 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4204 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4205 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4206 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4207 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4208 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4209 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4210 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4211 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4212 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4213 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4214 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4215 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4216 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4217 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4218 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4219 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4220 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4221 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4222 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4223 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4224 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4225 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4226 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4227 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4228 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4229 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4230 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4231 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4232 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4233 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4234 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4235 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4236 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4237 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4238 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4239 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4240 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4241 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4242 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4243 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4244 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4245 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4246 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4247 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4248 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4249 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4250 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4251 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4252 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4253 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4254 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4255 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4256 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4257 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4258 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4259 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4260 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4261 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4262 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4263 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4264 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4265 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4266 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4267 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4268 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4269 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4270 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4271 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4272 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4273 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4274 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4275 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4276 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4277 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4278 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4279 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4280 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4281 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4282 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4283 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4284 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4285 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4286 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4287 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4288 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4289 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4290 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4291 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4292 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4293 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4294 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4295 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4296 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4297 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4298 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4299 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4300 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4301 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4302 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4303 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4304 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4305 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4306 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4307 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4308 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4309 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4310 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4311 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4312 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4313 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4314 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4315 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4316 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4317 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4318 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4319 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4321 static void test_decodeCRLToBeSigned(DWORD dwEncoding)
4323 static const BYTE *corruptCRLs[] = { v1CRL, v2CRL };
4324 BOOL ret;
4325 BYTE *buf = NULL;
4326 DWORD size = 0, i;
4328 for (i = 0; i < sizeof(corruptCRLs) / sizeof(corruptCRLs[0]); i++)
4330 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4331 corruptCRLs[i], corruptCRLs[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4332 (BYTE *)&buf, &size);
4333 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4334 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4335 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4336 GetLastError());
4338 /* at a minimum, a CRL must contain an issuer: */
4339 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4340 v1CRLWithIssuer, v1CRLWithIssuer[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4341 (BYTE *)&buf, &size);
4342 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4343 if (buf)
4345 CRL_INFO *info = (CRL_INFO *)buf;
4347 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4348 ok(info->cCRLEntry == 0, "Expected 0 CRL entries, got %d\n",
4349 info->cCRLEntry);
4350 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4351 "Wrong issuer size %d\n", info->Issuer.cbData);
4352 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4353 "Unexpected issuer\n");
4354 LocalFree(buf);
4356 /* check decoding with an empty CRL entry */
4357 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4358 v1CRLWithIssuerAndEmptyEntry, v1CRLWithIssuerAndEmptyEntry[1] + 2,
4359 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4360 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4361 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4362 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4363 GetLastError());
4364 /* with a real CRL entry */
4365 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4366 v1CRLWithIssuerAndEntry, v1CRLWithIssuerAndEntry[1] + 2,
4367 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4368 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4369 if (buf)
4371 CRL_INFO *info = (CRL_INFO *)buf;
4372 CRL_ENTRY *entry;
4374 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4375 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4376 info->cCRLEntry);
4377 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4378 entry = info->rgCRLEntry;
4379 ok(entry->SerialNumber.cbData == 1,
4380 "Expected serial number size 1, got %d\n",
4381 entry->SerialNumber.cbData);
4382 ok(*entry->SerialNumber.pbData == *serialNum,
4383 "Expected serial number %d, got %d\n", *serialNum,
4384 *entry->SerialNumber.pbData);
4385 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4386 "Wrong issuer size %d\n", info->Issuer.cbData);
4387 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4388 "Unexpected issuer\n");
4389 LocalFree(buf);
4391 /* a real CRL from verisign that has extensions */
4392 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4393 verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG,
4394 NULL, (BYTE *)&buf, &size);
4395 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4396 if (buf)
4398 CRL_INFO *info = (CRL_INFO *)buf;
4399 CRL_ENTRY *entry;
4401 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4402 ok(info->cCRLEntry == 3, "Expected 3 CRL entries, got %d\n",
4403 info->cCRLEntry);
4404 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4405 entry = info->rgCRLEntry;
4406 ok(info->cExtension == 2, "Expected 2 extensions, got %d\n",
4407 info->cExtension);
4408 LocalFree(buf);
4410 /* another real CRL from verisign that has lots of entries */
4411 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4412 verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries),
4413 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4414 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4415 if (buf)
4417 CRL_INFO *info = (CRL_INFO *)buf;
4419 ok(size >= sizeof(CRL_INFO), "Got size %d\n", size);
4420 ok(info->cCRLEntry == 209, "Expected 209 CRL entries, got %d\n",
4421 info->cCRLEntry);
4422 ok(info->cExtension == 0, "Expected 0 extensions, got %d\n",
4423 info->cExtension);
4424 LocalFree(buf);
4426 /* and finally, with an extension */
4427 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4428 v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4429 NULL, (BYTE *)&buf, &size);
4430 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4431 if (buf)
4433 CRL_INFO *info = (CRL_INFO *)buf;
4434 CRL_ENTRY *entry;
4436 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4437 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4438 info->cCRLEntry);
4439 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4440 entry = info->rgCRLEntry;
4441 ok(entry->SerialNumber.cbData == 1,
4442 "Expected serial number size 1, got %d\n",
4443 entry->SerialNumber.cbData);
4444 ok(*entry->SerialNumber.pbData == *serialNum,
4445 "Expected serial number %d, got %d\n", *serialNum,
4446 *entry->SerialNumber.pbData);
4447 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4448 "Wrong issuer size %d\n", info->Issuer.cbData);
4449 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4450 "Unexpected issuer\n");
4451 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4452 info->cExtension);
4453 LocalFree(buf);
4455 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4456 v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4457 NULL, (BYTE *)&buf, &size);
4458 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4459 if (buf)
4461 CRL_INFO *info = (CRL_INFO *)buf;
4463 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4464 info->cExtension);
4465 LocalFree(buf);
4467 /* And again, with an issuing dist point */
4468 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4469 v2CRLWithIssuingDistPoint, sizeof(v2CRLWithIssuingDistPoint),
4470 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4471 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4472 if (buf)
4474 CRL_INFO *info = (CRL_INFO *)buf;
4476 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4477 info->cExtension);
4478 LocalFree(buf);
4482 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
4483 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
4484 static const BYTE encodedUsage[] = {
4485 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4486 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4487 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4489 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding)
4491 BOOL ret;
4492 BYTE *buf = NULL;
4493 DWORD size = 0;
4494 CERT_ENHKEY_USAGE usage;
4496 /* Test with empty usage */
4497 usage.cUsageIdentifier = 0;
4498 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4499 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4500 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4501 if (buf)
4503 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
4504 ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n");
4505 LocalFree(buf);
4507 /* Test with a few usages */
4508 usage.cUsageIdentifier = sizeof(keyUsages) / sizeof(keyUsages[0]);
4509 usage.rgpszUsageIdentifier = (LPSTR *)keyUsages;
4510 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4511 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4512 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4513 if (buf)
4515 ok(size == sizeof(encodedUsage), "Wrong size %d\n", size);
4516 ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n");
4517 LocalFree(buf);
4521 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding)
4523 BOOL ret;
4524 LPBYTE buf = NULL;
4525 DWORD size = 0;
4527 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4528 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4529 (BYTE *)&buf, &size);
4530 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4531 if (buf)
4533 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4535 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4536 "Wrong size %d\n", size);
4537 ok(usage->cUsageIdentifier == 0, "Expected 0 CRL entries, got %d\n",
4538 usage->cUsageIdentifier);
4539 LocalFree(buf);
4541 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4542 encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL,
4543 (BYTE *)&buf, &size);
4544 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4545 if (buf)
4547 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4548 DWORD i;
4550 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4551 "Wrong size %d\n", size);
4552 ok(usage->cUsageIdentifier == sizeof(keyUsages) / sizeof(keyUsages[0]),
4553 "Wrong CRL entries count %d\n", usage->cUsageIdentifier);
4554 for (i = 0; i < usage->cUsageIdentifier; i++)
4555 ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]),
4556 "Expected OID %s, got %s\n", keyUsages[i],
4557 usage->rgpszUsageIdentifier[i]);
4558 LocalFree(buf);
4562 static BYTE keyId[] = { 1,2,3,4 };
4563 static const BYTE authorityKeyIdWithId[] = {
4564 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4565 static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4566 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4567 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4568 static const BYTE authorityKeyIdWithSerial[] = { 0x30,0x03,0x82,0x01,0x01 };
4570 static void test_encodeAuthorityKeyId(DWORD dwEncoding)
4572 CERT_AUTHORITY_KEY_ID_INFO info = { { 0 } };
4573 BOOL ret;
4574 BYTE *buf = NULL;
4575 DWORD size = 0;
4577 /* Test with empty id */
4578 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4579 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4580 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4581 if (buf)
4583 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4584 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4585 LocalFree(buf);
4587 /* With just a key id */
4588 info.KeyId.cbData = sizeof(keyId);
4589 info.KeyId.pbData = keyId;
4590 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4591 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4592 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4593 if (buf)
4595 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", size);
4596 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4597 LocalFree(buf);
4599 /* With just an issuer */
4600 info.KeyId.cbData = 0;
4601 info.CertIssuer.cbData = sizeof(encodedCommonName);
4602 info.CertIssuer.pbData = (BYTE *)encodedCommonName;
4603 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4604 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4605 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4606 if (buf)
4608 ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %d\n",
4609 size);
4610 ok(!memcmp(buf, authorityKeyIdWithIssuer, size), "Unexpected value\n");
4611 LocalFree(buf);
4613 /* With just a serial number */
4614 info.CertIssuer.cbData = 0;
4615 info.CertSerialNumber.cbData = sizeof(serialNum);
4616 info.CertSerialNumber.pbData = (BYTE *)serialNum;
4617 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4618 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4619 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4620 if (buf)
4622 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4623 size);
4624 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4625 LocalFree(buf);
4629 static void test_decodeAuthorityKeyId(DWORD dwEncoding)
4631 BOOL ret;
4632 LPBYTE buf = NULL;
4633 DWORD size = 0;
4635 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4636 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4637 (BYTE *)&buf, &size);
4638 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4639 if (buf)
4641 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4643 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4644 size);
4645 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4646 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4647 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4648 LocalFree(buf);
4650 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4651 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4652 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4653 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4654 if (buf)
4656 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4658 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4659 size);
4660 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4661 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4662 "Unexpected key id\n");
4663 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4664 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4665 LocalFree(buf);
4667 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4668 authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer),
4669 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4670 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4671 if (buf)
4673 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4675 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4676 size);
4677 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4678 ok(info->CertIssuer.cbData == sizeof(encodedCommonName),
4679 "Unexpected issuer len\n");
4680 ok(!memcmp(info->CertIssuer.pbData, encodedCommonName,
4681 sizeof(encodedCommonName)), "Unexpected issuer\n");
4682 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4683 LocalFree(buf);
4685 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4686 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4687 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4688 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4689 if (buf)
4691 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4693 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4694 size);
4695 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4696 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4697 ok(info->CertSerialNumber.cbData == sizeof(serialNum),
4698 "Unexpected serial number len\n");
4699 ok(!memcmp(info->CertSerialNumber.pbData, serialNum, sizeof(serialNum)),
4700 "Unexpected serial number\n");
4701 LocalFree(buf);
4705 static const BYTE authorityKeyIdWithIssuerUrl[] = { 0x30,0x15,0xa1,0x13,0x86,
4706 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
4707 0x6f,0x72,0x67 };
4709 static void test_encodeAuthorityKeyId2(DWORD dwEncoding)
4711 CERT_AUTHORITY_KEY_ID2_INFO info = { { 0 } };
4712 CERT_ALT_NAME_ENTRY entry = { 0 };
4713 BOOL ret;
4714 BYTE *buf = NULL;
4715 DWORD size = 0;
4717 /* Test with empty id */
4718 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4719 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4720 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4721 if (buf)
4723 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4724 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4725 LocalFree(buf);
4727 /* With just a key id */
4728 info.KeyId.cbData = sizeof(keyId);
4729 info.KeyId.pbData = keyId;
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(authorityKeyIdWithId), "Unexpected size %d\n",
4736 size);
4737 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4738 LocalFree(buf);
4740 /* With a bogus issuer name */
4741 info.KeyId.cbData = 0;
4742 info.AuthorityCertIssuer.cAltEntry = 1;
4743 info.AuthorityCertIssuer.rgAltEntry = &entry;
4744 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4745 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4746 ok(!ret && GetLastError() == E_INVALIDARG,
4747 "Expected E_INVALIDARG, got %08x\n", GetLastError());
4748 /* With an issuer name */
4749 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
4750 U(entry).pwszURL = (LPWSTR)url;
4751 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4752 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4753 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4754 if (buf)
4756 ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %d\n",
4757 size);
4758 ok(!memcmp(buf, authorityKeyIdWithIssuerUrl, size),
4759 "Unexpected value\n");
4760 LocalFree(buf);
4762 /* With just a serial number */
4763 info.AuthorityCertIssuer.cAltEntry = 0;
4764 info.AuthorityCertSerialNumber.cbData = sizeof(serialNum);
4765 info.AuthorityCertSerialNumber.pbData = (BYTE *)serialNum;
4766 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4767 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4768 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4769 if (buf)
4771 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4772 size);
4773 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4774 LocalFree(buf);
4778 static void test_decodeAuthorityKeyId2(DWORD dwEncoding)
4780 BOOL ret;
4781 LPBYTE buf = NULL;
4782 DWORD size = 0;
4784 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4785 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4786 (BYTE *)&buf, &size);
4787 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4788 if (buf)
4790 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4792 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4793 size);
4794 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4795 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4796 "Expected no issuer name entries\n");
4797 ok(info->AuthorityCertSerialNumber.cbData == 0,
4798 "Expected no serial number\n");
4799 LocalFree(buf);
4801 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4802 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4803 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4804 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4805 if (buf)
4807 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4809 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4810 size);
4811 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4812 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4813 "Unexpected key id\n");
4814 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4815 "Expected no issuer name entries\n");
4816 ok(info->AuthorityCertSerialNumber.cbData == 0,
4817 "Expected no serial number\n");
4818 LocalFree(buf);
4820 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4821 authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl),
4822 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4823 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4824 if (buf)
4826 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4828 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4829 size);
4830 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4831 ok(info->AuthorityCertIssuer.cAltEntry == 1,
4832 "Expected 1 issuer entry, got %d\n",
4833 info->AuthorityCertIssuer.cAltEntry);
4834 ok(info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice ==
4835 CERT_ALT_NAME_URL, "Expected CERT_ALT_NAME_URL, got %d\n",
4836 info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice);
4837 ok(!lstrcmpW(U(info->AuthorityCertIssuer.rgAltEntry[0]).pwszURL,
4838 url), "Unexpected URL\n");
4839 ok(info->AuthorityCertSerialNumber.cbData == 0,
4840 "Expected no serial number\n");
4841 LocalFree(buf);
4843 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4844 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4845 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4846 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4847 if (buf)
4849 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4851 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4852 size);
4853 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4854 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4855 "Expected no issuer name entries\n");
4856 ok(info->AuthorityCertSerialNumber.cbData == sizeof(serialNum),
4857 "Unexpected serial number len\n");
4858 ok(!memcmp(info->AuthorityCertSerialNumber.pbData, serialNum,
4859 sizeof(serialNum)), "Unexpected serial number\n");
4860 LocalFree(buf);
4864 static const BYTE authorityInfoAccessWithUrl[] = {
4865 0x30,0x19,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
4866 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
4867 static const BYTE authorityInfoAccessWithUrlAndIPAddr[] = {
4868 0x30,0x29,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
4869 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x0e,0x06,
4870 0x02,0x2d,0x06,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
4872 static void test_encodeAuthorityInfoAccess(DWORD dwEncoding)
4874 static char oid1[] = "1.2.3";
4875 static char oid2[] = "1.5.6";
4876 BOOL ret;
4877 BYTE *buf = NULL;
4878 DWORD size = 0;
4879 CERT_ACCESS_DESCRIPTION accessDescription[2];
4880 CERT_AUTHORITY_INFO_ACCESS aia;
4882 memset(accessDescription, 0, sizeof(accessDescription));
4883 aia.cAccDescr = 0;
4884 aia.rgAccDescr = NULL;
4885 /* Having no access descriptions is allowed */
4886 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4887 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4888 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4889 if (buf)
4891 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
4892 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
4893 LocalFree(buf);
4894 buf = NULL;
4896 /* It can't have an empty access method */
4897 aia.cAccDescr = 1;
4898 aia.rgAccDescr = accessDescription;
4899 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4900 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4901 ok(!ret && (GetLastError() == E_INVALIDARG ||
4902 GetLastError() == OSS_LIMITED /* Win9x */),
4903 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
4904 /* It can't have an empty location */
4905 accessDescription[0].pszAccessMethod = oid1;
4906 SetLastError(0xdeadbeef);
4907 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4908 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4909 ok(!ret && GetLastError() == E_INVALIDARG,
4910 "expected E_INVALIDARG, got %08x\n", GetLastError());
4911 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
4912 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
4913 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4914 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4915 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4916 if (buf)
4918 ok(size == sizeof(authorityInfoAccessWithUrl), "unexpected size %d\n",
4919 size);
4920 ok(!memcmp(buf, authorityInfoAccessWithUrl, size),
4921 "unexpected value\n");
4922 LocalFree(buf);
4923 buf = NULL;
4925 accessDescription[1].pszAccessMethod = oid2;
4926 accessDescription[1].AccessLocation.dwAltNameChoice =
4927 CERT_ALT_NAME_IP_ADDRESS;
4928 U(accessDescription[1].AccessLocation).IPAddress.cbData =
4929 sizeof(encodedIPAddr);
4930 U(accessDescription[1].AccessLocation).IPAddress.pbData =
4931 (LPBYTE)encodedIPAddr;
4932 aia.cAccDescr = 2;
4933 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4934 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4935 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4936 if (buf)
4938 ok(size == sizeof(authorityInfoAccessWithUrlAndIPAddr),
4939 "unexpected size %d\n", size);
4940 ok(!memcmp(buf, authorityInfoAccessWithUrlAndIPAddr, size),
4941 "unexpected value\n");
4942 LocalFree(buf);
4943 buf = NULL;
4947 static void compareAuthorityInfoAccess(LPCSTR header,
4948 const CERT_AUTHORITY_INFO_ACCESS *expected,
4949 const CERT_AUTHORITY_INFO_ACCESS *got)
4951 DWORD i;
4953 ok(expected->cAccDescr == got->cAccDescr,
4954 "%s: expected %d access descriptions, got %d\n", header,
4955 expected->cAccDescr, got->cAccDescr);
4956 for (i = 0; i < expected->cAccDescr; i++)
4958 ok(!strcmp(expected->rgAccDescr[i].pszAccessMethod,
4959 got->rgAccDescr[i].pszAccessMethod), "%s[%d]: expected %s, got %s\n",
4960 header, i, expected->rgAccDescr[i].pszAccessMethod,
4961 got->rgAccDescr[i].pszAccessMethod);
4962 compareAltNameEntry(&expected->rgAccDescr[i].AccessLocation,
4963 &got->rgAccDescr[i].AccessLocation);
4967 static void test_decodeAuthorityInfoAccess(DWORD dwEncoding)
4969 static char oid1[] = "1.2.3";
4970 static char oid2[] = "1.5.6";
4971 BOOL ret;
4972 LPBYTE buf = NULL;
4973 DWORD size = 0;
4975 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
4976 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4977 (BYTE *)&buf, &size);
4978 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4979 if (buf)
4981 CERT_AUTHORITY_INFO_ACCESS aia = { 0, NULL };
4983 compareAuthorityInfoAccess("empty AIA", &aia,
4984 (CERT_AUTHORITY_INFO_ACCESS *)buf);
4985 LocalFree(buf);
4986 buf = NULL;
4988 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
4989 authorityInfoAccessWithUrl, sizeof(authorityInfoAccessWithUrl),
4990 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4991 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4992 if (buf)
4994 CERT_ACCESS_DESCRIPTION accessDescription;
4995 CERT_AUTHORITY_INFO_ACCESS aia;
4997 accessDescription.pszAccessMethod = oid1;
4998 accessDescription.AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
4999 U(accessDescription.AccessLocation).pwszURL = (LPWSTR)url;
5000 aia.cAccDescr = 1;
5001 aia.rgAccDescr = &accessDescription;
5002 compareAuthorityInfoAccess("AIA with URL", &aia,
5003 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5004 LocalFree(buf);
5005 buf = NULL;
5007 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5008 authorityInfoAccessWithUrlAndIPAddr,
5009 sizeof(authorityInfoAccessWithUrlAndIPAddr), CRYPT_DECODE_ALLOC_FLAG,
5010 NULL, (BYTE *)&buf, &size);
5011 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5012 if (buf)
5014 CERT_ACCESS_DESCRIPTION accessDescription[2];
5015 CERT_AUTHORITY_INFO_ACCESS aia;
5017 accessDescription[0].pszAccessMethod = oid1;
5018 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5019 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
5020 accessDescription[1].pszAccessMethod = oid2;
5021 accessDescription[1].AccessLocation.dwAltNameChoice =
5022 CERT_ALT_NAME_IP_ADDRESS;
5023 U(accessDescription[1].AccessLocation).IPAddress.cbData =
5024 sizeof(encodedIPAddr);
5025 U(accessDescription[1].AccessLocation).IPAddress.pbData =
5026 (LPBYTE)encodedIPAddr;
5027 aia.cAccDescr = 2;
5028 aia.rgAccDescr = accessDescription;
5029 compareAuthorityInfoAccess("AIA with URL and IP addr", &aia,
5030 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5031 LocalFree(buf);
5032 buf = NULL;
5036 static const BYTE emptyCTL[] = {
5037 0x30,0x17,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5038 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5039 static const BYTE emptyCTLWithVersion1[] = {
5040 0x30,0x1a,0x02,0x01,0x01,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5041 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5042 static const BYTE ctlWithUsageIdentifier[] = {
5043 0x30,0x1b,0x30,0x04,0x06,0x02,0x2a,0x03,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
5044 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5045 static const BYTE ctlWithListIdentifier[] = {
5046 0x30,0x1a,0x30,0x00,0x04,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5047 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5048 static const BYTE ctlWithSequenceNumber[] = {
5049 0x30,0x1a,0x30,0x00,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5050 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5051 static const BYTE ctlWithThisUpdate[] = {
5052 0x30,0x15,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5053 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5054 static const BYTE ctlWithThisAndNextUpdate[] = {
5055 0x30,0x24,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5056 0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5057 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5058 static const BYTE ctlWithAlgId[] = {
5059 0x30,0x1b,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5060 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5061 static const BYTE ctlWithBogusEntry[] = {
5062 0x30,0x29,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5063 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x10,0x30,0x0e,0x04,
5064 0x01,0x01,0x31,0x09,0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,0x01 };
5065 static const BYTE ctlWithOneEntry[] = {
5066 0x30,0x2a,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5067 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x11,0x30,0x0f,0x04,
5068 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00 };
5069 static const BYTE ctlWithTwoEntries[] = {
5070 0x30,0x41,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5071 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x28,0x30,0x0f,0x04,
5072 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00,0x30,
5073 0x15,0x04,0x01,0x01,0x31,0x10,0x30,0x0e,0x06,0x02,0x2d,0x06,0x31,0x08,0x30,
5074 0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5076 static void test_encodeCTL(DWORD dwEncoding)
5078 static char oid1[] = "1.2.3";
5079 static char oid2[] = "1.5.6";
5080 char *pOid1 = oid1;
5081 BOOL ret;
5082 BYTE *buf = NULL;
5083 DWORD size = 0;
5084 CTL_INFO info;
5085 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5086 CTL_ENTRY ctlEntry[2];
5087 CRYPT_ATTRIBUTE attr1, attr2;
5088 CRYPT_ATTR_BLOB value1, value2;
5090 memset(&info, 0, sizeof(info));
5091 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5092 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5093 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5094 if (buf)
5096 ok(size == sizeof(emptyCTL), "unexpected size %d\n", size);
5097 ok(!memcmp(buf, emptyCTL, size), "unexpected value\n");
5098 LocalFree(buf);
5099 buf = NULL;
5101 info.dwVersion = 1;
5102 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5103 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5104 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5105 if (buf)
5107 ok(size == sizeof(emptyCTLWithVersion1), "unexpected size %d\n", size);
5108 ok(!memcmp(buf, emptyCTLWithVersion1, size), "unexpected value\n");
5109 LocalFree(buf);
5110 buf = NULL;
5112 info.dwVersion = 0;
5113 info.SubjectUsage.cUsageIdentifier = 1;
5114 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5115 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5116 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5117 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5118 if (buf)
5120 ok(size == sizeof(ctlWithUsageIdentifier), "unexpected size %d\n",
5121 size);
5122 ok(!memcmp(buf, ctlWithUsageIdentifier, size), "unexpected value\n");
5123 LocalFree(buf);
5124 buf = NULL;
5126 info.SubjectUsage.cUsageIdentifier = 0;
5127 info.ListIdentifier.cbData = sizeof(serialNum);
5128 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5129 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5130 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5131 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5132 if (buf)
5134 ok(size == sizeof(ctlWithListIdentifier), "unexpected size %d\n", size);
5135 ok(!memcmp(buf, ctlWithListIdentifier, size), "unexpected value\n");
5136 LocalFree(buf);
5137 buf = NULL;
5139 info.ListIdentifier.cbData = 0;
5140 info.SequenceNumber.cbData = sizeof(serialNum);
5141 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5142 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5143 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5144 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5145 if (buf)
5147 ok(size == sizeof(ctlWithSequenceNumber), "unexpected size %d\n",
5148 size);
5149 ok(!memcmp(buf, ctlWithSequenceNumber, size), "unexpected value\n");
5150 LocalFree(buf);
5151 buf = NULL;
5153 info.SequenceNumber.cbData = 0;
5154 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5155 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5156 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5157 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5158 if (buf)
5160 ok(size == sizeof(ctlWithThisUpdate), "unexpected size %d\n", size);
5161 ok(!memcmp(buf, ctlWithThisUpdate, size), "unexpected value\n");
5162 LocalFree(buf);
5163 buf = NULL;
5165 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5166 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5167 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5168 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5169 if (buf)
5171 ok(size == sizeof(ctlWithThisAndNextUpdate), "unexpected size %d\n",
5172 size);
5173 ok(!memcmp(buf, ctlWithThisAndNextUpdate, size), "unexpected value\n");
5174 LocalFree(buf);
5175 buf = NULL;
5177 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5178 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5179 info.SubjectAlgorithm.pszObjId = oid2;
5180 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5181 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5182 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5183 if (buf)
5185 ok(size == sizeof(ctlWithAlgId), "unexpected size %d\n", size);
5186 ok(!memcmp(buf, ctlWithAlgId, size), "unexpected value\n");
5187 LocalFree(buf);
5188 buf = NULL;
5190 /* The value is supposed to be asn.1 encoded, so this'll fail to decode
5191 * (see tests below) but it'll encode fine.
5193 info.SubjectAlgorithm.pszObjId = NULL;
5194 value1.cbData = sizeof(serialNum);
5195 value1.pbData = (LPBYTE)serialNum;
5196 attr1.pszObjId = oid1;
5197 attr1.cValue = 1;
5198 attr1.rgValue = &value1;
5199 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5200 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5201 ctlEntry[0].cAttribute = 1;
5202 ctlEntry[0].rgAttribute = &attr1;
5203 info.cCTLEntry = 1;
5204 info.rgCTLEntry = ctlEntry;
5205 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5206 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5207 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5208 if (buf)
5210 ok(size == sizeof(ctlWithBogusEntry), "unexpected size %d\n", size);
5211 ok(!memcmp(buf, ctlWithBogusEntry, size), "unexpected value\n");
5212 LocalFree(buf);
5213 buf = NULL;
5215 value1.cbData = sizeof(emptySequence);
5216 value1.pbData = (LPBYTE)emptySequence;
5217 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5218 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5219 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5220 if (buf)
5222 ok(size == sizeof(ctlWithOneEntry), "unexpected size %d\n", size);
5223 ok(!memcmp(buf, ctlWithOneEntry, size), "unexpected value\n");
5224 LocalFree(buf);
5225 buf = NULL;
5227 value2.cbData = sizeof(encodedIPAddr);
5228 value2.pbData = (LPBYTE)encodedIPAddr;
5229 attr2.pszObjId = oid2;
5230 attr2.cValue = 1;
5231 attr2.rgValue = &value2;
5232 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5233 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5234 ctlEntry[1].cAttribute = 1;
5235 ctlEntry[1].rgAttribute = &attr2;
5236 info.cCTLEntry = 2;
5237 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5238 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5239 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5240 if (buf)
5242 ok(size == sizeof(ctlWithTwoEntries), "unexpected size %d\n", size);
5243 ok(!memcmp(buf, ctlWithTwoEntries, size), "unexpected value\n");
5244 LocalFree(buf);
5245 buf = NULL;
5249 static void compareCTLInfo(LPCSTR header, const CTL_INFO *expected,
5250 const CTL_INFO *got)
5252 DWORD i, j, k;
5254 ok(expected->dwVersion == got->dwVersion,
5255 "%s: expected version %d, got %d\n", header, expected->dwVersion,
5256 got->dwVersion);
5257 ok(expected->SubjectUsage.cUsageIdentifier ==
5258 got->SubjectUsage.cUsageIdentifier,
5259 "%s: expected %d usage identifiers, got %d\n", header,
5260 expected->SubjectUsage.cUsageIdentifier,
5261 got->SubjectUsage.cUsageIdentifier);
5262 for (i = 0; i < expected->SubjectUsage.cUsageIdentifier; i++)
5263 ok(!strcmp(expected->SubjectUsage.rgpszUsageIdentifier[i],
5264 got->SubjectUsage.rgpszUsageIdentifier[i]),
5265 "%s[%d]: expected %s, got %s\n", header, i,
5266 expected->SubjectUsage.rgpszUsageIdentifier[i],
5267 got->SubjectUsage.rgpszUsageIdentifier[i]);
5268 ok(expected->ListIdentifier.cbData == got->ListIdentifier.cbData,
5269 "%s: expected list identifier of %d bytes, got %d\n", header,
5270 expected->ListIdentifier.cbData, got->ListIdentifier.cbData);
5271 if (expected->ListIdentifier.cbData)
5272 ok(!memcmp(expected->ListIdentifier.pbData, got->ListIdentifier.pbData,
5273 expected->ListIdentifier.cbData),
5274 "%s: unexpected list identifier value\n", header);
5275 ok(expected->SequenceNumber.cbData == got->SequenceNumber.cbData,
5276 "%s: expected sequence number of %d bytes, got %d\n", header,
5277 expected->SequenceNumber.cbData, got->SequenceNumber.cbData);
5278 if (expected->SequenceNumber.cbData)
5279 ok(!memcmp(expected->SequenceNumber.pbData, got->SequenceNumber.pbData,
5280 expected->SequenceNumber.cbData),
5281 "%s: unexpected sequence number value\n", header);
5282 ok(!memcmp(&expected->ThisUpdate, &got->ThisUpdate, sizeof(FILETIME)),
5283 "%s: expected this update = (%d, %d), got (%d, %d)\n", header,
5284 expected->ThisUpdate.dwLowDateTime, expected->ThisUpdate.dwHighDateTime,
5285 got->ThisUpdate.dwLowDateTime, got->ThisUpdate.dwHighDateTime);
5286 ok(!memcmp(&expected->NextUpdate, &got->NextUpdate, sizeof(FILETIME)),
5287 "%s: expected next update = (%d, %d), got (%d, %d)\n", header,
5288 expected->NextUpdate.dwLowDateTime, expected->NextUpdate.dwHighDateTime,
5289 got->NextUpdate.dwLowDateTime, got->NextUpdate.dwHighDateTime);
5290 if (expected->SubjectAlgorithm.pszObjId &&
5291 *expected->SubjectAlgorithm.pszObjId && !got->SubjectAlgorithm.pszObjId)
5292 ok(0, "%s: expected subject algorithm %s, got NULL\n", header,
5293 expected->SubjectAlgorithm.pszObjId);
5294 if (expected->SubjectAlgorithm.pszObjId && got->SubjectAlgorithm.pszObjId)
5295 ok(!strcmp(expected->SubjectAlgorithm.pszObjId,
5296 got->SubjectAlgorithm.pszObjId),
5297 "%s: expected subject algorithm %s, got %s\n", header,
5298 expected->SubjectAlgorithm.pszObjId, got->SubjectAlgorithm.pszObjId);
5299 ok(expected->SubjectAlgorithm.Parameters.cbData ==
5300 got->SubjectAlgorithm.Parameters.cbData,
5301 "%s: expected subject algorithm parameters of %d bytes, got %d\n", header,
5302 expected->SubjectAlgorithm.Parameters.cbData,
5303 got->SubjectAlgorithm.Parameters.cbData);
5304 if (expected->SubjectAlgorithm.Parameters.cbData)
5305 ok(!memcmp(expected->SubjectAlgorithm.Parameters.pbData,
5306 got->SubjectAlgorithm.Parameters.pbData,
5307 expected->SubjectAlgorithm.Parameters.cbData),
5308 "%s: unexpected subject algorithm parameter value\n", header);
5309 ok(expected->cCTLEntry == got->cCTLEntry,
5310 "%s: expected %d CTL entries, got %d\n", header, expected->cCTLEntry,
5311 got->cCTLEntry);
5312 for (i = 0; i < expected->cCTLEntry; i++)
5314 ok(expected->rgCTLEntry[i].SubjectIdentifier.cbData ==
5315 got->rgCTLEntry[i].SubjectIdentifier.cbData,
5316 "%s[%d]: expected subject identifier of %d bytes, got %d\n",
5317 header, i, expected->rgCTLEntry[i].SubjectIdentifier.cbData,
5318 got->rgCTLEntry[i].SubjectIdentifier.cbData);
5319 if (expected->rgCTLEntry[i].SubjectIdentifier.cbData)
5320 ok(!memcmp(expected->rgCTLEntry[i].SubjectIdentifier.pbData,
5321 got->rgCTLEntry[i].SubjectIdentifier.pbData,
5322 expected->rgCTLEntry[i].SubjectIdentifier.cbData),
5323 "%s[%d]: unexpected subject identifier value\n",
5324 header, i);
5325 for (j = 0; j < expected->rgCTLEntry[i].cAttribute; j++)
5327 ok(!strcmp(expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5328 got->rgCTLEntry[i].rgAttribute[j].pszObjId),
5329 "%s[%d][%d]: expected attribute OID %s, got %s\n", header, i, j,
5330 expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5331 got->rgCTLEntry[i].rgAttribute[j].pszObjId);
5332 for (k = 0; k < expected->rgCTLEntry[i].rgAttribute[j].cValue; k++)
5334 ok(expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData ==
5335 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5336 "%s[%d][%d][%d]: expected value of %d bytes, got %d\n",
5337 header, i, j, k,
5338 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5339 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData);
5340 if (expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData)
5341 ok(!memcmp(
5342 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5343 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5344 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData),
5345 "%s[%d][%d][%d]: unexpected value\n",
5346 header, i, j, k);
5350 ok(expected->cExtension == got->cExtension,
5351 "%s: expected %d extensions, got %d\n", header, expected->cExtension,
5352 got->cExtension);
5353 for (i = 0; i < expected->cExtension; i++)
5355 ok(!strcmp(expected->rgExtension[i].pszObjId,
5356 got->rgExtension[i].pszObjId), "%s[%d]: expected %s, got %s\n",
5357 header, i, expected->rgExtension[i].pszObjId,
5358 got->rgExtension[i].pszObjId);
5359 ok(expected->rgExtension[i].fCritical == got->rgExtension[i].fCritical,
5360 "%s[%d]: expected fCritical = %d, got %d\n", header, i,
5361 expected->rgExtension[i].fCritical, got->rgExtension[i].fCritical);
5362 ok(expected->rgExtension[i].Value.cbData ==
5363 got->rgExtension[i].Value.cbData,
5364 "%s[%d]: expected extension value to have %d bytes, got %d\n",
5365 header, i, expected->rgExtension[i].Value.cbData,
5366 got->rgExtension[i].Value.cbData);
5367 if (expected->rgExtension[i].Value.cbData)
5368 ok(!memcmp(expected->rgExtension[i].Value.pbData,
5369 got->rgExtension[i].Value.pbData,
5370 expected->rgExtension[i].Value.cbData),
5371 "%s[%d]: unexpected extension value\n", header, i);
5375 static const BYTE signedCTL[] = {
5376 0x30,0x81,0xc7,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
5377 0x81,0xb9,0x30,0x81,0xb6,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
5378 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x28,0x06,0x09,0x2a,0x86,
5379 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x1b,0x04,0x19,0x30,0x17,0x30,0x00,
5380 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5381 0x30,0x5a,0x30,0x02,0x06,0x00,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
5382 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
5383 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
5384 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5385 0x00,0x04,0x40,0xca,0xd8,0x32,0xd1,0xbd,0x97,0x61,0x54,0xd6,0x80,0xcf,0x0d,
5386 0xbd,0xa2,0x42,0xc7,0xca,0x37,0x91,0x7d,0x9d,0xac,0x8c,0xdf,0x05,0x8a,0x39,
5387 0xc6,0x07,0xc1,0x37,0xe6,0xb9,0xd1,0x0d,0x26,0xec,0xa5,0xb0,0x8a,0x51,0x26,
5388 0x2b,0x4f,0x73,0x44,0x86,0x83,0x5e,0x2b,0x6e,0xcc,0xf8,0x1b,0x85,0x53,0xe9,
5389 0x7a,0x80,0x8f,0x6b,0x42,0x19,0x93 };
5390 static const BYTE signedCTLWithCTLInnerContent[] = {
5391 0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
5392 0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
5393 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
5394 0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
5395 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5396 0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
5397 0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
5398 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
5399 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
5400 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
5401 0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
5402 0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
5403 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
5404 0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5405 0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
5406 0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
5407 0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
5408 0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
5409 0x57,0x6c,0x0b,0x47,0xb8 };
5411 static void test_decodeCTL(DWORD dwEncoding)
5413 static char oid1[] = "1.2.3";
5414 static char oid2[] = "1.5.6";
5415 static BYTE nullData[] = { 5,0 };
5416 char *pOid1 = oid1;
5417 BOOL ret;
5418 BYTE *buf = NULL;
5419 DWORD size = 0;
5420 CTL_INFO info;
5421 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5422 CTL_ENTRY ctlEntry[2];
5423 CRYPT_ATTRIBUTE attr1, attr2;
5424 CRYPT_ATTR_BLOB value1, value2;
5426 memset(&info, 0, sizeof(info));
5427 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTL, sizeof(emptyCTL),
5428 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5429 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5430 if (buf)
5432 compareCTLInfo("empty CTL", &info, (CTL_INFO *)buf);
5433 LocalFree(buf);
5434 buf = NULL;
5436 info.dwVersion = 1;
5437 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTLWithVersion1,
5438 sizeof(emptyCTLWithVersion1), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
5439 &size);
5440 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5441 if (buf)
5443 compareCTLInfo("v1 CTL", &info, (CTL_INFO *)buf);
5444 LocalFree(buf);
5445 buf = NULL;
5447 info.dwVersion = 0;
5448 info.SubjectUsage.cUsageIdentifier = 1;
5449 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5450 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithUsageIdentifier,
5451 sizeof(ctlWithUsageIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5452 (BYTE *)&buf, &size);
5453 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5454 if (buf)
5456 compareCTLInfo("CTL with usage identifier", &info, (CTL_INFO *)buf);
5457 LocalFree(buf);
5458 buf = NULL;
5460 info.SubjectUsage.cUsageIdentifier = 0;
5461 info.ListIdentifier.cbData = sizeof(serialNum);
5462 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5463 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithListIdentifier,
5464 sizeof(ctlWithListIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5465 (BYTE *)&buf, &size);
5466 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5467 if (buf)
5469 compareCTLInfo("CTL with list identifier", &info, (CTL_INFO *)buf);
5470 LocalFree(buf);
5471 buf = NULL;
5473 info.ListIdentifier.cbData = 0;
5474 info.SequenceNumber.cbData = sizeof(serialNum);
5475 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5476 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithSequenceNumber,
5477 sizeof(ctlWithSequenceNumber), CRYPT_DECODE_ALLOC_FLAG, NULL,
5478 (BYTE *)&buf, &size);
5479 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5480 if (buf)
5482 compareCTLInfo("CTL with sequence number", &info, (CTL_INFO *)buf);
5483 LocalFree(buf);
5484 buf = NULL;
5486 info.SequenceNumber.cbData = 0;
5487 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5488 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisUpdate,
5489 sizeof(ctlWithThisUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5490 (BYTE *)&buf, &size);
5491 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5492 if (buf)
5494 compareCTLInfo("CTL with this update", &info, (CTL_INFO *)buf);
5495 LocalFree(buf);
5496 buf = NULL;
5498 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5499 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisAndNextUpdate,
5500 sizeof(ctlWithThisAndNextUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5501 (BYTE *)&buf, &size);
5502 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5503 if (buf)
5505 compareCTLInfo("CTL with this and next update", &info, (CTL_INFO *)buf);
5506 LocalFree(buf);
5507 buf = NULL;
5509 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5510 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5511 info.SubjectAlgorithm.pszObjId = oid2;
5512 info.SubjectAlgorithm.Parameters.cbData = sizeof(nullData);
5513 info.SubjectAlgorithm.Parameters.pbData = nullData;
5514 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithAlgId,
5515 sizeof(ctlWithAlgId), CRYPT_DECODE_ALLOC_FLAG, NULL,
5516 (BYTE *)&buf, &size);
5517 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5518 if (buf)
5520 compareCTLInfo("CTL with algorithm identifier", &info, (CTL_INFO *)buf);
5521 LocalFree(buf);
5522 buf = NULL;
5524 SetLastError(0xdeadbeef);
5525 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithBogusEntry,
5526 sizeof(ctlWithBogusEntry), CRYPT_DECODE_ALLOC_FLAG, NULL,
5527 (BYTE *)&buf, &size);
5528 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD || CRYPT_E_ASN1_CORRUPT),
5529 "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n",
5530 GetLastError());
5531 info.SubjectAlgorithm.Parameters.cbData = 0;
5532 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5533 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5534 info.SubjectAlgorithm.pszObjId = oid2;
5535 info.SubjectAlgorithm.pszObjId = NULL;
5536 value1.cbData = sizeof(emptySequence);
5537 value1.pbData = (LPBYTE)emptySequence;
5538 attr1.pszObjId = oid1;
5539 attr1.cValue = 1;
5540 attr1.rgValue = &value1;
5541 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5542 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5543 ctlEntry[0].cAttribute = 1;
5544 ctlEntry[0].rgAttribute = &attr1;
5545 info.cCTLEntry = 1;
5546 info.rgCTLEntry = ctlEntry;
5547 SetLastError(0xdeadbeef);
5548 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithOneEntry,
5549 sizeof(ctlWithOneEntry), CRYPT_DECODE_ALLOC_FLAG, NULL,
5550 (BYTE *)&buf, &size);
5551 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5552 if (buf)
5554 compareCTLInfo("CTL with one entry", &info, (CTL_INFO *)buf);
5555 LocalFree(buf);
5556 buf = NULL;
5558 value2.cbData = sizeof(encodedIPAddr);
5559 value2.pbData = (LPBYTE)encodedIPAddr;
5560 attr2.pszObjId = oid2;
5561 attr2.cValue = 1;
5562 attr2.rgValue = &value2;
5563 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5564 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5565 ctlEntry[1].cAttribute = 1;
5566 ctlEntry[1].rgAttribute = &attr2;
5567 info.cCTLEntry = 2;
5568 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithTwoEntries,
5569 sizeof(ctlWithTwoEntries), CRYPT_DECODE_ALLOC_FLAG, NULL,
5570 (BYTE *)&buf, &size);
5571 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5572 if (buf)
5574 compareCTLInfo("CTL with two entries", &info, (CTL_INFO *)buf);
5575 LocalFree(buf);
5576 buf = NULL;
5578 /* A signed CTL isn't decodable, even if the inner content is a CTL */
5579 SetLastError(0xdeadbeef);
5580 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, signedCTL,
5581 sizeof(signedCTL), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5582 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5583 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5584 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5585 GetLastError());
5586 SetLastError(0xdeadbeef);
5587 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL,
5588 signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent),
5589 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5590 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5591 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5592 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5593 GetLastError());
5596 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
5597 static const BYTE emptyPKCSContentInfoExtraBytes[] = { 0x30,0x04,0x06,0x02,0x2a,
5598 0x03,0,0,0,0,0,0 };
5599 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
5600 0xa0,0x01,0x01 };
5601 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
5602 0x03,0x02,0x01,0x01 };
5603 static BYTE bogusDER[] = { 1 };
5605 static void test_encodePKCSContentInfo(DWORD dwEncoding)
5607 BOOL ret;
5608 BYTE *buf = NULL;
5609 DWORD size = 0;
5610 CRYPT_CONTENT_INFO info = { 0 };
5611 char oid1[] = "1.2.3";
5613 if (0)
5615 /* Crashes on win9x */
5616 SetLastError(0xdeadbeef);
5617 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL,
5618 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5619 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5620 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5622 SetLastError(0xdeadbeef);
5623 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5624 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5625 ok(!ret && (GetLastError() == E_INVALIDARG ||
5626 GetLastError() == OSS_LIMITED /* Win9x */),
5627 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5628 info.pszObjId = oid1;
5629 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5630 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5631 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5632 if (buf)
5634 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size);
5635 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n");
5636 LocalFree(buf);
5638 info.Content.pbData = bogusDER;
5639 info.Content.cbData = sizeof(bogusDER);
5640 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5641 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5642 ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError());
5643 if (buf)
5645 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size);
5646 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n");
5647 LocalFree(buf);
5649 info.Content.pbData = (BYTE *)ints[0].encoded;
5650 info.Content.cbData = ints[0].encoded[1] + 2;
5651 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5652 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5653 if (buf)
5655 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size);
5656 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n");
5657 LocalFree(buf);
5661 static const BYTE indefiniteSignedPKCSContent[] = {
5662 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
5663 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
5664 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
5665 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
5666 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
5667 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
5668 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5669 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5670 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
5671 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5672 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5673 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
5674 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
5675 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
5676 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
5677 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
5678 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
5679 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
5680 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
5681 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5682 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5683 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
5684 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
5685 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
5686 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
5687 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
5688 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
5689 0x00,0x00,0x00,0x00,0x00,0x00 };
5691 static void test_decodePKCSContentInfo(DWORD dwEncoding)
5693 BOOL ret;
5694 LPBYTE buf = NULL;
5695 DWORD size = 0;
5696 CRYPT_CONTENT_INFO *info;
5698 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5699 emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo),
5700 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5701 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5702 if (buf)
5704 info = (CRYPT_CONTENT_INFO *)buf;
5706 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5707 info->pszObjId);
5708 ok(info->Content.cbData == 0, "Expected no data, got %d\n",
5709 info->Content.cbData);
5710 LocalFree(buf);
5712 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5713 emptyPKCSContentInfoExtraBytes, sizeof(emptyPKCSContentInfoExtraBytes),
5714 0, NULL, NULL, &size);
5715 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5716 SetLastError(0xdeadbeef);
5717 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5718 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo),
5719 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5720 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5721 * I doubt an app depends on that.
5723 ok((!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5724 GetLastError() == CRYPT_E_ASN1_CORRUPT)) || broken(ret),
5725 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5726 GetLastError());
5727 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5728 intPKCSContentInfo, sizeof(intPKCSContentInfo),
5729 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5730 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5731 if (buf)
5733 info = (CRYPT_CONTENT_INFO *)buf;
5735 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5736 info->pszObjId);
5737 ok(info->Content.cbData == ints[0].encoded[1] + 2,
5738 "Unexpected size %d\n", info->Content.cbData);
5739 ok(!memcmp(info->Content.pbData, ints[0].encoded,
5740 info->Content.cbData), "Unexpected value\n");
5741 LocalFree(buf);
5743 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5744 indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent),
5745 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5746 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5747 if (buf)
5749 info = (CRYPT_CONTENT_INFO *)buf;
5751 ok(!strcmp(info->pszObjId, szOID_RSA_signedData),
5752 "Expected %s, got %s\n", szOID_RSA_signedData, info->pszObjId);
5753 ok(info->Content.cbData == 392, "Expected 392, got %d\n",
5754 info->Content.cbData);
5755 LocalFree(buf);
5759 static const BYTE emptyPKCSAttr[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
5760 0x00 };
5761 static const BYTE bogusPKCSAttr[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
5762 0x01 };
5763 static const BYTE intPKCSAttr[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
5764 0x02,0x01,0x01 };
5766 static void test_encodePKCSAttribute(DWORD dwEncoding)
5768 CRYPT_ATTRIBUTE attr = { 0 };
5769 BOOL ret;
5770 LPBYTE buf = NULL;
5771 DWORD size = 0;
5772 CRYPT_ATTR_BLOB blob;
5773 char oid[] = "1.2.3";
5775 if (0)
5777 /* Crashes on win9x */
5778 SetLastError(0xdeadbeef);
5779 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, NULL,
5780 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5781 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5782 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5784 SetLastError(0xdeadbeef);
5785 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5786 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5787 ok(!ret && (GetLastError() == E_INVALIDARG ||
5788 GetLastError() == OSS_LIMITED /* Win9x */),
5789 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5790 attr.pszObjId = oid;
5791 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5792 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5793 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5794 if (buf)
5796 ok(size == sizeof(emptyPKCSAttr), "Unexpected size %d\n", size);
5797 ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n");
5798 LocalFree(buf);
5800 blob.cbData = sizeof(bogusDER);
5801 blob.pbData = bogusDER;
5802 attr.cValue = 1;
5803 attr.rgValue = &blob;
5804 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5805 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5806 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5807 if (buf)
5809 ok(size == sizeof(bogusPKCSAttr), "Unexpected size %d\n", size);
5810 ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n");
5811 LocalFree(buf);
5813 blob.pbData = (BYTE *)ints[0].encoded;
5814 blob.cbData = ints[0].encoded[1] + 2;
5815 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5816 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5817 if (buf)
5819 ok(size == sizeof(intPKCSAttr), "Unexpected size %d\n", size);
5820 ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n");
5821 LocalFree(buf);
5825 static void test_decodePKCSAttribute(DWORD dwEncoding)
5827 BOOL ret;
5828 LPBYTE buf = NULL;
5829 DWORD size = 0;
5830 CRYPT_ATTRIBUTE *attr;
5832 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5833 emptyPKCSAttr, sizeof(emptyPKCSAttr),
5834 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5835 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5836 if (buf)
5838 attr = (CRYPT_ATTRIBUTE *)buf;
5840 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5841 attr->pszObjId);
5842 ok(attr->cValue == 0, "Expected no value, got %d\n", attr->cValue);
5843 LocalFree(buf);
5845 SetLastError(0xdeadbeef);
5846 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5847 bogusPKCSAttr, sizeof(bogusPKCSAttr),
5848 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5849 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5850 * I doubt an app depends on that.
5852 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5853 GetLastError() == CRYPT_E_ASN1_CORRUPT || OSS_MORE_INPUT /* Win9x */),
5854 "Expected CRYPT_E_ASN1_EOD, CRYPT_E_ASN1_CORRUPT, or OSS_MORE_INPUT, got %x\n",
5855 GetLastError());
5856 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5857 intPKCSAttr, sizeof(intPKCSAttr),
5858 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5859 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5860 if (buf)
5862 attr = (CRYPT_ATTRIBUTE *)buf;
5864 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5865 attr->pszObjId);
5866 ok(attr->cValue == 1, "Expected 1 value, got %d\n", attr->cValue);
5867 ok(attr->rgValue[0].cbData == ints[0].encoded[1] + 2,
5868 "Unexpected size %d\n", attr->rgValue[0].cbData);
5869 ok(!memcmp(attr->rgValue[0].pbData, ints[0].encoded,
5870 attr->rgValue[0].cbData), "Unexpected value\n");
5871 LocalFree(buf);
5875 static const BYTE emptyPKCSAttributes[] = { 0x31,0x00 };
5876 static const BYTE singlePKCSAttributes[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
5877 0x2a,0x03,0x31,0x00 };
5878 static const BYTE doublePKCSAttributes[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
5879 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
5881 static void test_encodePKCSAttributes(DWORD dwEncoding)
5883 CRYPT_ATTRIBUTES attributes = { 0 };
5884 CRYPT_ATTRIBUTE attr[2] = { { 0 } };
5885 CRYPT_ATTR_BLOB blob;
5886 BOOL ret;
5887 LPBYTE buf = NULL;
5888 DWORD size = 0;
5889 char oid1[] = "1.2.3", oid2[] = "1.5.6";
5891 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5892 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5893 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5894 if (buf)
5896 ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %d\n", size);
5897 ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n");
5898 LocalFree(buf);
5900 attributes.cAttr = 1;
5901 attributes.rgAttr = attr;
5902 SetLastError(0xdeadbeef);
5903 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5904 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5905 ok(!ret && (GetLastError() == E_INVALIDARG ||
5906 GetLastError() == OSS_LIMITED /* Win9x */),
5907 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
5908 attr[0].pszObjId = oid1;
5909 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5910 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5911 if (buf)
5913 ok(size == sizeof(singlePKCSAttributes), "Unexpected size %d\n", size);
5914 ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n");
5915 LocalFree(buf);
5917 attr[1].pszObjId = oid2;
5918 attr[1].cValue = 1;
5919 attr[1].rgValue = &blob;
5920 blob.pbData = (BYTE *)ints[0].encoded;
5921 blob.cbData = ints[0].encoded[1] + 2;
5922 attributes.cAttr = 2;
5923 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5924 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5925 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5926 if (buf)
5928 ok(size == sizeof(doublePKCSAttributes), "Unexpected size %d\n", size);
5929 ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n");
5930 LocalFree(buf);
5934 static void test_decodePKCSAttributes(DWORD dwEncoding)
5936 BOOL ret;
5937 LPBYTE buf = NULL;
5938 DWORD size = 0;
5939 CRYPT_ATTRIBUTES *attributes;
5941 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5942 emptyPKCSAttributes, sizeof(emptyPKCSAttributes),
5943 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5944 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5945 if (buf)
5947 attributes = (CRYPT_ATTRIBUTES *)buf;
5948 ok(attributes->cAttr == 0, "Expected no attributes, got %d\n",
5949 attributes->cAttr);
5950 LocalFree(buf);
5952 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5953 singlePKCSAttributes, sizeof(singlePKCSAttributes),
5954 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5955 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5956 if (buf)
5958 attributes = (CRYPT_ATTRIBUTES *)buf;
5959 ok(attributes->cAttr == 1, "Expected 1 attribute, got %d\n",
5960 attributes->cAttr);
5961 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5962 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5963 ok(attributes->rgAttr[0].cValue == 0,
5964 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5965 LocalFree(buf);
5967 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5968 doublePKCSAttributes, sizeof(doublePKCSAttributes),
5969 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5970 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5971 if (buf)
5973 attributes = (CRYPT_ATTRIBUTES *)buf;
5974 ok(attributes->cAttr == 2, "Expected 2 attributes, got %d\n",
5975 attributes->cAttr);
5976 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5977 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5978 ok(attributes->rgAttr[0].cValue == 0,
5979 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5980 ok(!strcmp(attributes->rgAttr[1].pszObjId, "1.5.6"),
5981 "Expected 1.5.6, got %s\n", attributes->rgAttr[1].pszObjId);
5982 ok(attributes->rgAttr[1].cValue == 1,
5983 "Expected 1 attribute, got %d\n", attributes->rgAttr[1].cValue);
5984 ok(attributes->rgAttr[1].rgValue[0].cbData == ints[0].encoded[1] + 2,
5985 "Unexpected size %d\n", attributes->rgAttr[1].rgValue[0].cbData);
5986 ok(!memcmp(attributes->rgAttr[1].rgValue[0].pbData, ints[0].encoded,
5987 attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n");
5988 LocalFree(buf);
5992 static const BYTE singleCapability[] = {
5993 0x30,0x06,0x30,0x04,0x06,0x02,0x2d,0x06 };
5994 static const BYTE twoCapabilities[] = {
5995 0x30,0x0c,0x30,0x04,0x06,0x02,0x2d,0x06,0x30,0x04,0x06,0x02,0x2a,0x03 };
5996 static const BYTE singleCapabilitywithNULL[] = {
5997 0x30,0x08,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5999 static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding)
6001 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6002 BOOL ret;
6003 LPBYTE buf = NULL;
6004 DWORD size = 0;
6005 CRYPT_SMIME_CAPABILITY capability[2];
6006 CRYPT_SMIME_CAPABILITIES capabilities;
6008 /* An empty capabilities is allowed */
6009 capabilities.cCapability = 0;
6010 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6011 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6012 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6013 if (buf)
6015 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
6016 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
6017 LocalFree(buf);
6019 /* A non-empty capabilities with an empty capability (lacking an OID) is
6020 * not allowed
6022 capability[0].pszObjId = NULL;
6023 capability[0].Parameters.cbData = 0;
6024 capabilities.cCapability = 1;
6025 capabilities.rgCapability = capability;
6026 SetLastError(0xdeadbeef);
6027 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6028 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6029 ok(!ret && (GetLastError() == E_INVALIDARG ||
6030 GetLastError() == OSS_LIMITED /* Win9x */),
6031 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6032 capability[0].pszObjId = oid1;
6033 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6034 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6035 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6036 if (buf)
6038 ok(size == sizeof(singleCapability), "unexpected size %d\n", size);
6039 ok(!memcmp(buf, singleCapability, size), "unexpected value\n");
6040 LocalFree(buf);
6042 capability[1].pszObjId = oid2;
6043 capability[1].Parameters.cbData = 0;
6044 capabilities.cCapability = 2;
6045 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6046 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6047 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6048 if (buf)
6050 ok(size == sizeof(twoCapabilities), "unexpected size %d\n", size);
6051 ok(!memcmp(buf, twoCapabilities, size), "unexpected value\n");
6052 LocalFree(buf);
6056 static void compareSMimeCapabilities(LPCSTR header,
6057 const CRYPT_SMIME_CAPABILITIES *expected, const CRYPT_SMIME_CAPABILITIES *got)
6059 DWORD i;
6061 ok(got->cCapability == expected->cCapability,
6062 "%s: expected %d capabilities, got %d\n", header, expected->cCapability,
6063 got->cCapability);
6064 for (i = 0; i < expected->cCapability; i++)
6066 ok(!strcmp(expected->rgCapability[i].pszObjId,
6067 got->rgCapability[i].pszObjId), "%s[%d]: expected %s, got %s\n",
6068 header, i, expected->rgCapability[i].pszObjId,
6069 got->rgCapability[i].pszObjId);
6070 ok(expected->rgCapability[i].Parameters.cbData ==
6071 got->rgCapability[i].Parameters.cbData,
6072 "%s[%d]: expected %d bytes, got %d\n", header, i,
6073 expected->rgCapability[i].Parameters.cbData,
6074 got->rgCapability[i].Parameters.cbData);
6075 if (expected->rgCapability[i].Parameters.cbData)
6076 ok(!memcmp(expected->rgCapability[i].Parameters.pbData,
6077 got->rgCapability[i].Parameters.pbData,
6078 expected->rgCapability[i].Parameters.cbData),
6079 "%s[%d]: unexpected value\n", header, i);
6083 static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding)
6085 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6086 BOOL ret;
6087 DWORD size = 0;
6088 CRYPT_SMIME_CAPABILITY capability[2];
6089 CRYPT_SMIME_CAPABILITIES capabilities, *ptr;
6091 SetLastError(0xdeadbeef);
6092 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6093 emptySequence, sizeof(emptySequence),
6094 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&ptr, &size);
6095 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6096 if (ret)
6098 capabilities.cCapability = 0;
6099 compareSMimeCapabilities("empty capabilities", &capabilities, ptr);
6100 LocalFree(ptr);
6102 SetLastError(0xdeadbeef);
6103 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6104 singleCapability, sizeof(singleCapability), CRYPT_DECODE_ALLOC_FLAG, NULL,
6105 (BYTE *)&ptr, &size);
6106 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6107 if (ret)
6109 capability[0].pszObjId = oid1;
6110 capability[0].Parameters.cbData = 0;
6111 capabilities.cCapability = 1;
6112 capabilities.rgCapability = capability;
6113 compareSMimeCapabilities("single capability", &capabilities, ptr);
6114 LocalFree(ptr);
6116 SetLastError(0xdeadbeef);
6117 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6118 singleCapabilitywithNULL, sizeof(singleCapabilitywithNULL),
6119 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&ptr, &size);
6120 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6121 if (ret)
6123 BYTE NULLparam[] = {0x05, 0x00};
6124 capability[0].pszObjId = oid1;
6125 capability[0].Parameters.cbData = 2;
6126 capability[0].Parameters.pbData = NULLparam;
6127 capabilities.cCapability = 1;
6128 capabilities.rgCapability = capability;
6129 compareSMimeCapabilities("single capability with NULL", &capabilities,
6130 ptr);
6131 LocalFree(ptr);
6133 SetLastError(0xdeadbeef);
6134 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6135 twoCapabilities, sizeof(twoCapabilities), CRYPT_DECODE_ALLOC_FLAG, NULL,
6136 (BYTE *)&ptr, &size);
6137 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6138 if (ret)
6140 capability[0].Parameters.cbData = 0;
6141 capability[1].pszObjId = oid2;
6142 capability[1].Parameters.cbData = 0;
6143 capabilities.cCapability = 2;
6144 compareSMimeCapabilities("two capabilities", &capabilities, ptr);
6145 LocalFree(ptr);
6149 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
6150 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
6151 0x67 };
6152 static const BYTE minimalPKCSSigner[] = {
6153 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6154 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6155 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6156 static const BYTE PKCSSignerWithSerial[] = {
6157 0x30,0x2c,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,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
6160 0x00 };
6161 static const BYTE PKCSSignerWithHashAlgo[] = {
6162 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6163 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6164 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
6165 0x00,0x04,0x00 };
6166 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = {
6167 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6168 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6169 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6170 0x06,0x05,0x00,0x04,0x00 };
6171 static const BYTE PKCSSignerWithHash[] = {
6172 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6173 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6174 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6175 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
6176 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6177 static const BYTE PKCSSignerWithAuthAttr[] = {
6178 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6179 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6180 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
6181 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
6182 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
6183 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
6184 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6186 static void test_encodePKCSSignerInfo(DWORD dwEncoding)
6188 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6189 BOOL ret;
6190 LPBYTE buf = NULL;
6191 DWORD size = 0;
6192 CMSG_SIGNER_INFO info = { 0 };
6193 char oid_common_name[] = szOID_COMMON_NAME;
6194 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
6195 (LPBYTE)encodedCommonName };
6196 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
6198 SetLastError(0xdeadbeef);
6199 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6200 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6201 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6203 skip("no PKCS7_SIGNER_INFO encode support\n");
6204 return;
6206 ok(!ret && (GetLastError() == E_INVALIDARG ||
6207 GetLastError() == OSS_LIMITED /* Win9x */),
6208 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6209 /* To be encoded, a signer must have an issuer at least, and the encoding
6210 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
6211 * see decoding tests.)
6213 info.Issuer.cbData = sizeof(encodedCommonNameNoNull);
6214 info.Issuer.pbData = encodedCommonNameNoNull;
6215 SetLastError(0xdeadbeef);
6216 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6217 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6218 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6219 ok(!ret && GetLastError() == E_INVALIDARG,
6220 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6221 else
6223 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6224 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6225 if (buf)
6227 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6228 if (size == sizeof(minimalPKCSSigner))
6229 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6230 else
6231 ok(0, "Unexpected value\n");
6232 LocalFree(buf);
6235 info.SerialNumber.cbData = sizeof(serialNum);
6236 info.SerialNumber.pbData = (BYTE *)serialNum;
6237 SetLastError(0xdeadbeef);
6238 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6239 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6240 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6241 ok(!ret && GetLastError() == E_INVALIDARG,
6242 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6243 else
6245 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6246 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6247 if (buf)
6249 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6250 size);
6251 if (size == sizeof(PKCSSignerWithSerial))
6252 ok(!memcmp(buf, PKCSSignerWithSerial, size),
6253 "Unexpected value\n");
6254 else
6255 ok(0, "Unexpected value\n");
6256 LocalFree(buf);
6259 info.HashAlgorithm.pszObjId = oid1;
6260 SetLastError(0xdeadbeef);
6261 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6262 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6263 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6264 ok(!ret && GetLastError() == E_INVALIDARG,
6265 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6266 else
6268 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6269 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6270 if (buf)
6272 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6273 size);
6274 if (size == sizeof(PKCSSignerWithHashAlgo))
6275 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6276 "Unexpected value\n");
6277 else
6278 ok(0, "Unexpected value\n");
6279 LocalFree(buf);
6282 info.HashEncryptionAlgorithm.pszObjId = oid2;
6283 SetLastError(0xdeadbeef);
6284 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6285 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6286 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6287 ok(!ret && GetLastError() == E_INVALIDARG,
6288 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6289 else
6291 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6292 if (buf)
6294 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6295 "Unexpected size %d\n", size);
6296 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo))
6297 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6298 "Unexpected value\n");
6299 else
6300 ok(0, "Unexpected value\n");
6301 LocalFree(buf);
6304 info.EncryptedHash.cbData = sizeof(hash);
6305 info.EncryptedHash.pbData = (BYTE *)hash;
6306 SetLastError(0xdeadbeef);
6307 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6308 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6309 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6310 ok(!ret && GetLastError() == E_INVALIDARG,
6311 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6312 else
6314 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6315 if (buf)
6317 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6318 size);
6319 if (size == sizeof(PKCSSignerWithHash))
6320 ok(!memcmp(buf, PKCSSignerWithHash, size),
6321 "Unexpected value\n");
6322 else
6323 ok(0, "Unexpected value\n");
6324 LocalFree(buf);
6327 info.AuthAttrs.cAttr = 1;
6328 info.AuthAttrs.rgAttr = &attr;
6329 SetLastError(0xdeadbeef);
6330 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6331 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6332 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6333 ok(!ret && GetLastError() == E_INVALIDARG,
6334 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6335 else
6337 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6338 if (buf)
6340 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
6341 size);
6342 if (size == sizeof(PKCSSignerWithAuthAttr))
6343 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
6344 "Unexpected value\n");
6345 else
6346 ok(0, "Unexpected value\n");
6347 LocalFree(buf);
6352 static void test_decodePKCSSignerInfo(DWORD dwEncoding)
6354 BOOL ret;
6355 LPBYTE buf = NULL;
6356 DWORD size = 0;
6357 CMSG_SIGNER_INFO *info;
6359 /* A PKCS signer can't be decoded without a serial number. */
6360 SetLastError(0xdeadbeef);
6361 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6362 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6363 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6364 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
6365 GetLastError() == OSS_DATA_ERROR /* Win9x */),
6366 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %x\n",
6367 GetLastError());
6368 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6369 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6370 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6371 ok(ret || broken(GetLastError() == OSS_DATA_ERROR),
6372 "CryptDecodeObjectEx failed: %x\n", GetLastError());
6373 if (buf)
6375 info = (CMSG_SIGNER_INFO *)buf;
6376 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6377 info->dwVersion);
6378 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6379 "Unexpected size %d\n", info->Issuer.cbData);
6380 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6381 info->Issuer.cbData), "Unexpected value\n");
6382 ok(info->SerialNumber.cbData == sizeof(serialNum),
6383 "Unexpected size %d\n", info->SerialNumber.cbData);
6384 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6385 "Unexpected value\n");
6386 LocalFree(buf);
6388 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6389 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6390 CRYPT_DECODE_ALLOC_FLAG, 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 LocalFree(buf);
6408 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6409 PKCSSignerWithHashAndEncryptionAlgo,
6410 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6411 NULL, (BYTE *)&buf, &size);
6412 if (buf)
6414 info = (CMSG_SIGNER_INFO *)buf;
6415 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6416 info->dwVersion);
6417 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6418 "Unexpected size %d\n", info->Issuer.cbData);
6419 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6420 info->Issuer.cbData), "Unexpected value\n");
6421 ok(info->SerialNumber.cbData == sizeof(serialNum),
6422 "Unexpected size %d\n", info->SerialNumber.cbData);
6423 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6424 "Unexpected value\n");
6425 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6426 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6427 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6428 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6429 LocalFree(buf);
6431 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6432 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6433 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6434 if (buf)
6436 info = (CMSG_SIGNER_INFO *)buf;
6437 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6438 info->dwVersion);
6439 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6440 "Unexpected size %d\n", info->Issuer.cbData);
6441 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6442 info->Issuer.cbData), "Unexpected value\n");
6443 ok(info->SerialNumber.cbData == sizeof(serialNum),
6444 "Unexpected size %d\n", info->SerialNumber.cbData);
6445 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6446 "Unexpected value\n");
6447 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6448 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6449 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6450 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6451 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6452 info->EncryptedHash.cbData);
6453 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6454 "Unexpected value\n");
6455 LocalFree(buf);
6457 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6458 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
6459 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6460 if (buf)
6462 info = (CMSG_SIGNER_INFO *)buf;
6463 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n",
6464 info->AuthAttrs.cAttr);
6465 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
6466 "Expected %s, got %s\n", szOID_COMMON_NAME,
6467 info->AuthAttrs.rgAttr[0].pszObjId);
6468 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
6469 info->AuthAttrs.rgAttr[0].cValue);
6470 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
6471 sizeof(encodedCommonName), "Unexpected size %d\n",
6472 info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
6473 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
6474 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
6475 LocalFree(buf);
6479 static const BYTE CMSSignerWithKeyId[] = {
6480 0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,
6481 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6483 static void test_encodeCMSSignerInfo(DWORD dwEncoding)
6485 BOOL ret;
6486 LPBYTE buf = NULL;
6487 DWORD size = 0;
6488 CMSG_CMS_SIGNER_INFO info = { 0 };
6489 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6491 SetLastError(0xdeadbeef);
6492 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6493 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6494 ok(!ret, "Expected failure, got %d\n", ret);
6495 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6497 skip("no CMS_SIGNER_INFO encode support\n");
6498 return;
6500 ok(GetLastError() == E_INVALIDARG,
6501 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6502 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6503 SetLastError(0xdeadbeef);
6504 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6505 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6506 ok(!ret, "Expected failure, got %d\n", ret);
6507 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6509 skip("no CMS_SIGNER_INFO encode support\n");
6510 return;
6512 ok(GetLastError() == E_INVALIDARG,
6513 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6514 /* To be encoded, a signer must have a valid cert ID, where a valid ID may
6515 * be a key id or a issuer serial number with at least the issuer set, and
6516 * the encoding must include PKCS_7_ASN_ENCODING.
6517 * (That isn't enough to be decoded, see decoding tests.)
6519 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6520 sizeof(encodedCommonNameNoNull);
6521 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6522 SetLastError(0xdeadbeef);
6523 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6524 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6525 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6526 ok(!ret && GetLastError() == E_INVALIDARG,
6527 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6528 else
6530 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6531 if (buf)
6533 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6534 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6535 LocalFree(buf);
6538 U(info.SignerId).IssuerSerialNumber.SerialNumber.cbData = sizeof(serialNum);
6539 U(info.SignerId).IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
6540 SetLastError(0xdeadbeef);
6541 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6542 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6543 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6544 ok(!ret && GetLastError() == E_INVALIDARG,
6545 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6546 else
6548 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6549 if (buf)
6551 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6552 size);
6553 ok(!memcmp(buf, PKCSSignerWithSerial, size), "Unexpected value\n");
6554 LocalFree(buf);
6557 info.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
6558 U(info.SignerId).KeyId.cbData = sizeof(serialNum);
6559 U(info.SignerId).KeyId.pbData = (BYTE *)serialNum;
6560 SetLastError(0xdeadbeef);
6561 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6562 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6563 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6564 ok(!ret && GetLastError() == E_INVALIDARG,
6565 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6566 else
6568 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6569 if (buf)
6571 ok(size == sizeof(CMSSignerWithKeyId), "Unexpected size %d\n",
6572 size);
6573 ok(!memcmp(buf, CMSSignerWithKeyId, size), "Unexpected value\n");
6574 LocalFree(buf);
6577 /* While a CERT_ID can have a hash type, that's not allowed in CMS, where
6578 * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed
6579 * (see RFC 3852, section 5.3.)
6581 info.SignerId.dwIdChoice = CERT_ID_SHA1_HASH;
6582 U(info.SignerId).HashId.cbData = sizeof(hash);
6583 U(info.SignerId).HashId.pbData = (BYTE *)hash;
6584 SetLastError(0xdeadbeef);
6585 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6586 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6587 ok(!ret && GetLastError() == E_INVALIDARG,
6588 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6589 /* Now with a hash algo */
6590 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6591 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6592 sizeof(encodedCommonNameNoNull);
6593 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6594 info.HashAlgorithm.pszObjId = oid1;
6595 SetLastError(0xdeadbeef);
6596 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6597 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6598 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6599 ok(!ret && GetLastError() == E_INVALIDARG,
6600 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6601 else
6603 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6604 if (buf)
6606 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6607 size);
6608 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6609 "Unexpected value\n");
6610 LocalFree(buf);
6613 info.HashEncryptionAlgorithm.pszObjId = oid2;
6614 SetLastError(0xdeadbeef);
6615 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6616 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6617 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6618 ok(!ret && GetLastError() == E_INVALIDARG,
6619 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6620 else
6622 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6623 if (buf)
6625 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6626 "Unexpected size %d\n", size);
6627 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6628 "Unexpected value\n");
6629 LocalFree(buf);
6632 info.EncryptedHash.cbData = sizeof(hash);
6633 info.EncryptedHash.pbData = (BYTE *)hash;
6634 SetLastError(0xdeadbeef);
6635 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6636 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6637 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6638 ok(!ret && GetLastError() == E_INVALIDARG,
6639 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6640 else
6642 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6643 if (buf)
6645 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6646 size);
6647 ok(!memcmp(buf, PKCSSignerWithHash, size), "Unexpected value\n");
6648 LocalFree(buf);
6653 static void test_decodeCMSSignerInfo(DWORD dwEncoding)
6655 BOOL ret;
6656 LPBYTE buf = NULL;
6657 DWORD size = 0;
6658 CMSG_CMS_SIGNER_INFO *info;
6659 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6661 /* A CMS signer can't be decoded without a serial number. */
6662 SetLastError(0xdeadbeef);
6663 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6664 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6665 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6666 ok(!ret, "expected failure\n");
6667 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6669 skip("no CMS_SIGNER_INFO decode support\n");
6670 return;
6672 ok(GetLastError() == CRYPT_E_ASN1_CORRUPT,
6673 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
6674 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6675 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6676 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6677 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6678 if (buf)
6680 info = (CMSG_CMS_SIGNER_INFO *)buf;
6681 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6682 info->dwVersion);
6683 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6684 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6685 info->SignerId.dwIdChoice);
6686 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6687 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6688 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6689 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6690 encodedCommonNameNoNull,
6691 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6692 "Unexpected value\n");
6693 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6694 sizeof(serialNum), "Unexpected size %d\n",
6695 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6696 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6697 serialNum, sizeof(serialNum)), "Unexpected value\n");
6698 LocalFree(buf);
6700 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6701 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6702 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6703 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6704 if (buf)
6706 info = (CMSG_CMS_SIGNER_INFO *)buf;
6707 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6708 info->dwVersion);
6709 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6710 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6711 info->SignerId.dwIdChoice);
6712 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6713 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6714 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6715 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6716 encodedCommonNameNoNull,
6717 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6718 "Unexpected value\n");
6719 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6720 sizeof(serialNum), "Unexpected size %d\n",
6721 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6722 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6723 serialNum, sizeof(serialNum)), "Unexpected value\n");
6724 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6725 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6726 LocalFree(buf);
6728 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6729 PKCSSignerWithHashAndEncryptionAlgo,
6730 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6731 NULL, (BYTE *)&buf, &size);
6732 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6733 if (buf)
6735 info = (CMSG_CMS_SIGNER_INFO *)buf;
6736 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6737 info->dwVersion);
6738 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6739 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6740 info->SignerId.dwIdChoice);
6741 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6742 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6743 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6744 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6745 encodedCommonNameNoNull,
6746 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6747 "Unexpected value\n");
6748 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6749 sizeof(serialNum), "Unexpected size %d\n",
6750 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6751 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6752 serialNum, sizeof(serialNum)), "Unexpected value\n");
6753 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6754 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6755 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6756 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6757 LocalFree(buf);
6759 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6760 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6761 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6762 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6763 if (buf)
6765 info = (CMSG_CMS_SIGNER_INFO *)buf;
6766 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6767 info->dwVersion);
6768 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6769 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6770 info->SignerId.dwIdChoice);
6771 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6772 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6773 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6774 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6775 encodedCommonNameNoNull,
6776 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6777 "Unexpected value\n");
6778 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6779 sizeof(serialNum), "Unexpected size %d\n",
6780 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6781 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6782 serialNum, sizeof(serialNum)), "Unexpected value\n");
6783 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6784 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6785 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6786 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6787 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6788 info->EncryptedHash.cbData);
6789 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6790 "Unexpected value\n");
6791 LocalFree(buf);
6793 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6794 CMSSignerWithKeyId, sizeof(CMSSignerWithKeyId),
6795 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6796 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6797 if (buf)
6799 info = (CMSG_CMS_SIGNER_INFO *)buf;
6800 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6801 info->dwVersion);
6802 ok(info->SignerId.dwIdChoice == CERT_ID_KEY_IDENTIFIER,
6803 "Expected CERT_ID_KEY_IDENTIFIER, got %d\n",
6804 info->SignerId.dwIdChoice);
6805 ok(U(info->SignerId).KeyId.cbData == sizeof(serialNum),
6806 "Unexpected size %d\n", U(info->SignerId).KeyId.cbData);
6807 ok(!memcmp(U(info->SignerId).KeyId.pbData, serialNum, sizeof(serialNum)),
6808 "Unexpected value\n");
6809 LocalFree(buf);
6813 static BYTE emptyDNSPermittedConstraints[] = {
6814 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
6815 static BYTE emptyDNSExcludedConstraints[] = {
6816 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
6817 static BYTE DNSExcludedConstraints[] = {
6818 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
6819 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6820 static BYTE permittedAndExcludedConstraints[] = {
6821 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6822 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
6823 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6824 static BYTE permittedAndExcludedWithMinConstraints[] = {
6825 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6826 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
6827 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6828 static BYTE permittedAndExcludedWithMinMaxConstraints[] = {
6829 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6830 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
6831 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6833 static void test_encodeNameConstraints(DWORD dwEncoding)
6835 BOOL ret;
6836 CERT_NAME_CONSTRAINTS_INFO constraints = { 0 };
6837 CERT_GENERAL_SUBTREE permitted = { { 0 } };
6838 CERT_GENERAL_SUBTREE excluded = { { 0 } };
6839 LPBYTE buf;
6840 DWORD size;
6842 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6843 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6844 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6846 skip("no X509_NAME_CONSTRAINTS encode support\n");
6847 return;
6849 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6850 if (ret)
6852 ok(size == sizeof(emptySequence), "Unexpected size\n");
6853 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
6854 LocalFree(buf);
6856 constraints.cPermittedSubtree = 1;
6857 constraints.rgPermittedSubtree = &permitted;
6858 SetLastError(0xdeadbeef);
6859 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6860 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6861 ok(!ret && GetLastError() == E_INVALIDARG,
6862 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6863 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
6864 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6865 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6866 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6867 if (ret)
6869 ok(size == sizeof(emptyDNSPermittedConstraints), "Unexpected size\n");
6870 ok(!memcmp(buf, emptyDNSPermittedConstraints, size),
6871 "Unexpected value\n");
6872 LocalFree(buf);
6874 constraints.cPermittedSubtree = 0;
6875 constraints.cExcludedSubtree = 1;
6876 constraints.rgExcludedSubtree = &excluded;
6877 excluded.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
6878 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6879 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6880 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6881 if (ret)
6883 ok(size == sizeof(emptyDNSExcludedConstraints), "Unexpected size\n");
6884 ok(!memcmp(buf, emptyDNSExcludedConstraints, size),
6885 "Unexpected value\n");
6886 LocalFree(buf);
6888 U(excluded.Base).pwszURL = (LPWSTR)url;
6889 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6890 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6891 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6892 if (ret)
6894 ok(size == sizeof(DNSExcludedConstraints), "Unexpected size\n");
6895 ok(!memcmp(buf, DNSExcludedConstraints, size),
6896 "Unexpected value\n");
6897 LocalFree(buf);
6899 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
6900 U(permitted.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6901 U(permitted.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6902 constraints.cPermittedSubtree = 1;
6903 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6904 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6905 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6906 if (ret)
6908 ok(size == sizeof(permittedAndExcludedConstraints),
6909 "Unexpected size\n");
6910 ok(!memcmp(buf, permittedAndExcludedConstraints, size),
6911 "Unexpected value\n");
6912 LocalFree(buf);
6914 permitted.dwMinimum = 5;
6915 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6916 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6917 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6918 if (ret)
6920 ok(size == sizeof(permittedAndExcludedWithMinConstraints),
6921 "Unexpected size\n");
6922 ok(!memcmp(buf, permittedAndExcludedWithMinConstraints, size),
6923 "Unexpected value\n");
6924 LocalFree(buf);
6926 permitted.fMaximum = TRUE;
6927 permitted.dwMaximum = 3;
6928 SetLastError(0xdeadbeef);
6929 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6930 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6931 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6932 if (ret)
6934 ok(size == sizeof(permittedAndExcludedWithMinMaxConstraints),
6935 "Unexpected size\n");
6936 ok(!memcmp(buf, permittedAndExcludedWithMinMaxConstraints, size),
6937 "Unexpected value\n");
6938 LocalFree(buf);
6942 struct EncodedNameConstraints
6944 CRYPT_DATA_BLOB encoded;
6945 CERT_NAME_CONSTRAINTS_INFO constraints;
6948 static CERT_GENERAL_SUBTREE emptyDNSSubtree = {
6949 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
6950 static CERT_GENERAL_SUBTREE DNSSubtree = {
6951 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
6952 static CERT_GENERAL_SUBTREE IPAddressSubtree = {
6953 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 0 };
6954 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree = {
6955 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, 0 };
6956 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree = {
6957 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, TRUE, 3 };
6959 struct EncodedNameConstraints encodedNameConstraints[] = {
6960 { { sizeof(emptySequence), (LPBYTE)emptySequence }, { 0 } },
6961 { { sizeof(emptyDNSPermittedConstraints), emptyDNSPermittedConstraints },
6962 { 1, &emptyDNSSubtree, 0, NULL } },
6963 { { sizeof(emptyDNSExcludedConstraints), emptyDNSExcludedConstraints },
6964 { 0, NULL, 1, &emptyDNSSubtree } },
6965 { { sizeof(DNSExcludedConstraints), DNSExcludedConstraints },
6966 { 0, NULL, 1, &DNSSubtree } },
6967 { { sizeof(permittedAndExcludedConstraints), permittedAndExcludedConstraints },
6968 { 1, &IPAddressSubtree, 1, &DNSSubtree } },
6969 { { sizeof(permittedAndExcludedWithMinConstraints),
6970 permittedAndExcludedWithMinConstraints },
6971 { 1, &IPAddressWithMinSubtree, 1, &DNSSubtree } },
6972 { { sizeof(permittedAndExcludedWithMinMaxConstraints),
6973 permittedAndExcludedWithMinMaxConstraints },
6974 { 1, &IPAddressWithMinMaxSubtree, 1, &DNSSubtree } },
6977 static void test_decodeNameConstraints(DWORD dwEncoding)
6979 BOOL ret;
6980 DWORD i;
6981 CERT_NAME_CONSTRAINTS_INFO *constraints;
6983 U(DNSSubtree.Base).pwszURL = (LPWSTR)url;
6984 U(IPAddressSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6985 U(IPAddressSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6986 U(IPAddressWithMinSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6987 U(IPAddressWithMinSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6988 U(IPAddressWithMinMaxSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6989 U(IPAddressWithMinMaxSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6990 for (i = 0;
6991 i < sizeof(encodedNameConstraints) / sizeof(encodedNameConstraints[0]);
6992 i++)
6994 DWORD size;
6996 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS,
6997 encodedNameConstraints[i].encoded.pbData,
6998 encodedNameConstraints[i].encoded.cbData,
6999 CRYPT_DECODE_ALLOC_FLAG, NULL, &constraints, &size);
7000 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7002 skip("no X509_NAME_CONSTRAINTS decode support\n");
7003 return;
7005 ok(ret, "%d: CryptDecodeObjectEx failed: %08x\n", i, GetLastError());
7006 if (ret)
7008 DWORD j;
7010 if (constraints->cPermittedSubtree !=
7011 encodedNameConstraints[i].constraints.cPermittedSubtree)
7012 fprintf(stderr, "%d: expected %d permitted, got %d\n", i,
7013 encodedNameConstraints[i].constraints.cPermittedSubtree,
7014 constraints->cPermittedSubtree);
7015 if (constraints->cPermittedSubtree ==
7016 encodedNameConstraints[i].constraints.cPermittedSubtree)
7018 for (j = 0; j < constraints->cPermittedSubtree; j++)
7020 compareAltNameEntry(&constraints->rgPermittedSubtree[j].Base,
7021 &encodedNameConstraints[i].constraints.rgPermittedSubtree[j].Base);
7024 if (constraints->cExcludedSubtree !=
7025 encodedNameConstraints[i].constraints.cExcludedSubtree)
7026 fprintf(stderr, "%d: expected %d excluded, got %d\n", i,
7027 encodedNameConstraints[i].constraints.cExcludedSubtree,
7028 constraints->cExcludedSubtree);
7029 if (constraints->cExcludedSubtree ==
7030 encodedNameConstraints[i].constraints.cExcludedSubtree)
7032 for (j = 0; j < constraints->cExcludedSubtree; j++)
7034 compareAltNameEntry(&constraints->rgExcludedSubtree[j].Base,
7035 &encodedNameConstraints[i].constraints.rgExcludedSubtree[j].Base);
7038 LocalFree(constraints);
7043 static WCHAR noticeText[] = { 'T','h','i','s',' ','i','s',' ','a',' ',
7044 'n','o','t','i','c','e',0 };
7045 static const BYTE noticeWithDisplayText[] = {
7046 0x30,0x22,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,0x00,
7047 0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,0x74,
7048 0x00,0x69,0x00,0x63,0x00,0x65
7050 static char org[] = "Wine";
7051 static int noticeNumbers[] = { 2,3 };
7052 static BYTE noticeWithReference[] = {
7053 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7054 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7055 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7056 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7059 static void test_encodePolicyQualifierUserNotice(DWORD dwEncoding)
7061 BOOL ret;
7062 LPBYTE buf;
7063 DWORD size;
7064 CERT_POLICY_QUALIFIER_USER_NOTICE notice;
7065 CERT_POLICY_QUALIFIER_NOTICE_REFERENCE reference;
7067 memset(&notice, 0, sizeof(notice));
7068 ret = pCryptEncodeObjectEx(dwEncoding,
7069 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, &notice, CRYPT_ENCODE_ALLOC_FLAG,
7070 NULL, &buf, &size);
7071 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7073 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE encode support\n");
7074 return;
7076 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7077 if (ret)
7079 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size);
7080 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
7081 LocalFree(buf);
7083 notice.pszDisplayText = noticeText;
7084 ret = pCryptEncodeObjectEx(dwEncoding,
7085 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, &notice, CRYPT_ENCODE_ALLOC_FLAG,
7086 NULL, &buf, &size);
7087 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7088 if (ret)
7090 ok(sizeof(noticeWithDisplayText) == size, "unexpected size %d\n", size);
7091 ok(!memcmp(buf, noticeWithDisplayText, size), "unexpected value\n");
7092 LocalFree(buf);
7094 reference.pszOrganization = org;
7095 reference.cNoticeNumbers = 2;
7096 reference.rgNoticeNumbers = noticeNumbers;
7097 notice.pNoticeReference = &reference;
7098 ret = pCryptEncodeObjectEx(dwEncoding,
7099 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, &notice, CRYPT_ENCODE_ALLOC_FLAG,
7100 NULL, &buf, &size);
7101 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7102 if (ret)
7104 ok(sizeof(noticeWithReference) == size, "unexpected size %d\n", size);
7105 ok(!memcmp(buf, noticeWithReference, size), "unexpected value\n");
7106 LocalFree(buf);
7110 static void test_decodePolicyQualifierUserNotice(DWORD dwEncoding)
7112 BOOL ret;
7113 CERT_POLICY_QUALIFIER_USER_NOTICE *notice;
7114 DWORD size;
7116 ret = pCryptDecodeObjectEx(dwEncoding,
7117 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7118 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7119 &notice, &size);
7120 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7122 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE decode support\n");
7123 return;
7125 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7126 if (ret)
7128 ok(notice->pszDisplayText == NULL, "unexpected display text\n");
7129 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7130 LocalFree(notice);
7132 ret = pCryptDecodeObjectEx(dwEncoding,
7133 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7134 noticeWithDisplayText, sizeof(noticeWithDisplayText),
7135 CRYPT_DECODE_ALLOC_FLAG, NULL, &notice, &size);
7136 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7137 if (ret)
7139 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7140 "unexpected display text\n");
7141 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7142 LocalFree(notice);
7144 ret = pCryptDecodeObjectEx(dwEncoding,
7145 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7146 noticeWithReference, sizeof(noticeWithReference),
7147 CRYPT_DECODE_ALLOC_FLAG, NULL, &notice, &size);
7148 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7149 if (ret)
7151 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7152 "unexpected display text\n");
7153 ok(notice->pNoticeReference != NULL, "expected a notice reference\n");
7154 if (notice->pNoticeReference)
7156 ok(!strcmp(notice->pNoticeReference->pszOrganization, org),
7157 "unexpected organization %s\n",
7158 notice->pNoticeReference->pszOrganization);
7159 ok(notice->pNoticeReference->cNoticeNumbers == 2,
7160 "expected 2 notice numbers, got %d\n",
7161 notice->pNoticeReference->cNoticeNumbers);
7162 ok(notice->pNoticeReference->rgNoticeNumbers[0] == noticeNumbers[0],
7163 "unexpected notice number %d\n",
7164 notice->pNoticeReference->rgNoticeNumbers[0]);
7165 ok(notice->pNoticeReference->rgNoticeNumbers[1] == noticeNumbers[1],
7166 "unexpected notice number %d\n",
7167 notice->pNoticeReference->rgNoticeNumbers[1]);
7169 LocalFree(notice);
7173 static char oid_any_policy[] = "2.5.29.32.0";
7174 static const BYTE policiesWithAnyPolicy[] = {
7175 0x30,0x08,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00
7177 static char oid1[] = "1.2.3";
7178 static char oid_user_notice[] = "1.3.6.1.5.5.7.2.2";
7179 static const BYTE twoPolicies[] = {
7180 0x30,0x50,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00,0x30,0x46,0x06,0x02,0x2a,
7181 0x03,0x30,0x40,0x30,0x3e,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x02,
7182 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7183 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7184 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7185 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7188 static void test_encodeCertPolicies(DWORD dwEncoding)
7190 BOOL ret;
7191 CERT_POLICIES_INFO info;
7192 CERT_POLICY_INFO policy[2];
7193 CERT_POLICY_QUALIFIER_INFO qualifier;
7194 LPBYTE buf;
7195 DWORD size;
7197 memset(&info, 0, sizeof(info));
7198 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7199 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7200 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7201 if (ret)
7203 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size);
7204 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
7205 LocalFree(buf);
7207 memset(policy, 0, sizeof(policy));
7208 info.cPolicyInfo = 1;
7209 info.rgPolicyInfo = policy;
7210 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7211 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7212 ok(!ret && (GetLastError() == E_INVALIDARG ||
7213 GetLastError() == OSS_LIMITED /* Win9x/NT4 */),
7214 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
7215 policy[0].pszPolicyIdentifier = oid_any_policy;
7216 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7217 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7218 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7219 if (ret)
7221 ok(sizeof(policiesWithAnyPolicy) == size, "unexpected size %d\n", size);
7222 ok(!memcmp(buf, policiesWithAnyPolicy, size), "unexpected value\n");
7223 LocalFree(buf);
7225 policy[1].pszPolicyIdentifier = oid1;
7226 memset(&qualifier, 0, sizeof(qualifier));
7227 qualifier.pszPolicyQualifierId = oid_user_notice;
7228 qualifier.Qualifier.cbData = sizeof(noticeWithReference);
7229 qualifier.Qualifier.pbData = noticeWithReference;
7230 policy[1].cPolicyQualifier = 1;
7231 policy[1].rgPolicyQualifier = &qualifier;
7232 info.cPolicyInfo = 2;
7233 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7234 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7235 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7236 if (ret)
7238 ok(sizeof(twoPolicies) == size, "unexpected size %d\n", size);
7239 ok(!memcmp(buf, twoPolicies, size), "unexpected value\n");
7240 LocalFree(buf);
7244 static void test_decodeCertPolicies(DWORD dwEncoding)
7246 BOOL ret;
7247 CERT_POLICIES_INFO *info;
7248 DWORD size;
7250 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7251 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7252 &info, &size);
7253 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7254 if (ret)
7256 ok(info->cPolicyInfo == 0, "unexpected policy info %d\n",
7257 info->cPolicyInfo);
7258 LocalFree(info);
7260 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7261 policiesWithAnyPolicy, sizeof(policiesWithAnyPolicy),
7262 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7263 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7264 if (ret)
7266 ok(info->cPolicyInfo == 1, "unexpected policy info %d\n",
7267 info->cPolicyInfo);
7268 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy),
7269 "unexpected policy id %s\n",
7270 info->rgPolicyInfo[0].pszPolicyIdentifier);
7271 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0,
7272 "unexpected policy qualifier count %d\n",
7273 info->rgPolicyInfo[0].cPolicyQualifier);
7274 LocalFree(info);
7276 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7277 twoPolicies, sizeof(twoPolicies),
7278 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7279 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7280 if (ret)
7282 ok(info->cPolicyInfo == 2, "unexpected policy info %d\n",
7283 info->cPolicyInfo);
7284 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy),
7285 "unexpected policy id %s\n",
7286 info->rgPolicyInfo[0].pszPolicyIdentifier);
7287 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0,
7288 "unexpected policy qualifier count %d\n",
7289 info->rgPolicyInfo[0].cPolicyQualifier);
7290 ok(!strcmp(info->rgPolicyInfo[1].pszPolicyIdentifier, oid1),
7291 "unexpected policy id %s\n",
7292 info->rgPolicyInfo[1].pszPolicyIdentifier);
7293 ok(info->rgPolicyInfo[1].cPolicyQualifier == 1,
7294 "unexpected policy qualifier count %d\n",
7295 info->rgPolicyInfo[1].cPolicyQualifier);
7296 ok(!strcmp(
7297 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId,
7298 oid_user_notice), "unexpected policy qualifier id %s\n",
7299 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId);
7300 ok(info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData ==
7301 sizeof(noticeWithReference), "unexpected qualifier size %d\n",
7302 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData);
7303 ok(!memcmp(
7304 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.pbData,
7305 noticeWithReference, sizeof(noticeWithReference)),
7306 "unexpected qualifier value\n");
7307 LocalFree(info);
7311 /* Free *pInfo with HeapFree */
7312 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
7314 BOOL ret;
7315 DWORD size = 0;
7316 HCRYPTKEY key;
7318 /* This crashes
7319 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
7321 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size);
7322 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7323 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7324 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL,
7325 &size);
7326 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7327 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7328 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL,
7329 NULL, &size);
7330 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7331 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7332 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7333 0, NULL, NULL, &size);
7334 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7335 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7336 /* Test with no key */
7337 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7338 0, NULL, NULL, &size);
7339 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n",
7340 GetLastError());
7341 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
7342 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
7343 if (ret)
7345 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
7346 NULL, 0, NULL, NULL, &size);
7347 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
7348 *pInfo = HeapAlloc(GetProcessHeap(), 0, size);
7349 if (*pInfo)
7351 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
7352 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size);
7353 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n",
7354 GetLastError());
7355 if (ret)
7357 /* By default (we passed NULL as the OID) the OID is
7358 * szOID_RSA_RSA.
7360 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA),
7361 "Expected %s, got %s\n", szOID_RSA_RSA,
7362 (*pInfo)->Algorithm.pszObjId);
7366 CryptDestroyKey(key);
7369 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
7370 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
7371 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
7372 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7373 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7374 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7375 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
7376 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
7377 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7378 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7379 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7380 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
7381 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
7382 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
7383 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
7384 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
7385 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
7386 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
7387 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
7388 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
7389 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
7390 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
7391 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
7392 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
7393 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
7395 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info)
7397 BOOL ret;
7398 HCRYPTKEY key;
7399 PCCERT_CONTEXT context;
7400 DWORD dwSize;
7401 ALG_ID ai;
7403 /* These crash
7404 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
7405 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
7406 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
7407 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7408 NULL);
7410 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key);
7411 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7412 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7413 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key);
7414 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7415 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7416 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL,
7417 &key);
7418 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7419 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7421 /* Export key with standard algorithm (CALG_RSA_KEYX) */
7422 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7423 &key);
7424 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7426 dwSize = sizeof(ai);
7427 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7428 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7429 if(ret)
7431 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7432 ok(ai == CALG_RSA_KEYX, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai);
7435 CryptDestroyKey(key);
7437 /* Repeat with forced algorithm */
7438 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, CALG_RSA_SIGN, 0, NULL,
7439 &key);
7440 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7442 dwSize = sizeof(ai);
7443 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7444 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7445 if(ret)
7447 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7448 ok(ai == CALG_RSA_SIGN, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai);
7451 CryptDestroyKey(key);
7453 /* Test importing a public key from a certificate context */
7454 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert,
7455 sizeof(expiredCert));
7456 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
7457 GetLastError());
7458 if (context)
7460 ok(!strcmp(szOID_RSA_RSA,
7461 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId),
7462 "Expected %s, got %s\n", szOID_RSA_RSA,
7463 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
7464 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING,
7465 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
7466 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7467 CryptDestroyKey(key);
7468 CertFreeCertificateContext(context);
7472 static const char cspName[] = "WineCryptTemp";
7474 static void testPortPublicKeyInfo(void)
7476 HCRYPTPROV csp;
7477 BOOL ret;
7478 PCERT_PUBLIC_KEY_INFO info = NULL;
7480 /* Just in case a previous run failed, delete this thing */
7481 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7482 CRYPT_DELETEKEYSET);
7483 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7484 CRYPT_NEWKEYSET);
7486 testExportPublicKey(csp, &info);
7487 testImportPublicKey(csp, info);
7489 HeapFree(GetProcessHeap(), 0, info);
7490 CryptReleaseContext(csp, 0);
7491 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7492 CRYPT_DELETEKEYSET);
7495 START_TEST(encode)
7497 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
7498 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING };
7499 HMODULE hCrypt32;
7500 DWORD i;
7502 hCrypt32 = GetModuleHandleA("crypt32.dll");
7503 pCryptDecodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptDecodeObjectEx");
7504 pCryptEncodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptEncodeObjectEx");
7505 if (!pCryptDecodeObjectEx || !pCryptEncodeObjectEx)
7507 skip("CryptDecodeObjectEx() is not available\n");
7508 return;
7511 for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++)
7513 test_encodeInt(encodings[i]);
7514 test_decodeInt(encodings[i]);
7515 test_encodeEnumerated(encodings[i]);
7516 test_decodeEnumerated(encodings[i]);
7517 test_encodeFiletime(encodings[i]);
7518 test_decodeFiletime(encodings[i]);
7519 test_encodeName(encodings[i]);
7520 test_decodeName(encodings[i]);
7521 test_encodeUnicodeName(encodings[i]);
7522 test_decodeUnicodeName(encodings[i]);
7523 test_encodeNameValue(encodings[i]);
7524 test_decodeNameValue(encodings[i]);
7525 test_encodeUnicodeNameValue(encodings[i]);
7526 test_decodeUnicodeNameValue(encodings[i]);
7527 test_encodeAltName(encodings[i]);
7528 test_decodeAltName(encodings[i]);
7529 test_encodeOctets(encodings[i]);
7530 test_decodeOctets(encodings[i]);
7531 test_encodeBits(encodings[i]);
7532 test_decodeBits(encodings[i]);
7533 test_encodeBasicConstraints(encodings[i]);
7534 test_decodeBasicConstraints(encodings[i]);
7535 test_encodeRsaPublicKey(encodings[i]);
7536 test_decodeRsaPublicKey(encodings[i]);
7537 test_encodeSequenceOfAny(encodings[i]);
7538 test_decodeSequenceOfAny(encodings[i]);
7539 test_encodeExtensions(encodings[i]);
7540 test_decodeExtensions(encodings[i]);
7541 test_encodePublicKeyInfo(encodings[i]);
7542 test_decodePublicKeyInfo(encodings[i]);
7543 test_encodeCertToBeSigned(encodings[i]);
7544 test_decodeCertToBeSigned(encodings[i]);
7545 test_encodeCert(encodings[i]);
7546 test_decodeCert(encodings[i]);
7547 test_encodeCRLDistPoints(encodings[i]);
7548 test_decodeCRLDistPoints(encodings[i]);
7549 test_encodeCRLIssuingDistPoint(encodings[i]);
7550 test_decodeCRLIssuingDistPoint(encodings[i]);
7551 test_encodeCRLToBeSigned(encodings[i]);
7552 test_decodeCRLToBeSigned(encodings[i]);
7553 test_encodeEnhancedKeyUsage(encodings[i]);
7554 test_decodeEnhancedKeyUsage(encodings[i]);
7555 test_encodeAuthorityKeyId(encodings[i]);
7556 test_decodeAuthorityKeyId(encodings[i]);
7557 test_encodeAuthorityKeyId2(encodings[i]);
7558 test_decodeAuthorityKeyId2(encodings[i]);
7559 test_encodeAuthorityInfoAccess(encodings[i]);
7560 test_decodeAuthorityInfoAccess(encodings[i]);
7561 test_encodeCTL(encodings[i]);
7562 test_decodeCTL(encodings[i]);
7563 test_encodePKCSContentInfo(encodings[i]);
7564 test_decodePKCSContentInfo(encodings[i]);
7565 test_encodePKCSAttribute(encodings[i]);
7566 test_decodePKCSAttribute(encodings[i]);
7567 test_encodePKCSAttributes(encodings[i]);
7568 test_decodePKCSAttributes(encodings[i]);
7569 test_encodePKCSSMimeCapabilities(encodings[i]);
7570 test_decodePKCSSMimeCapabilities(encodings[i]);
7571 test_encodePKCSSignerInfo(encodings[i]);
7572 test_decodePKCSSignerInfo(encodings[i]);
7573 test_encodeCMSSignerInfo(encodings[i]);
7574 test_decodeCMSSignerInfo(encodings[i]);
7575 test_encodeNameConstraints(encodings[i]);
7576 test_decodeNameConstraints(encodings[i]);
7577 test_encodePolicyQualifierUserNotice(encodings[i]);
7578 test_decodePolicyQualifierUserNotice(encodings[i]);
7579 test_encodeCertPolicies(encodings[i]);
7580 test_decodeCertPolicies(encodings[i]);
7582 testPortPublicKeyInfo();