push 3cf4bc9cdb38c4fc36232fe19b9b904fd4d068e9
[wine/hacks.git] / dlls / crypt32 / tests / encode.c
blob952e24689362eb9f20e524ee1bbb0bbe3eff325d
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 broken(ret), /* Win9x and NT4 for bin38 */
667 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
668 GetLastError());
672 static const char commonName[] = "Juan Lang";
673 static const char surName[] = "Lang";
675 static const BYTE emptySequence[] = { 0x30, 0 };
676 static const BYTE emptyRDNs[] = { 0x30, 0x02, 0x31, 0 };
677 static const BYTE twoRDNs[] = {
678 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
679 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
680 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0};
681 static const BYTE encodedTwoRDNs[] = {
682 0x30,0x2e,0x31,0x2c,0x30,0x2a,0x06,0x03,0x55,0x04,0x03,0x30,0x23,0x31,0x21,
683 0x30,0x0c,0x06,0x03,0x55,0x04,0x04,0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,
684 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
685 0x6e,0x67,0x00,
688 static const BYTE us[] = { 0x55, 0x53 };
689 static const BYTE minnesota[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x73, 0x6f,
690 0x74, 0x61 };
691 static const BYTE minneapolis[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x61, 0x70,
692 0x6f, 0x6c, 0x69, 0x73 };
693 static const BYTE codeweavers[] = { 0x43, 0x6f, 0x64, 0x65, 0x57, 0x65, 0x61,
694 0x76, 0x65, 0x72, 0x73 };
695 static const BYTE wine[] = { 0x57, 0x69, 0x6e, 0x65, 0x20, 0x44, 0x65, 0x76,
696 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74 };
697 static const BYTE localhostAttr[] = { 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
698 0x73, 0x74 };
699 static const BYTE aric[] = { 0x61, 0x72, 0x69, 0x63, 0x40, 0x63, 0x6f, 0x64,
700 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d };
702 #define RDNA(arr) oid_ ## arr, CERT_RDN_PRINTABLE_STRING, { sizeof(arr), (LPBYTE)arr }
703 #define RDNIA5(arr) oid_ ## arr, CERT_RDN_IA5_STRING, { sizeof(arr), (LPBYTE)arr }
705 static CHAR oid_us[] = "2.5.4.6",
706 oid_minnesota[] = "2.5.4.8",
707 oid_minneapolis[] = "2.5.4.7",
708 oid_codeweavers[] = "2.5.4.10",
709 oid_wine[] = "2.5.4.11",
710 oid_localhostAttr[] = "2.5.4.3",
711 oid_aric[] = "1.2.840.113549.1.9.1";
712 static CERT_RDN_ATTR rdnAttrs[] = { { RDNA(us) },
713 { RDNA(minnesota) },
714 { RDNA(minneapolis) },
715 { RDNA(codeweavers) },
716 { RDNA(wine) },
717 { RDNA(localhostAttr) },
718 { RDNIA5(aric) } };
719 static CERT_RDN_ATTR decodedRdnAttrs[] = { { RDNA(us) },
720 { RDNA(localhostAttr) },
721 { RDNA(minnesota) },
722 { RDNA(minneapolis) },
723 { RDNA(codeweavers) },
724 { RDNA(wine) },
725 { RDNIA5(aric) } };
727 #undef RDNIA5
728 #undef RDNA
730 static const BYTE encodedRDNAttrs[] = {
731 0x30,0x81,0x96,0x31,0x81,0x93,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
732 0x53,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x68,
733 0x6f,0x73,0x74,0x30,0x10,0x06,0x03,0x55,0x04,0x08,0x13,0x09,0x4d,0x69,0x6e,0x6e,
734 0x65,0x73,0x6f,0x74,0x61,0x30,0x12,0x06,0x03,0x55,0x04,0x07,0x13,0x0b,0x4d,0x69,
735 0x6e,0x6e,0x65,0x61,0x70,0x6f,0x6c,0x69,0x73,0x30,0x12,0x06,0x03,0x55,0x04,0x0a,
736 0x13,0x0b,0x43,0x6f,0x64,0x65,0x57,0x65,0x61,0x76,0x65,0x72,0x73,0x30,0x17,0x06,
737 0x03,0x55,0x04,0x0b,0x13,0x10,0x57,0x69,0x6e,0x65,0x20,0x44,0x65,0x76,0x65,0x6c,
738 0x6f,0x70,0x6d,0x65,0x6e,0x74,0x30,0x21,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
739 0x01,0x09,0x01,0x16,0x14,0x61,0x72,0x69,0x63,0x40,0x63,0x6f,0x64,0x65,0x77,0x65,
740 0x61,0x76,0x65,0x72,0x73,0x2e,0x63,0x6f,0x6d
743 static void test_encodeName(DWORD dwEncoding)
745 CERT_RDN_ATTR attrs[2];
746 CERT_RDN rdn;
747 CERT_NAME_INFO info;
748 static CHAR oid_common_name[] = szOID_COMMON_NAME,
749 oid_sur_name[] = szOID_SUR_NAME;
750 BYTE *buf = NULL;
751 DWORD size = 0;
752 BOOL ret;
754 if (0)
756 /* Test with NULL pvStructInfo (crashes on win9x) */
757 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, NULL,
758 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
759 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
760 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
762 /* Test with empty CERT_NAME_INFO */
763 info.cRDN = 0;
764 info.rgRDN = NULL;
765 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
766 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
767 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
768 if (buf)
770 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
771 "Got unexpected encoding for empty name\n");
772 LocalFree(buf);
774 if (0)
776 /* Test with bogus CERT_RDN (crashes on win9x) */
777 info.cRDN = 1;
778 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
779 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
780 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
781 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
783 /* Test with empty CERT_RDN */
784 rdn.cRDNAttr = 0;
785 rdn.rgRDNAttr = NULL;
786 info.cRDN = 1;
787 info.rgRDN = &rdn;
788 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
789 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
790 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
791 if (buf)
793 ok(!memcmp(buf, emptyRDNs, sizeof(emptyRDNs)),
794 "Got unexpected encoding for empty RDN array\n");
795 LocalFree(buf);
797 if (0)
799 /* Test with bogus attr array (crashes on win9x) */
800 rdn.cRDNAttr = 1;
801 rdn.rgRDNAttr = NULL;
802 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
803 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
804 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
805 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
807 /* oddly, a bogus OID is accepted by Windows XP; not testing.
808 attrs[0].pszObjId = "bogus";
809 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
810 attrs[0].Value.cbData = sizeof(commonName);
811 attrs[0].Value.pbData = (BYTE *)commonName;
812 rdn.cRDNAttr = 1;
813 rdn.rgRDNAttr = attrs;
814 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
815 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
816 ok(!ret, "Expected failure, got success\n");
818 /* Check with two CERT_RDN_ATTRs. Note DER encoding forces the order of
819 * the encoded attributes to be swapped.
821 attrs[0].pszObjId = oid_common_name;
822 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
823 attrs[0].Value.cbData = sizeof(commonName);
824 attrs[0].Value.pbData = (BYTE *)commonName;
825 attrs[1].pszObjId = oid_sur_name;
826 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
827 attrs[1].Value.cbData = sizeof(surName);
828 attrs[1].Value.pbData = (BYTE *)surName;
829 rdn.cRDNAttr = 2;
830 rdn.rgRDNAttr = attrs;
831 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
832 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
833 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
834 if (buf)
836 ok(!memcmp(buf, twoRDNs, sizeof(twoRDNs)),
837 "Got unexpected encoding for two RDN array\n");
838 LocalFree(buf);
840 /* A name can be "encoded" with previously encoded RDN attrs. */
841 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
842 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
843 attrs[0].Value.cbData = sizeof(twoRDNs);
844 rdn.cRDNAttr = 1;
845 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
846 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
847 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
848 if (buf)
850 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
851 ok(!memcmp(buf, encodedTwoRDNs, size),
852 "Unexpected value for re-endoded two RDN array\n");
853 LocalFree(buf);
855 /* CERT_RDN_ANY_TYPE is too vague for X509_NAMEs, check the return */
856 rdn.cRDNAttr = 1;
857 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
858 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
859 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
860 ok(!ret && GetLastError() == E_INVALIDARG,
861 "Expected E_INVALIDARG, got %08x\n", GetLastError());
862 /* Test a more complex name */
863 rdn.cRDNAttr = sizeof(rdnAttrs) / sizeof(rdnAttrs[0]);
864 rdn.rgRDNAttr = (PCERT_RDN_ATTR)rdnAttrs;
865 info.cRDN = 1;
866 info.rgRDN = &rdn;
867 buf = NULL;
868 size = 0;
869 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, X509_NAME, &info,
870 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
871 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
872 if (ret)
874 ok(size == sizeof(encodedRDNAttrs), "Wrong size %d\n", size);
875 ok(!memcmp(buf, encodedRDNAttrs, size), "Unexpected value\n");
876 LocalFree(buf);
880 static WCHAR commonNameW[] = { 'J','u','a','n',' ','L','a','n','g',0 };
881 static WCHAR surNameW[] = { 'L','a','n','g',0 };
883 static const BYTE twoRDNsNoNull[] = {
884 0x30,0x21,0x31,0x1f,0x30,0x0b,0x06,0x03,0x55,0x04,0x04,0x13,0x04,0x4c,0x61,
885 0x6e,0x67,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,
886 0x20,0x4c,0x61,0x6e,0x67 };
887 static const BYTE anyType[] = {
888 0x30,0x2f,0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x1e,0x24,0x23,0x30,
889 0x21,0x31,0x0c,0x30,0x03,0x06,0x04,0x55,0x13,0x04,0x4c,0x05,0x6e,0x61,0x00,
890 0x67,0x11,0x30,0x03,0x06,0x04,0x55,0x13,0x03,0x4a,0x0a,0x61,0x75,0x20,0x6e,
891 0x61,0x4c,0x67,0x6e };
893 static void test_encodeUnicodeName(DWORD dwEncoding)
895 CERT_RDN_ATTR attrs[2];
896 CERT_RDN rdn;
897 CERT_NAME_INFO info;
898 static CHAR oid_common_name[] = szOID_COMMON_NAME,
899 oid_sur_name[] = szOID_SUR_NAME;
900 BYTE *buf = NULL;
901 DWORD size = 0;
902 BOOL ret;
904 if (0)
906 /* Test with NULL pvStructInfo (crashes on win9x) */
907 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, NULL,
908 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
909 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
910 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
912 /* Test with empty CERT_NAME_INFO */
913 info.cRDN = 0;
914 info.rgRDN = NULL;
915 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
916 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
917 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
918 if (buf)
920 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
921 "Got unexpected encoding for empty name\n");
922 LocalFree(buf);
924 /* Check with one CERT_RDN_ATTR, that has an invalid character for the
925 * encoding (the NULL).
927 attrs[0].pszObjId = oid_common_name;
928 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
929 attrs[0].Value.cbData = sizeof(commonNameW);
930 attrs[0].Value.pbData = (BYTE *)commonNameW;
931 rdn.cRDNAttr = 1;
932 rdn.rgRDNAttr = attrs;
933 info.cRDN = 1;
934 info.rgRDN = &rdn;
935 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
936 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
937 ok(!ret && GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING,
938 "Expected CRYPT_E_INVALID_PRINTABLE_STRING, got %08x\n", GetLastError());
939 ok(size == 9, "Unexpected error index %08x\n", size);
940 /* Check with two NULL-terminated CERT_RDN_ATTRs. Note DER encoding
941 * forces the order of the encoded attributes to be swapped.
943 attrs[0].pszObjId = oid_common_name;
944 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
945 attrs[0].Value.cbData = 0;
946 attrs[0].Value.pbData = (BYTE *)commonNameW;
947 attrs[1].pszObjId = oid_sur_name;
948 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
949 attrs[1].Value.cbData = 0;
950 attrs[1].Value.pbData = (BYTE *)surNameW;
951 rdn.cRDNAttr = 2;
952 rdn.rgRDNAttr = attrs;
953 info.cRDN = 1;
954 info.rgRDN = &rdn;
955 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
956 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
957 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
958 if (buf)
960 ok(!memcmp(buf, twoRDNsNoNull, sizeof(twoRDNsNoNull)),
961 "Got unexpected encoding for two RDN array\n");
962 LocalFree(buf);
964 /* A name can be "encoded" with previously encoded RDN attrs. */
965 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
966 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
967 attrs[0].Value.cbData = sizeof(twoRDNs);
968 rdn.cRDNAttr = 1;
969 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
970 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
971 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
972 if (buf)
974 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
975 ok(!memcmp(buf, encodedTwoRDNs, size),
976 "Unexpected value for re-endoded two RDN array\n");
977 LocalFree(buf);
979 /* Unicode names infer the type for CERT_RDN_ANY_TYPE */
980 rdn.cRDNAttr = 1;
981 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
982 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
983 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
984 todo_wine ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
985 if (buf)
987 ok(size == sizeof(anyType), "Unexpected size %d\n", size);
988 ok(!memcmp(buf, anyType, size), "Unexpected value\n");
989 LocalFree(buf);
993 static void compareNameValues(const CERT_NAME_VALUE *expected,
994 const CERT_NAME_VALUE *got)
996 ok(got->dwValueType == expected->dwValueType,
997 "Expected string type %d, got %d\n", expected->dwValueType,
998 got->dwValueType);
999 ok(got->Value.cbData == expected->Value.cbData,
1000 "String type %d: unexpected data size, got %d, expected %d\n",
1001 expected->dwValueType, got->Value.cbData, expected->Value.cbData);
1002 if (got->Value.cbData && got->Value.pbData)
1003 ok(!memcmp(got->Value.pbData, expected->Value.pbData,
1004 min(got->Value.cbData, expected->Value.cbData)),
1005 "String type %d: unexpected value\n", expected->dwValueType);
1008 static void compareRDNAttrs(const CERT_RDN_ATTR *expected,
1009 const CERT_RDN_ATTR *got)
1011 if (expected->pszObjId && strlen(expected->pszObjId))
1013 ok(got->pszObjId != NULL, "Expected OID %s, got NULL\n",
1014 expected->pszObjId);
1015 if (got->pszObjId)
1017 ok(!strcmp(got->pszObjId, expected->pszObjId),
1018 "Got unexpected OID %s, expected %s\n", got->pszObjId,
1019 expected->pszObjId);
1022 compareNameValues((const CERT_NAME_VALUE *)&expected->dwValueType,
1023 (const CERT_NAME_VALUE *)&got->dwValueType);
1026 static void compareRDNs(const CERT_RDN *expected, const CERT_RDN *got)
1028 ok(got->cRDNAttr == expected->cRDNAttr,
1029 "Expected %d RDN attrs, got %d\n", expected->cRDNAttr, got->cRDNAttr);
1030 if (got->cRDNAttr)
1032 DWORD i;
1034 for (i = 0; i < got->cRDNAttr; i++)
1035 compareRDNAttrs(&expected->rgRDNAttr[i], &got->rgRDNAttr[i]);
1039 static void compareNames(const CERT_NAME_INFO *expected,
1040 const CERT_NAME_INFO *got)
1042 ok(got->cRDN == expected->cRDN, "Expected %d RDNs, got %d\n",
1043 expected->cRDN, got->cRDN);
1044 if (got->cRDN)
1046 DWORD i;
1048 for (i = 0; i < got->cRDN; i++)
1049 compareRDNs(&expected->rgRDN[i], &got->rgRDN[i]);
1053 static const BYTE emptyIndefiniteSequence[] = { 0x30,0x80,0x00,0x00 };
1054 static const BYTE twoRDNsExtraBytes[] = {
1055 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
1056 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1057 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0,0,0,0,0,0};
1059 static void test_decodeName(DWORD dwEncoding)
1061 BYTE *buf = NULL;
1062 DWORD bufSize = 0;
1063 BOOL ret;
1064 CERT_RDN rdn;
1065 CERT_NAME_INFO info = { 1, &rdn };
1067 /* test empty name */
1068 bufSize = 0;
1069 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptySequence,
1070 emptySequence[1] + 2,
1071 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1072 (BYTE *)&buf, &bufSize);
1073 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1074 /* Interestingly, in Windows, if cRDN is 0, rgRGN may not be NULL. My
1075 * decoder works the same way, so only test the count.
1077 if (buf)
1079 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1080 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1081 "Expected 0 RDNs in empty info, got %d\n",
1082 ((CERT_NAME_INFO *)buf)->cRDN);
1083 LocalFree(buf);
1085 /* test empty name with indefinite-length encoding */
1086 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyIndefiniteSequence,
1087 sizeof(emptyIndefiniteSequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
1088 (BYTE *)&buf, &bufSize);
1089 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1090 if (ret)
1092 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1093 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1094 "Expected 0 RDNs in empty info, got %d\n",
1095 ((CERT_NAME_INFO *)buf)->cRDN);
1096 LocalFree(buf);
1098 /* test empty RDN */
1099 bufSize = 0;
1100 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyRDNs,
1101 emptyRDNs[1] + 2,
1102 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1103 (BYTE *)&buf, &bufSize);
1104 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1105 if (buf)
1107 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1109 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1110 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1111 "Got unexpected value for empty RDN\n");
1112 LocalFree(buf);
1114 /* test two RDN attrs */
1115 bufSize = 0;
1116 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNs,
1117 twoRDNs[1] + 2,
1118 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1119 (BYTE *)&buf, &bufSize);
1120 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1121 if (buf)
1123 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1124 oid_common_name[] = szOID_COMMON_NAME;
1126 CERT_RDN_ATTR attrs[] = {
1127 { oid_sur_name, CERT_RDN_PRINTABLE_STRING, { sizeof(surName),
1128 (BYTE *)surName } },
1129 { oid_common_name, CERT_RDN_PRINTABLE_STRING, { sizeof(commonName),
1130 (BYTE *)commonName } },
1133 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1134 rdn.rgRDNAttr = attrs;
1135 compareNames(&info, (CERT_NAME_INFO *)buf);
1136 LocalFree(buf);
1138 /* test that two RDN attrs with extra bytes succeeds */
1139 bufSize = 0;
1140 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNsExtraBytes,
1141 sizeof(twoRDNsExtraBytes), 0, NULL, NULL, &bufSize);
1142 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1143 /* And, a slightly more complicated name */
1144 buf = NULL;
1145 bufSize = 0;
1146 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME, encodedRDNAttrs,
1147 sizeof(encodedRDNAttrs), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1148 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1149 if (ret)
1151 rdn.cRDNAttr = sizeof(decodedRdnAttrs) / sizeof(decodedRdnAttrs[0]);
1152 rdn.rgRDNAttr = (PCERT_RDN_ATTR)decodedRdnAttrs;
1153 compareNames(&info, (CERT_NAME_INFO *)buf);
1154 LocalFree(buf);
1158 static void test_decodeUnicodeName(DWORD dwEncoding)
1160 BYTE *buf = NULL;
1161 DWORD bufSize = 0;
1162 BOOL ret;
1163 CERT_RDN rdn;
1164 CERT_NAME_INFO info = { 1, &rdn };
1166 /* test empty name */
1167 bufSize = 0;
1168 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptySequence,
1169 emptySequence[1] + 2,
1170 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1171 (BYTE *)&buf, &bufSize);
1172 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1173 if (buf)
1175 ok(bufSize == sizeof(CERT_NAME_INFO),
1176 "Got wrong bufSize %d\n", bufSize);
1177 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1178 "Expected 0 RDNs in empty info, got %d\n",
1179 ((CERT_NAME_INFO *)buf)->cRDN);
1180 LocalFree(buf);
1182 /* test empty RDN */
1183 bufSize = 0;
1184 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptyRDNs,
1185 emptyRDNs[1] + 2,
1186 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1187 (BYTE *)&buf, &bufSize);
1188 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1189 if (buf)
1191 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1193 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1194 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1195 "Got unexpected value for empty RDN\n");
1196 LocalFree(buf);
1198 /* test two RDN attrs */
1199 bufSize = 0;
1200 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, twoRDNsNoNull,
1201 sizeof(twoRDNsNoNull),
1202 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1203 (BYTE *)&buf, &bufSize);
1204 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1205 if (buf)
1207 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1208 oid_common_name[] = szOID_COMMON_NAME;
1210 CERT_RDN_ATTR attrs[] = {
1211 { oid_sur_name, CERT_RDN_PRINTABLE_STRING,
1212 { lstrlenW(surNameW) * sizeof(WCHAR), (BYTE *)surNameW } },
1213 { oid_common_name, CERT_RDN_PRINTABLE_STRING,
1214 { lstrlenW(commonNameW) * sizeof(WCHAR), (BYTE *)commonNameW } },
1217 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1218 rdn.rgRDNAttr = attrs;
1219 compareNames(&info, (CERT_NAME_INFO *)buf);
1220 LocalFree(buf);
1224 struct EncodedNameValue
1226 CERT_NAME_VALUE value;
1227 const BYTE *encoded;
1228 DWORD encodedSize;
1231 static const char bogusIA5[] = "\x80";
1232 static const char bogusPrintable[] = "~";
1233 static const char bogusNumeric[] = "A";
1234 static const BYTE bin42[] = { 0x16,0x02,0x80,0x00 };
1235 static const BYTE bin43[] = { 0x13,0x02,0x7e,0x00 };
1236 static const BYTE bin44[] = { 0x12,0x02,0x41,0x00 };
1237 static BYTE octetCommonNameValue[] = {
1238 0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1239 static BYTE numericCommonNameValue[] = {
1240 0x12,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1241 static BYTE printableCommonNameValue[] = {
1242 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1243 static BYTE t61CommonNameValue[] = {
1244 0x14,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1245 static BYTE videotexCommonNameValue[] = {
1246 0x15,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1247 static BYTE ia5CommonNameValue[] = {
1248 0x16,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1249 static BYTE graphicCommonNameValue[] = {
1250 0x19,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1251 static BYTE visibleCommonNameValue[] = {
1252 0x1a,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1253 static BYTE generalCommonNameValue[] = {
1254 0x1b,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1255 static BYTE bmpCommonNameValue[] = {
1256 0x1e,0x14,0x00,0x4a,0x00,0x75,0x00,0x61,0x00,0x6e,0x00,0x20,0x00,0x4c,0x00,
1257 0x61,0x00,0x6e,0x00,0x67,0x00,0x00 };
1258 static BYTE utf8CommonNameValue[] = {
1259 0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1261 static struct EncodedNameValue nameValues[] = {
1262 { { CERT_RDN_OCTET_STRING, { sizeof(commonName), (BYTE *)commonName } },
1263 octetCommonNameValue, sizeof(octetCommonNameValue) },
1264 { { CERT_RDN_NUMERIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1265 numericCommonNameValue, sizeof(numericCommonNameValue) },
1266 { { CERT_RDN_PRINTABLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1267 printableCommonNameValue, sizeof(printableCommonNameValue) },
1268 { { CERT_RDN_T61_STRING, { sizeof(commonName), (BYTE *)commonName } },
1269 t61CommonNameValue, sizeof(t61CommonNameValue) },
1270 { { CERT_RDN_VIDEOTEX_STRING, { sizeof(commonName), (BYTE *)commonName } },
1271 videotexCommonNameValue, sizeof(videotexCommonNameValue) },
1272 { { CERT_RDN_IA5_STRING, { sizeof(commonName), (BYTE *)commonName } },
1273 ia5CommonNameValue, sizeof(ia5CommonNameValue) },
1274 { { CERT_RDN_GRAPHIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1275 graphicCommonNameValue, sizeof(graphicCommonNameValue) },
1276 { { CERT_RDN_VISIBLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1277 visibleCommonNameValue, sizeof(visibleCommonNameValue) },
1278 { { CERT_RDN_GENERAL_STRING, { sizeof(commonName), (BYTE *)commonName } },
1279 generalCommonNameValue, sizeof(generalCommonNameValue) },
1280 { { CERT_RDN_BMP_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1281 bmpCommonNameValue, sizeof(bmpCommonNameValue) },
1282 { { CERT_RDN_UTF8_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1283 utf8CommonNameValue, sizeof(utf8CommonNameValue) },
1284 /* The following tests succeed under Windows, but really should fail,
1285 * they contain characters that are illegal for the encoding. I'm
1286 * including them to justify my lazy encoding.
1288 { { CERT_RDN_IA5_STRING, { sizeof(bogusIA5), (BYTE *)bogusIA5 } }, bin42,
1289 sizeof(bin42) },
1290 { { CERT_RDN_PRINTABLE_STRING, { sizeof(bogusPrintable),
1291 (BYTE *)bogusPrintable } }, bin43, sizeof(bin43) },
1292 { { CERT_RDN_NUMERIC_STRING, { sizeof(bogusNumeric), (BYTE *)bogusNumeric } },
1293 bin44, sizeof(bin44) },
1296 static void test_encodeNameValue(DWORD dwEncoding)
1298 BYTE *buf = NULL;
1299 DWORD size = 0, i;
1300 BOOL ret;
1301 CERT_NAME_VALUE value = { 0, { 0, NULL } };
1303 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1304 value.Value.pbData = printableCommonNameValue;
1305 value.Value.cbData = sizeof(printableCommonNameValue);
1306 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, &value,
1307 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1308 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1309 if (buf)
1311 ok(size == sizeof(printableCommonNameValue), "Unexpected size %d\n",
1312 size);
1313 ok(!memcmp(buf, printableCommonNameValue, size),
1314 "Unexpected encoding\n");
1315 LocalFree(buf);
1317 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1319 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE,
1320 &nameValues[i].value, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1321 &size);
1322 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH) /* NT4/Win9x */,
1323 "Type %d: CryptEncodeObjectEx failed: %08x\n",
1324 nameValues[i].value.dwValueType, GetLastError());
1325 if (ret)
1327 ok(size == nameValues[i].encodedSize,
1328 "Expected size %d, got %d\n", nameValues[i].encodedSize, size);
1329 ok(!memcmp(buf, nameValues[i].encoded, size),
1330 "Got unexpected encoding\n");
1331 LocalFree(buf);
1336 static void test_decodeNameValue(DWORD dwEncoding)
1338 int i;
1339 BYTE *buf = NULL;
1340 DWORD bufSize = 0;
1341 BOOL ret;
1343 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1345 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE,
1346 nameValues[i].encoded, nameValues[i].encoded[1] + 2,
1347 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1348 (BYTE *)&buf, &bufSize);
1349 ok(ret, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
1350 nameValues[i].value.dwValueType, GetLastError());
1351 if (ret)
1353 compareNameValues(&nameValues[i].value,
1354 (const CERT_NAME_VALUE *)buf);
1355 LocalFree(buf);
1360 static const BYTE emptyURL[] = { 0x30, 0x02, 0x86, 0x00 };
1361 static const BYTE emptyURLExtraBytes[] = { 0x30, 0x02, 0x86, 0x00, 0, 0, 0 };
1362 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e',
1363 'h','q','.','o','r','g',0 };
1364 static const BYTE encodedURL[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74,
1365 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e,
1366 0x6f, 0x72, 0x67 };
1367 static const WCHAR nihongoURL[] = { 'h','t','t','p',':','/','/',0x226f,
1368 0x575b, 0 };
1369 static const WCHAR dnsName[] = { 'w','i','n','e','h','q','.','o','r','g',0 };
1370 static const BYTE encodedDnsName[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69,
1371 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
1372 static const BYTE localhost[] = { 127, 0, 0, 1 };
1373 static const BYTE encodedIPAddr[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00,
1374 0x01 };
1375 static const unsigned char encodedCommonName[] = {
1376 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0};
1377 static const BYTE encodedOidName[] = { 0x30,0x04,0x88,0x02,0x2a,0x03 };
1378 static const BYTE encodedDirectoryName[] = {
1379 0x30,0x19,0xa4,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1380 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1382 static void test_encodeAltName(DWORD dwEncoding)
1384 CERT_ALT_NAME_INFO info = { 0 };
1385 CERT_ALT_NAME_ENTRY entry = { 0 };
1386 BYTE *buf = NULL;
1387 DWORD size = 0;
1388 BOOL ret;
1389 char oid[] = "1.2.3";
1391 /* Test with empty info */
1392 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1393 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1394 if (buf)
1396 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
1397 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
1398 LocalFree(buf);
1400 /* Test with an empty entry */
1401 info.cAltEntry = 1;
1402 info.rgAltEntry = &entry;
1403 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1404 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1405 ok(!ret && GetLastError() == E_INVALIDARG,
1406 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1407 /* Test with an empty pointer */
1408 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
1409 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1410 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1411 if (buf)
1413 ok(size == sizeof(emptyURL), "Wrong size %d\n", size);
1414 ok(!memcmp(buf, emptyURL, size), "Unexpected value\n");
1415 LocalFree(buf);
1417 /* Test with a real URL */
1418 U(entry).pwszURL = (LPWSTR)url;
1419 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1420 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1421 if (buf)
1423 ok(size == sizeof(encodedURL), "Wrong size %d\n", size);
1424 ok(!memcmp(buf, encodedURL, size), "Unexpected value\n");
1425 LocalFree(buf);
1427 /* Now with the URL containing an invalid IA5 char */
1428 U(entry).pwszURL = (LPWSTR)nihongoURL;
1429 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1430 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1431 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
1432 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
1433 /* The first invalid character is at index 7 */
1434 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
1435 "Expected invalid char at index 7, got %d\n",
1436 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
1437 /* Now with the URL missing a scheme */
1438 U(entry).pwszURL = (LPWSTR)dnsName;
1439 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1440 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1441 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1442 if (buf)
1444 /* This succeeds, but it shouldn't, so don't worry about conforming */
1445 LocalFree(buf);
1447 /* Now with a DNS name */
1448 entry.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
1449 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1450 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1451 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1452 if (buf)
1454 ok(size == sizeof(encodedDnsName), "Wrong size %d\n", size);
1455 ok(!memcmp(buf, encodedDnsName, size), "Unexpected value\n");
1456 LocalFree(buf);
1458 /* Test with an IP address */
1459 entry.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
1460 U(entry).IPAddress.cbData = sizeof(localhost);
1461 U(entry).IPAddress.pbData = (LPBYTE)localhost;
1462 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1463 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1464 if (buf)
1466 ok(size == sizeof(encodedIPAddr), "Wrong size %d\n", size);
1467 ok(!memcmp(buf, encodedIPAddr, size), "Unexpected value\n");
1468 LocalFree(buf);
1470 /* Test with OID */
1471 entry.dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID;
1472 U(entry).pszRegisteredID = oid;
1473 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1474 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1475 if (buf)
1477 ok(size == sizeof(encodedOidName), "Wrong size %d\n", size);
1478 ok(!memcmp(buf, encodedOidName, size), "Unexpected value\n");
1479 LocalFree(buf);
1481 /* Test with directory name */
1482 entry.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
1483 U(entry).DirectoryName.cbData = sizeof(encodedCommonName);
1484 U(entry).DirectoryName.pbData = (LPBYTE)encodedCommonName;
1485 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1486 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1487 if (buf)
1489 ok(size == sizeof(encodedDirectoryName), "Wrong size %d\n", size);
1490 ok(!memcmp(buf, encodedDirectoryName, size), "Unexpected value\n");
1491 LocalFree(buf);
1495 static void test_decodeAltName(DWORD dwEncoding)
1497 static const BYTE unimplementedType[] = { 0x30, 0x06, 0x85, 0x04, 0x7f,
1498 0x00, 0x00, 0x01 };
1499 static const BYTE bogusType[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00,
1500 0x01 };
1501 BOOL ret;
1502 BYTE *buf = NULL;
1503 DWORD bufSize = 0;
1504 CERT_ALT_NAME_INFO *info;
1506 /* Test some bogus ones first */
1507 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1508 unimplementedType, sizeof(unimplementedType), CRYPT_DECODE_ALLOC_FLAG,
1509 NULL, (BYTE *)&buf, &bufSize);
1510 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
1511 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1512 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
1513 GetLastError());
1514 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1515 bogusType, sizeof(bogusType), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1516 &bufSize);
1517 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
1518 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1519 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
1520 GetLastError());
1521 /* Now expected cases */
1522 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptySequence,
1523 emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1524 &bufSize);
1525 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1526 if (buf)
1528 info = (CERT_ALT_NAME_INFO *)buf;
1530 ok(info->cAltEntry == 0, "Expected 0 entries, got %d\n",
1531 info->cAltEntry);
1532 LocalFree(buf);
1534 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptyURL,
1535 emptyURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1536 &bufSize);
1537 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1538 if (buf)
1540 info = (CERT_ALT_NAME_INFO *)buf;
1542 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1543 info->cAltEntry);
1544 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1545 "Expected CERT_ALT_NAME_URL, got %d\n",
1546 info->rgAltEntry[0].dwAltNameChoice);
1547 ok(U(info->rgAltEntry[0]).pwszURL == NULL || !*U(info->rgAltEntry[0]).pwszURL,
1548 "Expected empty URL\n");
1549 LocalFree(buf);
1551 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1552 emptyURLExtraBytes, sizeof(emptyURLExtraBytes), 0, NULL, NULL, &bufSize);
1553 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1554 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedURL,
1555 encodedURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1556 &bufSize);
1557 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1558 if (buf)
1560 info = (CERT_ALT_NAME_INFO *)buf;
1562 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1563 info->cAltEntry);
1564 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1565 "Expected CERT_ALT_NAME_URL, got %d\n",
1566 info->rgAltEntry[0].dwAltNameChoice);
1567 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszURL, url), "Unexpected URL\n");
1568 LocalFree(buf);
1570 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedDnsName,
1571 encodedDnsName[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1572 &bufSize);
1573 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1574 if (buf)
1576 info = (CERT_ALT_NAME_INFO *)buf;
1578 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1579 info->cAltEntry);
1580 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1581 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1582 info->rgAltEntry[0].dwAltNameChoice);
1583 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszDNSName, dnsName),
1584 "Unexpected DNS name\n");
1585 LocalFree(buf);
1587 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedIPAddr,
1588 encodedIPAddr[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1589 &bufSize);
1590 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1591 if (buf)
1593 info = (CERT_ALT_NAME_INFO *)buf;
1595 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1596 info->cAltEntry);
1597 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS,
1598 "Expected CERT_ALT_NAME_IP_ADDRESS, got %d\n",
1599 info->rgAltEntry[0].dwAltNameChoice);
1600 ok(U(info->rgAltEntry[0]).IPAddress.cbData == sizeof(localhost),
1601 "Unexpected IP address length %d\n",
1602 U(info->rgAltEntry[0]).IPAddress.cbData);
1603 ok(!memcmp(U(info->rgAltEntry[0]).IPAddress.pbData, localhost,
1604 sizeof(localhost)), "Unexpected IP address value\n");
1605 LocalFree(buf);
1607 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedOidName,
1608 sizeof(encodedOidName), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1609 &bufSize);
1610 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1611 if (buf)
1613 info = (CERT_ALT_NAME_INFO *)buf;
1615 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1616 info->cAltEntry);
1617 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_REGISTERED_ID,
1618 "Expected CERT_ALT_NAME_REGISTERED_ID, got %d\n",
1619 info->rgAltEntry[0].dwAltNameChoice);
1620 ok(!strcmp(U(info->rgAltEntry[0]).pszRegisteredID, "1.2.3"),
1621 "Expected OID 1.2.3, got %s\n", U(info->rgAltEntry[0]).pszRegisteredID);
1622 LocalFree(buf);
1624 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1625 encodedDirectoryName, sizeof(encodedDirectoryName),
1626 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1627 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1628 if (buf)
1630 info = (CERT_ALT_NAME_INFO *)buf;
1632 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1633 info->cAltEntry);
1634 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME,
1635 "Expected CERT_ALT_NAME_DIRECTORY_NAME, got %d\n",
1636 info->rgAltEntry[0].dwAltNameChoice);
1637 ok(U(info->rgAltEntry[0]).DirectoryName.cbData ==
1638 sizeof(encodedCommonName), "Unexpected directory name length %d\n",
1639 U(info->rgAltEntry[0]).DirectoryName.cbData);
1640 ok(!memcmp(U(info->rgAltEntry[0]).DirectoryName.pbData,
1641 encodedCommonName, sizeof(encodedCommonName)),
1642 "Unexpected directory name value\n");
1643 LocalFree(buf);
1647 struct UnicodeExpectedError
1649 DWORD valueType;
1650 LPCWSTR str;
1651 DWORD errorIndex;
1652 DWORD error;
1655 static const WCHAR oneW[] = { '1',0 };
1656 static const WCHAR aW[] = { 'a',0 };
1657 static const WCHAR quoteW[] = { '"', 0 };
1659 static struct UnicodeExpectedError unicodeErrors[] = {
1660 { CERT_RDN_ANY_TYPE, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1661 { CERT_RDN_ENCODED_BLOB, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1662 { CERT_RDN_OCTET_STRING, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1663 { CERT_RDN_NUMERIC_STRING, aW, 0, CRYPT_E_INVALID_NUMERIC_STRING },
1664 { CERT_RDN_PRINTABLE_STRING, quoteW, 0, CRYPT_E_INVALID_PRINTABLE_STRING },
1665 { CERT_RDN_IA5_STRING, nihongoURL, 7, CRYPT_E_INVALID_IA5_STRING },
1668 struct UnicodeExpectedResult
1670 DWORD valueType;
1671 LPCWSTR str;
1672 CRYPT_DATA_BLOB encoded;
1675 static BYTE oneNumeric[] = { 0x12, 0x01, 0x31 };
1676 static BYTE onePrintable[] = { 0x13, 0x01, 0x31 };
1677 static BYTE oneTeletex[] = { 0x14, 0x01, 0x31 };
1678 static BYTE oneVideotex[] = { 0x15, 0x01, 0x31 };
1679 static BYTE oneIA5[] = { 0x16, 0x01, 0x31 };
1680 static BYTE oneGraphic[] = { 0x19, 0x01, 0x31 };
1681 static BYTE oneVisible[] = { 0x1a, 0x01, 0x31 };
1682 static BYTE oneUniversal[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 };
1683 static BYTE oneGeneral[] = { 0x1b, 0x01, 0x31 };
1684 static BYTE oneBMP[] = { 0x1e, 0x02, 0x00, 0x31 };
1685 static BYTE oneUTF8[] = { 0x0c, 0x01, 0x31 };
1686 static BYTE nihongoT61[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,
1687 0x5b };
1688 static BYTE nihongoGeneral[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1689 0x6f,0x5b };
1690 static BYTE nihongoBMP[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,
1691 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
1692 static BYTE nihongoUTF8[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1693 0xe2,0x89,0xaf,0xe5,0x9d,0x9b };
1695 static struct UnicodeExpectedResult unicodeResults[] = {
1696 { CERT_RDN_NUMERIC_STRING, oneW, { sizeof(oneNumeric), oneNumeric } },
1697 { CERT_RDN_PRINTABLE_STRING, oneW, { sizeof(onePrintable), onePrintable } },
1698 { CERT_RDN_TELETEX_STRING, oneW, { sizeof(oneTeletex), oneTeletex } },
1699 { CERT_RDN_VIDEOTEX_STRING, oneW, { sizeof(oneVideotex), oneVideotex } },
1700 { CERT_RDN_IA5_STRING, oneW, { sizeof(oneIA5), oneIA5 } },
1701 { CERT_RDN_GRAPHIC_STRING, oneW, { sizeof(oneGraphic), oneGraphic } },
1702 { CERT_RDN_VISIBLE_STRING, oneW, { sizeof(oneVisible), oneVisible } },
1703 { CERT_RDN_UNIVERSAL_STRING, oneW, { sizeof(oneUniversal), oneUniversal } },
1704 { CERT_RDN_GENERAL_STRING, oneW, { sizeof(oneGeneral), oneGeneral } },
1705 { CERT_RDN_BMP_STRING, oneW, { sizeof(oneBMP), oneBMP } },
1706 { CERT_RDN_UTF8_STRING, oneW, { sizeof(oneUTF8), oneUTF8 } },
1707 { CERT_RDN_BMP_STRING, nihongoURL, { sizeof(nihongoBMP), nihongoBMP } },
1708 { CERT_RDN_UTF8_STRING, nihongoURL, { sizeof(nihongoUTF8), nihongoUTF8 } },
1711 static struct UnicodeExpectedResult unicodeWeirdness[] = {
1712 { CERT_RDN_TELETEX_STRING, nihongoURL, { sizeof(nihongoT61), nihongoT61 } },
1713 { CERT_RDN_GENERAL_STRING, nihongoURL, { sizeof(nihongoGeneral), nihongoGeneral } },
1716 static void test_encodeUnicodeNameValue(DWORD dwEncoding)
1718 BYTE *buf = NULL;
1719 DWORD size = 0, i;
1720 BOOL ret;
1721 CERT_NAME_VALUE value;
1723 if (0)
1725 /* Crashes on win9x */
1726 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, NULL,
1727 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1728 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1729 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1731 /* Have to have a string of some sort */
1732 value.dwValueType = 0; /* aka CERT_RDN_ANY_TYPE */
1733 value.Value.pbData = NULL;
1734 value.Value.cbData = 0;
1735 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1736 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1737 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1738 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1739 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1740 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1741 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1742 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1743 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1744 value.dwValueType = CERT_RDN_ANY_TYPE;
1745 value.Value.pbData = (LPBYTE)oneW;
1746 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1747 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1748 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1749 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1750 value.Value.cbData = sizeof(oneW);
1751 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1752 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1753 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1754 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1755 /* An encoded string with specified length isn't good enough either */
1756 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1757 value.Value.pbData = oneUniversal;
1758 value.Value.cbData = sizeof(oneUniversal);
1759 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1760 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1761 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1762 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1763 /* More failure checking */
1764 value.Value.cbData = 0;
1765 for (i = 0; i < sizeof(unicodeErrors) / sizeof(unicodeErrors[0]); i++)
1767 value.Value.pbData = (LPBYTE)unicodeErrors[i].str;
1768 value.dwValueType = unicodeErrors[i].valueType;
1769 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1770 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1771 ok(!ret && GetLastError() == unicodeErrors[i].error,
1772 "Value type %d: expected %08x, got %08x\n", value.dwValueType,
1773 unicodeErrors[i].error, GetLastError());
1774 ok(size == unicodeErrors[i].errorIndex,
1775 "Expected error index %d, got %d\n", unicodeErrors[i].errorIndex,
1776 size);
1778 /* cbData can be zero if the string is NULL-terminated */
1779 value.Value.cbData = 0;
1780 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1782 value.Value.pbData = (LPBYTE)unicodeResults[i].str;
1783 value.dwValueType = unicodeResults[i].valueType;
1784 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1785 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1786 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
1787 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1788 if (buf)
1790 ok(size == unicodeResults[i].encoded.cbData,
1791 "Value type %d: expected size %d, got %d\n",
1792 value.dwValueType, unicodeResults[i].encoded.cbData, size);
1793 ok(!memcmp(unicodeResults[i].encoded.pbData, buf, size),
1794 "Value type %d: unexpected value\n", value.dwValueType);
1795 LocalFree(buf);
1798 /* These "encode," but they do so by truncating each unicode character
1799 * rather than properly encoding it. Kept separate from the proper results,
1800 * because the encoded forms won't decode to their original strings.
1802 for (i = 0; i < sizeof(unicodeWeirdness) / sizeof(unicodeWeirdness[0]); i++)
1804 value.Value.pbData = (LPBYTE)unicodeWeirdness[i].str;
1805 value.dwValueType = unicodeWeirdness[i].valueType;
1806 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1807 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1808 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1809 if (buf)
1811 ok(size == unicodeWeirdness[i].encoded.cbData,
1812 "Value type %d: expected size %d, got %d\n",
1813 value.dwValueType, unicodeWeirdness[i].encoded.cbData, size);
1814 ok(!memcmp(unicodeWeirdness[i].encoded.pbData, buf, size),
1815 "Value type %d: unexpected value\n", value.dwValueType);
1816 LocalFree(buf);
1821 static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
1823 if (n <= 0) return 0;
1824 while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
1825 return *str1 - *str2;
1828 static void test_decodeUnicodeNameValue(DWORD dwEncoding)
1830 DWORD i;
1832 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1834 BYTE *buf = NULL;
1835 BOOL ret;
1836 DWORD size = 0;
1838 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE,
1839 unicodeResults[i].encoded.pbData, unicodeResults[i].encoded.cbData,
1840 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1841 ok(ret || broken(GetLastError() == CRYPT_E_NOT_CHAR_STRING /* Win9x */),
1842 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1843 if (ret && buf)
1845 PCERT_NAME_VALUE value = (PCERT_NAME_VALUE)buf;
1847 ok(value->dwValueType == unicodeResults[i].valueType,
1848 "Expected value type %d, got %d\n", unicodeResults[i].valueType,
1849 value->dwValueType);
1850 ok(!strncmpW((LPWSTR)value->Value.pbData, unicodeResults[i].str,
1851 value->Value.cbData / sizeof(WCHAR)),
1852 "Unexpected decoded value for index %d (value type %d)\n", i,
1853 unicodeResults[i].valueType);
1854 LocalFree(buf);
1859 struct encodedOctets
1861 const BYTE *val;
1862 const BYTE *encoded;
1865 static const unsigned char bin46[] = { 'h','i',0 };
1866 static const unsigned char bin47[] = { 0x04,0x02,'h','i',0 };
1867 static const unsigned char bin48[] = {
1868 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1869 static const unsigned char bin49[] = {
1870 0x04,0x0f,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1871 static const unsigned char bin50[] = { 0 };
1872 static const unsigned char bin51[] = { 0x04,0x00,0 };
1874 static const struct encodedOctets octets[] = {
1875 { bin46, bin47 },
1876 { bin48, bin49 },
1877 { bin50, bin51 },
1880 static void test_encodeOctets(DWORD dwEncoding)
1882 CRYPT_DATA_BLOB blob;
1883 DWORD i;
1885 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1887 BYTE *buf = NULL;
1888 BOOL ret;
1889 DWORD bufSize = 0;
1891 blob.cbData = strlen((const char*)octets[i].val);
1892 blob.pbData = (BYTE*)octets[i].val;
1893 ret = pCryptEncodeObjectEx(dwEncoding, X509_OCTET_STRING, &blob,
1894 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1895 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
1896 if (buf)
1898 ok(buf[0] == 4,
1899 "Got unexpected type %d for octet string (expected 4)\n", buf[0]);
1900 ok(buf[1] == octets[i].encoded[1], "Got length %d, expected %d\n",
1901 buf[1], octets[i].encoded[1]);
1902 ok(!memcmp(buf + 1, octets[i].encoded + 1,
1903 octets[i].encoded[1] + 1), "Got unexpected value\n");
1904 LocalFree(buf);
1909 static void test_decodeOctets(DWORD dwEncoding)
1911 DWORD i;
1913 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1915 BYTE *buf = NULL;
1916 BOOL ret;
1917 DWORD bufSize = 0;
1919 ret = pCryptDecodeObjectEx(dwEncoding, X509_OCTET_STRING,
1920 (BYTE *)octets[i].encoded, octets[i].encoded[1] + 2,
1921 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1922 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1923 ok(bufSize >= sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1],
1924 "Expected size >= %d, got %d\n",
1925 (int)sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1], bufSize);
1926 ok(buf != NULL, "Expected allocated buffer\n");
1927 if (buf)
1929 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)buf;
1931 if (blob->cbData)
1932 ok(!memcmp(blob->pbData, octets[i].val, blob->cbData),
1933 "Unexpected value\n");
1934 LocalFree(buf);
1939 static const BYTE bytesToEncode[] = { 0xff, 0xff };
1941 struct encodedBits
1943 DWORD cUnusedBits;
1944 const BYTE *encoded;
1945 DWORD cbDecoded;
1946 const BYTE *decoded;
1949 static const unsigned char bin52[] = { 0x03,0x03,0x00,0xff,0xff };
1950 static const unsigned char bin53[] = { 0xff,0xff };
1951 static const unsigned char bin54[] = { 0x03,0x03,0x01,0xff,0xfe };
1952 static const unsigned char bin55[] = { 0xff,0xfe };
1953 static const unsigned char bin56[] = { 0x03,0x02,0x01,0xfe };
1954 static const unsigned char bin57[] = { 0xfe };
1955 static const unsigned char bin58[] = { 0x03,0x01,0x00 };
1957 static const struct encodedBits bits[] = {
1958 /* normal test cases */
1959 { 0, bin52, 2, bin53 },
1960 { 1, bin54, 2, bin55 },
1961 /* strange test case, showing cUnusedBits >= 8 is allowed */
1962 { 9, bin56, 1, bin57 },
1963 /* even stranger test case, showing cUnusedBits > cbData * 8 is allowed */
1964 { 17, bin58, 0, NULL },
1967 static void test_encodeBits(DWORD dwEncoding)
1969 DWORD i;
1971 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
1973 CRYPT_BIT_BLOB blob;
1974 BOOL ret;
1975 BYTE *buf = NULL;
1976 DWORD bufSize = 0;
1978 blob.cbData = sizeof(bytesToEncode);
1979 blob.pbData = (BYTE *)bytesToEncode;
1980 blob.cUnusedBits = bits[i].cUnusedBits;
1981 ret = pCryptEncodeObjectEx(dwEncoding, X509_BITS, &blob,
1982 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1983 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1984 if (buf)
1986 ok(bufSize == bits[i].encoded[1] + 2,
1987 "Got unexpected size %d, expected %d\n", bufSize,
1988 bits[i].encoded[1] + 2);
1989 ok(!memcmp(buf, bits[i].encoded, bits[i].encoded[1] + 2),
1990 "Unexpected value\n");
1991 LocalFree(buf);
1996 static void test_decodeBits(DWORD dwEncoding)
1998 static const BYTE ber[] = "\x03\x02\x01\xff";
1999 static const BYTE berDecoded = 0xfe;
2000 DWORD i;
2001 BOOL ret;
2002 BYTE *buf = NULL;
2003 DWORD bufSize = 0;
2005 /* normal cases */
2006 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
2008 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, bits[i].encoded,
2009 bits[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2010 &bufSize);
2011 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2012 if (buf)
2014 CRYPT_BIT_BLOB *blob;
2016 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + bits[i].cbDecoded,
2017 "Got unexpected size %d\n", bufSize);
2018 blob = (CRYPT_BIT_BLOB *)buf;
2019 ok(blob->cbData == bits[i].cbDecoded,
2020 "Got unexpected length %d, expected %d\n", blob->cbData,
2021 bits[i].cbDecoded);
2022 if (blob->cbData && bits[i].cbDecoded)
2023 ok(!memcmp(blob->pbData, bits[i].decoded, bits[i].cbDecoded),
2024 "Unexpected value\n");
2025 LocalFree(buf);
2028 /* special case: check that something that's valid in BER but not in DER
2029 * decodes successfully
2031 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, ber, ber[1] + 2,
2032 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2033 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2034 if (buf)
2036 CRYPT_BIT_BLOB *blob;
2038 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + sizeof(berDecoded),
2039 "Got unexpected size %d\n", bufSize);
2040 blob = (CRYPT_BIT_BLOB *)buf;
2041 ok(blob->cbData == sizeof(berDecoded),
2042 "Got unexpected length %d\n", blob->cbData);
2043 if (blob->cbData)
2044 ok(*blob->pbData == berDecoded, "Unexpected value\n");
2045 LocalFree(buf);
2049 struct Constraints2
2051 CERT_BASIC_CONSTRAINTS2_INFO info;
2052 const BYTE *encoded;
2055 static const unsigned char bin59[] = { 0x30,0x00 };
2056 static const unsigned char bin60[] = { 0x30,0x03,0x01,0x01,0xff };
2057 static const unsigned char bin61[] = { 0x30,0x03,0x02,0x01,0x00 };
2058 static const unsigned char bin62[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2059 static const struct Constraints2 constraints2[] = {
2060 /* empty constraints */
2061 { { FALSE, FALSE, 0}, bin59 },
2062 /* can be a CA */
2063 { { TRUE, FALSE, 0}, bin60 },
2064 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well,
2065 * but that's not the case
2067 { { FALSE, TRUE, 0}, bin61 },
2068 /* can be a CA and has path length constraints set */
2069 { { TRUE, TRUE, 1}, bin62 },
2072 static const BYTE emptyConstraint[] = { 0x30, 0x03, 0x03, 0x01, 0x00 };
2073 static const BYTE encodedDomainName[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11,
2074 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
2075 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
2076 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2077 static const BYTE constraintWithDomainName[] = { 0x30, 0x32, 0x03, 0x01, 0x00,
2078 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
2079 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30,
2080 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
2081 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2083 static void test_encodeBasicConstraints(DWORD dwEncoding)
2085 DWORD i, bufSize = 0;
2086 CERT_BASIC_CONSTRAINTS_INFO info = { { 0 } };
2087 CERT_NAME_BLOB nameBlob = { sizeof(encodedDomainName),
2088 (LPBYTE)encodedDomainName };
2089 BOOL ret;
2090 BYTE *buf = NULL;
2092 /* First test with the simpler info2 */
2093 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2095 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2096 &constraints2[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2097 &bufSize);
2098 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2099 if (buf)
2101 ok(bufSize == constraints2[i].encoded[1] + 2,
2102 "Expected %d bytes, got %d\n", constraints2[i].encoded[1] + 2,
2103 bufSize);
2104 ok(!memcmp(buf, constraints2[i].encoded,
2105 constraints2[i].encoded[1] + 2), "Unexpected value\n");
2106 LocalFree(buf);
2109 /* Now test with more complex basic constraints */
2110 info.SubjectType.cbData = 0;
2111 info.fPathLenConstraint = FALSE;
2112 info.cSubtreesConstraint = 0;
2113 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2114 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2115 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2116 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2117 if (buf)
2119 ok(bufSize == sizeof(emptyConstraint), "Wrong size %d\n", bufSize);
2120 ok(!memcmp(buf, emptyConstraint, sizeof(emptyConstraint)),
2121 "Unexpected value\n");
2122 LocalFree(buf);
2124 /* None of the certs I examined had any subtree constraint, but I test one
2125 * anyway just in case.
2127 info.cSubtreesConstraint = 1;
2128 info.rgSubtreesConstraint = &nameBlob;
2129 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2130 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2131 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2132 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2133 if (buf)
2135 ok(bufSize == sizeof(constraintWithDomainName), "Wrong size %d\n", bufSize);
2136 ok(!memcmp(buf, constraintWithDomainName,
2137 sizeof(constraintWithDomainName)), "Unexpected value\n");
2138 LocalFree(buf);
2140 /* FIXME: test encoding with subject type. */
2143 static const unsigned char bin63[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 };
2145 static void test_decodeBasicConstraints(DWORD dwEncoding)
2147 static const BYTE inverted[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01,
2148 0xff };
2149 static const struct Constraints2 badBool = { { TRUE, TRUE, 1 }, bin63 };
2150 DWORD i;
2151 BOOL ret;
2152 BYTE *buf = NULL;
2153 DWORD bufSize = 0;
2155 /* First test with simpler info2 */
2156 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2158 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2159 constraints2[i].encoded, constraints2[i].encoded[1] + 2,
2160 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2161 ok(ret, "CryptDecodeObjectEx failed for item %d: %08x\n", i,
2162 GetLastError());
2163 if (buf)
2165 CERT_BASIC_CONSTRAINTS2_INFO *info =
2166 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2168 ok(!memcmp(info, &constraints2[i].info, sizeof(*info)),
2169 "Unexpected value for item %d\n", i);
2170 LocalFree(buf);
2173 /* Check with the order of encoded elements inverted */
2174 buf = (PBYTE)1;
2175 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2176 inverted, inverted[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2177 &bufSize);
2178 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2179 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2180 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2181 GetLastError());
2182 ok(!buf, "Expected buf to be set to NULL\n");
2183 /* Check with a non-DER bool */
2184 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2185 badBool.encoded, badBool.encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2186 (BYTE *)&buf, &bufSize);
2187 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2188 if (buf)
2190 CERT_BASIC_CONSTRAINTS2_INFO *info =
2191 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2193 ok(!memcmp(info, &badBool.info, sizeof(*info)), "Unexpected value\n");
2194 LocalFree(buf);
2196 /* Check with a non-basic constraints value */
2197 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2198 (LPBYTE)encodedCommonName, encodedCommonName[1] + 2,
2199 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2200 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2201 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2202 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2203 GetLastError());
2204 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */
2205 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2206 emptyConstraint, sizeof(emptyConstraint), CRYPT_DECODE_ALLOC_FLAG, NULL,
2207 (BYTE *)&buf, &bufSize);
2208 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2209 if (buf)
2211 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2213 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2214 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2215 ok(info->cSubtreesConstraint == 0, "Expected no subtree constraints\n");
2216 LocalFree(buf);
2218 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2219 constraintWithDomainName, sizeof(constraintWithDomainName),
2220 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2221 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2222 if (buf)
2224 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2226 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2227 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2228 ok(info->cSubtreesConstraint == 1, "Expected a subtree constraint\n");
2229 if (info->cSubtreesConstraint && info->rgSubtreesConstraint)
2231 ok(info->rgSubtreesConstraint[0].cbData ==
2232 sizeof(encodedDomainName), "Wrong size %d\n",
2233 info->rgSubtreesConstraint[0].cbData);
2234 ok(!memcmp(info->rgSubtreesConstraint[0].pbData, encodedDomainName,
2235 sizeof(encodedDomainName)), "Unexpected value\n");
2237 LocalFree(buf);
2241 /* These are terrible public keys of course, I'm just testing encoding */
2242 static const BYTE modulus1[] = { 0,0,0,1,1,1,1,1 };
2243 static const BYTE modulus2[] = { 1,1,1,1,1,0,0,0 };
2244 static const BYTE modulus3[] = { 0x80,1,1,1,1,0,0,0 };
2245 static const BYTE modulus4[] = { 1,1,1,1,1,0,0,0x80 };
2246 static const BYTE mod1_encoded[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 };
2247 static const BYTE mod2_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2248 static const BYTE mod3_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 };
2249 static const BYTE mod4_encoded[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2251 struct EncodedRSAPubKey
2253 const BYTE *modulus;
2254 size_t modulusLen;
2255 const BYTE *encoded;
2256 size_t decodedModulusLen;
2259 struct EncodedRSAPubKey rsaPubKeys[] = {
2260 { modulus1, sizeof(modulus1), mod1_encoded, sizeof(modulus1) },
2261 { modulus2, sizeof(modulus2), mod2_encoded, 5 },
2262 { modulus3, sizeof(modulus3), mod3_encoded, 5 },
2263 { modulus4, sizeof(modulus4), mod4_encoded, 8 },
2266 static void test_encodeRsaPublicKey(DWORD dwEncoding)
2268 BYTE toEncode[sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + sizeof(modulus1)];
2269 BLOBHEADER *hdr = (BLOBHEADER *)toEncode;
2270 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(toEncode + sizeof(BLOBHEADER));
2271 BOOL ret;
2272 BYTE *buf = NULL;
2273 DWORD bufSize = 0, i;
2275 /* Try with a bogus blob type */
2276 hdr->bType = 2;
2277 hdr->bVersion = CUR_BLOB_VERSION;
2278 hdr->reserved = 0;
2279 hdr->aiKeyAlg = CALG_RSA_KEYX;
2280 rsaPubKey->magic = 0x31415352;
2281 rsaPubKey->bitlen = sizeof(modulus1) * 8;
2282 rsaPubKey->pubexp = 65537;
2283 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), modulus1,
2284 sizeof(modulus1));
2286 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2287 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2288 &bufSize);
2289 ok(!ret && GetLastError() == E_INVALIDARG,
2290 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2291 /* Now with a bogus reserved field */
2292 hdr->bType = PUBLICKEYBLOB;
2293 hdr->reserved = 1;
2294 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2295 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2296 &bufSize);
2297 if (buf)
2299 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2300 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2301 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2302 LocalFree(buf);
2304 /* Now with a bogus blob version */
2305 hdr->reserved = 0;
2306 hdr->bVersion = 0;
2307 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2308 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2309 &bufSize);
2310 if (buf)
2312 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2313 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2314 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2315 LocalFree(buf);
2317 /* And with a bogus alg ID */
2318 hdr->bVersion = CUR_BLOB_VERSION;
2319 hdr->aiKeyAlg = CALG_DES;
2320 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2321 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2322 &bufSize);
2323 if (buf)
2325 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2326 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2327 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2328 LocalFree(buf);
2330 /* Check a couple of RSA-related OIDs */
2331 hdr->aiKeyAlg = CALG_RSA_KEYX;
2332 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_RSA,
2333 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2334 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2335 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2336 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2337 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2338 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2339 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2340 /* Finally, all valid */
2341 hdr->aiKeyAlg = CALG_RSA_KEYX;
2342 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2344 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2345 rsaPubKeys[i].modulus, rsaPubKeys[i].modulusLen);
2346 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2347 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2348 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2349 if (buf)
2351 ok(bufSize == rsaPubKeys[i].encoded[1] + 2,
2352 "Expected size %d, got %d\n", rsaPubKeys[i].encoded[1] + 2,
2353 bufSize);
2354 ok(!memcmp(buf, rsaPubKeys[i].encoded, bufSize),
2355 "Unexpected value\n");
2356 LocalFree(buf);
2361 static void test_decodeRsaPublicKey(DWORD dwEncoding)
2363 DWORD i;
2364 LPBYTE buf = NULL;
2365 DWORD bufSize = 0;
2366 BOOL ret;
2368 /* Try with a bad length */
2369 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2370 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1],
2371 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2372 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
2373 GetLastError() == OSS_MORE_INPUT /* Win9x/NT4 */),
2374 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n",
2375 GetLastError());
2376 /* Try with a couple of RSA-related OIDs */
2377 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_RSA,
2378 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2379 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2380 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2381 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2382 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2383 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2384 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2385 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2386 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2387 /* Now try success cases */
2388 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2390 bufSize = 0;
2391 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2392 rsaPubKeys[i].encoded, rsaPubKeys[i].encoded[1] + 2,
2393 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2394 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2395 if (buf)
2397 BLOBHEADER *hdr = (BLOBHEADER *)buf;
2398 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER));
2400 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2401 rsaPubKeys[i].decodedModulusLen,
2402 "Wrong size %d\n", bufSize);
2403 ok(hdr->bType == PUBLICKEYBLOB,
2404 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB,
2405 hdr->bType);
2406 ok(hdr->bVersion == CUR_BLOB_VERSION,
2407 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
2408 CUR_BLOB_VERSION, hdr->bVersion);
2409 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n",
2410 hdr->reserved);
2411 ok(hdr->aiKeyAlg == CALG_RSA_KEYX,
2412 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg);
2413 ok(rsaPubKey->magic == 0x31415352,
2414 "Expected magic RSA1, got %08x\n", rsaPubKey->magic);
2415 ok(rsaPubKey->bitlen == rsaPubKeys[i].decodedModulusLen * 8,
2416 "Wrong bit len %d\n", rsaPubKey->bitlen);
2417 ok(rsaPubKey->pubexp == 65537, "Expected pubexp 65537, got %d\n",
2418 rsaPubKey->pubexp);
2419 ok(!memcmp(buf + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2420 rsaPubKeys[i].modulus, rsaPubKeys[i].decodedModulusLen),
2421 "Unexpected modulus\n");
2422 LocalFree(buf);
2427 static const BYTE intSequence[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01,
2428 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02,
2429 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2431 static const BYTE mixedSequence[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
2432 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f,
2433 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02,
2434 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2436 static void test_encodeSequenceOfAny(DWORD dwEncoding)
2438 CRYPT_DER_BLOB blobs[sizeof(ints) / sizeof(ints[0])];
2439 CRYPT_SEQUENCE_OF_ANY seq;
2440 DWORD i;
2441 BOOL ret;
2442 BYTE *buf = NULL;
2443 DWORD bufSize = 0;
2445 /* Encode a homogeneous sequence */
2446 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
2448 blobs[i].cbData = ints[i].encoded[1] + 2;
2449 blobs[i].pbData = (BYTE *)ints[i].encoded;
2451 seq.cValue = sizeof(ints) / sizeof(ints[0]);
2452 seq.rgValue = blobs;
2454 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2455 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2456 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2457 if (buf)
2459 ok(bufSize == sizeof(intSequence), "Wrong size %d\n", bufSize);
2460 ok(!memcmp(buf, intSequence, intSequence[1] + 2), "Unexpected value\n");
2461 LocalFree(buf);
2463 /* Change the type of the first element in the sequence, and give it
2464 * another go
2466 blobs[0].cbData = times[0].encodedTime[1] + 2;
2467 blobs[0].pbData = (BYTE *)times[0].encodedTime;
2468 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2469 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2470 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2471 if (buf)
2473 ok(bufSize == sizeof(mixedSequence), "Wrong size %d\n", bufSize);
2474 ok(!memcmp(buf, mixedSequence, mixedSequence[1] + 2),
2475 "Unexpected value\n");
2476 LocalFree(buf);
2480 static void test_decodeSequenceOfAny(DWORD dwEncoding)
2482 BOOL ret;
2483 BYTE *buf = NULL;
2484 DWORD bufSize = 0;
2486 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, intSequence,
2487 intSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2488 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2489 if (buf)
2491 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2492 DWORD i;
2494 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2495 "Wrong elements %d\n", seq->cValue);
2496 for (i = 0; i < min(seq->cValue, sizeof(ints) / sizeof(ints[0])); i++)
2498 ok(seq->rgValue[i].cbData == ints[i].encoded[1] + 2,
2499 "Expected %d bytes, got %d\n", ints[i].encoded[1] + 2,
2500 seq->rgValue[i].cbData);
2501 ok(!memcmp(seq->rgValue[i].pbData, ints[i].encoded,
2502 ints[i].encoded[1] + 2), "Unexpected value\n");
2504 LocalFree(buf);
2506 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, mixedSequence,
2507 mixedSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2508 &bufSize);
2509 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2510 if (buf)
2512 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2514 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2515 "Wrong elements %d\n", seq->cValue);
2516 /* Just check the first element since it's all that changed */
2517 ok(seq->rgValue[0].cbData == times[0].encodedTime[1] + 2,
2518 "Expected %d bytes, got %d\n", times[0].encodedTime[1] + 2,
2519 seq->rgValue[0].cbData);
2520 ok(!memcmp(seq->rgValue[0].pbData, times[0].encodedTime,
2521 times[0].encodedTime[1] + 2), "Unexpected value\n");
2522 LocalFree(buf);
2526 struct encodedExtensions
2528 CERT_EXTENSIONS exts;
2529 const BYTE *encoded;
2532 static BYTE crit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2533 static BYTE noncrit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2534 static CHAR oid_basic_constraints2[] = szOID_BASIC_CONSTRAINTS2;
2535 static CERT_EXTENSION criticalExt =
2536 { oid_basic_constraints2, TRUE, { 8, crit_ext_data } };
2537 static CERT_EXTENSION nonCriticalExt =
2538 { oid_basic_constraints2, FALSE, { 8, noncrit_ext_data } };
2540 static const BYTE ext0[] = { 0x30,0x00 };
2541 static const BYTE ext1[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2542 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2543 static const BYTE ext2[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2544 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2546 static const struct encodedExtensions exts[] = {
2547 { { 0, NULL }, ext0 },
2548 { { 1, &criticalExt }, ext1 },
2549 { { 1, &nonCriticalExt }, ext2 },
2552 static void test_encodeExtensions(DWORD dwEncoding)
2554 DWORD i;
2556 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2558 BOOL ret;
2559 BYTE *buf = NULL;
2560 DWORD bufSize = 0;
2562 ret = pCryptEncodeObjectEx(dwEncoding, X509_EXTENSIONS, &exts[i].exts,
2563 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2564 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2565 if (buf)
2567 ok(bufSize == exts[i].encoded[1] + 2,
2568 "Expected %d bytes, got %d\n", exts[i].encoded[1] + 2, bufSize);
2569 ok(!memcmp(buf, exts[i].encoded, exts[i].encoded[1] + 2),
2570 "Unexpected value\n");
2571 LocalFree(buf);
2576 static void test_decodeExtensions(DWORD dwEncoding)
2578 DWORD i;
2580 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2582 BOOL ret;
2583 BYTE *buf = NULL;
2584 DWORD bufSize = 0;
2586 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS,
2587 exts[i].encoded, exts[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2588 NULL, (BYTE *)&buf, &bufSize);
2589 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2590 if (buf)
2592 CERT_EXTENSIONS *ext = (CERT_EXTENSIONS *)buf;
2593 DWORD j;
2595 ok(ext->cExtension == exts[i].exts.cExtension,
2596 "Expected %d extensions, see %d\n", exts[i].exts.cExtension,
2597 ext->cExtension);
2598 for (j = 0; j < min(ext->cExtension, exts[i].exts.cExtension); j++)
2600 ok(!strcmp(ext->rgExtension[j].pszObjId,
2601 exts[i].exts.rgExtension[j].pszObjId),
2602 "Expected OID %s, got %s\n",
2603 exts[i].exts.rgExtension[j].pszObjId,
2604 ext->rgExtension[j].pszObjId);
2605 ok(!memcmp(ext->rgExtension[j].Value.pbData,
2606 exts[i].exts.rgExtension[j].Value.pbData,
2607 exts[i].exts.rgExtension[j].Value.cbData),
2608 "Unexpected value\n");
2610 LocalFree(buf);
2615 /* MS encodes public key info with a NULL if the algorithm identifier's
2616 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2617 * it encodes them by omitting the algorithm parameters. This latter approach
2618 * seems more correct, so accept either form.
2620 struct encodedPublicKey
2622 CERT_PUBLIC_KEY_INFO info;
2623 const BYTE *encoded;
2624 const BYTE *encodedNoNull;
2625 CERT_PUBLIC_KEY_INFO decoded;
2628 static const BYTE aKey[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2629 0xe, 0xf };
2630 static const BYTE params[] = { 0x02, 0x01, 0x01 };
2632 static const unsigned char bin64[] = {
2633 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2634 static const unsigned char bin65[] = {
2635 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2636 static const unsigned char bin66[] = {
2637 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2638 static const unsigned char bin67[] = {
2639 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2640 static const unsigned char bin68[] = {
2641 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01,
2642 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2643 static const unsigned char bin69[] = {
2644 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2645 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2646 static const unsigned char bin70[] = {
2647 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2648 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2649 0x0f};
2650 static const unsigned char bin71[] = {
2651 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2652 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2653 0x0f};
2654 static unsigned char bin72[] = { 0x05,0x00};
2656 static CHAR oid_bogus[] = "1.2.3",
2657 oid_rsa[] = szOID_RSA;
2659 static const struct encodedPublicKey pubKeys[] = {
2660 /* with a bogus OID */
2661 { { { oid_bogus, { 0, NULL } }, { 0, NULL, 0 } },
2662 bin64, bin65,
2663 { { oid_bogus, { 2, bin72 } }, { 0, NULL, 0 } } },
2664 /* some normal keys */
2665 { { { oid_rsa, { 0, NULL } }, { 0, NULL, 0} },
2666 bin66, bin67,
2667 { { oid_rsa, { 2, bin72 } }, { 0, NULL, 0 } } },
2668 { { { oid_rsa, { 0, NULL } }, { sizeof(aKey), (BYTE *)aKey, 0} },
2669 bin68, bin69,
2670 { { oid_rsa, { 2, bin72 } }, { sizeof(aKey), (BYTE *)aKey, 0} } },
2671 /* with add'l parameters--note they must be DER-encoded */
2672 { { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2673 (BYTE *)aKey, 0 } },
2674 bin70, bin71,
2675 { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2676 (BYTE *)aKey, 0 } } },
2679 static void test_encodePublicKeyInfo(DWORD dwEncoding)
2681 DWORD i;
2683 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2685 BOOL ret;
2686 BYTE *buf = NULL;
2687 DWORD bufSize = 0;
2689 ret = pCryptEncodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2690 &pubKeys[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2691 &bufSize);
2692 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2693 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2694 if (buf)
2696 ok(bufSize == pubKeys[i].encoded[1] + 2 ||
2697 bufSize == pubKeys[i].encodedNoNull[1] + 2,
2698 "Expected %d or %d bytes, got %d\n", pubKeys[i].encoded[1] + 2,
2699 pubKeys[i].encodedNoNull[1] + 2, bufSize);
2700 if (bufSize == pubKeys[i].encoded[1] + 2)
2701 ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2),
2702 "Unexpected value\n");
2703 else if (bufSize == pubKeys[i].encodedNoNull[1] + 2)
2704 ok(!memcmp(buf, pubKeys[i].encodedNoNull,
2705 pubKeys[i].encodedNoNull[1] + 2), "Unexpected value\n");
2706 LocalFree(buf);
2711 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO *expected,
2712 const CERT_PUBLIC_KEY_INFO *got)
2714 ok(!strcmp(expected->Algorithm.pszObjId, got->Algorithm.pszObjId),
2715 "Expected OID %s, got %s\n", expected->Algorithm.pszObjId,
2716 got->Algorithm.pszObjId);
2717 ok(expected->Algorithm.Parameters.cbData ==
2718 got->Algorithm.Parameters.cbData,
2719 "Expected parameters of %d bytes, got %d\n",
2720 expected->Algorithm.Parameters.cbData, got->Algorithm.Parameters.cbData);
2721 if (expected->Algorithm.Parameters.cbData)
2722 ok(!memcmp(expected->Algorithm.Parameters.pbData,
2723 got->Algorithm.Parameters.pbData, got->Algorithm.Parameters.cbData),
2724 "Unexpected algorithm parameters\n");
2725 ok(expected->PublicKey.cbData == got->PublicKey.cbData,
2726 "Expected public key of %d bytes, got %d\n",
2727 expected->PublicKey.cbData, got->PublicKey.cbData);
2728 if (expected->PublicKey.cbData)
2729 ok(!memcmp(expected->PublicKey.pbData, got->PublicKey.pbData,
2730 got->PublicKey.cbData), "Unexpected public key value\n");
2733 static void test_decodePublicKeyInfo(DWORD dwEncoding)
2735 static const BYTE bogusPubKeyInfo[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
2736 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
2737 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
2738 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2739 DWORD i;
2740 BOOL ret;
2741 BYTE *buf = NULL;
2742 DWORD bufSize = 0;
2744 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2746 /* The NULL form decodes to the decoded member */
2747 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2748 pubKeys[i].encoded, pubKeys[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2749 NULL, (BYTE *)&buf, &bufSize);
2750 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2751 if (buf)
2753 comparePublicKeyInfo(&pubKeys[i].decoded,
2754 (CERT_PUBLIC_KEY_INFO *)buf);
2755 LocalFree(buf);
2757 /* The non-NULL form decodes to the original */
2758 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2759 pubKeys[i].encodedNoNull, pubKeys[i].encodedNoNull[1] + 2,
2760 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2761 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2762 if (buf)
2764 comparePublicKeyInfo(&pubKeys[i].info, (CERT_PUBLIC_KEY_INFO *)buf);
2765 LocalFree(buf);
2768 /* Test with bogus (not valid DER) parameters */
2769 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2770 bogusPubKeyInfo, bogusPubKeyInfo[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2771 NULL, (BYTE *)&buf, &bufSize);
2772 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2773 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2774 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2775 GetLastError());
2778 static const BYTE v1Cert[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
2779 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2780 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
2781 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
2782 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2783 static const BYTE v2Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02,
2784 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2785 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2786 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2787 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2788 static const BYTE v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2789 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2790 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2791 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2792 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2793 static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
2794 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2795 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2796 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2797 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2798 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2799 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2800 static const BYTE v1CertWithSerial[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
2801 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2802 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2803 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2804 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2805 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2806 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2807 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2808 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
2809 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
2810 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
2811 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
2812 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
2813 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
2814 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
2815 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
2816 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2817 static const BYTE v1CertWithPubKey[] = {
2818 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2819 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2820 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2821 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2822 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2823 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2824 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2825 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2826 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
2827 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
2828 0x01,0x01 };
2829 static const BYTE v1CertWithPubKeyNoNull[] = {
2830 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2831 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2832 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2833 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2834 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2835 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2836 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2837 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2838 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
2839 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2840 static const BYTE v1CertWithSubjectKeyId[] = {
2841 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2842 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2843 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2844 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2845 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2846 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2847 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
2848 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2849 0x4c,0x61,0x6e,0x67,0x00 };
2851 static const BYTE serialNum[] = { 0x01 };
2853 static void test_encodeCertToBeSigned(DWORD dwEncoding)
2855 BOOL ret;
2856 BYTE *buf = NULL;
2857 DWORD size = 0;
2858 CERT_INFO info = { 0 };
2859 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2860 static char oid_subject_key_identifier[] = szOID_SUBJECT_KEY_IDENTIFIER;
2861 CERT_EXTENSION ext;
2863 if (0)
2865 /* Test with NULL pvStructInfo (crashes on win9x) */
2866 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL,
2867 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2868 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2869 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2871 /* Test with a V1 cert */
2872 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2873 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2874 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2875 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2876 if (buf)
2878 ok(size == v1Cert[1] + 2, "Expected size %d, got %d\n",
2879 v1Cert[1] + 2, size);
2880 ok(!memcmp(buf, v1Cert, size), "Got unexpected value\n");
2881 LocalFree(buf);
2883 /* Test v2 cert */
2884 info.dwVersion = CERT_V2;
2885 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2886 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2887 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2888 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2889 if (buf)
2891 ok(size == sizeof(v2Cert), "Wrong size %d\n", size);
2892 ok(!memcmp(buf, v2Cert, size), "Got unexpected value\n");
2893 LocalFree(buf);
2895 /* Test v3 cert */
2896 info.dwVersion = CERT_V3;
2897 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2898 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2899 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2900 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2901 if (buf)
2903 ok(size == sizeof(v3Cert), "Wrong size %d\n", size);
2904 ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n");
2905 LocalFree(buf);
2907 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
2908 * API doesn't prevent it)
2910 info.dwVersion = CERT_V1;
2911 info.cExtension = 1;
2912 info.rgExtension = &criticalExt;
2913 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2914 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2915 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2916 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2917 if (buf)
2919 ok(size == sizeof(v1CertWithConstraints), "Wrong size %d\n", size);
2920 ok(!memcmp(buf, v1CertWithConstraints, size), "Got unexpected value\n");
2921 LocalFree(buf);
2923 /* test v1 cert with a serial number */
2924 info.SerialNumber.cbData = sizeof(serialNum);
2925 info.SerialNumber.pbData = (BYTE *)serialNum;
2926 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2927 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2928 if (buf)
2930 ok(size == sizeof(v1CertWithSerial), "Wrong size %d\n", size);
2931 ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n");
2932 LocalFree(buf);
2934 /* Test v1 cert with an issuer name, a subject name, and a serial number */
2935 info.Issuer.cbData = sizeof(encodedCommonName);
2936 info.Issuer.pbData = (BYTE *)encodedCommonName;
2937 info.Subject.cbData = sizeof(encodedCommonName);
2938 info.Subject.pbData = (BYTE *)encodedCommonName;
2939 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2940 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2941 if (buf)
2943 ok(size == sizeof(bigCert), "Wrong size %d\n", size);
2944 ok(!memcmp(buf, bigCert, size), "Got unexpected value\n");
2945 LocalFree(buf);
2947 /* Add a public key */
2948 info.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2949 info.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2950 info.SubjectPublicKeyInfo.PublicKey.pbData = (LPBYTE)aKey;
2951 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2952 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2953 if (buf)
2955 ok(size == sizeof(v1CertWithPubKey) ||
2956 size == sizeof(v1CertWithPubKeyNoNull), "Wrong size %d\n", size);
2957 if (size == sizeof(v1CertWithPubKey))
2958 ok(!memcmp(buf, v1CertWithPubKey, size), "Got unexpected value\n");
2959 else if (size == sizeof(v1CertWithPubKeyNoNull))
2960 ok(!memcmp(buf, v1CertWithPubKeyNoNull, size),
2961 "Got unexpected value\n");
2962 LocalFree(buf);
2964 /* Remove the public key, and add a subject key identifier extension */
2965 info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2966 info.SubjectPublicKeyInfo.PublicKey.cbData = 0;
2967 info.SubjectPublicKeyInfo.PublicKey.pbData = NULL;
2968 ext.pszObjId = oid_subject_key_identifier;
2969 ext.fCritical = FALSE;
2970 ext.Value.cbData = sizeof(octetCommonNameValue);
2971 ext.Value.pbData = (BYTE *)octetCommonNameValue;
2972 info.cExtension = 1;
2973 info.rgExtension = &ext;
2974 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2975 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2976 if (buf)
2978 ok(size == sizeof(v1CertWithSubjectKeyId), "Wrong size %d\n", size);
2979 ok(!memcmp(buf, v1CertWithSubjectKeyId, size), "Unexpected value\n");
2980 LocalFree(buf);
2984 static void test_decodeCertToBeSigned(DWORD dwEncoding)
2986 static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert,
2987 v1CertWithConstraints, v1CertWithSerial };
2988 BOOL ret;
2989 BYTE *buf = NULL;
2990 DWORD size = 0, i;
2992 /* Test with NULL pbEncoded */
2993 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 0,
2994 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2995 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
2996 GetLastError() == OSS_BAD_ARG /* Win9x */),
2997 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
2998 if (0)
3000 /* Crashes on win9x */
3001 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 1,
3002 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3003 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3004 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3006 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT, because at a
3007 * minimum a cert must have a non-zero serial number, an issuer, and a
3008 * subject.
3010 for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++)
3012 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3013 corruptCerts[i], corruptCerts[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3014 (BYTE *)&buf, &size);
3015 ok(!ret, "Expected failure\n");
3017 /* Now check with serial number, subject and issuer specified */
3018 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert,
3019 sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3020 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3021 if (buf)
3023 CERT_INFO *info = (CERT_INFO *)buf;
3025 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3026 ok(info->SerialNumber.cbData == 1,
3027 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3028 ok(*info->SerialNumber.pbData == *serialNum,
3029 "Expected serial number %d, got %d\n", *serialNum,
3030 *info->SerialNumber.pbData);
3031 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3032 "Wrong size %d\n", info->Issuer.cbData);
3033 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3034 "Unexpected issuer\n");
3035 ok(info->Subject.cbData == sizeof(encodedCommonName),
3036 "Wrong size %d\n", info->Subject.cbData);
3037 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3038 info->Subject.cbData), "Unexpected subject\n");
3039 LocalFree(buf);
3041 /* Check again with pub key specified */
3042 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3043 v1CertWithPubKey, sizeof(v1CertWithPubKey), CRYPT_DECODE_ALLOC_FLAG, NULL,
3044 (BYTE *)&buf, &size);
3045 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3046 if (buf)
3048 CERT_INFO *info = (CERT_INFO *)buf;
3050 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3051 ok(info->SerialNumber.cbData == 1,
3052 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3053 ok(*info->SerialNumber.pbData == *serialNum,
3054 "Expected serial number %d, got %d\n", *serialNum,
3055 *info->SerialNumber.pbData);
3056 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3057 "Wrong size %d\n", info->Issuer.cbData);
3058 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3059 "Unexpected issuer\n");
3060 ok(info->Subject.cbData == sizeof(encodedCommonName),
3061 "Wrong size %d\n", info->Subject.cbData);
3062 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3063 info->Subject.cbData), "Unexpected subject\n");
3064 ok(!strcmp(info->SubjectPublicKeyInfo.Algorithm.pszObjId,
3065 szOID_RSA_RSA), "Expected szOID_RSA_RSA, got %s\n",
3066 info->SubjectPublicKeyInfo.Algorithm.pszObjId);
3067 ok(info->SubjectPublicKeyInfo.PublicKey.cbData == sizeof(aKey),
3068 "Wrong size %d\n", info->SubjectPublicKeyInfo.PublicKey.cbData);
3069 ok(!memcmp(info->SubjectPublicKeyInfo.PublicKey.pbData, aKey,
3070 sizeof(aKey)), "Unexpected public key\n");
3071 LocalFree(buf);
3075 static const BYTE hash[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
3076 0xe, 0xf };
3078 static const BYTE signedBigCert[] = {
3079 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
3080 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
3081 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
3082 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3083 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
3084 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
3085 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
3086 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
3087 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
3088 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3089 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
3090 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
3092 static void test_encodeCert(DWORD dwEncoding)
3094 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
3095 * also that bigCert is a NULL-terminated string, so don't count its
3096 * last byte (otherwise the signed cert won't decode.)
3098 CERT_SIGNED_CONTENT_INFO info = { { sizeof(bigCert), (BYTE *)bigCert },
3099 { NULL, { 0, NULL } }, { sizeof(hash), (BYTE *)hash, 0 } };
3100 BOOL ret;
3101 BYTE *buf = NULL;
3102 DWORD bufSize = 0;
3104 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT, &info,
3105 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
3106 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3107 if (buf)
3109 ok(bufSize == sizeof(signedBigCert), "Wrong size %d\n", bufSize);
3110 ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n");
3111 LocalFree(buf);
3115 static void test_decodeCert(DWORD dwEncoding)
3117 BOOL ret;
3118 BYTE *buf = NULL;
3119 DWORD size = 0;
3121 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert,
3122 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3123 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3124 if (buf)
3126 CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf;
3128 ok(info->ToBeSigned.cbData == sizeof(bigCert),
3129 "Wrong cert size %d\n", info->ToBeSigned.cbData);
3130 ok(!memcmp(info->ToBeSigned.pbData, bigCert, info->ToBeSigned.cbData),
3131 "Unexpected cert\n");
3132 ok(info->Signature.cbData == sizeof(hash),
3133 "Wrong signature size %d\n", info->Signature.cbData);
3134 ok(!memcmp(info->Signature.pbData, hash, info->Signature.cbData),
3135 "Unexpected signature\n");
3136 LocalFree(buf);
3138 /* A signed cert decodes as a CERT_INFO too */
3139 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCert,
3140 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3141 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3142 if (buf)
3144 CERT_INFO *info = (CERT_INFO *)buf;
3146 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3147 ok(info->SerialNumber.cbData == 1,
3148 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3149 ok(*info->SerialNumber.pbData == *serialNum,
3150 "Expected serial number %d, got %d\n", *serialNum,
3151 *info->SerialNumber.pbData);
3152 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3153 "Wrong size %d\n", info->Issuer.cbData);
3154 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3155 "Unexpected issuer\n");
3156 ok(info->Subject.cbData == sizeof(encodedCommonName),
3157 "Wrong size %d\n", info->Subject.cbData);
3158 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3159 info->Subject.cbData), "Unexpected subject\n");
3160 LocalFree(buf);
3164 static const BYTE emptyDistPoint[] = { 0x30, 0x02, 0x30, 0x00 };
3165 static const BYTE distPointWithUrl[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3166 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3167 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3168 static const BYTE distPointWithReason[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3169 0x00, 0x03 };
3170 static const BYTE distPointWithIssuer[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3171 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3172 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3173 static const BYTE distPointWithUrlAndIssuer[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3174 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3175 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3176 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3177 0x2e, 0x6f, 0x72, 0x67 };
3178 static const BYTE crlReason = CRL_REASON_KEY_COMPROMISE |
3179 CRL_REASON_AFFILIATION_CHANGED;
3181 static void test_encodeCRLDistPoints(DWORD dwEncoding)
3183 CRL_DIST_POINTS_INFO info = { 0 };
3184 CRL_DIST_POINT point = { { 0 } };
3185 CERT_ALT_NAME_ENTRY entry = { 0 };
3186 BOOL ret;
3187 BYTE *buf = NULL;
3188 DWORD size = 0;
3190 /* Test with an empty info */
3191 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3192 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3193 ok(!ret && GetLastError() == E_INVALIDARG,
3194 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3195 /* Test with one empty dist point */
3196 info.cDistPoint = 1;
3197 info.rgDistPoint = &point;
3198 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3199 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3200 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3201 if (buf)
3203 ok(size == sizeof(emptyDistPoint), "Wrong size %d\n", size);
3204 ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n");
3205 LocalFree(buf);
3207 /* A dist point with an invalid name */
3208 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3209 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3210 U(entry).pwszURL = (LPWSTR)nihongoURL;
3211 U(point.DistPointName).FullName.cAltEntry = 1;
3212 U(point.DistPointName).FullName.rgAltEntry = &entry;
3213 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3214 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3215 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
3216 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
3217 /* The first invalid character is at index 7 */
3218 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
3219 "Expected invalid char at index 7, got %d\n",
3220 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
3221 /* A dist point with (just) a valid name */
3222 U(entry).pwszURL = (LPWSTR)url;
3223 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3224 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3225 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3226 if (buf)
3228 ok(size == sizeof(distPointWithUrl), "Wrong size %d\n", size);
3229 ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n");
3230 LocalFree(buf);
3232 /* A dist point with (just) reason flags */
3233 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3234 point.ReasonFlags.cbData = sizeof(crlReason);
3235 point.ReasonFlags.pbData = (LPBYTE)&crlReason;
3236 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3237 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3238 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3239 if (buf)
3241 ok(size == sizeof(distPointWithReason), "Wrong size %d\n", size);
3242 ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n");
3243 LocalFree(buf);
3245 /* A dist point with just an issuer */
3246 point.ReasonFlags.cbData = 0;
3247 point.CRLIssuer.cAltEntry = 1;
3248 point.CRLIssuer.rgAltEntry = &entry;
3249 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3250 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3251 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3252 if (buf)
3254 ok(size == sizeof(distPointWithIssuer), "Wrong size %d\n", size);
3255 ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n");
3256 LocalFree(buf);
3258 /* A dist point with both a name and an issuer */
3259 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3260 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3261 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3262 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3263 if (buf)
3265 ok(size == sizeof(distPointWithUrlAndIssuer),
3266 "Wrong size %d\n", size);
3267 ok(!memcmp(buf, distPointWithUrlAndIssuer, size), "Unexpected value\n");
3268 LocalFree(buf);
3272 static void test_decodeCRLDistPoints(DWORD dwEncoding)
3274 BOOL ret;
3275 BYTE *buf = NULL;
3276 DWORD size = 0;
3277 PCRL_DIST_POINTS_INFO info;
3278 PCRL_DIST_POINT point;
3279 PCERT_ALT_NAME_ENTRY entry;
3281 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3282 emptyDistPoint, emptyDistPoint[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3283 (BYTE *)&buf, &size);
3284 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3285 if (ret)
3287 info = (PCRL_DIST_POINTS_INFO)buf;
3288 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3289 "Wrong size %d\n", size);
3290 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3291 info->cDistPoint);
3292 point = info->rgDistPoint;
3293 ok(point->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_NO_NAME,
3294 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3295 point->DistPointName.dwDistPointNameChoice);
3296 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3297 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3298 LocalFree(buf);
3300 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3301 distPointWithUrl, distPointWithUrl[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3302 (BYTE *)&buf, &size);
3303 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3304 if (ret)
3306 info = (PCRL_DIST_POINTS_INFO)buf;
3307 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3308 "Wrong size %d\n", size);
3309 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3310 info->cDistPoint);
3311 point = info->rgDistPoint;
3312 ok(point->DistPointName.dwDistPointNameChoice ==
3313 CRL_DIST_POINT_FULL_NAME,
3314 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3315 point->DistPointName.dwDistPointNameChoice);
3316 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3317 "Expected 1 name entry, got %d\n",
3318 U(point->DistPointName).FullName.cAltEntry);
3319 entry = U(point->DistPointName).FullName.rgAltEntry;
3320 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3321 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3322 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3323 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3324 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3325 LocalFree(buf);
3327 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3328 distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
3329 NULL, (BYTE *)&buf, &size);
3330 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3331 if (ret)
3333 info = (PCRL_DIST_POINTS_INFO)buf;
3334 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3335 "Wrong size %d\n", size);
3336 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3337 info->cDistPoint);
3338 point = info->rgDistPoint;
3339 ok(point->DistPointName.dwDistPointNameChoice ==
3340 CRL_DIST_POINT_NO_NAME,
3341 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3342 point->DistPointName.dwDistPointNameChoice);
3343 ok(point->ReasonFlags.cbData == sizeof(crlReason),
3344 "Expected reason length\n");
3345 ok(!memcmp(point->ReasonFlags.pbData, &crlReason, sizeof(crlReason)),
3346 "Unexpected reason\n");
3347 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3348 LocalFree(buf);
3350 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3351 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2,
3352 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3353 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3354 if (ret)
3356 info = (PCRL_DIST_POINTS_INFO)buf;
3357 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3358 "Wrong size %d\n", size);
3359 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3360 info->cDistPoint);
3361 point = info->rgDistPoint;
3362 ok(point->DistPointName.dwDistPointNameChoice ==
3363 CRL_DIST_POINT_FULL_NAME,
3364 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3365 point->DistPointName.dwDistPointNameChoice);
3366 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3367 "Expected 1 name entry, got %d\n",
3368 U(point->DistPointName).FullName.cAltEntry);
3369 entry = U(point->DistPointName).FullName.rgAltEntry;
3370 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3371 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3372 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3373 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3374 ok(point->CRLIssuer.cAltEntry == 1,
3375 "Expected 1 issuer entry, got %d\n", point->CRLIssuer.cAltEntry);
3376 entry = point->CRLIssuer.rgAltEntry;
3377 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3378 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3379 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3380 LocalFree(buf);
3384 static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3385 static const BYTE emptyNameIDP[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3386 static const BYTE urlIDP[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3387 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3388 0x67 };
3390 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding)
3392 BOOL ret;
3393 BYTE *buf = NULL;
3394 DWORD size = 0;
3395 CRL_ISSUING_DIST_POINT point = { { 0 } };
3396 CERT_ALT_NAME_ENTRY entry;
3398 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, NULL,
3399 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3400 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3402 skip("no X509_ISSUING_DIST_POINT encode support\n");
3403 return;
3405 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3406 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3407 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3408 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3409 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3410 if (buf)
3412 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
3413 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
3414 LocalFree(buf);
3416 /* nonsensical flags */
3417 point.fOnlyContainsUserCerts = TRUE;
3418 point.fOnlyContainsCACerts = TRUE;
3419 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3420 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3421 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3422 if (buf)
3424 ok(size == sizeof(badFlagsIDP), "Unexpected size %d\n", size);
3425 ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n");
3426 LocalFree(buf);
3428 /* unimplemented name type */
3429 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3430 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_ISSUER_RDN_NAME;
3431 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3432 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3433 ok(!ret && GetLastError() == E_INVALIDARG,
3434 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3435 /* empty name */
3436 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3437 U(point.DistPointName).FullName.cAltEntry = 0;
3438 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3439 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3440 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3441 if (buf)
3443 ok(size == sizeof(emptyNameIDP), "Unexpected size %d\n", size);
3444 ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n");
3445 LocalFree(buf);
3447 /* name with URL entry */
3448 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3449 U(entry).pwszURL = (LPWSTR)url;
3450 U(point.DistPointName).FullName.cAltEntry = 1;
3451 U(point.DistPointName).FullName.rgAltEntry = &entry;
3452 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3453 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3454 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3455 if (buf)
3457 ok(size == sizeof(urlIDP), "Unexpected size %d\n", size);
3458 ok(!memcmp(buf, urlIDP, size), "Unexpected value\n");
3459 LocalFree(buf);
3463 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY *expected,
3464 const CERT_ALT_NAME_ENTRY *got)
3466 ok(expected->dwAltNameChoice == got->dwAltNameChoice,
3467 "Expected name choice %d, got %d\n", expected->dwAltNameChoice,
3468 got->dwAltNameChoice);
3469 if (expected->dwAltNameChoice == got->dwAltNameChoice)
3471 switch (got->dwAltNameChoice)
3473 case CERT_ALT_NAME_RFC822_NAME:
3474 case CERT_ALT_NAME_DNS_NAME:
3475 case CERT_ALT_NAME_EDI_PARTY_NAME:
3476 case CERT_ALT_NAME_URL:
3477 case CERT_ALT_NAME_REGISTERED_ID:
3478 ok((!U(*expected).pwszURL && !U(*got).pwszURL) ||
3479 (!U(*expected).pwszURL && !lstrlenW(U(*got).pwszURL)) ||
3480 (!U(*got).pwszURL && !lstrlenW(U(*expected).pwszURL)) ||
3481 !lstrcmpW(U(*expected).pwszURL, U(*got).pwszURL),
3482 "Unexpected name\n");
3483 break;
3484 case CERT_ALT_NAME_X400_ADDRESS:
3485 case CERT_ALT_NAME_DIRECTORY_NAME:
3486 case CERT_ALT_NAME_IP_ADDRESS:
3487 ok(U(*got).IPAddress.cbData == U(*expected).IPAddress.cbData,
3488 "Unexpected IP address length %d\n", U(*got).IPAddress.cbData);
3489 ok(!memcmp(U(*got).IPAddress.pbData, U(*got).IPAddress.pbData,
3490 U(*got).IPAddress.cbData), "Unexpected value\n");
3491 break;
3496 static void compareAltNameInfo(const CERT_ALT_NAME_INFO *expected,
3497 const CERT_ALT_NAME_INFO *got)
3499 DWORD i;
3501 ok(expected->cAltEntry == got->cAltEntry, "Expected %d entries, got %d\n",
3502 expected->cAltEntry, got->cAltEntry);
3503 for (i = 0; i < min(expected->cAltEntry, got->cAltEntry); i++)
3504 compareAltNameEntry(&expected->rgAltEntry[i], &got->rgAltEntry[i]);
3507 static void compareDistPointName(const CRL_DIST_POINT_NAME *expected,
3508 const CRL_DIST_POINT_NAME *got)
3510 ok(got->dwDistPointNameChoice == expected->dwDistPointNameChoice,
3511 "Unexpected name choice %d\n", got->dwDistPointNameChoice);
3512 if (got->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME)
3513 compareAltNameInfo(&(U(*expected).FullName), &(U(*got).FullName));
3516 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT *expected,
3517 const CRL_ISSUING_DIST_POINT *got)
3519 compareDistPointName(&expected->DistPointName, &got->DistPointName);
3520 ok(got->fOnlyContainsUserCerts == expected->fOnlyContainsUserCerts,
3521 "Unexpected fOnlyContainsUserCerts\n");
3522 ok(got->fOnlyContainsCACerts == expected->fOnlyContainsCACerts,
3523 "Unexpected fOnlyContainsCACerts\n");
3524 ok(got->OnlySomeReasonFlags.cbData == expected->OnlySomeReasonFlags.cbData,
3525 "Unexpected reason flags\n");
3526 ok(got->fIndirectCRL == expected->fIndirectCRL,
3527 "Unexpected fIndirectCRL\n");
3530 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding)
3532 BOOL ret;
3533 BYTE *buf = NULL;
3534 DWORD size = 0;
3535 CRL_ISSUING_DIST_POINT point = { { 0 } };
3537 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3538 emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3539 (BYTE *)&buf, &size);
3540 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3542 skip("no X509_ISSUING_DIST_POINT decode support\n");
3543 return;
3545 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3546 if (ret)
3548 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3549 LocalFree(buf);
3551 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3552 badFlagsIDP, badFlagsIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3553 (BYTE *)&buf, &size);
3554 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3555 if (ret)
3557 point.fOnlyContainsUserCerts = point.fOnlyContainsCACerts = TRUE;
3558 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3559 LocalFree(buf);
3561 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3562 emptyNameIDP, emptyNameIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3563 (BYTE *)&buf, &size);
3564 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3565 if (ret)
3567 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3568 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3569 U(point.DistPointName).FullName.cAltEntry = 0;
3570 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3571 LocalFree(buf);
3573 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3574 urlIDP, urlIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3575 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3576 if (ret)
3578 CERT_ALT_NAME_ENTRY entry;
3580 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3581 U(entry).pwszURL = (LPWSTR)url;
3582 U(point.DistPointName).FullName.cAltEntry = 1;
3583 U(point.DistPointName).FullName.rgAltEntry = &entry;
3584 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3585 LocalFree(buf);
3589 static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3590 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3591 0x30, 0x5a };
3592 static const BYTE v2CRL[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3593 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3594 0x30, 0x30, 0x30, 0x30, 0x5a };
3595 static const BYTE v1CRLWithIssuer[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3596 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3597 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3598 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3599 0x5a };
3600 static const BYTE v1CRLWithIssuerAndEmptyEntry[] = { 0x30, 0x43, 0x30, 0x02,
3601 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3602 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3603 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3604 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3605 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3606 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3607 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3608 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3609 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3610 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3611 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3612 static const BYTE v1CRLWithEntryExt[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3613 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3614 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3615 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3616 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3617 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3618 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3619 static const BYTE v1CRLWithExt[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3620 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3621 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3622 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
3623 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3624 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
3625 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3626 static const BYTE v2CRLWithExt[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
3627 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
3628 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
3629 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
3630 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
3631 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
3632 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3633 static const BYTE v2CRLWithIssuingDistPoint[] = { 0x30,0x5c,0x02,0x01,0x01,
3634 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
3635 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
3636 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
3637 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3638 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
3639 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3641 static void test_encodeCRLToBeSigned(DWORD dwEncoding)
3643 BOOL ret;
3644 BYTE *buf = NULL;
3645 static CHAR oid_issuing_dist_point[] = szOID_ISSUING_DIST_POINT;
3646 DWORD size = 0;
3647 CRL_INFO info = { 0 };
3648 CRL_ENTRY entry = { { 0 }, { 0 }, 0, 0 };
3649 CERT_EXTENSION ext;
3651 /* Test with a V1 CRL */
3652 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3653 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3654 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3655 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3656 if (buf)
3658 ok(size == sizeof(v1CRL), "Wrong size %d\n", size);
3659 ok(!memcmp(buf, v1CRL, size), "Got unexpected value\n");
3660 LocalFree(buf);
3662 /* Test v2 CRL */
3663 info.dwVersion = CRL_V2;
3664 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3665 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3666 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3667 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3668 if (buf)
3670 ok(size == v2CRL[1] + 2, "Expected size %d, got %d\n",
3671 v2CRL[1] + 2, size);
3672 ok(!memcmp(buf, v2CRL, size), "Got unexpected value\n");
3673 LocalFree(buf);
3675 /* v1 CRL with a name */
3676 info.dwVersion = CRL_V1;
3677 info.Issuer.cbData = sizeof(encodedCommonName);
3678 info.Issuer.pbData = (BYTE *)encodedCommonName;
3679 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3680 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3681 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3682 if (buf)
3684 ok(size == sizeof(v1CRLWithIssuer), "Wrong size %d\n", size);
3685 ok(!memcmp(buf, v1CRLWithIssuer, size), "Got unexpected value\n");
3686 LocalFree(buf);
3688 if (0)
3690 /* v1 CRL with a name and a NULL entry pointer (crashes on win9x) */
3691 info.cCRLEntry = 1;
3692 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3693 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3694 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3695 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3697 /* now set an empty entry */
3698 info.cCRLEntry = 1;
3699 info.rgCRLEntry = &entry;
3700 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3701 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3702 if (buf)
3704 ok(size == sizeof(v1CRLWithIssuerAndEmptyEntry),
3705 "Wrong size %d\n", size);
3706 ok(!memcmp(buf, v1CRLWithIssuerAndEmptyEntry, size),
3707 "Got unexpected value\n");
3708 LocalFree(buf);
3710 /* an entry with a serial number */
3711 entry.SerialNumber.cbData = sizeof(serialNum);
3712 entry.SerialNumber.pbData = (BYTE *)serialNum;
3713 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3714 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3715 if (buf)
3717 ok(size == sizeof(v1CRLWithIssuerAndEntry),
3718 "Wrong size %d\n", size);
3719 ok(!memcmp(buf, v1CRLWithIssuerAndEntry, size),
3720 "Got unexpected value\n");
3721 LocalFree(buf);
3723 /* an entry with an extension */
3724 entry.cExtension = 1;
3725 entry.rgExtension = &criticalExt;
3726 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3727 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3728 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3729 if (buf)
3731 ok(size == sizeof(v1CRLWithEntryExt), "Wrong size %d\n", size);
3732 ok(!memcmp(buf, v1CRLWithEntryExt, size), "Got unexpected value\n");
3733 LocalFree(buf);
3735 /* a CRL with an extension */
3736 entry.cExtension = 0;
3737 info.cExtension = 1;
3738 info.rgExtension = &criticalExt;
3739 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3740 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3741 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3742 if (buf)
3744 ok(size == sizeof(v1CRLWithExt), "Wrong size %d\n", size);
3745 ok(!memcmp(buf, v1CRLWithExt, size), "Got unexpected value\n");
3746 LocalFree(buf);
3748 /* a v2 CRL with an extension, this time non-critical */
3749 info.dwVersion = CRL_V2;
3750 info.rgExtension = &nonCriticalExt;
3751 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3752 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3753 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3754 if (buf)
3756 ok(size == sizeof(v2CRLWithExt), "Wrong size %d\n", size);
3757 ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n");
3758 LocalFree(buf);
3760 /* a v2 CRL with an issuing dist point extension */
3761 ext.pszObjId = oid_issuing_dist_point;
3762 ext.fCritical = TRUE;
3763 ext.Value.cbData = sizeof(urlIDP);
3764 ext.Value.pbData = (LPBYTE)urlIDP;
3765 entry.rgExtension = &ext;
3766 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3767 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3768 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3769 if (buf)
3771 ok(size == sizeof(v2CRLWithIssuingDistPoint), "Wrong size %d\n", size);
3772 ok(!memcmp(buf, v2CRLWithIssuingDistPoint, size), "Unexpected value\n");
3773 LocalFree(buf);
3777 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
3778 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
3779 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
3780 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
3781 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
3782 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
3783 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
3784 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
3785 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
3786 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
3787 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
3788 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
3789 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
3790 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
3791 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
3792 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
3793 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
3794 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
3795 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
3796 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
3797 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
3798 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
3799 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
3800 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
3801 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
3802 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
3803 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
3804 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
3805 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
3806 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
3807 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
3808 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
3809 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
3810 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
3811 0xcd };
3812 static const BYTE verisignCRLWithLotsOfEntries[] = {
3813 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
3814 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
3815 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
3816 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
3817 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
3818 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
3819 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
3820 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
3821 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
3822 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
3823 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
3824 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
3825 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
3826 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
3827 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
3828 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
3829 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3830 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
3831 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
3832 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3833 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
3834 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
3835 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
3836 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
3837 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
3838 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
3839 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
3840 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
3841 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
3842 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
3843 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3844 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
3845 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
3846 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3847 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
3848 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
3849 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
3850 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
3851 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
3852 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
3853 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
3854 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
3855 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
3856 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
3857 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
3858 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
3859 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
3860 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
3861 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
3862 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
3863 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
3864 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
3865 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
3866 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
3867 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3868 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
3869 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
3870 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
3871 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
3872 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
3873 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
3874 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
3875 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
3876 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
3877 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
3878 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
3879 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
3880 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
3881 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
3882 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
3883 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
3884 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
3885 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
3886 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
3887 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
3888 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
3889 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
3890 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
3891 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
3892 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
3893 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
3894 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
3895 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3896 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
3897 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
3898 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
3899 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
3900 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
3901 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
3902 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
3903 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
3904 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
3905 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
3906 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
3907 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
3908 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
3909 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
3910 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
3911 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
3912 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
3913 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
3914 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
3915 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
3916 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
3917 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
3918 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
3919 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
3920 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
3921 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
3922 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
3923 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3924 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
3925 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
3926 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
3927 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
3928 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
3929 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
3930 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
3931 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
3932 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
3933 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
3934 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
3935 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
3936 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
3937 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3938 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
3939 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
3940 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
3941 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
3942 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
3943 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
3944 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
3945 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
3946 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
3947 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
3948 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
3949 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
3950 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
3951 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
3952 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
3953 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
3954 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
3955 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
3956 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
3957 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
3958 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
3959 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
3960 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
3961 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
3962 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
3963 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
3964 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
3965 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
3966 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
3967 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
3968 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
3969 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
3970 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
3971 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
3972 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
3973 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
3974 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
3975 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
3976 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
3977 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
3978 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
3979 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
3980 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
3981 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
3982 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
3983 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
3984 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
3985 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
3986 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
3987 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
3988 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
3989 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
3990 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
3991 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
3992 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
3993 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
3994 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
3995 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
3996 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
3997 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
3998 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
3999 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
4000 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
4001 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
4002 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
4003 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
4004 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
4005 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
4006 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
4007 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
4008 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
4009 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
4010 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
4011 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
4012 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
4013 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
4014 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
4015 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
4016 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
4017 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
4018 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
4019 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
4020 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
4021 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
4022 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
4023 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
4024 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
4025 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
4026 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
4027 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
4028 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
4029 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
4030 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
4031 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
4032 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
4033 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
4034 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
4035 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
4036 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
4037 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
4038 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
4039 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
4040 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
4041 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
4042 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
4043 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
4044 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
4045 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
4046 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
4047 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
4048 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
4049 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
4050 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
4051 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
4052 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
4053 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
4054 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
4055 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
4056 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
4057 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
4058 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
4059 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
4060 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
4061 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
4062 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
4063 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
4064 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
4065 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
4066 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
4067 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
4068 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
4069 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
4070 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
4071 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
4072 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
4073 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
4074 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
4075 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
4076 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
4077 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
4078 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
4079 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
4080 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
4081 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
4082 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
4083 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
4084 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
4085 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
4086 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
4087 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
4088 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
4089 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
4090 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
4091 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
4092 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
4093 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
4094 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
4095 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
4096 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
4097 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
4098 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
4099 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
4100 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
4101 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
4102 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
4103 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
4104 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
4105 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
4106 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
4107 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
4108 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
4109 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
4110 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
4111 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
4112 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
4113 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
4114 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
4115 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
4116 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4117 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4118 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4119 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4120 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4121 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4122 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4123 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4124 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4125 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4126 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4127 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4128 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4129 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4130 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4131 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4132 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4133 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4134 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4135 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4136 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4137 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4138 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4139 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4140 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4141 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4142 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4143 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4144 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4145 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4146 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4147 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4148 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4149 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4150 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4151 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4152 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4153 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4154 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4155 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4156 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4157 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4158 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4159 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4160 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4161 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4162 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4163 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4164 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4165 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4166 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4167 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4168 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4169 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4170 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4171 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4172 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4173 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4174 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4175 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4176 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4177 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4178 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4179 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4180 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4181 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4182 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4183 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4184 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4185 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4186 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4187 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4188 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4189 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4190 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4191 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4192 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4193 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4194 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4195 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4196 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4197 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4198 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4199 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4200 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4201 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4202 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4203 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4204 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4205 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4206 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4207 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4208 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4209 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4210 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4211 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4212 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4213 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4214 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4215 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4216 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4217 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4218 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4219 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4220 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4221 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4222 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4223 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4224 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4225 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4226 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4227 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4228 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4229 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4230 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4231 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4232 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4233 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4234 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4235 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4236 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4237 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4238 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4239 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4240 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4241 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4242 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4243 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4244 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4245 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4246 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4247 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4248 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4249 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4250 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4251 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4252 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4253 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4254 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4255 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4256 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4257 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4258 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4259 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4260 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4261 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4262 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4263 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4264 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4265 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4266 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4267 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4268 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4269 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4270 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4271 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4272 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4273 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4274 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4275 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4276 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4277 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4278 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4279 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4280 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4281 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4282 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4283 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4284 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4285 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4286 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4287 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4288 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4289 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4290 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4291 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4292 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4293 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4294 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4295 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4296 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4297 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4298 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4299 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4300 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4301 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4302 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4303 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4304 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4305 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4306 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4307 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4308 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4309 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4310 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4311 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4312 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4313 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4314 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4315 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4316 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4317 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4318 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4319 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4320 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4322 static void test_decodeCRLToBeSigned(DWORD dwEncoding)
4324 static const BYTE *corruptCRLs[] = { v1CRL, v2CRL };
4325 BOOL ret;
4326 BYTE *buf = NULL;
4327 DWORD size = 0, i;
4329 for (i = 0; i < sizeof(corruptCRLs) / sizeof(corruptCRLs[0]); i++)
4331 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4332 corruptCRLs[i], corruptCRLs[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4333 (BYTE *)&buf, &size);
4334 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4335 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4336 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4337 GetLastError());
4339 /* at a minimum, a CRL must contain an issuer: */
4340 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4341 v1CRLWithIssuer, v1CRLWithIssuer[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4342 (BYTE *)&buf, &size);
4343 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4344 if (buf)
4346 CRL_INFO *info = (CRL_INFO *)buf;
4348 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4349 ok(info->cCRLEntry == 0, "Expected 0 CRL entries, got %d\n",
4350 info->cCRLEntry);
4351 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4352 "Wrong issuer size %d\n", info->Issuer.cbData);
4353 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4354 "Unexpected issuer\n");
4355 LocalFree(buf);
4357 /* check decoding with an empty CRL entry */
4358 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4359 v1CRLWithIssuerAndEmptyEntry, v1CRLWithIssuerAndEmptyEntry[1] + 2,
4360 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4361 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4362 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4363 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4364 GetLastError());
4365 /* with a real CRL entry */
4366 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4367 v1CRLWithIssuerAndEntry, v1CRLWithIssuerAndEntry[1] + 2,
4368 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4369 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4370 if (buf)
4372 CRL_INFO *info = (CRL_INFO *)buf;
4373 CRL_ENTRY *entry;
4375 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4376 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4377 info->cCRLEntry);
4378 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4379 entry = info->rgCRLEntry;
4380 ok(entry->SerialNumber.cbData == 1,
4381 "Expected serial number size 1, got %d\n",
4382 entry->SerialNumber.cbData);
4383 ok(*entry->SerialNumber.pbData == *serialNum,
4384 "Expected serial number %d, got %d\n", *serialNum,
4385 *entry->SerialNumber.pbData);
4386 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4387 "Wrong issuer size %d\n", info->Issuer.cbData);
4388 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4389 "Unexpected issuer\n");
4390 LocalFree(buf);
4392 /* a real CRL from verisign that has extensions */
4393 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4394 verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG,
4395 NULL, (BYTE *)&buf, &size);
4396 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4397 if (buf)
4399 CRL_INFO *info = (CRL_INFO *)buf;
4400 CRL_ENTRY *entry;
4402 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4403 ok(info->cCRLEntry == 3, "Expected 3 CRL entries, got %d\n",
4404 info->cCRLEntry);
4405 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4406 entry = info->rgCRLEntry;
4407 ok(info->cExtension == 2, "Expected 2 extensions, got %d\n",
4408 info->cExtension);
4409 LocalFree(buf);
4411 /* another real CRL from verisign that has lots of entries */
4412 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4413 verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries),
4414 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4415 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4416 if (buf)
4418 CRL_INFO *info = (CRL_INFO *)buf;
4420 ok(size >= sizeof(CRL_INFO), "Got size %d\n", size);
4421 ok(info->cCRLEntry == 209, "Expected 209 CRL entries, got %d\n",
4422 info->cCRLEntry);
4423 ok(info->cExtension == 0, "Expected 0 extensions, got %d\n",
4424 info->cExtension);
4425 LocalFree(buf);
4427 /* and finally, with an extension */
4428 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4429 v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4430 NULL, (BYTE *)&buf, &size);
4431 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4432 if (buf)
4434 CRL_INFO *info = (CRL_INFO *)buf;
4435 CRL_ENTRY *entry;
4437 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4438 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4439 info->cCRLEntry);
4440 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4441 entry = info->rgCRLEntry;
4442 ok(entry->SerialNumber.cbData == 1,
4443 "Expected serial number size 1, got %d\n",
4444 entry->SerialNumber.cbData);
4445 ok(*entry->SerialNumber.pbData == *serialNum,
4446 "Expected serial number %d, got %d\n", *serialNum,
4447 *entry->SerialNumber.pbData);
4448 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4449 "Wrong issuer size %d\n", info->Issuer.cbData);
4450 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4451 "Unexpected issuer\n");
4452 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4453 info->cExtension);
4454 LocalFree(buf);
4456 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4457 v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4458 NULL, (BYTE *)&buf, &size);
4459 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4460 if (buf)
4462 CRL_INFO *info = (CRL_INFO *)buf;
4464 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4465 info->cExtension);
4466 LocalFree(buf);
4468 /* And again, with an issuing dist point */
4469 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4470 v2CRLWithIssuingDistPoint, sizeof(v2CRLWithIssuingDistPoint),
4471 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4472 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4473 if (buf)
4475 CRL_INFO *info = (CRL_INFO *)buf;
4477 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4478 info->cExtension);
4479 LocalFree(buf);
4483 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
4484 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
4485 static const BYTE encodedUsage[] = {
4486 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4487 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4488 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4490 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding)
4492 BOOL ret;
4493 BYTE *buf = NULL;
4494 DWORD size = 0;
4495 CERT_ENHKEY_USAGE usage;
4497 /* Test with empty usage */
4498 usage.cUsageIdentifier = 0;
4499 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4500 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4501 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4502 if (buf)
4504 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
4505 ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n");
4506 LocalFree(buf);
4508 /* Test with a few usages */
4509 usage.cUsageIdentifier = sizeof(keyUsages) / sizeof(keyUsages[0]);
4510 usage.rgpszUsageIdentifier = (LPSTR *)keyUsages;
4511 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4512 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4513 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4514 if (buf)
4516 ok(size == sizeof(encodedUsage), "Wrong size %d\n", size);
4517 ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n");
4518 LocalFree(buf);
4522 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding)
4524 BOOL ret;
4525 LPBYTE buf = NULL;
4526 DWORD size = 0;
4528 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4529 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4530 (BYTE *)&buf, &size);
4531 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4532 if (buf)
4534 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4536 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4537 "Wrong size %d\n", size);
4538 ok(usage->cUsageIdentifier == 0, "Expected 0 CRL entries, got %d\n",
4539 usage->cUsageIdentifier);
4540 LocalFree(buf);
4542 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4543 encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL,
4544 (BYTE *)&buf, &size);
4545 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4546 if (buf)
4548 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4549 DWORD i;
4551 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4552 "Wrong size %d\n", size);
4553 ok(usage->cUsageIdentifier == sizeof(keyUsages) / sizeof(keyUsages[0]),
4554 "Wrong CRL entries count %d\n", usage->cUsageIdentifier);
4555 for (i = 0; i < usage->cUsageIdentifier; i++)
4556 ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]),
4557 "Expected OID %s, got %s\n", keyUsages[i],
4558 usage->rgpszUsageIdentifier[i]);
4559 LocalFree(buf);
4563 static BYTE keyId[] = { 1,2,3,4 };
4564 static const BYTE authorityKeyIdWithId[] = {
4565 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4566 static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4567 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4568 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4569 static const BYTE authorityKeyIdWithSerial[] = { 0x30,0x03,0x82,0x01,0x01 };
4571 static void test_encodeAuthorityKeyId(DWORD dwEncoding)
4573 CERT_AUTHORITY_KEY_ID_INFO info = { { 0 } };
4574 BOOL ret;
4575 BYTE *buf = NULL;
4576 DWORD size = 0;
4578 /* Test with empty id */
4579 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4580 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4581 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4582 if (buf)
4584 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4585 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4586 LocalFree(buf);
4588 /* With just a key id */
4589 info.KeyId.cbData = sizeof(keyId);
4590 info.KeyId.pbData = keyId;
4591 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4592 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4593 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4594 if (buf)
4596 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", size);
4597 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4598 LocalFree(buf);
4600 /* With just an issuer */
4601 info.KeyId.cbData = 0;
4602 info.CertIssuer.cbData = sizeof(encodedCommonName);
4603 info.CertIssuer.pbData = (BYTE *)encodedCommonName;
4604 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4605 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4606 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4607 if (buf)
4609 ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %d\n",
4610 size);
4611 ok(!memcmp(buf, authorityKeyIdWithIssuer, size), "Unexpected value\n");
4612 LocalFree(buf);
4614 /* With just a serial number */
4615 info.CertIssuer.cbData = 0;
4616 info.CertSerialNumber.cbData = sizeof(serialNum);
4617 info.CertSerialNumber.pbData = (BYTE *)serialNum;
4618 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4619 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4620 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4621 if (buf)
4623 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4624 size);
4625 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4626 LocalFree(buf);
4630 static void test_decodeAuthorityKeyId(DWORD dwEncoding)
4632 BOOL ret;
4633 LPBYTE buf = NULL;
4634 DWORD size = 0;
4636 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4637 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4638 (BYTE *)&buf, &size);
4639 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4640 if (buf)
4642 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4644 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4645 size);
4646 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4647 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4648 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4649 LocalFree(buf);
4651 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4652 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4653 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4654 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4655 if (buf)
4657 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4659 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4660 size);
4661 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4662 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4663 "Unexpected key id\n");
4664 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4665 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4666 LocalFree(buf);
4668 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4669 authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer),
4670 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4671 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4672 if (buf)
4674 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4676 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4677 size);
4678 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4679 ok(info->CertIssuer.cbData == sizeof(encodedCommonName),
4680 "Unexpected issuer len\n");
4681 ok(!memcmp(info->CertIssuer.pbData, encodedCommonName,
4682 sizeof(encodedCommonName)), "Unexpected issuer\n");
4683 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4684 LocalFree(buf);
4686 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4687 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4688 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4689 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4690 if (buf)
4692 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4694 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4695 size);
4696 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4697 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4698 ok(info->CertSerialNumber.cbData == sizeof(serialNum),
4699 "Unexpected serial number len\n");
4700 ok(!memcmp(info->CertSerialNumber.pbData, serialNum, sizeof(serialNum)),
4701 "Unexpected serial number\n");
4702 LocalFree(buf);
4706 static const BYTE authorityKeyIdWithIssuerUrl[] = { 0x30,0x15,0xa1,0x13,0x86,
4707 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
4708 0x6f,0x72,0x67 };
4710 static void test_encodeAuthorityKeyId2(DWORD dwEncoding)
4712 CERT_AUTHORITY_KEY_ID2_INFO info = { { 0 } };
4713 CERT_ALT_NAME_ENTRY entry = { 0 };
4714 BOOL ret;
4715 BYTE *buf = NULL;
4716 DWORD size = 0;
4718 /* Test with empty id */
4719 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4720 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4721 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4722 if (buf)
4724 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4725 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4726 LocalFree(buf);
4728 /* With just a key id */
4729 info.KeyId.cbData = sizeof(keyId);
4730 info.KeyId.pbData = keyId;
4731 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4732 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4733 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4734 if (buf)
4736 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n",
4737 size);
4738 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4739 LocalFree(buf);
4741 /* With a bogus issuer name */
4742 info.KeyId.cbData = 0;
4743 info.AuthorityCertIssuer.cAltEntry = 1;
4744 info.AuthorityCertIssuer.rgAltEntry = &entry;
4745 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4746 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4747 ok(!ret && GetLastError() == E_INVALIDARG,
4748 "Expected E_INVALIDARG, got %08x\n", GetLastError());
4749 /* With an issuer name */
4750 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
4751 U(entry).pwszURL = (LPWSTR)url;
4752 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4753 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4754 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4755 if (buf)
4757 ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %d\n",
4758 size);
4759 ok(!memcmp(buf, authorityKeyIdWithIssuerUrl, size),
4760 "Unexpected value\n");
4761 LocalFree(buf);
4763 /* With just a serial number */
4764 info.AuthorityCertIssuer.cAltEntry = 0;
4765 info.AuthorityCertSerialNumber.cbData = sizeof(serialNum);
4766 info.AuthorityCertSerialNumber.pbData = (BYTE *)serialNum;
4767 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4768 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4769 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4770 if (buf)
4772 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4773 size);
4774 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4775 LocalFree(buf);
4779 static void test_decodeAuthorityKeyId2(DWORD dwEncoding)
4781 BOOL ret;
4782 LPBYTE buf = NULL;
4783 DWORD size = 0;
4785 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4786 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4787 (BYTE *)&buf, &size);
4788 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4789 if (buf)
4791 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4793 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4794 size);
4795 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4796 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4797 "Expected no issuer name entries\n");
4798 ok(info->AuthorityCertSerialNumber.cbData == 0,
4799 "Expected no serial number\n");
4800 LocalFree(buf);
4802 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4803 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4804 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4805 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4806 if (buf)
4808 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4810 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4811 size);
4812 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4813 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4814 "Unexpected key id\n");
4815 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4816 "Expected no issuer name entries\n");
4817 ok(info->AuthorityCertSerialNumber.cbData == 0,
4818 "Expected no serial number\n");
4819 LocalFree(buf);
4821 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4822 authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl),
4823 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4824 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4825 if (buf)
4827 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4829 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4830 size);
4831 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4832 ok(info->AuthorityCertIssuer.cAltEntry == 1,
4833 "Expected 1 issuer entry, got %d\n",
4834 info->AuthorityCertIssuer.cAltEntry);
4835 ok(info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice ==
4836 CERT_ALT_NAME_URL, "Expected CERT_ALT_NAME_URL, got %d\n",
4837 info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice);
4838 ok(!lstrcmpW(U(info->AuthorityCertIssuer.rgAltEntry[0]).pwszURL,
4839 url), "Unexpected URL\n");
4840 ok(info->AuthorityCertSerialNumber.cbData == 0,
4841 "Expected no serial number\n");
4842 LocalFree(buf);
4844 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4845 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4846 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4847 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4848 if (buf)
4850 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4852 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4853 size);
4854 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4855 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4856 "Expected no issuer name entries\n");
4857 ok(info->AuthorityCertSerialNumber.cbData == sizeof(serialNum),
4858 "Unexpected serial number len\n");
4859 ok(!memcmp(info->AuthorityCertSerialNumber.pbData, serialNum,
4860 sizeof(serialNum)), "Unexpected serial number\n");
4861 LocalFree(buf);
4865 static const BYTE authorityInfoAccessWithUrl[] = {
4866 0x30,0x19,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
4867 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
4868 static const BYTE authorityInfoAccessWithUrlAndIPAddr[] = {
4869 0x30,0x29,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
4870 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x0e,0x06,
4871 0x02,0x2d,0x06,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
4873 static void test_encodeAuthorityInfoAccess(DWORD dwEncoding)
4875 static char oid1[] = "1.2.3";
4876 static char oid2[] = "1.5.6";
4877 BOOL ret;
4878 BYTE *buf = NULL;
4879 DWORD size = 0;
4880 CERT_ACCESS_DESCRIPTION accessDescription[2];
4881 CERT_AUTHORITY_INFO_ACCESS aia;
4883 memset(accessDescription, 0, sizeof(accessDescription));
4884 aia.cAccDescr = 0;
4885 aia.rgAccDescr = NULL;
4886 /* Having no access descriptions is allowed */
4887 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4888 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4889 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4890 if (buf)
4892 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
4893 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
4894 LocalFree(buf);
4895 buf = NULL;
4897 /* It can't have an empty access method */
4898 aia.cAccDescr = 1;
4899 aia.rgAccDescr = accessDescription;
4900 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4901 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4902 ok(!ret && (GetLastError() == E_INVALIDARG ||
4903 GetLastError() == OSS_LIMITED /* Win9x */),
4904 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
4905 /* It can't have an empty location */
4906 accessDescription[0].pszAccessMethod = oid1;
4907 SetLastError(0xdeadbeef);
4908 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4909 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4910 ok(!ret && GetLastError() == E_INVALIDARG,
4911 "expected E_INVALIDARG, got %08x\n", GetLastError());
4912 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
4913 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
4914 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4915 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4916 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4917 if (buf)
4919 ok(size == sizeof(authorityInfoAccessWithUrl), "unexpected size %d\n",
4920 size);
4921 ok(!memcmp(buf, authorityInfoAccessWithUrl, size),
4922 "unexpected value\n");
4923 LocalFree(buf);
4924 buf = NULL;
4926 accessDescription[1].pszAccessMethod = oid2;
4927 accessDescription[1].AccessLocation.dwAltNameChoice =
4928 CERT_ALT_NAME_IP_ADDRESS;
4929 U(accessDescription[1].AccessLocation).IPAddress.cbData =
4930 sizeof(encodedIPAddr);
4931 U(accessDescription[1].AccessLocation).IPAddress.pbData =
4932 (LPBYTE)encodedIPAddr;
4933 aia.cAccDescr = 2;
4934 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4935 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4936 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4937 if (buf)
4939 ok(size == sizeof(authorityInfoAccessWithUrlAndIPAddr),
4940 "unexpected size %d\n", size);
4941 ok(!memcmp(buf, authorityInfoAccessWithUrlAndIPAddr, size),
4942 "unexpected value\n");
4943 LocalFree(buf);
4944 buf = NULL;
4948 static void compareAuthorityInfoAccess(LPCSTR header,
4949 const CERT_AUTHORITY_INFO_ACCESS *expected,
4950 const CERT_AUTHORITY_INFO_ACCESS *got)
4952 DWORD i;
4954 ok(expected->cAccDescr == got->cAccDescr,
4955 "%s: expected %d access descriptions, got %d\n", header,
4956 expected->cAccDescr, got->cAccDescr);
4957 for (i = 0; i < expected->cAccDescr; i++)
4959 ok(!strcmp(expected->rgAccDescr[i].pszAccessMethod,
4960 got->rgAccDescr[i].pszAccessMethod), "%s[%d]: expected %s, got %s\n",
4961 header, i, expected->rgAccDescr[i].pszAccessMethod,
4962 got->rgAccDescr[i].pszAccessMethod);
4963 compareAltNameEntry(&expected->rgAccDescr[i].AccessLocation,
4964 &got->rgAccDescr[i].AccessLocation);
4968 static void test_decodeAuthorityInfoAccess(DWORD dwEncoding)
4970 static char oid1[] = "1.2.3";
4971 static char oid2[] = "1.5.6";
4972 BOOL ret;
4973 LPBYTE buf = NULL;
4974 DWORD size = 0;
4976 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
4977 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4978 (BYTE *)&buf, &size);
4979 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4980 if (buf)
4982 CERT_AUTHORITY_INFO_ACCESS aia = { 0, NULL };
4984 compareAuthorityInfoAccess("empty AIA", &aia,
4985 (CERT_AUTHORITY_INFO_ACCESS *)buf);
4986 LocalFree(buf);
4987 buf = NULL;
4989 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
4990 authorityInfoAccessWithUrl, sizeof(authorityInfoAccessWithUrl),
4991 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4992 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4993 if (buf)
4995 CERT_ACCESS_DESCRIPTION accessDescription;
4996 CERT_AUTHORITY_INFO_ACCESS aia;
4998 accessDescription.pszAccessMethod = oid1;
4999 accessDescription.AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5000 U(accessDescription.AccessLocation).pwszURL = (LPWSTR)url;
5001 aia.cAccDescr = 1;
5002 aia.rgAccDescr = &accessDescription;
5003 compareAuthorityInfoAccess("AIA with URL", &aia,
5004 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5005 LocalFree(buf);
5006 buf = NULL;
5008 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5009 authorityInfoAccessWithUrlAndIPAddr,
5010 sizeof(authorityInfoAccessWithUrlAndIPAddr), CRYPT_DECODE_ALLOC_FLAG,
5011 NULL, (BYTE *)&buf, &size);
5012 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5013 if (buf)
5015 CERT_ACCESS_DESCRIPTION accessDescription[2];
5016 CERT_AUTHORITY_INFO_ACCESS aia;
5018 accessDescription[0].pszAccessMethod = oid1;
5019 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5020 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
5021 accessDescription[1].pszAccessMethod = oid2;
5022 accessDescription[1].AccessLocation.dwAltNameChoice =
5023 CERT_ALT_NAME_IP_ADDRESS;
5024 U(accessDescription[1].AccessLocation).IPAddress.cbData =
5025 sizeof(encodedIPAddr);
5026 U(accessDescription[1].AccessLocation).IPAddress.pbData =
5027 (LPBYTE)encodedIPAddr;
5028 aia.cAccDescr = 2;
5029 aia.rgAccDescr = accessDescription;
5030 compareAuthorityInfoAccess("AIA with URL and IP addr", &aia,
5031 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5032 LocalFree(buf);
5033 buf = NULL;
5037 static const BYTE emptyCTL[] = {
5038 0x30,0x17,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5039 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5040 static const BYTE emptyCTLWithVersion1[] = {
5041 0x30,0x1a,0x02,0x01,0x01,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5042 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5043 static const BYTE ctlWithUsageIdentifier[] = {
5044 0x30,0x1b,0x30,0x04,0x06,0x02,0x2a,0x03,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
5045 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5046 static const BYTE ctlWithListIdentifier[] = {
5047 0x30,0x1a,0x30,0x00,0x04,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5048 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5049 static const BYTE ctlWithSequenceNumber[] = {
5050 0x30,0x1a,0x30,0x00,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5051 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5052 static const BYTE ctlWithThisUpdate[] = {
5053 0x30,0x15,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5054 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5055 static const BYTE ctlWithThisAndNextUpdate[] = {
5056 0x30,0x24,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5057 0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5058 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5059 static const BYTE ctlWithAlgId[] = {
5060 0x30,0x1b,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5061 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5062 static const BYTE ctlWithBogusEntry[] = {
5063 0x30,0x29,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5064 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x10,0x30,0x0e,0x04,
5065 0x01,0x01,0x31,0x09,0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,0x01 };
5066 static const BYTE ctlWithOneEntry[] = {
5067 0x30,0x2a,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5068 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x11,0x30,0x0f,0x04,
5069 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00 };
5070 static const BYTE ctlWithTwoEntries[] = {
5071 0x30,0x41,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5072 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x28,0x30,0x0f,0x04,
5073 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00,0x30,
5074 0x15,0x04,0x01,0x01,0x31,0x10,0x30,0x0e,0x06,0x02,0x2d,0x06,0x31,0x08,0x30,
5075 0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5077 static void test_encodeCTL(DWORD dwEncoding)
5079 static char oid1[] = "1.2.3";
5080 static char oid2[] = "1.5.6";
5081 char *pOid1 = oid1;
5082 BOOL ret;
5083 BYTE *buf = NULL;
5084 DWORD size = 0;
5085 CTL_INFO info;
5086 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5087 CTL_ENTRY ctlEntry[2];
5088 CRYPT_ATTRIBUTE attr1, attr2;
5089 CRYPT_ATTR_BLOB value1, value2;
5091 memset(&info, 0, sizeof(info));
5092 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5093 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5094 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5095 if (buf)
5097 ok(size == sizeof(emptyCTL), "unexpected size %d\n", size);
5098 ok(!memcmp(buf, emptyCTL, size), "unexpected value\n");
5099 LocalFree(buf);
5100 buf = NULL;
5102 info.dwVersion = 1;
5103 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5104 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5105 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5106 if (buf)
5108 ok(size == sizeof(emptyCTLWithVersion1), "unexpected size %d\n", size);
5109 ok(!memcmp(buf, emptyCTLWithVersion1, size), "unexpected value\n");
5110 LocalFree(buf);
5111 buf = NULL;
5113 info.dwVersion = 0;
5114 info.SubjectUsage.cUsageIdentifier = 1;
5115 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5116 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5117 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5118 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5119 if (buf)
5121 ok(size == sizeof(ctlWithUsageIdentifier), "unexpected size %d\n",
5122 size);
5123 ok(!memcmp(buf, ctlWithUsageIdentifier, size), "unexpected value\n");
5124 LocalFree(buf);
5125 buf = NULL;
5127 info.SubjectUsage.cUsageIdentifier = 0;
5128 info.ListIdentifier.cbData = sizeof(serialNum);
5129 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5130 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5131 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5132 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5133 if (buf)
5135 ok(size == sizeof(ctlWithListIdentifier), "unexpected size %d\n", size);
5136 ok(!memcmp(buf, ctlWithListIdentifier, size), "unexpected value\n");
5137 LocalFree(buf);
5138 buf = NULL;
5140 info.ListIdentifier.cbData = 0;
5141 info.SequenceNumber.cbData = sizeof(serialNum);
5142 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5143 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5144 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5145 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5146 if (buf)
5148 ok(size == sizeof(ctlWithSequenceNumber), "unexpected size %d\n",
5149 size);
5150 ok(!memcmp(buf, ctlWithSequenceNumber, size), "unexpected value\n");
5151 LocalFree(buf);
5152 buf = NULL;
5154 info.SequenceNumber.cbData = 0;
5155 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5156 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5157 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5158 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5159 if (buf)
5161 ok(size == sizeof(ctlWithThisUpdate), "unexpected size %d\n", size);
5162 ok(!memcmp(buf, ctlWithThisUpdate, size), "unexpected value\n");
5163 LocalFree(buf);
5164 buf = NULL;
5166 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5167 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5168 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5169 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5170 if (buf)
5172 ok(size == sizeof(ctlWithThisAndNextUpdate), "unexpected size %d\n",
5173 size);
5174 ok(!memcmp(buf, ctlWithThisAndNextUpdate, size), "unexpected value\n");
5175 LocalFree(buf);
5176 buf = NULL;
5178 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5179 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5180 info.SubjectAlgorithm.pszObjId = oid2;
5181 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5182 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5183 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5184 if (buf)
5186 ok(size == sizeof(ctlWithAlgId), "unexpected size %d\n", size);
5187 ok(!memcmp(buf, ctlWithAlgId, size), "unexpected value\n");
5188 LocalFree(buf);
5189 buf = NULL;
5191 /* The value is supposed to be asn.1 encoded, so this'll fail to decode
5192 * (see tests below) but it'll encode fine.
5194 info.SubjectAlgorithm.pszObjId = NULL;
5195 value1.cbData = sizeof(serialNum);
5196 value1.pbData = (LPBYTE)serialNum;
5197 attr1.pszObjId = oid1;
5198 attr1.cValue = 1;
5199 attr1.rgValue = &value1;
5200 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5201 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5202 ctlEntry[0].cAttribute = 1;
5203 ctlEntry[0].rgAttribute = &attr1;
5204 info.cCTLEntry = 1;
5205 info.rgCTLEntry = ctlEntry;
5206 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5207 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5208 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5209 if (buf)
5211 ok(size == sizeof(ctlWithBogusEntry), "unexpected size %d\n", size);
5212 ok(!memcmp(buf, ctlWithBogusEntry, size), "unexpected value\n");
5213 LocalFree(buf);
5214 buf = NULL;
5216 value1.cbData = sizeof(emptySequence);
5217 value1.pbData = (LPBYTE)emptySequence;
5218 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5219 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5220 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5221 if (buf)
5223 ok(size == sizeof(ctlWithOneEntry), "unexpected size %d\n", size);
5224 ok(!memcmp(buf, ctlWithOneEntry, size), "unexpected value\n");
5225 LocalFree(buf);
5226 buf = NULL;
5228 value2.cbData = sizeof(encodedIPAddr);
5229 value2.pbData = (LPBYTE)encodedIPAddr;
5230 attr2.pszObjId = oid2;
5231 attr2.cValue = 1;
5232 attr2.rgValue = &value2;
5233 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5234 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5235 ctlEntry[1].cAttribute = 1;
5236 ctlEntry[1].rgAttribute = &attr2;
5237 info.cCTLEntry = 2;
5238 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5239 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5240 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5241 if (buf)
5243 ok(size == sizeof(ctlWithTwoEntries), "unexpected size %d\n", size);
5244 ok(!memcmp(buf, ctlWithTwoEntries, size), "unexpected value\n");
5245 LocalFree(buf);
5246 buf = NULL;
5250 static void compareCTLInfo(LPCSTR header, const CTL_INFO *expected,
5251 const CTL_INFO *got)
5253 DWORD i, j, k;
5255 ok(expected->dwVersion == got->dwVersion,
5256 "%s: expected version %d, got %d\n", header, expected->dwVersion,
5257 got->dwVersion);
5258 ok(expected->SubjectUsage.cUsageIdentifier ==
5259 got->SubjectUsage.cUsageIdentifier,
5260 "%s: expected %d usage identifiers, got %d\n", header,
5261 expected->SubjectUsage.cUsageIdentifier,
5262 got->SubjectUsage.cUsageIdentifier);
5263 for (i = 0; i < expected->SubjectUsage.cUsageIdentifier; i++)
5264 ok(!strcmp(expected->SubjectUsage.rgpszUsageIdentifier[i],
5265 got->SubjectUsage.rgpszUsageIdentifier[i]),
5266 "%s[%d]: expected %s, got %s\n", header, i,
5267 expected->SubjectUsage.rgpszUsageIdentifier[i],
5268 got->SubjectUsage.rgpszUsageIdentifier[i]);
5269 ok(expected->ListIdentifier.cbData == got->ListIdentifier.cbData,
5270 "%s: expected list identifier of %d bytes, got %d\n", header,
5271 expected->ListIdentifier.cbData, got->ListIdentifier.cbData);
5272 if (expected->ListIdentifier.cbData)
5273 ok(!memcmp(expected->ListIdentifier.pbData, got->ListIdentifier.pbData,
5274 expected->ListIdentifier.cbData),
5275 "%s: unexpected list identifier value\n", header);
5276 ok(expected->SequenceNumber.cbData == got->SequenceNumber.cbData,
5277 "%s: expected sequence number of %d bytes, got %d\n", header,
5278 expected->SequenceNumber.cbData, got->SequenceNumber.cbData);
5279 if (expected->SequenceNumber.cbData)
5280 ok(!memcmp(expected->SequenceNumber.pbData, got->SequenceNumber.pbData,
5281 expected->SequenceNumber.cbData),
5282 "%s: unexpected sequence number value\n", header);
5283 ok(!memcmp(&expected->ThisUpdate, &got->ThisUpdate, sizeof(FILETIME)),
5284 "%s: expected this update = (%d, %d), got (%d, %d)\n", header,
5285 expected->ThisUpdate.dwLowDateTime, expected->ThisUpdate.dwHighDateTime,
5286 got->ThisUpdate.dwLowDateTime, got->ThisUpdate.dwHighDateTime);
5287 ok(!memcmp(&expected->NextUpdate, &got->NextUpdate, sizeof(FILETIME)),
5288 "%s: expected next update = (%d, %d), got (%d, %d)\n", header,
5289 expected->NextUpdate.dwLowDateTime, expected->NextUpdate.dwHighDateTime,
5290 got->NextUpdate.dwLowDateTime, got->NextUpdate.dwHighDateTime);
5291 if (expected->SubjectAlgorithm.pszObjId &&
5292 *expected->SubjectAlgorithm.pszObjId && !got->SubjectAlgorithm.pszObjId)
5293 ok(0, "%s: expected subject algorithm %s, got NULL\n", header,
5294 expected->SubjectAlgorithm.pszObjId);
5295 if (expected->SubjectAlgorithm.pszObjId && got->SubjectAlgorithm.pszObjId)
5296 ok(!strcmp(expected->SubjectAlgorithm.pszObjId,
5297 got->SubjectAlgorithm.pszObjId),
5298 "%s: expected subject algorithm %s, got %s\n", header,
5299 expected->SubjectAlgorithm.pszObjId, got->SubjectAlgorithm.pszObjId);
5300 ok(expected->SubjectAlgorithm.Parameters.cbData ==
5301 got->SubjectAlgorithm.Parameters.cbData,
5302 "%s: expected subject algorithm parameters of %d bytes, got %d\n", header,
5303 expected->SubjectAlgorithm.Parameters.cbData,
5304 got->SubjectAlgorithm.Parameters.cbData);
5305 if (expected->SubjectAlgorithm.Parameters.cbData)
5306 ok(!memcmp(expected->SubjectAlgorithm.Parameters.pbData,
5307 got->SubjectAlgorithm.Parameters.pbData,
5308 expected->SubjectAlgorithm.Parameters.cbData),
5309 "%s: unexpected subject algorithm parameter value\n", header);
5310 ok(expected->cCTLEntry == got->cCTLEntry,
5311 "%s: expected %d CTL entries, got %d\n", header, expected->cCTLEntry,
5312 got->cCTLEntry);
5313 for (i = 0; i < expected->cCTLEntry; i++)
5315 ok(expected->rgCTLEntry[i].SubjectIdentifier.cbData ==
5316 got->rgCTLEntry[i].SubjectIdentifier.cbData,
5317 "%s[%d]: expected subject identifier of %d bytes, got %d\n",
5318 header, i, expected->rgCTLEntry[i].SubjectIdentifier.cbData,
5319 got->rgCTLEntry[i].SubjectIdentifier.cbData);
5320 if (expected->rgCTLEntry[i].SubjectIdentifier.cbData)
5321 ok(!memcmp(expected->rgCTLEntry[i].SubjectIdentifier.pbData,
5322 got->rgCTLEntry[i].SubjectIdentifier.pbData,
5323 expected->rgCTLEntry[i].SubjectIdentifier.cbData),
5324 "%s[%d]: unexpected subject identifier value\n",
5325 header, i);
5326 for (j = 0; j < expected->rgCTLEntry[i].cAttribute; j++)
5328 ok(!strcmp(expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5329 got->rgCTLEntry[i].rgAttribute[j].pszObjId),
5330 "%s[%d][%d]: expected attribute OID %s, got %s\n", header, i, j,
5331 expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5332 got->rgCTLEntry[i].rgAttribute[j].pszObjId);
5333 for (k = 0; k < expected->rgCTLEntry[i].rgAttribute[j].cValue; k++)
5335 ok(expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData ==
5336 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5337 "%s[%d][%d][%d]: expected value of %d bytes, got %d\n",
5338 header, i, j, k,
5339 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5340 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData);
5341 if (expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData)
5342 ok(!memcmp(
5343 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5344 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5345 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData),
5346 "%s[%d][%d][%d]: unexpected value\n",
5347 header, i, j, k);
5351 ok(expected->cExtension == got->cExtension,
5352 "%s: expected %d extensions, got %d\n", header, expected->cExtension,
5353 got->cExtension);
5354 for (i = 0; i < expected->cExtension; i++)
5356 ok(!strcmp(expected->rgExtension[i].pszObjId,
5357 got->rgExtension[i].pszObjId), "%s[%d]: expected %s, got %s\n",
5358 header, i, expected->rgExtension[i].pszObjId,
5359 got->rgExtension[i].pszObjId);
5360 ok(expected->rgExtension[i].fCritical == got->rgExtension[i].fCritical,
5361 "%s[%d]: expected fCritical = %d, got %d\n", header, i,
5362 expected->rgExtension[i].fCritical, got->rgExtension[i].fCritical);
5363 ok(expected->rgExtension[i].Value.cbData ==
5364 got->rgExtension[i].Value.cbData,
5365 "%s[%d]: expected extension value to have %d bytes, got %d\n",
5366 header, i, expected->rgExtension[i].Value.cbData,
5367 got->rgExtension[i].Value.cbData);
5368 if (expected->rgExtension[i].Value.cbData)
5369 ok(!memcmp(expected->rgExtension[i].Value.pbData,
5370 got->rgExtension[i].Value.pbData,
5371 expected->rgExtension[i].Value.cbData),
5372 "%s[%d]: unexpected extension value\n", header, i);
5376 static const BYTE signedCTL[] = {
5377 0x30,0x81,0xc7,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
5378 0x81,0xb9,0x30,0x81,0xb6,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
5379 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x28,0x06,0x09,0x2a,0x86,
5380 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x1b,0x04,0x19,0x30,0x17,0x30,0x00,
5381 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5382 0x30,0x5a,0x30,0x02,0x06,0x00,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
5383 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
5384 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
5385 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5386 0x00,0x04,0x40,0xca,0xd8,0x32,0xd1,0xbd,0x97,0x61,0x54,0xd6,0x80,0xcf,0x0d,
5387 0xbd,0xa2,0x42,0xc7,0xca,0x37,0x91,0x7d,0x9d,0xac,0x8c,0xdf,0x05,0x8a,0x39,
5388 0xc6,0x07,0xc1,0x37,0xe6,0xb9,0xd1,0x0d,0x26,0xec,0xa5,0xb0,0x8a,0x51,0x26,
5389 0x2b,0x4f,0x73,0x44,0x86,0x83,0x5e,0x2b,0x6e,0xcc,0xf8,0x1b,0x85,0x53,0xe9,
5390 0x7a,0x80,0x8f,0x6b,0x42,0x19,0x93 };
5391 static const BYTE signedCTLWithCTLInnerContent[] = {
5392 0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
5393 0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
5394 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
5395 0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
5396 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5397 0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
5398 0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
5399 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
5400 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
5401 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
5402 0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
5403 0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
5404 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
5405 0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5406 0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
5407 0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
5408 0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
5409 0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
5410 0x57,0x6c,0x0b,0x47,0xb8 };
5412 static void test_decodeCTL(DWORD dwEncoding)
5414 static char oid1[] = "1.2.3";
5415 static char oid2[] = "1.5.6";
5416 static BYTE nullData[] = { 5,0 };
5417 char *pOid1 = oid1;
5418 BOOL ret;
5419 BYTE *buf = NULL;
5420 DWORD size = 0;
5421 CTL_INFO info;
5422 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5423 CTL_ENTRY ctlEntry[2];
5424 CRYPT_ATTRIBUTE attr1, attr2;
5425 CRYPT_ATTR_BLOB value1, value2;
5427 memset(&info, 0, sizeof(info));
5428 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTL, sizeof(emptyCTL),
5429 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5430 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5431 if (buf)
5433 compareCTLInfo("empty CTL", &info, (CTL_INFO *)buf);
5434 LocalFree(buf);
5435 buf = NULL;
5437 info.dwVersion = 1;
5438 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTLWithVersion1,
5439 sizeof(emptyCTLWithVersion1), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
5440 &size);
5441 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5442 if (buf)
5444 compareCTLInfo("v1 CTL", &info, (CTL_INFO *)buf);
5445 LocalFree(buf);
5446 buf = NULL;
5448 info.dwVersion = 0;
5449 info.SubjectUsage.cUsageIdentifier = 1;
5450 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5451 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithUsageIdentifier,
5452 sizeof(ctlWithUsageIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5453 (BYTE *)&buf, &size);
5454 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5455 if (buf)
5457 compareCTLInfo("CTL with usage identifier", &info, (CTL_INFO *)buf);
5458 LocalFree(buf);
5459 buf = NULL;
5461 info.SubjectUsage.cUsageIdentifier = 0;
5462 info.ListIdentifier.cbData = sizeof(serialNum);
5463 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5464 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithListIdentifier,
5465 sizeof(ctlWithListIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5466 (BYTE *)&buf, &size);
5467 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5468 if (buf)
5470 compareCTLInfo("CTL with list identifier", &info, (CTL_INFO *)buf);
5471 LocalFree(buf);
5472 buf = NULL;
5474 info.ListIdentifier.cbData = 0;
5475 info.SequenceNumber.cbData = sizeof(serialNum);
5476 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5477 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithSequenceNumber,
5478 sizeof(ctlWithSequenceNumber), CRYPT_DECODE_ALLOC_FLAG, NULL,
5479 (BYTE *)&buf, &size);
5480 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5481 if (buf)
5483 compareCTLInfo("CTL with sequence number", &info, (CTL_INFO *)buf);
5484 LocalFree(buf);
5485 buf = NULL;
5487 info.SequenceNumber.cbData = 0;
5488 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5489 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisUpdate,
5490 sizeof(ctlWithThisUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5491 (BYTE *)&buf, &size);
5492 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5493 if (buf)
5495 compareCTLInfo("CTL with this update", &info, (CTL_INFO *)buf);
5496 LocalFree(buf);
5497 buf = NULL;
5499 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5500 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisAndNextUpdate,
5501 sizeof(ctlWithThisAndNextUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5502 (BYTE *)&buf, &size);
5503 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5504 if (buf)
5506 compareCTLInfo("CTL with this and next update", &info, (CTL_INFO *)buf);
5507 LocalFree(buf);
5508 buf = NULL;
5510 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5511 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5512 info.SubjectAlgorithm.pszObjId = oid2;
5513 info.SubjectAlgorithm.Parameters.cbData = sizeof(nullData);
5514 info.SubjectAlgorithm.Parameters.pbData = nullData;
5515 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithAlgId,
5516 sizeof(ctlWithAlgId), CRYPT_DECODE_ALLOC_FLAG, NULL,
5517 (BYTE *)&buf, &size);
5518 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5519 if (buf)
5521 compareCTLInfo("CTL with algorithm identifier", &info, (CTL_INFO *)buf);
5522 LocalFree(buf);
5523 buf = NULL;
5525 SetLastError(0xdeadbeef);
5526 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithBogusEntry,
5527 sizeof(ctlWithBogusEntry), CRYPT_DECODE_ALLOC_FLAG, NULL,
5528 (BYTE *)&buf, &size);
5529 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD || CRYPT_E_ASN1_CORRUPT),
5530 "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n",
5531 GetLastError());
5532 info.SubjectAlgorithm.Parameters.cbData = 0;
5533 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5534 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5535 info.SubjectAlgorithm.pszObjId = oid2;
5536 info.SubjectAlgorithm.pszObjId = NULL;
5537 value1.cbData = sizeof(emptySequence);
5538 value1.pbData = (LPBYTE)emptySequence;
5539 attr1.pszObjId = oid1;
5540 attr1.cValue = 1;
5541 attr1.rgValue = &value1;
5542 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5543 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5544 ctlEntry[0].cAttribute = 1;
5545 ctlEntry[0].rgAttribute = &attr1;
5546 info.cCTLEntry = 1;
5547 info.rgCTLEntry = ctlEntry;
5548 SetLastError(0xdeadbeef);
5549 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithOneEntry,
5550 sizeof(ctlWithOneEntry), CRYPT_DECODE_ALLOC_FLAG, NULL,
5551 (BYTE *)&buf, &size);
5552 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5553 if (buf)
5555 compareCTLInfo("CTL with one entry", &info, (CTL_INFO *)buf);
5556 LocalFree(buf);
5557 buf = NULL;
5559 value2.cbData = sizeof(encodedIPAddr);
5560 value2.pbData = (LPBYTE)encodedIPAddr;
5561 attr2.pszObjId = oid2;
5562 attr2.cValue = 1;
5563 attr2.rgValue = &value2;
5564 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5565 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5566 ctlEntry[1].cAttribute = 1;
5567 ctlEntry[1].rgAttribute = &attr2;
5568 info.cCTLEntry = 2;
5569 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithTwoEntries,
5570 sizeof(ctlWithTwoEntries), CRYPT_DECODE_ALLOC_FLAG, NULL,
5571 (BYTE *)&buf, &size);
5572 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5573 if (buf)
5575 compareCTLInfo("CTL with two entries", &info, (CTL_INFO *)buf);
5576 LocalFree(buf);
5577 buf = NULL;
5579 /* A signed CTL isn't decodable, even if the inner content is a CTL */
5580 SetLastError(0xdeadbeef);
5581 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, signedCTL,
5582 sizeof(signedCTL), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5583 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5584 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5585 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5586 GetLastError());
5587 SetLastError(0xdeadbeef);
5588 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL,
5589 signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent),
5590 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5591 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5592 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5593 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5594 GetLastError());
5597 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
5598 static const BYTE emptyPKCSContentInfoExtraBytes[] = { 0x30,0x04,0x06,0x02,0x2a,
5599 0x03,0,0,0,0,0,0 };
5600 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
5601 0xa0,0x01,0x01 };
5602 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
5603 0x03,0x02,0x01,0x01 };
5604 static BYTE bogusDER[] = { 1 };
5606 static void test_encodePKCSContentInfo(DWORD dwEncoding)
5608 BOOL ret;
5609 BYTE *buf = NULL;
5610 DWORD size = 0;
5611 CRYPT_CONTENT_INFO info = { 0 };
5612 char oid1[] = "1.2.3";
5614 if (0)
5616 /* Crashes on win9x */
5617 SetLastError(0xdeadbeef);
5618 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL,
5619 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5620 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5621 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5623 SetLastError(0xdeadbeef);
5624 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5625 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5626 ok(!ret && (GetLastError() == E_INVALIDARG ||
5627 GetLastError() == OSS_LIMITED /* Win9x */),
5628 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5629 info.pszObjId = oid1;
5630 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5631 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5632 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5633 if (buf)
5635 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size);
5636 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n");
5637 LocalFree(buf);
5639 info.Content.pbData = bogusDER;
5640 info.Content.cbData = sizeof(bogusDER);
5641 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5642 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5643 ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError());
5644 if (buf)
5646 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size);
5647 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n");
5648 LocalFree(buf);
5650 info.Content.pbData = (BYTE *)ints[0].encoded;
5651 info.Content.cbData = ints[0].encoded[1] + 2;
5652 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5653 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5654 if (buf)
5656 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size);
5657 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n");
5658 LocalFree(buf);
5662 static const BYTE indefiniteSignedPKCSContent[] = {
5663 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
5664 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
5665 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
5666 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
5667 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
5668 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
5669 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5670 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5671 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
5672 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5673 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5674 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
5675 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
5676 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
5677 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
5678 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
5679 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
5680 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
5681 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
5682 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5683 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5684 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
5685 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
5686 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
5687 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
5688 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
5689 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
5690 0x00,0x00,0x00,0x00,0x00,0x00 };
5692 static void test_decodePKCSContentInfo(DWORD dwEncoding)
5694 BOOL ret;
5695 LPBYTE buf = NULL;
5696 DWORD size = 0;
5697 CRYPT_CONTENT_INFO *info;
5699 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5700 emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo),
5701 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5702 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5703 if (buf)
5705 info = (CRYPT_CONTENT_INFO *)buf;
5707 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5708 info->pszObjId);
5709 ok(info->Content.cbData == 0, "Expected no data, got %d\n",
5710 info->Content.cbData);
5711 LocalFree(buf);
5713 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5714 emptyPKCSContentInfoExtraBytes, sizeof(emptyPKCSContentInfoExtraBytes),
5715 0, NULL, NULL, &size);
5716 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5717 SetLastError(0xdeadbeef);
5718 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5719 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo),
5720 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5721 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5722 * I doubt an app depends on that.
5724 ok((!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5725 GetLastError() == CRYPT_E_ASN1_CORRUPT)) || broken(ret),
5726 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5727 GetLastError());
5728 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5729 intPKCSContentInfo, sizeof(intPKCSContentInfo),
5730 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5731 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5732 if (buf)
5734 info = (CRYPT_CONTENT_INFO *)buf;
5736 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5737 info->pszObjId);
5738 ok(info->Content.cbData == ints[0].encoded[1] + 2,
5739 "Unexpected size %d\n", info->Content.cbData);
5740 ok(!memcmp(info->Content.pbData, ints[0].encoded,
5741 info->Content.cbData), "Unexpected value\n");
5742 LocalFree(buf);
5744 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5745 indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent),
5746 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5747 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5748 if (buf)
5750 info = (CRYPT_CONTENT_INFO *)buf;
5752 ok(!strcmp(info->pszObjId, szOID_RSA_signedData),
5753 "Expected %s, got %s\n", szOID_RSA_signedData, info->pszObjId);
5754 ok(info->Content.cbData == 392, "Expected 392, got %d\n",
5755 info->Content.cbData);
5756 LocalFree(buf);
5760 static const BYTE emptyPKCSAttr[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
5761 0x00 };
5762 static const BYTE bogusPKCSAttr[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
5763 0x01 };
5764 static const BYTE intPKCSAttr[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
5765 0x02,0x01,0x01 };
5767 static void test_encodePKCSAttribute(DWORD dwEncoding)
5769 CRYPT_ATTRIBUTE attr = { 0 };
5770 BOOL ret;
5771 LPBYTE buf = NULL;
5772 DWORD size = 0;
5773 CRYPT_ATTR_BLOB blob;
5774 char oid[] = "1.2.3";
5776 if (0)
5778 /* Crashes on win9x */
5779 SetLastError(0xdeadbeef);
5780 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, NULL,
5781 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5782 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5783 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5785 SetLastError(0xdeadbeef);
5786 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5787 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5788 ok(!ret && (GetLastError() == E_INVALIDARG ||
5789 GetLastError() == OSS_LIMITED /* Win9x */),
5790 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5791 attr.pszObjId = oid;
5792 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5793 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5794 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5795 if (buf)
5797 ok(size == sizeof(emptyPKCSAttr), "Unexpected size %d\n", size);
5798 ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n");
5799 LocalFree(buf);
5801 blob.cbData = sizeof(bogusDER);
5802 blob.pbData = bogusDER;
5803 attr.cValue = 1;
5804 attr.rgValue = &blob;
5805 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5806 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5807 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5808 if (buf)
5810 ok(size == sizeof(bogusPKCSAttr), "Unexpected size %d\n", size);
5811 ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n");
5812 LocalFree(buf);
5814 blob.pbData = (BYTE *)ints[0].encoded;
5815 blob.cbData = ints[0].encoded[1] + 2;
5816 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5817 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5818 if (buf)
5820 ok(size == sizeof(intPKCSAttr), "Unexpected size %d\n", size);
5821 ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n");
5822 LocalFree(buf);
5826 static void test_decodePKCSAttribute(DWORD dwEncoding)
5828 BOOL ret;
5829 LPBYTE buf = NULL;
5830 DWORD size = 0;
5831 CRYPT_ATTRIBUTE *attr;
5833 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5834 emptyPKCSAttr, sizeof(emptyPKCSAttr),
5835 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5836 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5837 if (buf)
5839 attr = (CRYPT_ATTRIBUTE *)buf;
5841 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5842 attr->pszObjId);
5843 ok(attr->cValue == 0, "Expected no value, got %d\n", attr->cValue);
5844 LocalFree(buf);
5846 SetLastError(0xdeadbeef);
5847 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5848 bogusPKCSAttr, sizeof(bogusPKCSAttr),
5849 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5850 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5851 * I doubt an app depends on that.
5853 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5854 GetLastError() == CRYPT_E_ASN1_CORRUPT || OSS_MORE_INPUT /* Win9x */),
5855 "Expected CRYPT_E_ASN1_EOD, CRYPT_E_ASN1_CORRUPT, or OSS_MORE_INPUT, got %x\n",
5856 GetLastError());
5857 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5858 intPKCSAttr, sizeof(intPKCSAttr),
5859 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5860 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5861 if (buf)
5863 attr = (CRYPT_ATTRIBUTE *)buf;
5865 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5866 attr->pszObjId);
5867 ok(attr->cValue == 1, "Expected 1 value, got %d\n", attr->cValue);
5868 ok(attr->rgValue[0].cbData == ints[0].encoded[1] + 2,
5869 "Unexpected size %d\n", attr->rgValue[0].cbData);
5870 ok(!memcmp(attr->rgValue[0].pbData, ints[0].encoded,
5871 attr->rgValue[0].cbData), "Unexpected value\n");
5872 LocalFree(buf);
5876 static const BYTE emptyPKCSAttributes[] = { 0x31,0x00 };
5877 static const BYTE singlePKCSAttributes[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
5878 0x2a,0x03,0x31,0x00 };
5879 static const BYTE doublePKCSAttributes[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
5880 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
5882 static void test_encodePKCSAttributes(DWORD dwEncoding)
5884 CRYPT_ATTRIBUTES attributes = { 0 };
5885 CRYPT_ATTRIBUTE attr[2] = { { 0 } };
5886 CRYPT_ATTR_BLOB blob;
5887 BOOL ret;
5888 LPBYTE buf = NULL;
5889 DWORD size = 0;
5890 char oid1[] = "1.2.3", oid2[] = "1.5.6";
5892 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5893 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5894 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5895 if (buf)
5897 ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %d\n", size);
5898 ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n");
5899 LocalFree(buf);
5901 attributes.cAttr = 1;
5902 attributes.rgAttr = attr;
5903 SetLastError(0xdeadbeef);
5904 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5905 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5906 ok(!ret && (GetLastError() == E_INVALIDARG ||
5907 GetLastError() == OSS_LIMITED /* Win9x */),
5908 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
5909 attr[0].pszObjId = oid1;
5910 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5911 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5912 if (buf)
5914 ok(size == sizeof(singlePKCSAttributes), "Unexpected size %d\n", size);
5915 ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n");
5916 LocalFree(buf);
5918 attr[1].pszObjId = oid2;
5919 attr[1].cValue = 1;
5920 attr[1].rgValue = &blob;
5921 blob.pbData = (BYTE *)ints[0].encoded;
5922 blob.cbData = ints[0].encoded[1] + 2;
5923 attributes.cAttr = 2;
5924 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5925 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5926 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5927 if (buf)
5929 ok(size == sizeof(doublePKCSAttributes), "Unexpected size %d\n", size);
5930 ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n");
5931 LocalFree(buf);
5935 static void test_decodePKCSAttributes(DWORD dwEncoding)
5937 BOOL ret;
5938 LPBYTE buf = NULL;
5939 DWORD size = 0;
5940 CRYPT_ATTRIBUTES *attributes;
5942 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5943 emptyPKCSAttributes, sizeof(emptyPKCSAttributes),
5944 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5945 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5946 if (buf)
5948 attributes = (CRYPT_ATTRIBUTES *)buf;
5949 ok(attributes->cAttr == 0, "Expected no attributes, got %d\n",
5950 attributes->cAttr);
5951 LocalFree(buf);
5953 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5954 singlePKCSAttributes, sizeof(singlePKCSAttributes),
5955 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5956 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5957 if (buf)
5959 attributes = (CRYPT_ATTRIBUTES *)buf;
5960 ok(attributes->cAttr == 1, "Expected 1 attribute, got %d\n",
5961 attributes->cAttr);
5962 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5963 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5964 ok(attributes->rgAttr[0].cValue == 0,
5965 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5966 LocalFree(buf);
5968 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5969 doublePKCSAttributes, sizeof(doublePKCSAttributes),
5970 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5971 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5972 if (buf)
5974 attributes = (CRYPT_ATTRIBUTES *)buf;
5975 ok(attributes->cAttr == 2, "Expected 2 attributes, got %d\n",
5976 attributes->cAttr);
5977 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5978 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5979 ok(attributes->rgAttr[0].cValue == 0,
5980 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5981 ok(!strcmp(attributes->rgAttr[1].pszObjId, "1.5.6"),
5982 "Expected 1.5.6, got %s\n", attributes->rgAttr[1].pszObjId);
5983 ok(attributes->rgAttr[1].cValue == 1,
5984 "Expected 1 attribute, got %d\n", attributes->rgAttr[1].cValue);
5985 ok(attributes->rgAttr[1].rgValue[0].cbData == ints[0].encoded[1] + 2,
5986 "Unexpected size %d\n", attributes->rgAttr[1].rgValue[0].cbData);
5987 ok(!memcmp(attributes->rgAttr[1].rgValue[0].pbData, ints[0].encoded,
5988 attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n");
5989 LocalFree(buf);
5993 static const BYTE singleCapability[] = {
5994 0x30,0x06,0x30,0x04,0x06,0x02,0x2d,0x06 };
5995 static const BYTE twoCapabilities[] = {
5996 0x30,0x0c,0x30,0x04,0x06,0x02,0x2d,0x06,0x30,0x04,0x06,0x02,0x2a,0x03 };
5997 static const BYTE singleCapabilitywithNULL[] = {
5998 0x30,0x08,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
6000 static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding)
6002 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6003 BOOL ret;
6004 LPBYTE buf = NULL;
6005 DWORD size = 0;
6006 CRYPT_SMIME_CAPABILITY capability[2];
6007 CRYPT_SMIME_CAPABILITIES capabilities;
6009 /* An empty capabilities is allowed */
6010 capabilities.cCapability = 0;
6011 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6012 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6013 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6014 if (buf)
6016 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
6017 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
6018 LocalFree(buf);
6020 /* A non-empty capabilities with an empty capability (lacking an OID) is
6021 * not allowed
6023 capability[0].pszObjId = NULL;
6024 capability[0].Parameters.cbData = 0;
6025 capabilities.cCapability = 1;
6026 capabilities.rgCapability = capability;
6027 SetLastError(0xdeadbeef);
6028 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6029 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6030 ok(!ret && (GetLastError() == E_INVALIDARG ||
6031 GetLastError() == OSS_LIMITED /* Win9x */),
6032 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6033 capability[0].pszObjId = oid1;
6034 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6035 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6036 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6037 if (buf)
6039 ok(size == sizeof(singleCapability), "unexpected size %d\n", size);
6040 ok(!memcmp(buf, singleCapability, size), "unexpected value\n");
6041 LocalFree(buf);
6043 capability[1].pszObjId = oid2;
6044 capability[1].Parameters.cbData = 0;
6045 capabilities.cCapability = 2;
6046 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6047 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6048 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6049 if (buf)
6051 ok(size == sizeof(twoCapabilities), "unexpected size %d\n", size);
6052 ok(!memcmp(buf, twoCapabilities, size), "unexpected value\n");
6053 LocalFree(buf);
6057 static void compareSMimeCapabilities(LPCSTR header,
6058 const CRYPT_SMIME_CAPABILITIES *expected, const CRYPT_SMIME_CAPABILITIES *got)
6060 DWORD i;
6062 ok(got->cCapability == expected->cCapability,
6063 "%s: expected %d capabilities, got %d\n", header, expected->cCapability,
6064 got->cCapability);
6065 for (i = 0; i < expected->cCapability; i++)
6067 ok(!strcmp(expected->rgCapability[i].pszObjId,
6068 got->rgCapability[i].pszObjId), "%s[%d]: expected %s, got %s\n",
6069 header, i, expected->rgCapability[i].pszObjId,
6070 got->rgCapability[i].pszObjId);
6071 ok(expected->rgCapability[i].Parameters.cbData ==
6072 got->rgCapability[i].Parameters.cbData,
6073 "%s[%d]: expected %d bytes, got %d\n", header, i,
6074 expected->rgCapability[i].Parameters.cbData,
6075 got->rgCapability[i].Parameters.cbData);
6076 if (expected->rgCapability[i].Parameters.cbData)
6077 ok(!memcmp(expected->rgCapability[i].Parameters.pbData,
6078 got->rgCapability[i].Parameters.pbData,
6079 expected->rgCapability[i].Parameters.cbData),
6080 "%s[%d]: unexpected value\n", header, i);
6084 static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding)
6086 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6087 BOOL ret;
6088 DWORD size = 0;
6089 CRYPT_SMIME_CAPABILITY capability[2];
6090 CRYPT_SMIME_CAPABILITIES capabilities, *ptr;
6092 SetLastError(0xdeadbeef);
6093 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6094 emptySequence, sizeof(emptySequence),
6095 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&ptr, &size);
6096 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6097 if (ret)
6099 capabilities.cCapability = 0;
6100 compareSMimeCapabilities("empty capabilities", &capabilities, ptr);
6101 LocalFree(ptr);
6103 SetLastError(0xdeadbeef);
6104 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6105 singleCapability, sizeof(singleCapability), CRYPT_DECODE_ALLOC_FLAG, NULL,
6106 (BYTE *)&ptr, &size);
6107 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6108 if (ret)
6110 capability[0].pszObjId = oid1;
6111 capability[0].Parameters.cbData = 0;
6112 capabilities.cCapability = 1;
6113 capabilities.rgCapability = capability;
6114 compareSMimeCapabilities("single capability", &capabilities, ptr);
6115 LocalFree(ptr);
6117 SetLastError(0xdeadbeef);
6118 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6119 singleCapabilitywithNULL, sizeof(singleCapabilitywithNULL),
6120 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&ptr, &size);
6121 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6122 if (ret)
6124 BYTE NULLparam[] = {0x05, 0x00};
6125 capability[0].pszObjId = oid1;
6126 capability[0].Parameters.cbData = 2;
6127 capability[0].Parameters.pbData = NULLparam;
6128 capabilities.cCapability = 1;
6129 capabilities.rgCapability = capability;
6130 compareSMimeCapabilities("single capability with NULL", &capabilities,
6131 ptr);
6132 LocalFree(ptr);
6134 SetLastError(0xdeadbeef);
6135 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6136 twoCapabilities, sizeof(twoCapabilities), CRYPT_DECODE_ALLOC_FLAG, NULL,
6137 (BYTE *)&ptr, &size);
6138 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6139 if (ret)
6141 capability[0].Parameters.cbData = 0;
6142 capability[1].pszObjId = oid2;
6143 capability[1].Parameters.cbData = 0;
6144 capabilities.cCapability = 2;
6145 compareSMimeCapabilities("two capabilities", &capabilities, ptr);
6146 LocalFree(ptr);
6150 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
6151 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
6152 0x67 };
6153 static const BYTE minimalPKCSSigner[] = {
6154 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6155 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6156 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6157 static const BYTE PKCSSignerWithSerial[] = {
6158 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6159 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6160 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
6161 0x00 };
6162 static const BYTE PKCSSignerWithHashAlgo[] = {
6163 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6164 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6165 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
6166 0x00,0x04,0x00 };
6167 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = {
6168 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6169 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6170 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6171 0x06,0x05,0x00,0x04,0x00 };
6172 static const BYTE PKCSSignerWithHash[] = {
6173 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6174 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6175 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6176 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
6177 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6178 static const BYTE PKCSSignerWithAuthAttr[] = {
6179 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6180 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6181 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
6182 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
6183 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
6184 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
6185 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6187 static void test_encodePKCSSignerInfo(DWORD dwEncoding)
6189 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6190 BOOL ret;
6191 LPBYTE buf = NULL;
6192 DWORD size = 0;
6193 CMSG_SIGNER_INFO info = { 0 };
6194 char oid_common_name[] = szOID_COMMON_NAME;
6195 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
6196 (LPBYTE)encodedCommonName };
6197 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
6199 SetLastError(0xdeadbeef);
6200 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6201 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6202 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6204 skip("no PKCS7_SIGNER_INFO encode support\n");
6205 return;
6207 ok(!ret && (GetLastError() == E_INVALIDARG ||
6208 GetLastError() == OSS_LIMITED /* Win9x */),
6209 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6210 /* To be encoded, a signer must have an issuer at least, and the encoding
6211 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
6212 * see decoding tests.)
6214 info.Issuer.cbData = sizeof(encodedCommonNameNoNull);
6215 info.Issuer.pbData = encodedCommonNameNoNull;
6216 SetLastError(0xdeadbeef);
6217 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6218 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6219 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6220 ok(!ret && GetLastError() == E_INVALIDARG,
6221 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6222 else
6224 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6225 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6226 if (buf)
6228 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6229 if (size == sizeof(minimalPKCSSigner))
6230 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6231 else
6232 ok(0, "Unexpected value\n");
6233 LocalFree(buf);
6236 info.SerialNumber.cbData = sizeof(serialNum);
6237 info.SerialNumber.pbData = (BYTE *)serialNum;
6238 SetLastError(0xdeadbeef);
6239 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6240 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6241 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6242 ok(!ret && GetLastError() == E_INVALIDARG,
6243 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6244 else
6246 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6247 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6248 if (buf)
6250 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6251 size);
6252 if (size == sizeof(PKCSSignerWithSerial))
6253 ok(!memcmp(buf, PKCSSignerWithSerial, size),
6254 "Unexpected value\n");
6255 else
6256 ok(0, "Unexpected value\n");
6257 LocalFree(buf);
6260 info.HashAlgorithm.pszObjId = oid1;
6261 SetLastError(0xdeadbeef);
6262 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6263 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6264 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6265 ok(!ret && GetLastError() == E_INVALIDARG,
6266 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6267 else
6269 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6270 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6271 if (buf)
6273 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6274 size);
6275 if (size == sizeof(PKCSSignerWithHashAlgo))
6276 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6277 "Unexpected value\n");
6278 else
6279 ok(0, "Unexpected value\n");
6280 LocalFree(buf);
6283 info.HashEncryptionAlgorithm.pszObjId = oid2;
6284 SetLastError(0xdeadbeef);
6285 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6286 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6287 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6288 ok(!ret && GetLastError() == E_INVALIDARG,
6289 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6290 else
6292 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6293 if (buf)
6295 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6296 "Unexpected size %d\n", size);
6297 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo))
6298 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6299 "Unexpected value\n");
6300 else
6301 ok(0, "Unexpected value\n");
6302 LocalFree(buf);
6305 info.EncryptedHash.cbData = sizeof(hash);
6306 info.EncryptedHash.pbData = (BYTE *)hash;
6307 SetLastError(0xdeadbeef);
6308 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6309 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6310 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6311 ok(!ret && GetLastError() == E_INVALIDARG,
6312 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6313 else
6315 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6316 if (buf)
6318 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6319 size);
6320 if (size == sizeof(PKCSSignerWithHash))
6321 ok(!memcmp(buf, PKCSSignerWithHash, size),
6322 "Unexpected value\n");
6323 else
6324 ok(0, "Unexpected value\n");
6325 LocalFree(buf);
6328 info.AuthAttrs.cAttr = 1;
6329 info.AuthAttrs.rgAttr = &attr;
6330 SetLastError(0xdeadbeef);
6331 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6332 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6333 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6334 ok(!ret && GetLastError() == E_INVALIDARG,
6335 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6336 else
6338 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6339 if (buf)
6341 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
6342 size);
6343 if (size == sizeof(PKCSSignerWithAuthAttr))
6344 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
6345 "Unexpected value\n");
6346 else
6347 ok(0, "Unexpected value\n");
6348 LocalFree(buf);
6353 static void test_decodePKCSSignerInfo(DWORD dwEncoding)
6355 BOOL ret;
6356 LPBYTE buf = NULL;
6357 DWORD size = 0;
6358 CMSG_SIGNER_INFO *info;
6360 /* A PKCS signer can't be decoded without a serial number. */
6361 SetLastError(0xdeadbeef);
6362 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6363 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6364 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6365 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
6366 GetLastError() == OSS_DATA_ERROR /* Win9x */),
6367 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %x\n",
6368 GetLastError());
6369 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6370 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6371 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6372 ok(ret || broken(GetLastError() == OSS_DATA_ERROR),
6373 "CryptDecodeObjectEx failed: %x\n", GetLastError());
6374 if (buf)
6376 info = (CMSG_SIGNER_INFO *)buf;
6377 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6378 info->dwVersion);
6379 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6380 "Unexpected size %d\n", info->Issuer.cbData);
6381 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6382 info->Issuer.cbData), "Unexpected value\n");
6383 ok(info->SerialNumber.cbData == sizeof(serialNum),
6384 "Unexpected size %d\n", info->SerialNumber.cbData);
6385 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6386 "Unexpected value\n");
6387 LocalFree(buf);
6389 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6390 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6391 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6392 if (buf)
6394 info = (CMSG_SIGNER_INFO *)buf;
6395 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6396 info->dwVersion);
6397 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6398 "Unexpected size %d\n", info->Issuer.cbData);
6399 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6400 info->Issuer.cbData), "Unexpected value\n");
6401 ok(info->SerialNumber.cbData == sizeof(serialNum),
6402 "Unexpected size %d\n", info->SerialNumber.cbData);
6403 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6404 "Unexpected value\n");
6405 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6406 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6407 LocalFree(buf);
6409 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6410 PKCSSignerWithHashAndEncryptionAlgo,
6411 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6412 NULL, (BYTE *)&buf, &size);
6413 if (buf)
6415 info = (CMSG_SIGNER_INFO *)buf;
6416 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6417 info->dwVersion);
6418 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6419 "Unexpected size %d\n", info->Issuer.cbData);
6420 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6421 info->Issuer.cbData), "Unexpected value\n");
6422 ok(info->SerialNumber.cbData == sizeof(serialNum),
6423 "Unexpected size %d\n", info->SerialNumber.cbData);
6424 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6425 "Unexpected value\n");
6426 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6427 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6428 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6429 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6430 LocalFree(buf);
6432 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6433 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6434 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6435 if (buf)
6437 info = (CMSG_SIGNER_INFO *)buf;
6438 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6439 info->dwVersion);
6440 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6441 "Unexpected size %d\n", info->Issuer.cbData);
6442 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6443 info->Issuer.cbData), "Unexpected value\n");
6444 ok(info->SerialNumber.cbData == sizeof(serialNum),
6445 "Unexpected size %d\n", info->SerialNumber.cbData);
6446 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6447 "Unexpected value\n");
6448 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6449 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6450 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6451 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6452 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6453 info->EncryptedHash.cbData);
6454 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6455 "Unexpected value\n");
6456 LocalFree(buf);
6458 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6459 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
6460 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6461 if (buf)
6463 info = (CMSG_SIGNER_INFO *)buf;
6464 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n",
6465 info->AuthAttrs.cAttr);
6466 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
6467 "Expected %s, got %s\n", szOID_COMMON_NAME,
6468 info->AuthAttrs.rgAttr[0].pszObjId);
6469 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
6470 info->AuthAttrs.rgAttr[0].cValue);
6471 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
6472 sizeof(encodedCommonName), "Unexpected size %d\n",
6473 info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
6474 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
6475 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
6476 LocalFree(buf);
6480 static const BYTE CMSSignerWithKeyId[] = {
6481 0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,
6482 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6484 static void test_encodeCMSSignerInfo(DWORD dwEncoding)
6486 BOOL ret;
6487 LPBYTE buf = NULL;
6488 DWORD size = 0;
6489 CMSG_CMS_SIGNER_INFO info = { 0 };
6490 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6492 SetLastError(0xdeadbeef);
6493 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6494 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6495 ok(!ret, "Expected failure, got %d\n", ret);
6496 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6498 skip("no CMS_SIGNER_INFO encode support\n");
6499 return;
6501 ok(GetLastError() == E_INVALIDARG,
6502 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6503 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6504 SetLastError(0xdeadbeef);
6505 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6506 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6507 ok(!ret, "Expected failure, got %d\n", ret);
6508 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6510 skip("no CMS_SIGNER_INFO encode support\n");
6511 return;
6513 ok(GetLastError() == E_INVALIDARG,
6514 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6515 /* To be encoded, a signer must have a valid cert ID, where a valid ID may
6516 * be a key id or a issuer serial number with at least the issuer set, and
6517 * the encoding must include PKCS_7_ASN_ENCODING.
6518 * (That isn't enough to be decoded, see decoding tests.)
6520 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6521 sizeof(encodedCommonNameNoNull);
6522 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6523 SetLastError(0xdeadbeef);
6524 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6525 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6526 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6527 ok(!ret && GetLastError() == E_INVALIDARG,
6528 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6529 else
6531 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6532 if (buf)
6534 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6535 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6536 LocalFree(buf);
6539 U(info.SignerId).IssuerSerialNumber.SerialNumber.cbData = sizeof(serialNum);
6540 U(info.SignerId).IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
6541 SetLastError(0xdeadbeef);
6542 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6543 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6544 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6545 ok(!ret && GetLastError() == E_INVALIDARG,
6546 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6547 else
6549 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6550 if (buf)
6552 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6553 size);
6554 ok(!memcmp(buf, PKCSSignerWithSerial, size), "Unexpected value\n");
6555 LocalFree(buf);
6558 info.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
6559 U(info.SignerId).KeyId.cbData = sizeof(serialNum);
6560 U(info.SignerId).KeyId.pbData = (BYTE *)serialNum;
6561 SetLastError(0xdeadbeef);
6562 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6563 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6564 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6565 ok(!ret && GetLastError() == E_INVALIDARG,
6566 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6567 else
6569 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6570 if (buf)
6572 ok(size == sizeof(CMSSignerWithKeyId), "Unexpected size %d\n",
6573 size);
6574 ok(!memcmp(buf, CMSSignerWithKeyId, size), "Unexpected value\n");
6575 LocalFree(buf);
6578 /* While a CERT_ID can have a hash type, that's not allowed in CMS, where
6579 * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed
6580 * (see RFC 3852, section 5.3.)
6582 info.SignerId.dwIdChoice = CERT_ID_SHA1_HASH;
6583 U(info.SignerId).HashId.cbData = sizeof(hash);
6584 U(info.SignerId).HashId.pbData = (BYTE *)hash;
6585 SetLastError(0xdeadbeef);
6586 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6587 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6588 ok(!ret && GetLastError() == E_INVALIDARG,
6589 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6590 /* Now with a hash algo */
6591 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6592 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6593 sizeof(encodedCommonNameNoNull);
6594 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6595 info.HashAlgorithm.pszObjId = oid1;
6596 SetLastError(0xdeadbeef);
6597 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6598 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6599 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6600 ok(!ret && GetLastError() == E_INVALIDARG,
6601 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6602 else
6604 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6605 if (buf)
6607 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6608 size);
6609 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6610 "Unexpected value\n");
6611 LocalFree(buf);
6614 info.HashEncryptionAlgorithm.pszObjId = oid2;
6615 SetLastError(0xdeadbeef);
6616 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6617 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6618 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6619 ok(!ret && GetLastError() == E_INVALIDARG,
6620 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6621 else
6623 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6624 if (buf)
6626 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6627 "Unexpected size %d\n", size);
6628 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6629 "Unexpected value\n");
6630 LocalFree(buf);
6633 info.EncryptedHash.cbData = sizeof(hash);
6634 info.EncryptedHash.pbData = (BYTE *)hash;
6635 SetLastError(0xdeadbeef);
6636 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6637 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6638 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6639 ok(!ret && GetLastError() == E_INVALIDARG,
6640 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6641 else
6643 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6644 if (buf)
6646 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6647 size);
6648 ok(!memcmp(buf, PKCSSignerWithHash, size), "Unexpected value\n");
6649 LocalFree(buf);
6654 static void test_decodeCMSSignerInfo(DWORD dwEncoding)
6656 BOOL ret;
6657 LPBYTE buf = NULL;
6658 DWORD size = 0;
6659 CMSG_CMS_SIGNER_INFO *info;
6660 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6662 /* A CMS signer can't be decoded without a serial number. */
6663 SetLastError(0xdeadbeef);
6664 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6665 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6666 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6667 ok(!ret, "expected failure\n");
6668 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6670 skip("no CMS_SIGNER_INFO decode support\n");
6671 return;
6673 ok(GetLastError() == CRYPT_E_ASN1_CORRUPT,
6674 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
6675 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6676 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6677 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6678 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6679 if (buf)
6681 info = (CMSG_CMS_SIGNER_INFO *)buf;
6682 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6683 info->dwVersion);
6684 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6685 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6686 info->SignerId.dwIdChoice);
6687 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6688 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6689 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6690 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6691 encodedCommonNameNoNull,
6692 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6693 "Unexpected value\n");
6694 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6695 sizeof(serialNum), "Unexpected size %d\n",
6696 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6697 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6698 serialNum, sizeof(serialNum)), "Unexpected value\n");
6699 LocalFree(buf);
6701 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6702 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6703 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6704 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6705 if (buf)
6707 info = (CMSG_CMS_SIGNER_INFO *)buf;
6708 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6709 info->dwVersion);
6710 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6711 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6712 info->SignerId.dwIdChoice);
6713 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6714 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6715 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6716 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6717 encodedCommonNameNoNull,
6718 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6719 "Unexpected value\n");
6720 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6721 sizeof(serialNum), "Unexpected size %d\n",
6722 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6723 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6724 serialNum, sizeof(serialNum)), "Unexpected value\n");
6725 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6726 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6727 LocalFree(buf);
6729 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6730 PKCSSignerWithHashAndEncryptionAlgo,
6731 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6732 NULL, (BYTE *)&buf, &size);
6733 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6734 if (buf)
6736 info = (CMSG_CMS_SIGNER_INFO *)buf;
6737 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6738 info->dwVersion);
6739 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6740 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6741 info->SignerId.dwIdChoice);
6742 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6743 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6744 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6745 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6746 encodedCommonNameNoNull,
6747 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6748 "Unexpected value\n");
6749 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6750 sizeof(serialNum), "Unexpected size %d\n",
6751 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6752 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6753 serialNum, sizeof(serialNum)), "Unexpected value\n");
6754 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6755 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6756 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6757 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6758 LocalFree(buf);
6760 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6761 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6762 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6763 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6764 if (buf)
6766 info = (CMSG_CMS_SIGNER_INFO *)buf;
6767 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6768 info->dwVersion);
6769 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6770 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6771 info->SignerId.dwIdChoice);
6772 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6773 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6774 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6775 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6776 encodedCommonNameNoNull,
6777 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6778 "Unexpected value\n");
6779 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6780 sizeof(serialNum), "Unexpected size %d\n",
6781 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6782 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6783 serialNum, sizeof(serialNum)), "Unexpected value\n");
6784 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6785 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6786 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6787 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6788 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6789 info->EncryptedHash.cbData);
6790 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6791 "Unexpected value\n");
6792 LocalFree(buf);
6794 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6795 CMSSignerWithKeyId, sizeof(CMSSignerWithKeyId),
6796 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6797 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6798 if (buf)
6800 info = (CMSG_CMS_SIGNER_INFO *)buf;
6801 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6802 info->dwVersion);
6803 ok(info->SignerId.dwIdChoice == CERT_ID_KEY_IDENTIFIER,
6804 "Expected CERT_ID_KEY_IDENTIFIER, got %d\n",
6805 info->SignerId.dwIdChoice);
6806 ok(U(info->SignerId).KeyId.cbData == sizeof(serialNum),
6807 "Unexpected size %d\n", U(info->SignerId).KeyId.cbData);
6808 ok(!memcmp(U(info->SignerId).KeyId.pbData, serialNum, sizeof(serialNum)),
6809 "Unexpected value\n");
6810 LocalFree(buf);
6814 static BYTE emptyDNSPermittedConstraints[] = {
6815 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
6816 static BYTE emptyDNSExcludedConstraints[] = {
6817 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
6818 static BYTE DNSExcludedConstraints[] = {
6819 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
6820 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6821 static BYTE permittedAndExcludedConstraints[] = {
6822 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6823 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
6824 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6825 static BYTE permittedAndExcludedWithMinConstraints[] = {
6826 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6827 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
6828 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6829 static BYTE permittedAndExcludedWithMinMaxConstraints[] = {
6830 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6831 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
6832 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6834 static void test_encodeNameConstraints(DWORD dwEncoding)
6836 BOOL ret;
6837 CERT_NAME_CONSTRAINTS_INFO constraints = { 0 };
6838 CERT_GENERAL_SUBTREE permitted = { { 0 } };
6839 CERT_GENERAL_SUBTREE excluded = { { 0 } };
6840 LPBYTE buf;
6841 DWORD size;
6843 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6844 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6845 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6847 skip("no X509_NAME_CONSTRAINTS encode support\n");
6848 return;
6850 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6851 if (ret)
6853 ok(size == sizeof(emptySequence), "Unexpected size\n");
6854 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
6855 LocalFree(buf);
6857 constraints.cPermittedSubtree = 1;
6858 constraints.rgPermittedSubtree = &permitted;
6859 SetLastError(0xdeadbeef);
6860 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6861 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6862 ok(!ret && GetLastError() == E_INVALIDARG,
6863 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6864 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
6865 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6866 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6867 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6868 if (ret)
6870 ok(size == sizeof(emptyDNSPermittedConstraints), "Unexpected size\n");
6871 ok(!memcmp(buf, emptyDNSPermittedConstraints, size),
6872 "Unexpected value\n");
6873 LocalFree(buf);
6875 constraints.cPermittedSubtree = 0;
6876 constraints.cExcludedSubtree = 1;
6877 constraints.rgExcludedSubtree = &excluded;
6878 excluded.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
6879 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6880 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6881 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6882 if (ret)
6884 ok(size == sizeof(emptyDNSExcludedConstraints), "Unexpected size\n");
6885 ok(!memcmp(buf, emptyDNSExcludedConstraints, size),
6886 "Unexpected value\n");
6887 LocalFree(buf);
6889 U(excluded.Base).pwszURL = (LPWSTR)url;
6890 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6891 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6892 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6893 if (ret)
6895 ok(size == sizeof(DNSExcludedConstraints), "Unexpected size\n");
6896 ok(!memcmp(buf, DNSExcludedConstraints, size),
6897 "Unexpected value\n");
6898 LocalFree(buf);
6900 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
6901 U(permitted.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6902 U(permitted.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6903 constraints.cPermittedSubtree = 1;
6904 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6905 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6906 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6907 if (ret)
6909 ok(size == sizeof(permittedAndExcludedConstraints),
6910 "Unexpected size\n");
6911 ok(!memcmp(buf, permittedAndExcludedConstraints, size),
6912 "Unexpected value\n");
6913 LocalFree(buf);
6915 permitted.dwMinimum = 5;
6916 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6917 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6918 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6919 if (ret)
6921 ok(size == sizeof(permittedAndExcludedWithMinConstraints),
6922 "Unexpected size\n");
6923 ok(!memcmp(buf, permittedAndExcludedWithMinConstraints, size),
6924 "Unexpected value\n");
6925 LocalFree(buf);
6927 permitted.fMaximum = TRUE;
6928 permitted.dwMaximum = 3;
6929 SetLastError(0xdeadbeef);
6930 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6931 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6932 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6933 if (ret)
6935 ok(size == sizeof(permittedAndExcludedWithMinMaxConstraints),
6936 "Unexpected size\n");
6937 ok(!memcmp(buf, permittedAndExcludedWithMinMaxConstraints, size),
6938 "Unexpected value\n");
6939 LocalFree(buf);
6943 struct EncodedNameConstraints
6945 CRYPT_DATA_BLOB encoded;
6946 CERT_NAME_CONSTRAINTS_INFO constraints;
6949 static CERT_GENERAL_SUBTREE emptyDNSSubtree = {
6950 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
6951 static CERT_GENERAL_SUBTREE DNSSubtree = {
6952 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
6953 static CERT_GENERAL_SUBTREE IPAddressSubtree = {
6954 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 0 };
6955 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree = {
6956 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, 0 };
6957 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree = {
6958 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, TRUE, 3 };
6960 struct EncodedNameConstraints encodedNameConstraints[] = {
6961 { { sizeof(emptySequence), (LPBYTE)emptySequence }, { 0 } },
6962 { { sizeof(emptyDNSPermittedConstraints), emptyDNSPermittedConstraints },
6963 { 1, &emptyDNSSubtree, 0, NULL } },
6964 { { sizeof(emptyDNSExcludedConstraints), emptyDNSExcludedConstraints },
6965 { 0, NULL, 1, &emptyDNSSubtree } },
6966 { { sizeof(DNSExcludedConstraints), DNSExcludedConstraints },
6967 { 0, NULL, 1, &DNSSubtree } },
6968 { { sizeof(permittedAndExcludedConstraints), permittedAndExcludedConstraints },
6969 { 1, &IPAddressSubtree, 1, &DNSSubtree } },
6970 { { sizeof(permittedAndExcludedWithMinConstraints),
6971 permittedAndExcludedWithMinConstraints },
6972 { 1, &IPAddressWithMinSubtree, 1, &DNSSubtree } },
6973 { { sizeof(permittedAndExcludedWithMinMaxConstraints),
6974 permittedAndExcludedWithMinMaxConstraints },
6975 { 1, &IPAddressWithMinMaxSubtree, 1, &DNSSubtree } },
6978 static void test_decodeNameConstraints(DWORD dwEncoding)
6980 BOOL ret;
6981 DWORD i;
6982 CERT_NAME_CONSTRAINTS_INFO *constraints;
6984 U(DNSSubtree.Base).pwszURL = (LPWSTR)url;
6985 U(IPAddressSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6986 U(IPAddressSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6987 U(IPAddressWithMinSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6988 U(IPAddressWithMinSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6989 U(IPAddressWithMinMaxSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6990 U(IPAddressWithMinMaxSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6991 for (i = 0;
6992 i < sizeof(encodedNameConstraints) / sizeof(encodedNameConstraints[0]);
6993 i++)
6995 DWORD size;
6997 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS,
6998 encodedNameConstraints[i].encoded.pbData,
6999 encodedNameConstraints[i].encoded.cbData,
7000 CRYPT_DECODE_ALLOC_FLAG, NULL, &constraints, &size);
7001 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7003 skip("no X509_NAME_CONSTRAINTS decode support\n");
7004 return;
7006 ok(ret, "%d: CryptDecodeObjectEx failed: %08x\n", i, GetLastError());
7007 if (ret)
7009 DWORD j;
7011 if (constraints->cPermittedSubtree !=
7012 encodedNameConstraints[i].constraints.cPermittedSubtree)
7013 fprintf(stderr, "%d: expected %d permitted, got %d\n", i,
7014 encodedNameConstraints[i].constraints.cPermittedSubtree,
7015 constraints->cPermittedSubtree);
7016 if (constraints->cPermittedSubtree ==
7017 encodedNameConstraints[i].constraints.cPermittedSubtree)
7019 for (j = 0; j < constraints->cPermittedSubtree; j++)
7021 compareAltNameEntry(&constraints->rgPermittedSubtree[j].Base,
7022 &encodedNameConstraints[i].constraints.rgPermittedSubtree[j].Base);
7025 if (constraints->cExcludedSubtree !=
7026 encodedNameConstraints[i].constraints.cExcludedSubtree)
7027 fprintf(stderr, "%d: expected %d excluded, got %d\n", i,
7028 encodedNameConstraints[i].constraints.cExcludedSubtree,
7029 constraints->cExcludedSubtree);
7030 if (constraints->cExcludedSubtree ==
7031 encodedNameConstraints[i].constraints.cExcludedSubtree)
7033 for (j = 0; j < constraints->cExcludedSubtree; j++)
7035 compareAltNameEntry(&constraints->rgExcludedSubtree[j].Base,
7036 &encodedNameConstraints[i].constraints.rgExcludedSubtree[j].Base);
7039 LocalFree(constraints);
7044 static WCHAR noticeText[] = { 'T','h','i','s',' ','i','s',' ','a',' ',
7045 'n','o','t','i','c','e',0 };
7046 static const BYTE noticeWithDisplayText[] = {
7047 0x30,0x22,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,0x00,
7048 0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,0x74,
7049 0x00,0x69,0x00,0x63,0x00,0x65
7051 static char org[] = "Wine";
7052 static int noticeNumbers[] = { 2,3 };
7053 static BYTE noticeWithReference[] = {
7054 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7055 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7056 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7057 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7060 static void test_encodePolicyQualifierUserNotice(DWORD dwEncoding)
7062 BOOL ret;
7063 LPBYTE buf;
7064 DWORD size;
7065 CERT_POLICY_QUALIFIER_USER_NOTICE notice;
7066 CERT_POLICY_QUALIFIER_NOTICE_REFERENCE reference;
7068 memset(&notice, 0, sizeof(notice));
7069 ret = pCryptEncodeObjectEx(dwEncoding,
7070 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, &notice, CRYPT_ENCODE_ALLOC_FLAG,
7071 NULL, &buf, &size);
7072 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7074 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE encode support\n");
7075 return;
7077 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7078 if (ret)
7080 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size);
7081 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
7082 LocalFree(buf);
7084 notice.pszDisplayText = noticeText;
7085 ret = pCryptEncodeObjectEx(dwEncoding,
7086 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, &notice, CRYPT_ENCODE_ALLOC_FLAG,
7087 NULL, &buf, &size);
7088 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7089 if (ret)
7091 ok(sizeof(noticeWithDisplayText) == size, "unexpected size %d\n", size);
7092 ok(!memcmp(buf, noticeWithDisplayText, size), "unexpected value\n");
7093 LocalFree(buf);
7095 reference.pszOrganization = org;
7096 reference.cNoticeNumbers = 2;
7097 reference.rgNoticeNumbers = noticeNumbers;
7098 notice.pNoticeReference = &reference;
7099 ret = pCryptEncodeObjectEx(dwEncoding,
7100 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, &notice, CRYPT_ENCODE_ALLOC_FLAG,
7101 NULL, &buf, &size);
7102 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7103 if (ret)
7105 ok(sizeof(noticeWithReference) == size, "unexpected size %d\n", size);
7106 ok(!memcmp(buf, noticeWithReference, size), "unexpected value\n");
7107 LocalFree(buf);
7111 static void test_decodePolicyQualifierUserNotice(DWORD dwEncoding)
7113 BOOL ret;
7114 CERT_POLICY_QUALIFIER_USER_NOTICE *notice;
7115 DWORD size;
7117 ret = pCryptDecodeObjectEx(dwEncoding,
7118 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7119 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7120 &notice, &size);
7121 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7123 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE decode support\n");
7124 return;
7126 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7127 if (ret)
7129 ok(notice->pszDisplayText == NULL, "unexpected display text\n");
7130 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7131 LocalFree(notice);
7133 ret = pCryptDecodeObjectEx(dwEncoding,
7134 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7135 noticeWithDisplayText, sizeof(noticeWithDisplayText),
7136 CRYPT_DECODE_ALLOC_FLAG, NULL, &notice, &size);
7137 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7138 if (ret)
7140 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7141 "unexpected display text\n");
7142 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7143 LocalFree(notice);
7145 ret = pCryptDecodeObjectEx(dwEncoding,
7146 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7147 noticeWithReference, sizeof(noticeWithReference),
7148 CRYPT_DECODE_ALLOC_FLAG, NULL, &notice, &size);
7149 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7150 if (ret)
7152 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7153 "unexpected display text\n");
7154 ok(notice->pNoticeReference != NULL, "expected a notice reference\n");
7155 if (notice->pNoticeReference)
7157 ok(!strcmp(notice->pNoticeReference->pszOrganization, org),
7158 "unexpected organization %s\n",
7159 notice->pNoticeReference->pszOrganization);
7160 ok(notice->pNoticeReference->cNoticeNumbers == 2,
7161 "expected 2 notice numbers, got %d\n",
7162 notice->pNoticeReference->cNoticeNumbers);
7163 ok(notice->pNoticeReference->rgNoticeNumbers[0] == noticeNumbers[0],
7164 "unexpected notice number %d\n",
7165 notice->pNoticeReference->rgNoticeNumbers[0]);
7166 ok(notice->pNoticeReference->rgNoticeNumbers[1] == noticeNumbers[1],
7167 "unexpected notice number %d\n",
7168 notice->pNoticeReference->rgNoticeNumbers[1]);
7170 LocalFree(notice);
7174 static char oid_any_policy[] = "2.5.29.32.0";
7175 static const BYTE policiesWithAnyPolicy[] = {
7176 0x30,0x08,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00
7178 static char oid1[] = "1.2.3";
7179 static char oid_user_notice[] = "1.3.6.1.5.5.7.2.2";
7180 static const BYTE twoPolicies[] = {
7181 0x30,0x50,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00,0x30,0x46,0x06,0x02,0x2a,
7182 0x03,0x30,0x40,0x30,0x3e,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x02,
7183 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7184 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7185 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7186 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7189 static void test_encodeCertPolicies(DWORD dwEncoding)
7191 BOOL ret;
7192 CERT_POLICIES_INFO info;
7193 CERT_POLICY_INFO policy[2];
7194 CERT_POLICY_QUALIFIER_INFO qualifier;
7195 LPBYTE buf;
7196 DWORD size;
7198 memset(&info, 0, sizeof(info));
7199 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7200 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7201 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7202 if (ret)
7204 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size);
7205 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
7206 LocalFree(buf);
7208 memset(policy, 0, sizeof(policy));
7209 info.cPolicyInfo = 1;
7210 info.rgPolicyInfo = policy;
7211 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7212 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7213 ok(!ret && (GetLastError() == E_INVALIDARG ||
7214 GetLastError() == OSS_LIMITED /* Win9x/NT4 */),
7215 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
7216 policy[0].pszPolicyIdentifier = oid_any_policy;
7217 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7218 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7219 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7220 if (ret)
7222 ok(sizeof(policiesWithAnyPolicy) == size, "unexpected size %d\n", size);
7223 ok(!memcmp(buf, policiesWithAnyPolicy, size), "unexpected value\n");
7224 LocalFree(buf);
7226 policy[1].pszPolicyIdentifier = oid1;
7227 memset(&qualifier, 0, sizeof(qualifier));
7228 qualifier.pszPolicyQualifierId = oid_user_notice;
7229 qualifier.Qualifier.cbData = sizeof(noticeWithReference);
7230 qualifier.Qualifier.pbData = noticeWithReference;
7231 policy[1].cPolicyQualifier = 1;
7232 policy[1].rgPolicyQualifier = &qualifier;
7233 info.cPolicyInfo = 2;
7234 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7235 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7236 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7237 if (ret)
7239 ok(sizeof(twoPolicies) == size, "unexpected size %d\n", size);
7240 ok(!memcmp(buf, twoPolicies, size), "unexpected value\n");
7241 LocalFree(buf);
7245 static void test_decodeCertPolicies(DWORD dwEncoding)
7247 BOOL ret;
7248 CERT_POLICIES_INFO *info;
7249 DWORD size;
7251 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7252 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7253 &info, &size);
7254 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7255 if (ret)
7257 ok(info->cPolicyInfo == 0, "unexpected policy info %d\n",
7258 info->cPolicyInfo);
7259 LocalFree(info);
7261 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7262 policiesWithAnyPolicy, sizeof(policiesWithAnyPolicy),
7263 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7264 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7265 if (ret)
7267 ok(info->cPolicyInfo == 1, "unexpected policy info %d\n",
7268 info->cPolicyInfo);
7269 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy),
7270 "unexpected policy id %s\n",
7271 info->rgPolicyInfo[0].pszPolicyIdentifier);
7272 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0,
7273 "unexpected policy qualifier count %d\n",
7274 info->rgPolicyInfo[0].cPolicyQualifier);
7275 LocalFree(info);
7277 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7278 twoPolicies, sizeof(twoPolicies),
7279 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7280 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7281 if (ret)
7283 ok(info->cPolicyInfo == 2, "unexpected policy info %d\n",
7284 info->cPolicyInfo);
7285 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy),
7286 "unexpected policy id %s\n",
7287 info->rgPolicyInfo[0].pszPolicyIdentifier);
7288 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0,
7289 "unexpected policy qualifier count %d\n",
7290 info->rgPolicyInfo[0].cPolicyQualifier);
7291 ok(!strcmp(info->rgPolicyInfo[1].pszPolicyIdentifier, oid1),
7292 "unexpected policy id %s\n",
7293 info->rgPolicyInfo[1].pszPolicyIdentifier);
7294 ok(info->rgPolicyInfo[1].cPolicyQualifier == 1,
7295 "unexpected policy qualifier count %d\n",
7296 info->rgPolicyInfo[1].cPolicyQualifier);
7297 ok(!strcmp(
7298 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId,
7299 oid_user_notice), "unexpected policy qualifier id %s\n",
7300 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId);
7301 ok(info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData ==
7302 sizeof(noticeWithReference), "unexpected qualifier size %d\n",
7303 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData);
7304 ok(!memcmp(
7305 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.pbData,
7306 noticeWithReference, sizeof(noticeWithReference)),
7307 "unexpected qualifier value\n");
7308 LocalFree(info);
7312 /* Free *pInfo with HeapFree */
7313 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
7315 BOOL ret;
7316 DWORD size = 0;
7317 HCRYPTKEY key;
7319 /* This crashes
7320 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
7322 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size);
7323 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7324 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7325 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL,
7326 &size);
7327 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7328 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7329 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL,
7330 NULL, &size);
7331 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7332 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7333 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7334 0, NULL, NULL, &size);
7335 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7336 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7337 /* Test with no key */
7338 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7339 0, NULL, NULL, &size);
7340 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n",
7341 GetLastError());
7342 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
7343 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
7344 if (ret)
7346 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
7347 NULL, 0, NULL, NULL, &size);
7348 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
7349 *pInfo = HeapAlloc(GetProcessHeap(), 0, size);
7350 if (*pInfo)
7352 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
7353 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size);
7354 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n",
7355 GetLastError());
7356 if (ret)
7358 /* By default (we passed NULL as the OID) the OID is
7359 * szOID_RSA_RSA.
7361 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA),
7362 "Expected %s, got %s\n", szOID_RSA_RSA,
7363 (*pInfo)->Algorithm.pszObjId);
7367 CryptDestroyKey(key);
7370 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
7371 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
7372 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
7373 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7374 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7375 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7376 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
7377 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
7378 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7379 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7380 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7381 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
7382 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
7383 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
7384 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
7385 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
7386 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
7387 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
7388 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
7389 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
7390 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
7391 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
7392 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
7393 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
7394 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
7396 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info)
7398 BOOL ret;
7399 HCRYPTKEY key;
7400 PCCERT_CONTEXT context;
7401 DWORD dwSize;
7402 ALG_ID ai;
7404 /* These crash
7405 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
7406 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
7407 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
7408 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7409 NULL);
7411 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key);
7412 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7413 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7414 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key);
7415 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7416 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7417 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL,
7418 &key);
7419 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7420 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7422 /* Export key with standard algorithm (CALG_RSA_KEYX) */
7423 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7424 &key);
7425 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7427 dwSize = sizeof(ai);
7428 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7429 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7430 if(ret)
7432 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7433 ok(ai == CALG_RSA_KEYX, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai);
7436 CryptDestroyKey(key);
7438 /* Repeat with forced algorithm */
7439 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, CALG_RSA_SIGN, 0, NULL,
7440 &key);
7441 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7443 dwSize = sizeof(ai);
7444 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7445 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7446 if(ret)
7448 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7449 ok(ai == CALG_RSA_SIGN, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai);
7452 CryptDestroyKey(key);
7454 /* Test importing a public key from a certificate context */
7455 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert,
7456 sizeof(expiredCert));
7457 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
7458 GetLastError());
7459 if (context)
7461 ok(!strcmp(szOID_RSA_RSA,
7462 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId),
7463 "Expected %s, got %s\n", szOID_RSA_RSA,
7464 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
7465 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING,
7466 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
7467 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7468 CryptDestroyKey(key);
7469 CertFreeCertificateContext(context);
7473 static const char cspName[] = "WineCryptTemp";
7475 static void testPortPublicKeyInfo(void)
7477 HCRYPTPROV csp;
7478 BOOL ret;
7479 PCERT_PUBLIC_KEY_INFO info = NULL;
7481 /* Just in case a previous run failed, delete this thing */
7482 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7483 CRYPT_DELETEKEYSET);
7484 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7485 CRYPT_NEWKEYSET);
7487 testExportPublicKey(csp, &info);
7488 testImportPublicKey(csp, info);
7490 HeapFree(GetProcessHeap(), 0, info);
7491 CryptReleaseContext(csp, 0);
7492 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7493 CRYPT_DELETEKEYSET);
7496 START_TEST(encode)
7498 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
7499 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING };
7500 HMODULE hCrypt32;
7501 DWORD i;
7503 hCrypt32 = GetModuleHandleA("crypt32.dll");
7504 pCryptDecodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptDecodeObjectEx");
7505 pCryptEncodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptEncodeObjectEx");
7506 if (!pCryptDecodeObjectEx || !pCryptEncodeObjectEx)
7508 skip("CryptDecodeObjectEx() is not available\n");
7509 return;
7512 for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++)
7514 test_encodeInt(encodings[i]);
7515 test_decodeInt(encodings[i]);
7516 test_encodeEnumerated(encodings[i]);
7517 test_decodeEnumerated(encodings[i]);
7518 test_encodeFiletime(encodings[i]);
7519 test_decodeFiletime(encodings[i]);
7520 test_encodeName(encodings[i]);
7521 test_decodeName(encodings[i]);
7522 test_encodeUnicodeName(encodings[i]);
7523 test_decodeUnicodeName(encodings[i]);
7524 test_encodeNameValue(encodings[i]);
7525 test_decodeNameValue(encodings[i]);
7526 test_encodeUnicodeNameValue(encodings[i]);
7527 test_decodeUnicodeNameValue(encodings[i]);
7528 test_encodeAltName(encodings[i]);
7529 test_decodeAltName(encodings[i]);
7530 test_encodeOctets(encodings[i]);
7531 test_decodeOctets(encodings[i]);
7532 test_encodeBits(encodings[i]);
7533 test_decodeBits(encodings[i]);
7534 test_encodeBasicConstraints(encodings[i]);
7535 test_decodeBasicConstraints(encodings[i]);
7536 test_encodeRsaPublicKey(encodings[i]);
7537 test_decodeRsaPublicKey(encodings[i]);
7538 test_encodeSequenceOfAny(encodings[i]);
7539 test_decodeSequenceOfAny(encodings[i]);
7540 test_encodeExtensions(encodings[i]);
7541 test_decodeExtensions(encodings[i]);
7542 test_encodePublicKeyInfo(encodings[i]);
7543 test_decodePublicKeyInfo(encodings[i]);
7544 test_encodeCertToBeSigned(encodings[i]);
7545 test_decodeCertToBeSigned(encodings[i]);
7546 test_encodeCert(encodings[i]);
7547 test_decodeCert(encodings[i]);
7548 test_encodeCRLDistPoints(encodings[i]);
7549 test_decodeCRLDistPoints(encodings[i]);
7550 test_encodeCRLIssuingDistPoint(encodings[i]);
7551 test_decodeCRLIssuingDistPoint(encodings[i]);
7552 test_encodeCRLToBeSigned(encodings[i]);
7553 test_decodeCRLToBeSigned(encodings[i]);
7554 test_encodeEnhancedKeyUsage(encodings[i]);
7555 test_decodeEnhancedKeyUsage(encodings[i]);
7556 test_encodeAuthorityKeyId(encodings[i]);
7557 test_decodeAuthorityKeyId(encodings[i]);
7558 test_encodeAuthorityKeyId2(encodings[i]);
7559 test_decodeAuthorityKeyId2(encodings[i]);
7560 test_encodeAuthorityInfoAccess(encodings[i]);
7561 test_decodeAuthorityInfoAccess(encodings[i]);
7562 test_encodeCTL(encodings[i]);
7563 test_decodeCTL(encodings[i]);
7564 test_encodePKCSContentInfo(encodings[i]);
7565 test_decodePKCSContentInfo(encodings[i]);
7566 test_encodePKCSAttribute(encodings[i]);
7567 test_decodePKCSAttribute(encodings[i]);
7568 test_encodePKCSAttributes(encodings[i]);
7569 test_decodePKCSAttributes(encodings[i]);
7570 test_encodePKCSSMimeCapabilities(encodings[i]);
7571 test_decodePKCSSMimeCapabilities(encodings[i]);
7572 test_encodePKCSSignerInfo(encodings[i]);
7573 test_decodePKCSSignerInfo(encodings[i]);
7574 test_encodeCMSSignerInfo(encodings[i]);
7575 test_decodeCMSSignerInfo(encodings[i]);
7576 test_encodeNameConstraints(encodings[i]);
7577 test_decodeNameConstraints(encodings[i]);
7578 test_encodePolicyQualifierUserNotice(encodings[i]);
7579 test_decodePolicyQualifierUserNotice(encodings[i]);
7580 test_encodeCertPolicies(encodings[i]);
7581 test_decodeCertPolicies(encodings[i]);
7583 testPortPublicKeyInfo();