push edc49a132052b6e245fe2c0c0797f387fa16f3c6
[wine/hacks.git] / dlls / crypt32 / tests / encode.c
blobbb60798388ebf506d8ffe865ca6bd3c0ca4169a7
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 } };
2539 static CHAR oid_short[] = "1.1";
2540 static CERT_EXTENSION extWithShortOid =
2541 { oid_short, FALSE, { 0, NULL } };
2543 static const BYTE ext0[] = { 0x30,0x00 };
2544 static const BYTE ext1[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2545 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2546 static const BYTE ext2[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2547 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2548 static const BYTE ext3[] = { 0x30,0x07,0x30,0x05,0x06,0x01,0x29,0x04,0x00 };
2550 static const struct encodedExtensions exts[] = {
2551 { { 0, NULL }, ext0 },
2552 { { 1, &criticalExt }, ext1 },
2553 { { 1, &nonCriticalExt }, ext2 },
2554 { { 1, &extWithShortOid }, ext3 }
2557 static void test_encodeExtensions(DWORD dwEncoding)
2559 DWORD i;
2561 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2563 BOOL ret;
2564 BYTE *buf = NULL;
2565 DWORD bufSize = 0;
2567 ret = pCryptEncodeObjectEx(dwEncoding, X509_EXTENSIONS, &exts[i].exts,
2568 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2569 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2570 if (buf)
2572 ok(bufSize == exts[i].encoded[1] + 2,
2573 "Expected %d bytes, got %d\n", exts[i].encoded[1] + 2, bufSize);
2574 ok(!memcmp(buf, exts[i].encoded, exts[i].encoded[1] + 2),
2575 "Unexpected value\n");
2576 LocalFree(buf);
2581 static void test_decodeExtensions(DWORD dwEncoding)
2583 DWORD i;
2585 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2587 BOOL ret;
2588 BYTE *buf = NULL;
2589 DWORD bufSize = 0;
2591 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS,
2592 exts[i].encoded, exts[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2593 NULL, (BYTE *)&buf, &bufSize);
2594 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2595 if (buf)
2597 CERT_EXTENSIONS *ext = (CERT_EXTENSIONS *)buf;
2598 DWORD j;
2600 ok(ext->cExtension == exts[i].exts.cExtension,
2601 "Expected %d extensions, see %d\n", exts[i].exts.cExtension,
2602 ext->cExtension);
2603 for (j = 0; j < min(ext->cExtension, exts[i].exts.cExtension); j++)
2605 ok(!strcmp(ext->rgExtension[j].pszObjId,
2606 exts[i].exts.rgExtension[j].pszObjId),
2607 "Expected OID %s, got %s\n",
2608 exts[i].exts.rgExtension[j].pszObjId,
2609 ext->rgExtension[j].pszObjId);
2610 ok(!memcmp(ext->rgExtension[j].Value.pbData,
2611 exts[i].exts.rgExtension[j].Value.pbData,
2612 exts[i].exts.rgExtension[j].Value.cbData),
2613 "Unexpected value\n");
2615 LocalFree(buf);
2620 /* MS encodes public key info with a NULL if the algorithm identifier's
2621 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2622 * it encodes them by omitting the algorithm parameters. This latter approach
2623 * seems more correct, so accept either form.
2625 struct encodedPublicKey
2627 CERT_PUBLIC_KEY_INFO info;
2628 const BYTE *encoded;
2629 const BYTE *encodedNoNull;
2630 CERT_PUBLIC_KEY_INFO decoded;
2633 static const BYTE aKey[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2634 0xe, 0xf };
2635 static const BYTE params[] = { 0x02, 0x01, 0x01 };
2637 static const unsigned char bin64[] = {
2638 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2639 static const unsigned char bin65[] = {
2640 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2641 static const unsigned char bin66[] = {
2642 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2643 static const unsigned char bin67[] = {
2644 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2645 static const unsigned char bin68[] = {
2646 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01,
2647 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2648 static const unsigned char bin69[] = {
2649 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2650 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2651 static const unsigned char bin70[] = {
2652 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2653 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2654 0x0f};
2655 static const unsigned char bin71[] = {
2656 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2657 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2658 0x0f};
2659 static unsigned char bin72[] = { 0x05,0x00};
2661 static CHAR oid_bogus[] = "1.2.3",
2662 oid_rsa[] = szOID_RSA;
2664 static const struct encodedPublicKey pubKeys[] = {
2665 /* with a bogus OID */
2666 { { { oid_bogus, { 0, NULL } }, { 0, NULL, 0 } },
2667 bin64, bin65,
2668 { { oid_bogus, { 2, bin72 } }, { 0, NULL, 0 } } },
2669 /* some normal keys */
2670 { { { oid_rsa, { 0, NULL } }, { 0, NULL, 0} },
2671 bin66, bin67,
2672 { { oid_rsa, { 2, bin72 } }, { 0, NULL, 0 } } },
2673 { { { oid_rsa, { 0, NULL } }, { sizeof(aKey), (BYTE *)aKey, 0} },
2674 bin68, bin69,
2675 { { oid_rsa, { 2, bin72 } }, { sizeof(aKey), (BYTE *)aKey, 0} } },
2676 /* with add'l parameters--note they must be DER-encoded */
2677 { { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2678 (BYTE *)aKey, 0 } },
2679 bin70, bin71,
2680 { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2681 (BYTE *)aKey, 0 } } },
2684 static void test_encodePublicKeyInfo(DWORD dwEncoding)
2686 DWORD i;
2688 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2690 BOOL ret;
2691 BYTE *buf = NULL;
2692 DWORD bufSize = 0;
2694 ret = pCryptEncodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2695 &pubKeys[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2696 &bufSize);
2697 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2698 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2699 if (buf)
2701 ok(bufSize == pubKeys[i].encoded[1] + 2 ||
2702 bufSize == pubKeys[i].encodedNoNull[1] + 2,
2703 "Expected %d or %d bytes, got %d\n", pubKeys[i].encoded[1] + 2,
2704 pubKeys[i].encodedNoNull[1] + 2, bufSize);
2705 if (bufSize == pubKeys[i].encoded[1] + 2)
2706 ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2),
2707 "Unexpected value\n");
2708 else if (bufSize == pubKeys[i].encodedNoNull[1] + 2)
2709 ok(!memcmp(buf, pubKeys[i].encodedNoNull,
2710 pubKeys[i].encodedNoNull[1] + 2), "Unexpected value\n");
2711 LocalFree(buf);
2716 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO *expected,
2717 const CERT_PUBLIC_KEY_INFO *got)
2719 ok(!strcmp(expected->Algorithm.pszObjId, got->Algorithm.pszObjId),
2720 "Expected OID %s, got %s\n", expected->Algorithm.pszObjId,
2721 got->Algorithm.pszObjId);
2722 ok(expected->Algorithm.Parameters.cbData ==
2723 got->Algorithm.Parameters.cbData,
2724 "Expected parameters of %d bytes, got %d\n",
2725 expected->Algorithm.Parameters.cbData, got->Algorithm.Parameters.cbData);
2726 if (expected->Algorithm.Parameters.cbData)
2727 ok(!memcmp(expected->Algorithm.Parameters.pbData,
2728 got->Algorithm.Parameters.pbData, got->Algorithm.Parameters.cbData),
2729 "Unexpected algorithm parameters\n");
2730 ok(expected->PublicKey.cbData == got->PublicKey.cbData,
2731 "Expected public key of %d bytes, got %d\n",
2732 expected->PublicKey.cbData, got->PublicKey.cbData);
2733 if (expected->PublicKey.cbData)
2734 ok(!memcmp(expected->PublicKey.pbData, got->PublicKey.pbData,
2735 got->PublicKey.cbData), "Unexpected public key value\n");
2738 static void test_decodePublicKeyInfo(DWORD dwEncoding)
2740 static const BYTE bogusPubKeyInfo[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
2741 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
2742 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
2743 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2744 DWORD i;
2745 BOOL ret;
2746 BYTE *buf = NULL;
2747 DWORD bufSize = 0;
2749 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2751 /* The NULL form decodes to the decoded member */
2752 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2753 pubKeys[i].encoded, pubKeys[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2754 NULL, (BYTE *)&buf, &bufSize);
2755 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2756 if (buf)
2758 comparePublicKeyInfo(&pubKeys[i].decoded,
2759 (CERT_PUBLIC_KEY_INFO *)buf);
2760 LocalFree(buf);
2762 /* The non-NULL form decodes to the original */
2763 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2764 pubKeys[i].encodedNoNull, pubKeys[i].encodedNoNull[1] + 2,
2765 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2766 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2767 if (buf)
2769 comparePublicKeyInfo(&pubKeys[i].info, (CERT_PUBLIC_KEY_INFO *)buf);
2770 LocalFree(buf);
2773 /* Test with bogus (not valid DER) parameters */
2774 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2775 bogusPubKeyInfo, bogusPubKeyInfo[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2776 NULL, (BYTE *)&buf, &bufSize);
2777 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2778 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2779 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2780 GetLastError());
2783 static const BYTE v1Cert[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
2784 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2785 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
2786 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
2787 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2788 static const BYTE v2Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 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 v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2794 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2795 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2796 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2797 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2798 static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
2799 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2800 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2801 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2802 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2803 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2804 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2805 static const BYTE v1CertWithSerial[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
2806 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2807 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2808 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2809 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2810 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2811 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2812 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2813 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
2814 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
2815 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
2816 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
2817 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
2818 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
2819 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
2820 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
2821 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2822 static const BYTE v1CertWithPubKey[] = {
2823 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2824 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2825 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2826 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2827 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2828 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2829 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2830 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2831 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
2832 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
2833 0x01,0x01 };
2834 static const BYTE v1CertWithPubKeyNoNull[] = {
2835 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2836 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2837 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2838 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2839 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2840 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2841 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2842 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2843 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
2844 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2845 static const BYTE v1CertWithSubjectKeyId[] = {
2846 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2847 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2848 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2849 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2850 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2851 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2852 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
2853 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2854 0x4c,0x61,0x6e,0x67,0x00 };
2856 static const BYTE serialNum[] = { 0x01 };
2858 static void test_encodeCertToBeSigned(DWORD dwEncoding)
2860 BOOL ret;
2861 BYTE *buf = NULL;
2862 DWORD size = 0;
2863 CERT_INFO info = { 0 };
2864 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2865 static char oid_subject_key_identifier[] = szOID_SUBJECT_KEY_IDENTIFIER;
2866 CERT_EXTENSION ext;
2868 if (0)
2870 /* Test with NULL pvStructInfo (crashes on win9x) */
2871 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL,
2872 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2873 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2874 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2876 /* Test with a V1 cert */
2877 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2878 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2879 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2880 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2881 if (buf)
2883 ok(size == v1Cert[1] + 2, "Expected size %d, got %d\n",
2884 v1Cert[1] + 2, size);
2885 ok(!memcmp(buf, v1Cert, size), "Got unexpected value\n");
2886 LocalFree(buf);
2888 /* Test v2 cert */
2889 info.dwVersion = CERT_V2;
2890 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2891 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2892 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2893 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2894 if (buf)
2896 ok(size == sizeof(v2Cert), "Wrong size %d\n", size);
2897 ok(!memcmp(buf, v2Cert, size), "Got unexpected value\n");
2898 LocalFree(buf);
2900 /* Test v3 cert */
2901 info.dwVersion = CERT_V3;
2902 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2903 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2904 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2905 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2906 if (buf)
2908 ok(size == sizeof(v3Cert), "Wrong size %d\n", size);
2909 ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n");
2910 LocalFree(buf);
2912 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
2913 * API doesn't prevent it)
2915 info.dwVersion = CERT_V1;
2916 info.cExtension = 1;
2917 info.rgExtension = &criticalExt;
2918 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2919 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2920 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2921 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2922 if (buf)
2924 ok(size == sizeof(v1CertWithConstraints), "Wrong size %d\n", size);
2925 ok(!memcmp(buf, v1CertWithConstraints, size), "Got unexpected value\n");
2926 LocalFree(buf);
2928 /* test v1 cert with a serial number */
2929 info.SerialNumber.cbData = sizeof(serialNum);
2930 info.SerialNumber.pbData = (BYTE *)serialNum;
2931 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2932 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2933 if (buf)
2935 ok(size == sizeof(v1CertWithSerial), "Wrong size %d\n", size);
2936 ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n");
2937 LocalFree(buf);
2939 /* Test v1 cert with an issuer name, a subject name, and a serial number */
2940 info.Issuer.cbData = sizeof(encodedCommonName);
2941 info.Issuer.pbData = (BYTE *)encodedCommonName;
2942 info.Subject.cbData = sizeof(encodedCommonName);
2943 info.Subject.pbData = (BYTE *)encodedCommonName;
2944 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2945 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2946 if (buf)
2948 ok(size == sizeof(bigCert), "Wrong size %d\n", size);
2949 ok(!memcmp(buf, bigCert, size), "Got unexpected value\n");
2950 LocalFree(buf);
2952 /* Add a public key */
2953 info.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2954 info.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2955 info.SubjectPublicKeyInfo.PublicKey.pbData = (LPBYTE)aKey;
2956 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2957 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2958 if (buf)
2960 ok(size == sizeof(v1CertWithPubKey) ||
2961 size == sizeof(v1CertWithPubKeyNoNull), "Wrong size %d\n", size);
2962 if (size == sizeof(v1CertWithPubKey))
2963 ok(!memcmp(buf, v1CertWithPubKey, size), "Got unexpected value\n");
2964 else if (size == sizeof(v1CertWithPubKeyNoNull))
2965 ok(!memcmp(buf, v1CertWithPubKeyNoNull, size),
2966 "Got unexpected value\n");
2967 LocalFree(buf);
2969 /* Remove the public key, and add a subject key identifier extension */
2970 info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2971 info.SubjectPublicKeyInfo.PublicKey.cbData = 0;
2972 info.SubjectPublicKeyInfo.PublicKey.pbData = NULL;
2973 ext.pszObjId = oid_subject_key_identifier;
2974 ext.fCritical = FALSE;
2975 ext.Value.cbData = sizeof(octetCommonNameValue);
2976 ext.Value.pbData = (BYTE *)octetCommonNameValue;
2977 info.cExtension = 1;
2978 info.rgExtension = &ext;
2979 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2980 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2981 if (buf)
2983 ok(size == sizeof(v1CertWithSubjectKeyId), "Wrong size %d\n", size);
2984 ok(!memcmp(buf, v1CertWithSubjectKeyId, size), "Unexpected value\n");
2985 LocalFree(buf);
2989 static void test_decodeCertToBeSigned(DWORD dwEncoding)
2991 static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert,
2992 v1CertWithConstraints, v1CertWithSerial };
2993 BOOL ret;
2994 BYTE *buf = NULL;
2995 DWORD size = 0, i;
2997 /* Test with NULL pbEncoded */
2998 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 0,
2999 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3000 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
3001 GetLastError() == OSS_BAD_ARG /* Win9x */),
3002 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
3003 if (0)
3005 /* Crashes on win9x */
3006 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 1,
3007 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3008 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3009 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3011 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT, because at a
3012 * minimum a cert must have a non-zero serial number, an issuer, and a
3013 * subject.
3015 for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++)
3017 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3018 corruptCerts[i], corruptCerts[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3019 (BYTE *)&buf, &size);
3020 ok(!ret, "Expected failure\n");
3022 /* Now check with serial number, subject and issuer specified */
3023 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert,
3024 sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3025 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3026 if (buf)
3028 CERT_INFO *info = (CERT_INFO *)buf;
3030 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3031 ok(info->SerialNumber.cbData == 1,
3032 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3033 ok(*info->SerialNumber.pbData == *serialNum,
3034 "Expected serial number %d, got %d\n", *serialNum,
3035 *info->SerialNumber.pbData);
3036 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3037 "Wrong size %d\n", info->Issuer.cbData);
3038 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3039 "Unexpected issuer\n");
3040 ok(info->Subject.cbData == sizeof(encodedCommonName),
3041 "Wrong size %d\n", info->Subject.cbData);
3042 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3043 info->Subject.cbData), "Unexpected subject\n");
3044 LocalFree(buf);
3046 /* Check again with pub key specified */
3047 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3048 v1CertWithPubKey, sizeof(v1CertWithPubKey), CRYPT_DECODE_ALLOC_FLAG, NULL,
3049 (BYTE *)&buf, &size);
3050 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3051 if (buf)
3053 CERT_INFO *info = (CERT_INFO *)buf;
3055 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3056 ok(info->SerialNumber.cbData == 1,
3057 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3058 ok(*info->SerialNumber.pbData == *serialNum,
3059 "Expected serial number %d, got %d\n", *serialNum,
3060 *info->SerialNumber.pbData);
3061 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3062 "Wrong size %d\n", info->Issuer.cbData);
3063 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3064 "Unexpected issuer\n");
3065 ok(info->Subject.cbData == sizeof(encodedCommonName),
3066 "Wrong size %d\n", info->Subject.cbData);
3067 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3068 info->Subject.cbData), "Unexpected subject\n");
3069 ok(!strcmp(info->SubjectPublicKeyInfo.Algorithm.pszObjId,
3070 szOID_RSA_RSA), "Expected szOID_RSA_RSA, got %s\n",
3071 info->SubjectPublicKeyInfo.Algorithm.pszObjId);
3072 ok(info->SubjectPublicKeyInfo.PublicKey.cbData == sizeof(aKey),
3073 "Wrong size %d\n", info->SubjectPublicKeyInfo.PublicKey.cbData);
3074 ok(!memcmp(info->SubjectPublicKeyInfo.PublicKey.pbData, aKey,
3075 sizeof(aKey)), "Unexpected public key\n");
3076 LocalFree(buf);
3080 static const BYTE hash[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
3081 0xe, 0xf };
3083 static const BYTE signedBigCert[] = {
3084 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
3085 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
3086 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
3087 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3088 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
3089 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
3090 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
3091 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
3092 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
3093 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3094 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
3095 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
3097 static void test_encodeCert(DWORD dwEncoding)
3099 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
3100 * also that bigCert is a NULL-terminated string, so don't count its
3101 * last byte (otherwise the signed cert won't decode.)
3103 CERT_SIGNED_CONTENT_INFO info = { { sizeof(bigCert), (BYTE *)bigCert },
3104 { NULL, { 0, NULL } }, { sizeof(hash), (BYTE *)hash, 0 } };
3105 BOOL ret;
3106 BYTE *buf = NULL;
3107 DWORD bufSize = 0;
3109 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT, &info,
3110 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
3111 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3112 if (buf)
3114 ok(bufSize == sizeof(signedBigCert), "Wrong size %d\n", bufSize);
3115 ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n");
3116 LocalFree(buf);
3120 static void test_decodeCert(DWORD dwEncoding)
3122 BOOL ret;
3123 BYTE *buf = NULL;
3124 DWORD size = 0;
3126 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert,
3127 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3128 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3129 if (buf)
3131 CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf;
3133 ok(info->ToBeSigned.cbData == sizeof(bigCert),
3134 "Wrong cert size %d\n", info->ToBeSigned.cbData);
3135 ok(!memcmp(info->ToBeSigned.pbData, bigCert, info->ToBeSigned.cbData),
3136 "Unexpected cert\n");
3137 ok(info->Signature.cbData == sizeof(hash),
3138 "Wrong signature size %d\n", info->Signature.cbData);
3139 ok(!memcmp(info->Signature.pbData, hash, info->Signature.cbData),
3140 "Unexpected signature\n");
3141 LocalFree(buf);
3143 /* A signed cert decodes as a CERT_INFO too */
3144 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCert,
3145 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3146 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3147 if (buf)
3149 CERT_INFO *info = (CERT_INFO *)buf;
3151 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3152 ok(info->SerialNumber.cbData == 1,
3153 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3154 ok(*info->SerialNumber.pbData == *serialNum,
3155 "Expected serial number %d, got %d\n", *serialNum,
3156 *info->SerialNumber.pbData);
3157 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3158 "Wrong size %d\n", info->Issuer.cbData);
3159 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3160 "Unexpected issuer\n");
3161 ok(info->Subject.cbData == sizeof(encodedCommonName),
3162 "Wrong size %d\n", info->Subject.cbData);
3163 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3164 info->Subject.cbData), "Unexpected subject\n");
3165 LocalFree(buf);
3169 static const BYTE emptyDistPoint[] = { 0x30, 0x02, 0x30, 0x00 };
3170 static const BYTE distPointWithUrl[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3171 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3172 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3173 static const BYTE distPointWithReason[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3174 0x00, 0x03 };
3175 static const BYTE distPointWithIssuer[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3176 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3177 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3178 static const BYTE distPointWithUrlAndIssuer[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3179 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3180 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3181 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3182 0x2e, 0x6f, 0x72, 0x67 };
3183 static const BYTE crlReason = CRL_REASON_KEY_COMPROMISE |
3184 CRL_REASON_AFFILIATION_CHANGED;
3186 static void test_encodeCRLDistPoints(DWORD dwEncoding)
3188 CRL_DIST_POINTS_INFO info = { 0 };
3189 CRL_DIST_POINT point = { { 0 } };
3190 CERT_ALT_NAME_ENTRY entry = { 0 };
3191 BOOL ret;
3192 BYTE *buf = NULL;
3193 DWORD size = 0;
3195 /* Test with an empty info */
3196 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3197 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3198 ok(!ret && GetLastError() == E_INVALIDARG,
3199 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3200 /* Test with one empty dist point */
3201 info.cDistPoint = 1;
3202 info.rgDistPoint = &point;
3203 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3204 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3205 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3206 if (buf)
3208 ok(size == sizeof(emptyDistPoint), "Wrong size %d\n", size);
3209 ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n");
3210 LocalFree(buf);
3212 /* A dist point with an invalid name */
3213 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3214 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3215 U(entry).pwszURL = (LPWSTR)nihongoURL;
3216 U(point.DistPointName).FullName.cAltEntry = 1;
3217 U(point.DistPointName).FullName.rgAltEntry = &entry;
3218 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3219 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3220 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
3221 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
3222 /* The first invalid character is at index 7 */
3223 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
3224 "Expected invalid char at index 7, got %d\n",
3225 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
3226 /* A dist point with (just) a valid name */
3227 U(entry).pwszURL = (LPWSTR)url;
3228 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3229 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3230 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3231 if (buf)
3233 ok(size == sizeof(distPointWithUrl), "Wrong size %d\n", size);
3234 ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n");
3235 LocalFree(buf);
3237 /* A dist point with (just) reason flags */
3238 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3239 point.ReasonFlags.cbData = sizeof(crlReason);
3240 point.ReasonFlags.pbData = (LPBYTE)&crlReason;
3241 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3242 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3243 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3244 if (buf)
3246 ok(size == sizeof(distPointWithReason), "Wrong size %d\n", size);
3247 ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n");
3248 LocalFree(buf);
3250 /* A dist point with just an issuer */
3251 point.ReasonFlags.cbData = 0;
3252 point.CRLIssuer.cAltEntry = 1;
3253 point.CRLIssuer.rgAltEntry = &entry;
3254 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3255 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3256 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3257 if (buf)
3259 ok(size == sizeof(distPointWithIssuer), "Wrong size %d\n", size);
3260 ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n");
3261 LocalFree(buf);
3263 /* A dist point with both a name and an issuer */
3264 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3265 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3266 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3267 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3268 if (buf)
3270 ok(size == sizeof(distPointWithUrlAndIssuer),
3271 "Wrong size %d\n", size);
3272 ok(!memcmp(buf, distPointWithUrlAndIssuer, size), "Unexpected value\n");
3273 LocalFree(buf);
3277 static void test_decodeCRLDistPoints(DWORD dwEncoding)
3279 BOOL ret;
3280 BYTE *buf = NULL;
3281 DWORD size = 0;
3282 PCRL_DIST_POINTS_INFO info;
3283 PCRL_DIST_POINT point;
3284 PCERT_ALT_NAME_ENTRY entry;
3286 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3287 emptyDistPoint, emptyDistPoint[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3288 (BYTE *)&buf, &size);
3289 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3290 if (ret)
3292 info = (PCRL_DIST_POINTS_INFO)buf;
3293 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3294 "Wrong size %d\n", size);
3295 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3296 info->cDistPoint);
3297 point = info->rgDistPoint;
3298 ok(point->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_NO_NAME,
3299 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3300 point->DistPointName.dwDistPointNameChoice);
3301 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3302 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3303 LocalFree(buf);
3305 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3306 distPointWithUrl, distPointWithUrl[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3307 (BYTE *)&buf, &size);
3308 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3309 if (ret)
3311 info = (PCRL_DIST_POINTS_INFO)buf;
3312 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3313 "Wrong size %d\n", size);
3314 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3315 info->cDistPoint);
3316 point = info->rgDistPoint;
3317 ok(point->DistPointName.dwDistPointNameChoice ==
3318 CRL_DIST_POINT_FULL_NAME,
3319 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3320 point->DistPointName.dwDistPointNameChoice);
3321 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3322 "Expected 1 name entry, got %d\n",
3323 U(point->DistPointName).FullName.cAltEntry);
3324 entry = U(point->DistPointName).FullName.rgAltEntry;
3325 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3326 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3327 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3328 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3329 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3330 LocalFree(buf);
3332 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3333 distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
3334 NULL, (BYTE *)&buf, &size);
3335 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3336 if (ret)
3338 info = (PCRL_DIST_POINTS_INFO)buf;
3339 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3340 "Wrong size %d\n", size);
3341 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3342 info->cDistPoint);
3343 point = info->rgDistPoint;
3344 ok(point->DistPointName.dwDistPointNameChoice ==
3345 CRL_DIST_POINT_NO_NAME,
3346 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3347 point->DistPointName.dwDistPointNameChoice);
3348 ok(point->ReasonFlags.cbData == sizeof(crlReason),
3349 "Expected reason length\n");
3350 ok(!memcmp(point->ReasonFlags.pbData, &crlReason, sizeof(crlReason)),
3351 "Unexpected reason\n");
3352 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3353 LocalFree(buf);
3355 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3356 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2,
3357 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3358 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3359 if (ret)
3361 info = (PCRL_DIST_POINTS_INFO)buf;
3362 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3363 "Wrong size %d\n", size);
3364 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3365 info->cDistPoint);
3366 point = info->rgDistPoint;
3367 ok(point->DistPointName.dwDistPointNameChoice ==
3368 CRL_DIST_POINT_FULL_NAME,
3369 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3370 point->DistPointName.dwDistPointNameChoice);
3371 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3372 "Expected 1 name entry, got %d\n",
3373 U(point->DistPointName).FullName.cAltEntry);
3374 entry = U(point->DistPointName).FullName.rgAltEntry;
3375 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3376 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3377 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3378 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3379 ok(point->CRLIssuer.cAltEntry == 1,
3380 "Expected 1 issuer entry, got %d\n", point->CRLIssuer.cAltEntry);
3381 entry = point->CRLIssuer.rgAltEntry;
3382 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3383 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3384 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3385 LocalFree(buf);
3389 static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3390 static const BYTE emptyNameIDP[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3391 static const BYTE urlIDP[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3392 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3393 0x67 };
3395 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding)
3397 BOOL ret;
3398 BYTE *buf = NULL;
3399 DWORD size = 0;
3400 CRL_ISSUING_DIST_POINT point = { { 0 } };
3401 CERT_ALT_NAME_ENTRY entry;
3403 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, NULL,
3404 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3405 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3407 skip("no X509_ISSUING_DIST_POINT encode support\n");
3408 return;
3410 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3411 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3412 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3413 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3414 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3415 if (buf)
3417 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
3418 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
3419 LocalFree(buf);
3421 /* nonsensical flags */
3422 point.fOnlyContainsUserCerts = TRUE;
3423 point.fOnlyContainsCACerts = TRUE;
3424 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3425 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3426 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3427 if (buf)
3429 ok(size == sizeof(badFlagsIDP), "Unexpected size %d\n", size);
3430 ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n");
3431 LocalFree(buf);
3433 /* unimplemented name type */
3434 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3435 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_ISSUER_RDN_NAME;
3436 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3437 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3438 ok(!ret && GetLastError() == E_INVALIDARG,
3439 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3440 /* empty name */
3441 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3442 U(point.DistPointName).FullName.cAltEntry = 0;
3443 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3444 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3445 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3446 if (buf)
3448 ok(size == sizeof(emptyNameIDP), "Unexpected size %d\n", size);
3449 ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n");
3450 LocalFree(buf);
3452 /* name with URL entry */
3453 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3454 U(entry).pwszURL = (LPWSTR)url;
3455 U(point.DistPointName).FullName.cAltEntry = 1;
3456 U(point.DistPointName).FullName.rgAltEntry = &entry;
3457 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3458 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3459 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3460 if (buf)
3462 ok(size == sizeof(urlIDP), "Unexpected size %d\n", size);
3463 ok(!memcmp(buf, urlIDP, size), "Unexpected value\n");
3464 LocalFree(buf);
3468 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY *expected,
3469 const CERT_ALT_NAME_ENTRY *got)
3471 ok(expected->dwAltNameChoice == got->dwAltNameChoice,
3472 "Expected name choice %d, got %d\n", expected->dwAltNameChoice,
3473 got->dwAltNameChoice);
3474 if (expected->dwAltNameChoice == got->dwAltNameChoice)
3476 switch (got->dwAltNameChoice)
3478 case CERT_ALT_NAME_RFC822_NAME:
3479 case CERT_ALT_NAME_DNS_NAME:
3480 case CERT_ALT_NAME_EDI_PARTY_NAME:
3481 case CERT_ALT_NAME_URL:
3482 case CERT_ALT_NAME_REGISTERED_ID:
3483 ok((!U(*expected).pwszURL && !U(*got).pwszURL) ||
3484 (!U(*expected).pwszURL && !lstrlenW(U(*got).pwszURL)) ||
3485 (!U(*got).pwszURL && !lstrlenW(U(*expected).pwszURL)) ||
3486 !lstrcmpW(U(*expected).pwszURL, U(*got).pwszURL),
3487 "Unexpected name\n");
3488 break;
3489 case CERT_ALT_NAME_X400_ADDRESS:
3490 case CERT_ALT_NAME_DIRECTORY_NAME:
3491 case CERT_ALT_NAME_IP_ADDRESS:
3492 ok(U(*got).IPAddress.cbData == U(*expected).IPAddress.cbData,
3493 "Unexpected IP address length %d\n", U(*got).IPAddress.cbData);
3494 ok(!memcmp(U(*got).IPAddress.pbData, U(*got).IPAddress.pbData,
3495 U(*got).IPAddress.cbData), "Unexpected value\n");
3496 break;
3501 static void compareAltNameInfo(const CERT_ALT_NAME_INFO *expected,
3502 const CERT_ALT_NAME_INFO *got)
3504 DWORD i;
3506 ok(expected->cAltEntry == got->cAltEntry, "Expected %d entries, got %d\n",
3507 expected->cAltEntry, got->cAltEntry);
3508 for (i = 0; i < min(expected->cAltEntry, got->cAltEntry); i++)
3509 compareAltNameEntry(&expected->rgAltEntry[i], &got->rgAltEntry[i]);
3512 static void compareDistPointName(const CRL_DIST_POINT_NAME *expected,
3513 const CRL_DIST_POINT_NAME *got)
3515 ok(got->dwDistPointNameChoice == expected->dwDistPointNameChoice,
3516 "Unexpected name choice %d\n", got->dwDistPointNameChoice);
3517 if (got->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME)
3518 compareAltNameInfo(&(U(*expected).FullName), &(U(*got).FullName));
3521 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT *expected,
3522 const CRL_ISSUING_DIST_POINT *got)
3524 compareDistPointName(&expected->DistPointName, &got->DistPointName);
3525 ok(got->fOnlyContainsUserCerts == expected->fOnlyContainsUserCerts,
3526 "Unexpected fOnlyContainsUserCerts\n");
3527 ok(got->fOnlyContainsCACerts == expected->fOnlyContainsCACerts,
3528 "Unexpected fOnlyContainsCACerts\n");
3529 ok(got->OnlySomeReasonFlags.cbData == expected->OnlySomeReasonFlags.cbData,
3530 "Unexpected reason flags\n");
3531 ok(got->fIndirectCRL == expected->fIndirectCRL,
3532 "Unexpected fIndirectCRL\n");
3535 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding)
3537 BOOL ret;
3538 BYTE *buf = NULL;
3539 DWORD size = 0;
3540 CRL_ISSUING_DIST_POINT point = { { 0 } };
3542 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3543 emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3544 (BYTE *)&buf, &size);
3545 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3547 skip("no X509_ISSUING_DIST_POINT decode support\n");
3548 return;
3550 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3551 if (ret)
3553 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3554 LocalFree(buf);
3556 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3557 badFlagsIDP, badFlagsIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3558 (BYTE *)&buf, &size);
3559 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3560 if (ret)
3562 point.fOnlyContainsUserCerts = point.fOnlyContainsCACerts = TRUE;
3563 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3564 LocalFree(buf);
3566 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3567 emptyNameIDP, emptyNameIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3568 (BYTE *)&buf, &size);
3569 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3570 if (ret)
3572 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3573 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3574 U(point.DistPointName).FullName.cAltEntry = 0;
3575 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3576 LocalFree(buf);
3578 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3579 urlIDP, urlIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3580 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3581 if (ret)
3583 CERT_ALT_NAME_ENTRY entry;
3585 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3586 U(entry).pwszURL = (LPWSTR)url;
3587 U(point.DistPointName).FullName.cAltEntry = 1;
3588 U(point.DistPointName).FullName.rgAltEntry = &entry;
3589 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3590 LocalFree(buf);
3594 static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3595 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3596 0x30, 0x5a };
3597 static const BYTE v2CRL[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3598 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3599 0x30, 0x30, 0x30, 0x30, 0x5a };
3600 static const BYTE v1CRLWithIssuer[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3601 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3602 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3603 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3604 0x5a };
3605 static const BYTE v1CRLWithIssuerAndEmptyEntry[] = { 0x30, 0x43, 0x30, 0x02,
3606 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3607 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3608 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3609 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3610 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3611 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3612 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3613 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3614 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3615 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3616 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3617 static const BYTE v1CRLWithEntryExt[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3618 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3619 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3620 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3621 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3622 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3623 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3624 static const BYTE v1CRLWithExt[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3625 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3626 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3627 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
3628 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3629 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
3630 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3631 static const BYTE v2CRLWithExt[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
3632 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
3633 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
3634 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
3635 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
3636 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
3637 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3638 static const BYTE v2CRLWithIssuingDistPoint[] = { 0x30,0x5c,0x02,0x01,0x01,
3639 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
3640 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
3641 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
3642 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3643 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
3644 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3646 static void test_encodeCRLToBeSigned(DWORD dwEncoding)
3648 BOOL ret;
3649 BYTE *buf = NULL;
3650 static CHAR oid_issuing_dist_point[] = szOID_ISSUING_DIST_POINT;
3651 DWORD size = 0;
3652 CRL_INFO info = { 0 };
3653 CRL_ENTRY entry = { { 0 }, { 0 }, 0, 0 };
3654 CERT_EXTENSION ext;
3656 /* Test with a V1 CRL */
3657 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3658 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3659 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3660 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3661 if (buf)
3663 ok(size == sizeof(v1CRL), "Wrong size %d\n", size);
3664 ok(!memcmp(buf, v1CRL, size), "Got unexpected value\n");
3665 LocalFree(buf);
3667 /* Test v2 CRL */
3668 info.dwVersion = CRL_V2;
3669 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3670 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3671 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3672 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3673 if (buf)
3675 ok(size == v2CRL[1] + 2, "Expected size %d, got %d\n",
3676 v2CRL[1] + 2, size);
3677 ok(!memcmp(buf, v2CRL, size), "Got unexpected value\n");
3678 LocalFree(buf);
3680 /* v1 CRL with a name */
3681 info.dwVersion = CRL_V1;
3682 info.Issuer.cbData = sizeof(encodedCommonName);
3683 info.Issuer.pbData = (BYTE *)encodedCommonName;
3684 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3685 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3686 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3687 if (buf)
3689 ok(size == sizeof(v1CRLWithIssuer), "Wrong size %d\n", size);
3690 ok(!memcmp(buf, v1CRLWithIssuer, size), "Got unexpected value\n");
3691 LocalFree(buf);
3693 if (0)
3695 /* v1 CRL with a name and a NULL entry pointer (crashes on win9x) */
3696 info.cCRLEntry = 1;
3697 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3698 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3699 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3700 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3702 /* now set an empty entry */
3703 info.cCRLEntry = 1;
3704 info.rgCRLEntry = &entry;
3705 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3706 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3707 if (buf)
3709 ok(size == sizeof(v1CRLWithIssuerAndEmptyEntry),
3710 "Wrong size %d\n", size);
3711 ok(!memcmp(buf, v1CRLWithIssuerAndEmptyEntry, size),
3712 "Got unexpected value\n");
3713 LocalFree(buf);
3715 /* an entry with a serial number */
3716 entry.SerialNumber.cbData = sizeof(serialNum);
3717 entry.SerialNumber.pbData = (BYTE *)serialNum;
3718 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3719 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3720 if (buf)
3722 ok(size == sizeof(v1CRLWithIssuerAndEntry),
3723 "Wrong size %d\n", size);
3724 ok(!memcmp(buf, v1CRLWithIssuerAndEntry, size),
3725 "Got unexpected value\n");
3726 LocalFree(buf);
3728 /* an entry with an extension */
3729 entry.cExtension = 1;
3730 entry.rgExtension = &criticalExt;
3731 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3732 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3733 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3734 if (buf)
3736 ok(size == sizeof(v1CRLWithEntryExt), "Wrong size %d\n", size);
3737 ok(!memcmp(buf, v1CRLWithEntryExt, size), "Got unexpected value\n");
3738 LocalFree(buf);
3740 /* a CRL with an extension */
3741 entry.cExtension = 0;
3742 info.cExtension = 1;
3743 info.rgExtension = &criticalExt;
3744 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3745 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3746 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3747 if (buf)
3749 ok(size == sizeof(v1CRLWithExt), "Wrong size %d\n", size);
3750 ok(!memcmp(buf, v1CRLWithExt, size), "Got unexpected value\n");
3751 LocalFree(buf);
3753 /* a v2 CRL with an extension, this time non-critical */
3754 info.dwVersion = CRL_V2;
3755 info.rgExtension = &nonCriticalExt;
3756 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3757 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3758 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3759 if (buf)
3761 ok(size == sizeof(v2CRLWithExt), "Wrong size %d\n", size);
3762 ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n");
3763 LocalFree(buf);
3765 /* a v2 CRL with an issuing dist point extension */
3766 ext.pszObjId = oid_issuing_dist_point;
3767 ext.fCritical = TRUE;
3768 ext.Value.cbData = sizeof(urlIDP);
3769 ext.Value.pbData = (LPBYTE)urlIDP;
3770 entry.rgExtension = &ext;
3771 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3772 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3773 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3774 if (buf)
3776 ok(size == sizeof(v2CRLWithIssuingDistPoint), "Wrong size %d\n", size);
3777 ok(!memcmp(buf, v2CRLWithIssuingDistPoint, size), "Unexpected value\n");
3778 LocalFree(buf);
3782 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
3783 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
3784 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
3785 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
3786 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
3787 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
3788 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
3789 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
3790 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
3791 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
3792 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
3793 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
3794 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
3795 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
3796 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
3797 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
3798 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
3799 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
3800 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
3801 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
3802 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
3803 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
3804 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
3805 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
3806 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
3807 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
3808 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
3809 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
3810 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
3811 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
3812 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
3813 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
3814 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
3815 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
3816 0xcd };
3817 static const BYTE verisignCRLWithLotsOfEntries[] = {
3818 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
3819 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
3820 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
3821 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
3822 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
3823 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
3824 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
3825 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
3826 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
3827 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
3828 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
3829 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
3830 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
3831 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
3832 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
3833 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
3834 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3835 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
3836 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
3837 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3838 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
3839 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
3840 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
3841 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
3842 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
3843 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
3844 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
3845 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
3846 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
3847 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
3848 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3849 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
3850 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
3851 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3852 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
3853 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
3854 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
3855 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
3856 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
3857 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
3858 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
3859 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
3860 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
3861 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
3862 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
3863 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
3864 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
3865 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
3866 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
3867 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
3868 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
3869 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
3870 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
3871 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
3872 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3873 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
3874 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
3875 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
3876 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
3877 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
3878 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
3879 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
3880 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
3881 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
3882 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
3883 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
3884 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
3885 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
3886 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
3887 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
3888 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
3889 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
3890 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
3891 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
3892 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
3893 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
3894 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
3895 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
3896 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
3897 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
3898 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
3899 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
3900 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3901 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
3902 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
3903 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
3904 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
3905 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
3906 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
3907 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
3908 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
3909 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
3910 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
3911 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
3912 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
3913 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
3914 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
3915 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
3916 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
3917 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
3918 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
3919 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
3920 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
3921 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
3922 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
3923 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
3924 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
3925 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
3926 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
3927 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
3928 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3929 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
3930 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
3931 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
3932 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
3933 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
3934 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
3935 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
3936 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
3937 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
3938 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
3939 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
3940 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
3941 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
3942 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3943 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
3944 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
3945 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
3946 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
3947 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
3948 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
3949 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
3950 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
3951 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
3952 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
3953 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
3954 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
3955 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
3956 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
3957 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
3958 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
3959 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
3960 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
3961 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
3962 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
3963 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
3964 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
3965 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
3966 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
3967 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
3968 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
3969 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
3970 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
3971 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
3972 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
3973 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
3974 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
3975 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
3976 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
3977 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
3978 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
3979 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
3980 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
3981 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
3982 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
3983 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
3984 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
3985 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
3986 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
3987 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
3988 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
3989 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
3990 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
3991 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
3992 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
3993 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
3994 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
3995 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
3996 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
3997 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
3998 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
3999 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
4000 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
4001 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
4002 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
4003 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
4004 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
4005 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
4006 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
4007 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
4008 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
4009 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
4010 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
4011 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
4012 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
4013 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
4014 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
4015 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
4016 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
4017 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
4018 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
4019 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
4020 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
4021 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
4022 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
4023 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
4024 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
4025 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
4026 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
4027 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
4028 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
4029 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
4030 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
4031 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
4032 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
4033 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
4034 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
4035 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
4036 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
4037 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
4038 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
4039 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
4040 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
4041 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
4042 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
4043 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
4044 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
4045 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
4046 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
4047 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
4048 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
4049 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
4050 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
4051 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
4052 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
4053 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
4054 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
4055 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
4056 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
4057 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
4058 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
4059 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
4060 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
4061 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
4062 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
4063 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
4064 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
4065 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
4066 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
4067 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
4068 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
4069 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
4070 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
4071 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
4072 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
4073 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
4074 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
4075 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
4076 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
4077 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
4078 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
4079 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
4080 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
4081 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
4082 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
4083 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
4084 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
4085 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
4086 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
4087 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
4088 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
4089 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
4090 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
4091 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
4092 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
4093 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
4094 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
4095 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
4096 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
4097 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
4098 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
4099 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
4100 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
4101 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
4102 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
4103 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
4104 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
4105 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
4106 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
4107 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
4108 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
4109 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
4110 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
4111 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
4112 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
4113 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
4114 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
4115 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
4116 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
4117 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
4118 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
4119 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
4120 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
4121 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4122 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4123 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4124 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4125 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4126 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4127 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4128 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4129 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4130 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4131 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4132 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4133 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4134 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4135 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4136 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4137 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4138 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4139 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4140 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4141 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4142 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4143 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4144 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4145 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4146 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4147 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4148 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4149 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4150 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4151 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4152 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4153 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4154 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4155 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4156 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4157 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4158 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4159 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4160 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4161 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4162 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4163 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4164 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4165 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4166 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4167 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4168 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4169 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4170 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4171 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4172 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4173 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4174 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4175 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4176 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4177 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4178 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4179 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4180 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4181 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4182 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4183 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4184 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4185 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4186 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4187 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4188 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4189 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4190 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4191 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4192 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4193 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4194 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4195 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4196 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4197 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4198 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4199 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4200 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4201 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4202 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4203 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4204 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4205 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4206 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4207 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4208 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4209 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4210 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4211 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4212 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4213 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4214 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4215 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4216 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4217 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4218 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4219 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4220 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4221 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4222 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4223 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4224 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4225 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4226 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4227 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4228 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4229 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4230 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4231 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4232 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4233 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4234 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4235 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4236 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4237 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4238 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4239 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4240 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4241 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4242 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4243 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4244 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4245 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4246 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4247 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4248 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4249 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4250 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4251 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4252 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4253 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4254 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4255 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4256 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4257 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4258 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4259 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4260 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4261 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4262 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4263 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4264 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4265 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4266 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4267 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4268 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4269 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4270 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4271 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4272 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4273 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4274 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4275 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4276 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4277 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4278 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4279 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4280 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4281 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4282 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4283 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4284 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4285 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4286 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4287 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4288 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4289 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4290 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4291 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4292 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4293 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4294 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4295 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4296 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4297 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4298 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4299 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4300 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4301 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4302 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4303 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4304 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4305 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4306 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4307 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4308 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4309 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4310 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4311 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4312 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4313 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4314 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4315 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4316 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4317 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4318 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4319 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4320 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4321 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4322 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4323 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4324 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4325 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4327 static void test_decodeCRLToBeSigned(DWORD dwEncoding)
4329 static const BYTE *corruptCRLs[] = { v1CRL, v2CRL };
4330 BOOL ret;
4331 BYTE *buf = NULL;
4332 DWORD size = 0, i;
4334 for (i = 0; i < sizeof(corruptCRLs) / sizeof(corruptCRLs[0]); i++)
4336 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4337 corruptCRLs[i], corruptCRLs[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4338 (BYTE *)&buf, &size);
4339 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4340 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4341 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4342 GetLastError());
4344 /* at a minimum, a CRL must contain an issuer: */
4345 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4346 v1CRLWithIssuer, v1CRLWithIssuer[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4347 (BYTE *)&buf, &size);
4348 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4349 if (buf)
4351 CRL_INFO *info = (CRL_INFO *)buf;
4353 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4354 ok(info->cCRLEntry == 0, "Expected 0 CRL entries, got %d\n",
4355 info->cCRLEntry);
4356 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4357 "Wrong issuer size %d\n", info->Issuer.cbData);
4358 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4359 "Unexpected issuer\n");
4360 LocalFree(buf);
4362 /* check decoding with an empty CRL entry */
4363 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4364 v1CRLWithIssuerAndEmptyEntry, v1CRLWithIssuerAndEmptyEntry[1] + 2,
4365 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4366 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4367 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4368 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4369 GetLastError());
4370 /* with a real CRL entry */
4371 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4372 v1CRLWithIssuerAndEntry, v1CRLWithIssuerAndEntry[1] + 2,
4373 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4374 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4375 if (buf)
4377 CRL_INFO *info = (CRL_INFO *)buf;
4378 CRL_ENTRY *entry;
4380 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4381 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4382 info->cCRLEntry);
4383 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4384 entry = info->rgCRLEntry;
4385 ok(entry->SerialNumber.cbData == 1,
4386 "Expected serial number size 1, got %d\n",
4387 entry->SerialNumber.cbData);
4388 ok(*entry->SerialNumber.pbData == *serialNum,
4389 "Expected serial number %d, got %d\n", *serialNum,
4390 *entry->SerialNumber.pbData);
4391 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4392 "Wrong issuer size %d\n", info->Issuer.cbData);
4393 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4394 "Unexpected issuer\n");
4395 LocalFree(buf);
4397 /* a real CRL from verisign that has extensions */
4398 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4399 verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG,
4400 NULL, (BYTE *)&buf, &size);
4401 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4402 if (buf)
4404 CRL_INFO *info = (CRL_INFO *)buf;
4405 CRL_ENTRY *entry;
4407 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4408 ok(info->cCRLEntry == 3, "Expected 3 CRL entries, got %d\n",
4409 info->cCRLEntry);
4410 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4411 entry = info->rgCRLEntry;
4412 ok(info->cExtension == 2, "Expected 2 extensions, got %d\n",
4413 info->cExtension);
4414 LocalFree(buf);
4416 /* another real CRL from verisign that has lots of entries */
4417 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4418 verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries),
4419 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4420 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4421 if (buf)
4423 CRL_INFO *info = (CRL_INFO *)buf;
4425 ok(size >= sizeof(CRL_INFO), "Got size %d\n", size);
4426 ok(info->cCRLEntry == 209, "Expected 209 CRL entries, got %d\n",
4427 info->cCRLEntry);
4428 ok(info->cExtension == 0, "Expected 0 extensions, got %d\n",
4429 info->cExtension);
4430 LocalFree(buf);
4432 /* and finally, with an extension */
4433 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4434 v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4435 NULL, (BYTE *)&buf, &size);
4436 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4437 if (buf)
4439 CRL_INFO *info = (CRL_INFO *)buf;
4440 CRL_ENTRY *entry;
4442 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4443 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4444 info->cCRLEntry);
4445 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4446 entry = info->rgCRLEntry;
4447 ok(entry->SerialNumber.cbData == 1,
4448 "Expected serial number size 1, got %d\n",
4449 entry->SerialNumber.cbData);
4450 ok(*entry->SerialNumber.pbData == *serialNum,
4451 "Expected serial number %d, got %d\n", *serialNum,
4452 *entry->SerialNumber.pbData);
4453 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4454 "Wrong issuer size %d\n", info->Issuer.cbData);
4455 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4456 "Unexpected issuer\n");
4457 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4458 info->cExtension);
4459 LocalFree(buf);
4461 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4462 v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4463 NULL, (BYTE *)&buf, &size);
4464 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4465 if (buf)
4467 CRL_INFO *info = (CRL_INFO *)buf;
4469 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4470 info->cExtension);
4471 LocalFree(buf);
4473 /* And again, with an issuing dist point */
4474 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4475 v2CRLWithIssuingDistPoint, sizeof(v2CRLWithIssuingDistPoint),
4476 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4477 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4478 if (buf)
4480 CRL_INFO *info = (CRL_INFO *)buf;
4482 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4483 info->cExtension);
4484 LocalFree(buf);
4488 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
4489 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
4490 static const BYTE encodedUsage[] = {
4491 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4492 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4493 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4495 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding)
4497 BOOL ret;
4498 BYTE *buf = NULL;
4499 DWORD size = 0;
4500 CERT_ENHKEY_USAGE usage;
4502 /* Test with empty usage */
4503 usage.cUsageIdentifier = 0;
4504 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4505 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4506 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4507 if (buf)
4509 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
4510 ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n");
4511 LocalFree(buf);
4513 /* Test with a few usages */
4514 usage.cUsageIdentifier = sizeof(keyUsages) / sizeof(keyUsages[0]);
4515 usage.rgpszUsageIdentifier = (LPSTR *)keyUsages;
4516 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4517 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4518 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4519 if (buf)
4521 ok(size == sizeof(encodedUsage), "Wrong size %d\n", size);
4522 ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n");
4523 LocalFree(buf);
4527 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding)
4529 BOOL ret;
4530 LPBYTE buf = NULL;
4531 DWORD size = 0;
4533 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4534 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4535 (BYTE *)&buf, &size);
4536 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4537 if (buf)
4539 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4541 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4542 "Wrong size %d\n", size);
4543 ok(usage->cUsageIdentifier == 0, "Expected 0 CRL entries, got %d\n",
4544 usage->cUsageIdentifier);
4545 LocalFree(buf);
4547 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4548 encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL,
4549 (BYTE *)&buf, &size);
4550 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4551 if (buf)
4553 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4554 DWORD i;
4556 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4557 "Wrong size %d\n", size);
4558 ok(usage->cUsageIdentifier == sizeof(keyUsages) / sizeof(keyUsages[0]),
4559 "Wrong CRL entries count %d\n", usage->cUsageIdentifier);
4560 for (i = 0; i < usage->cUsageIdentifier; i++)
4561 ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]),
4562 "Expected OID %s, got %s\n", keyUsages[i],
4563 usage->rgpszUsageIdentifier[i]);
4564 LocalFree(buf);
4568 static BYTE keyId[] = { 1,2,3,4 };
4569 static const BYTE authorityKeyIdWithId[] = {
4570 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4571 static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4572 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4573 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4574 static const BYTE authorityKeyIdWithSerial[] = { 0x30,0x03,0x82,0x01,0x01 };
4576 static void test_encodeAuthorityKeyId(DWORD dwEncoding)
4578 CERT_AUTHORITY_KEY_ID_INFO info = { { 0 } };
4579 BOOL ret;
4580 BYTE *buf = NULL;
4581 DWORD size = 0;
4583 /* Test with empty id */
4584 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4585 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4586 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4587 if (buf)
4589 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4590 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4591 LocalFree(buf);
4593 /* With just a key id */
4594 info.KeyId.cbData = sizeof(keyId);
4595 info.KeyId.pbData = keyId;
4596 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4597 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4598 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4599 if (buf)
4601 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", size);
4602 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4603 LocalFree(buf);
4605 /* With just an issuer */
4606 info.KeyId.cbData = 0;
4607 info.CertIssuer.cbData = sizeof(encodedCommonName);
4608 info.CertIssuer.pbData = (BYTE *)encodedCommonName;
4609 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4610 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4611 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4612 if (buf)
4614 ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %d\n",
4615 size);
4616 ok(!memcmp(buf, authorityKeyIdWithIssuer, size), "Unexpected value\n");
4617 LocalFree(buf);
4619 /* With just a serial number */
4620 info.CertIssuer.cbData = 0;
4621 info.CertSerialNumber.cbData = sizeof(serialNum);
4622 info.CertSerialNumber.pbData = (BYTE *)serialNum;
4623 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4624 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4625 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4626 if (buf)
4628 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4629 size);
4630 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4631 LocalFree(buf);
4635 static void test_decodeAuthorityKeyId(DWORD dwEncoding)
4637 BOOL ret;
4638 LPBYTE buf = NULL;
4639 DWORD size = 0;
4641 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4642 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4643 (BYTE *)&buf, &size);
4644 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4645 if (buf)
4647 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4649 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4650 size);
4651 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4652 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4653 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4654 LocalFree(buf);
4656 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4657 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4658 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4659 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4660 if (buf)
4662 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4664 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4665 size);
4666 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4667 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4668 "Unexpected key id\n");
4669 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4670 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4671 LocalFree(buf);
4673 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4674 authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer),
4675 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4676 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4677 if (buf)
4679 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4681 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4682 size);
4683 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4684 ok(info->CertIssuer.cbData == sizeof(encodedCommonName),
4685 "Unexpected issuer len\n");
4686 ok(!memcmp(info->CertIssuer.pbData, encodedCommonName,
4687 sizeof(encodedCommonName)), "Unexpected issuer\n");
4688 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4689 LocalFree(buf);
4691 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4692 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4693 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4694 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4695 if (buf)
4697 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4699 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4700 size);
4701 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4702 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4703 ok(info->CertSerialNumber.cbData == sizeof(serialNum),
4704 "Unexpected serial number len\n");
4705 ok(!memcmp(info->CertSerialNumber.pbData, serialNum, sizeof(serialNum)),
4706 "Unexpected serial number\n");
4707 LocalFree(buf);
4711 static const BYTE authorityKeyIdWithIssuerUrl[] = { 0x30,0x15,0xa1,0x13,0x86,
4712 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
4713 0x6f,0x72,0x67 };
4715 static void test_encodeAuthorityKeyId2(DWORD dwEncoding)
4717 CERT_AUTHORITY_KEY_ID2_INFO info = { { 0 } };
4718 CERT_ALT_NAME_ENTRY entry = { 0 };
4719 BOOL ret;
4720 BYTE *buf = NULL;
4721 DWORD size = 0;
4723 /* Test with empty id */
4724 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4725 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4726 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4727 if (buf)
4729 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4730 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4731 LocalFree(buf);
4733 /* With just a key id */
4734 info.KeyId.cbData = sizeof(keyId);
4735 info.KeyId.pbData = keyId;
4736 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4737 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4738 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4739 if (buf)
4741 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n",
4742 size);
4743 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4744 LocalFree(buf);
4746 /* With a bogus issuer name */
4747 info.KeyId.cbData = 0;
4748 info.AuthorityCertIssuer.cAltEntry = 1;
4749 info.AuthorityCertIssuer.rgAltEntry = &entry;
4750 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4751 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4752 ok(!ret && GetLastError() == E_INVALIDARG,
4753 "Expected E_INVALIDARG, got %08x\n", GetLastError());
4754 /* With an issuer name */
4755 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
4756 U(entry).pwszURL = (LPWSTR)url;
4757 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4758 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4759 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4760 if (buf)
4762 ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %d\n",
4763 size);
4764 ok(!memcmp(buf, authorityKeyIdWithIssuerUrl, size),
4765 "Unexpected value\n");
4766 LocalFree(buf);
4768 /* With just a serial number */
4769 info.AuthorityCertIssuer.cAltEntry = 0;
4770 info.AuthorityCertSerialNumber.cbData = sizeof(serialNum);
4771 info.AuthorityCertSerialNumber.pbData = (BYTE *)serialNum;
4772 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4773 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4774 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4775 if (buf)
4777 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4778 size);
4779 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4780 LocalFree(buf);
4784 static void test_decodeAuthorityKeyId2(DWORD dwEncoding)
4786 BOOL ret;
4787 LPBYTE buf = NULL;
4788 DWORD size = 0;
4790 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4791 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4792 (BYTE *)&buf, &size);
4793 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4794 if (buf)
4796 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4798 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4799 size);
4800 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4801 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4802 "Expected no issuer name entries\n");
4803 ok(info->AuthorityCertSerialNumber.cbData == 0,
4804 "Expected no serial number\n");
4805 LocalFree(buf);
4807 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4808 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4809 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4810 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4811 if (buf)
4813 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4815 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4816 size);
4817 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4818 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4819 "Unexpected key id\n");
4820 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4821 "Expected no issuer name entries\n");
4822 ok(info->AuthorityCertSerialNumber.cbData == 0,
4823 "Expected no serial number\n");
4824 LocalFree(buf);
4826 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4827 authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl),
4828 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4829 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4830 if (buf)
4832 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4834 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4835 size);
4836 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4837 ok(info->AuthorityCertIssuer.cAltEntry == 1,
4838 "Expected 1 issuer entry, got %d\n",
4839 info->AuthorityCertIssuer.cAltEntry);
4840 ok(info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice ==
4841 CERT_ALT_NAME_URL, "Expected CERT_ALT_NAME_URL, got %d\n",
4842 info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice);
4843 ok(!lstrcmpW(U(info->AuthorityCertIssuer.rgAltEntry[0]).pwszURL,
4844 url), "Unexpected URL\n");
4845 ok(info->AuthorityCertSerialNumber.cbData == 0,
4846 "Expected no serial number\n");
4847 LocalFree(buf);
4849 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4850 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4851 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4852 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4853 if (buf)
4855 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4857 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4858 size);
4859 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4860 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4861 "Expected no issuer name entries\n");
4862 ok(info->AuthorityCertSerialNumber.cbData == sizeof(serialNum),
4863 "Unexpected serial number len\n");
4864 ok(!memcmp(info->AuthorityCertSerialNumber.pbData, serialNum,
4865 sizeof(serialNum)), "Unexpected serial number\n");
4866 LocalFree(buf);
4870 static const BYTE authorityInfoAccessWithUrl[] = {
4871 0x30,0x19,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
4872 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
4873 static const BYTE authorityInfoAccessWithUrlAndIPAddr[] = {
4874 0x30,0x29,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
4875 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x0e,0x06,
4876 0x02,0x2d,0x06,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
4878 static void test_encodeAuthorityInfoAccess(DWORD dwEncoding)
4880 static char oid1[] = "1.2.3";
4881 static char oid2[] = "1.5.6";
4882 BOOL ret;
4883 BYTE *buf = NULL;
4884 DWORD size = 0;
4885 CERT_ACCESS_DESCRIPTION accessDescription[2];
4886 CERT_AUTHORITY_INFO_ACCESS aia;
4888 memset(accessDescription, 0, sizeof(accessDescription));
4889 aia.cAccDescr = 0;
4890 aia.rgAccDescr = NULL;
4891 /* Having no access descriptions is allowed */
4892 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4893 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4894 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4895 if (buf)
4897 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
4898 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
4899 LocalFree(buf);
4900 buf = NULL;
4902 /* It can't have an empty access method */
4903 aia.cAccDescr = 1;
4904 aia.rgAccDescr = accessDescription;
4905 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4906 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4907 ok(!ret && (GetLastError() == E_INVALIDARG ||
4908 GetLastError() == OSS_LIMITED /* Win9x */),
4909 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
4910 /* It can't have an empty location */
4911 accessDescription[0].pszAccessMethod = oid1;
4912 SetLastError(0xdeadbeef);
4913 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4914 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4915 ok(!ret && GetLastError() == E_INVALIDARG,
4916 "expected E_INVALIDARG, got %08x\n", GetLastError());
4917 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
4918 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
4919 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4920 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4921 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4922 if (buf)
4924 ok(size == sizeof(authorityInfoAccessWithUrl), "unexpected size %d\n",
4925 size);
4926 ok(!memcmp(buf, authorityInfoAccessWithUrl, size),
4927 "unexpected value\n");
4928 LocalFree(buf);
4929 buf = NULL;
4931 accessDescription[1].pszAccessMethod = oid2;
4932 accessDescription[1].AccessLocation.dwAltNameChoice =
4933 CERT_ALT_NAME_IP_ADDRESS;
4934 U(accessDescription[1].AccessLocation).IPAddress.cbData =
4935 sizeof(encodedIPAddr);
4936 U(accessDescription[1].AccessLocation).IPAddress.pbData =
4937 (LPBYTE)encodedIPAddr;
4938 aia.cAccDescr = 2;
4939 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4940 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4941 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4942 if (buf)
4944 ok(size == sizeof(authorityInfoAccessWithUrlAndIPAddr),
4945 "unexpected size %d\n", size);
4946 ok(!memcmp(buf, authorityInfoAccessWithUrlAndIPAddr, size),
4947 "unexpected value\n");
4948 LocalFree(buf);
4949 buf = NULL;
4953 static void compareAuthorityInfoAccess(LPCSTR header,
4954 const CERT_AUTHORITY_INFO_ACCESS *expected,
4955 const CERT_AUTHORITY_INFO_ACCESS *got)
4957 DWORD i;
4959 ok(expected->cAccDescr == got->cAccDescr,
4960 "%s: expected %d access descriptions, got %d\n", header,
4961 expected->cAccDescr, got->cAccDescr);
4962 for (i = 0; i < expected->cAccDescr; i++)
4964 ok(!strcmp(expected->rgAccDescr[i].pszAccessMethod,
4965 got->rgAccDescr[i].pszAccessMethod), "%s[%d]: expected %s, got %s\n",
4966 header, i, expected->rgAccDescr[i].pszAccessMethod,
4967 got->rgAccDescr[i].pszAccessMethod);
4968 compareAltNameEntry(&expected->rgAccDescr[i].AccessLocation,
4969 &got->rgAccDescr[i].AccessLocation);
4973 static void test_decodeAuthorityInfoAccess(DWORD dwEncoding)
4975 static char oid1[] = "1.2.3";
4976 static char oid2[] = "1.5.6";
4977 BOOL ret;
4978 LPBYTE buf = NULL;
4979 DWORD size = 0;
4981 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
4982 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4983 (BYTE *)&buf, &size);
4984 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4985 if (buf)
4987 CERT_AUTHORITY_INFO_ACCESS aia = { 0, NULL };
4989 compareAuthorityInfoAccess("empty AIA", &aia,
4990 (CERT_AUTHORITY_INFO_ACCESS *)buf);
4991 LocalFree(buf);
4992 buf = NULL;
4994 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
4995 authorityInfoAccessWithUrl, sizeof(authorityInfoAccessWithUrl),
4996 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4997 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4998 if (buf)
5000 CERT_ACCESS_DESCRIPTION accessDescription;
5001 CERT_AUTHORITY_INFO_ACCESS aia;
5003 accessDescription.pszAccessMethod = oid1;
5004 accessDescription.AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5005 U(accessDescription.AccessLocation).pwszURL = (LPWSTR)url;
5006 aia.cAccDescr = 1;
5007 aia.rgAccDescr = &accessDescription;
5008 compareAuthorityInfoAccess("AIA with URL", &aia,
5009 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5010 LocalFree(buf);
5011 buf = NULL;
5013 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5014 authorityInfoAccessWithUrlAndIPAddr,
5015 sizeof(authorityInfoAccessWithUrlAndIPAddr), CRYPT_DECODE_ALLOC_FLAG,
5016 NULL, (BYTE *)&buf, &size);
5017 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5018 if (buf)
5020 CERT_ACCESS_DESCRIPTION accessDescription[2];
5021 CERT_AUTHORITY_INFO_ACCESS aia;
5023 accessDescription[0].pszAccessMethod = oid1;
5024 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5025 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
5026 accessDescription[1].pszAccessMethod = oid2;
5027 accessDescription[1].AccessLocation.dwAltNameChoice =
5028 CERT_ALT_NAME_IP_ADDRESS;
5029 U(accessDescription[1].AccessLocation).IPAddress.cbData =
5030 sizeof(encodedIPAddr);
5031 U(accessDescription[1].AccessLocation).IPAddress.pbData =
5032 (LPBYTE)encodedIPAddr;
5033 aia.cAccDescr = 2;
5034 aia.rgAccDescr = accessDescription;
5035 compareAuthorityInfoAccess("AIA with URL and IP addr", &aia,
5036 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5037 LocalFree(buf);
5038 buf = NULL;
5042 static const BYTE emptyCTL[] = {
5043 0x30,0x17,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5044 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5045 static const BYTE emptyCTLWithVersion1[] = {
5046 0x30,0x1a,0x02,0x01,0x01,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5047 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5048 static const BYTE ctlWithUsageIdentifier[] = {
5049 0x30,0x1b,0x30,0x04,0x06,0x02,0x2a,0x03,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
5050 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5051 static const BYTE ctlWithListIdentifier[] = {
5052 0x30,0x1a,0x30,0x00,0x04,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5053 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5054 static const BYTE ctlWithSequenceNumber[] = {
5055 0x30,0x1a,0x30,0x00,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5056 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5057 static const BYTE ctlWithThisUpdate[] = {
5058 0x30,0x15,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5059 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5060 static const BYTE ctlWithThisAndNextUpdate[] = {
5061 0x30,0x24,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5062 0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5063 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5064 static const BYTE ctlWithAlgId[] = {
5065 0x30,0x1b,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5066 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5067 static const BYTE ctlWithBogusEntry[] = {
5068 0x30,0x29,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5069 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x10,0x30,0x0e,0x04,
5070 0x01,0x01,0x31,0x09,0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,0x01 };
5071 static const BYTE ctlWithOneEntry[] = {
5072 0x30,0x2a,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5073 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x11,0x30,0x0f,0x04,
5074 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00 };
5075 static const BYTE ctlWithTwoEntries[] = {
5076 0x30,0x41,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5077 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x28,0x30,0x0f,0x04,
5078 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00,0x30,
5079 0x15,0x04,0x01,0x01,0x31,0x10,0x30,0x0e,0x06,0x02,0x2d,0x06,0x31,0x08,0x30,
5080 0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5082 static void test_encodeCTL(DWORD dwEncoding)
5084 static char oid1[] = "1.2.3";
5085 static char oid2[] = "1.5.6";
5086 char *pOid1 = oid1;
5087 BOOL ret;
5088 BYTE *buf = NULL;
5089 DWORD size = 0;
5090 CTL_INFO info;
5091 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5092 CTL_ENTRY ctlEntry[2];
5093 CRYPT_ATTRIBUTE attr1, attr2;
5094 CRYPT_ATTR_BLOB value1, value2;
5096 memset(&info, 0, sizeof(info));
5097 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5098 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5099 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5100 if (buf)
5102 ok(size == sizeof(emptyCTL), "unexpected size %d\n", size);
5103 ok(!memcmp(buf, emptyCTL, size), "unexpected value\n");
5104 LocalFree(buf);
5105 buf = NULL;
5107 info.dwVersion = 1;
5108 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5109 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5110 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5111 if (buf)
5113 ok(size == sizeof(emptyCTLWithVersion1), "unexpected size %d\n", size);
5114 ok(!memcmp(buf, emptyCTLWithVersion1, size), "unexpected value\n");
5115 LocalFree(buf);
5116 buf = NULL;
5118 info.dwVersion = 0;
5119 info.SubjectUsage.cUsageIdentifier = 1;
5120 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5121 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5122 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5123 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5124 if (buf)
5126 ok(size == sizeof(ctlWithUsageIdentifier), "unexpected size %d\n",
5127 size);
5128 ok(!memcmp(buf, ctlWithUsageIdentifier, size), "unexpected value\n");
5129 LocalFree(buf);
5130 buf = NULL;
5132 info.SubjectUsage.cUsageIdentifier = 0;
5133 info.ListIdentifier.cbData = sizeof(serialNum);
5134 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5135 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5136 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5137 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5138 if (buf)
5140 ok(size == sizeof(ctlWithListIdentifier), "unexpected size %d\n", size);
5141 ok(!memcmp(buf, ctlWithListIdentifier, size), "unexpected value\n");
5142 LocalFree(buf);
5143 buf = NULL;
5145 info.ListIdentifier.cbData = 0;
5146 info.SequenceNumber.cbData = sizeof(serialNum);
5147 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5148 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5149 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5150 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5151 if (buf)
5153 ok(size == sizeof(ctlWithSequenceNumber), "unexpected size %d\n",
5154 size);
5155 ok(!memcmp(buf, ctlWithSequenceNumber, size), "unexpected value\n");
5156 LocalFree(buf);
5157 buf = NULL;
5159 info.SequenceNumber.cbData = 0;
5160 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5161 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5162 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5163 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5164 if (buf)
5166 ok(size == sizeof(ctlWithThisUpdate), "unexpected size %d\n", size);
5167 ok(!memcmp(buf, ctlWithThisUpdate, size), "unexpected value\n");
5168 LocalFree(buf);
5169 buf = NULL;
5171 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5172 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5173 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5174 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5175 if (buf)
5177 ok(size == sizeof(ctlWithThisAndNextUpdate), "unexpected size %d\n",
5178 size);
5179 ok(!memcmp(buf, ctlWithThisAndNextUpdate, size), "unexpected value\n");
5180 LocalFree(buf);
5181 buf = NULL;
5183 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5184 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5185 info.SubjectAlgorithm.pszObjId = oid2;
5186 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5187 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5188 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5189 if (buf)
5191 ok(size == sizeof(ctlWithAlgId), "unexpected size %d\n", size);
5192 ok(!memcmp(buf, ctlWithAlgId, size), "unexpected value\n");
5193 LocalFree(buf);
5194 buf = NULL;
5196 /* The value is supposed to be asn.1 encoded, so this'll fail to decode
5197 * (see tests below) but it'll encode fine.
5199 info.SubjectAlgorithm.pszObjId = NULL;
5200 value1.cbData = sizeof(serialNum);
5201 value1.pbData = (LPBYTE)serialNum;
5202 attr1.pszObjId = oid1;
5203 attr1.cValue = 1;
5204 attr1.rgValue = &value1;
5205 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5206 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5207 ctlEntry[0].cAttribute = 1;
5208 ctlEntry[0].rgAttribute = &attr1;
5209 info.cCTLEntry = 1;
5210 info.rgCTLEntry = ctlEntry;
5211 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5212 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5213 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5214 if (buf)
5216 ok(size == sizeof(ctlWithBogusEntry), "unexpected size %d\n", size);
5217 ok(!memcmp(buf, ctlWithBogusEntry, size), "unexpected value\n");
5218 LocalFree(buf);
5219 buf = NULL;
5221 value1.cbData = sizeof(emptySequence);
5222 value1.pbData = (LPBYTE)emptySequence;
5223 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5224 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5225 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5226 if (buf)
5228 ok(size == sizeof(ctlWithOneEntry), "unexpected size %d\n", size);
5229 ok(!memcmp(buf, ctlWithOneEntry, size), "unexpected value\n");
5230 LocalFree(buf);
5231 buf = NULL;
5233 value2.cbData = sizeof(encodedIPAddr);
5234 value2.pbData = (LPBYTE)encodedIPAddr;
5235 attr2.pszObjId = oid2;
5236 attr2.cValue = 1;
5237 attr2.rgValue = &value2;
5238 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5239 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5240 ctlEntry[1].cAttribute = 1;
5241 ctlEntry[1].rgAttribute = &attr2;
5242 info.cCTLEntry = 2;
5243 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5244 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5245 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5246 if (buf)
5248 ok(size == sizeof(ctlWithTwoEntries), "unexpected size %d\n", size);
5249 ok(!memcmp(buf, ctlWithTwoEntries, size), "unexpected value\n");
5250 LocalFree(buf);
5251 buf = NULL;
5255 static void compareCTLInfo(LPCSTR header, const CTL_INFO *expected,
5256 const CTL_INFO *got)
5258 DWORD i, j, k;
5260 ok(expected->dwVersion == got->dwVersion,
5261 "%s: expected version %d, got %d\n", header, expected->dwVersion,
5262 got->dwVersion);
5263 ok(expected->SubjectUsage.cUsageIdentifier ==
5264 got->SubjectUsage.cUsageIdentifier,
5265 "%s: expected %d usage identifiers, got %d\n", header,
5266 expected->SubjectUsage.cUsageIdentifier,
5267 got->SubjectUsage.cUsageIdentifier);
5268 for (i = 0; i < expected->SubjectUsage.cUsageIdentifier; i++)
5269 ok(!strcmp(expected->SubjectUsage.rgpszUsageIdentifier[i],
5270 got->SubjectUsage.rgpszUsageIdentifier[i]),
5271 "%s[%d]: expected %s, got %s\n", header, i,
5272 expected->SubjectUsage.rgpszUsageIdentifier[i],
5273 got->SubjectUsage.rgpszUsageIdentifier[i]);
5274 ok(expected->ListIdentifier.cbData == got->ListIdentifier.cbData,
5275 "%s: expected list identifier of %d bytes, got %d\n", header,
5276 expected->ListIdentifier.cbData, got->ListIdentifier.cbData);
5277 if (expected->ListIdentifier.cbData)
5278 ok(!memcmp(expected->ListIdentifier.pbData, got->ListIdentifier.pbData,
5279 expected->ListIdentifier.cbData),
5280 "%s: unexpected list identifier value\n", header);
5281 ok(expected->SequenceNumber.cbData == got->SequenceNumber.cbData,
5282 "%s: expected sequence number of %d bytes, got %d\n", header,
5283 expected->SequenceNumber.cbData, got->SequenceNumber.cbData);
5284 if (expected->SequenceNumber.cbData)
5285 ok(!memcmp(expected->SequenceNumber.pbData, got->SequenceNumber.pbData,
5286 expected->SequenceNumber.cbData),
5287 "%s: unexpected sequence number value\n", header);
5288 ok(!memcmp(&expected->ThisUpdate, &got->ThisUpdate, sizeof(FILETIME)),
5289 "%s: expected this update = (%d, %d), got (%d, %d)\n", header,
5290 expected->ThisUpdate.dwLowDateTime, expected->ThisUpdate.dwHighDateTime,
5291 got->ThisUpdate.dwLowDateTime, got->ThisUpdate.dwHighDateTime);
5292 ok(!memcmp(&expected->NextUpdate, &got->NextUpdate, sizeof(FILETIME)),
5293 "%s: expected next update = (%d, %d), got (%d, %d)\n", header,
5294 expected->NextUpdate.dwLowDateTime, expected->NextUpdate.dwHighDateTime,
5295 got->NextUpdate.dwLowDateTime, got->NextUpdate.dwHighDateTime);
5296 if (expected->SubjectAlgorithm.pszObjId &&
5297 *expected->SubjectAlgorithm.pszObjId && !got->SubjectAlgorithm.pszObjId)
5298 ok(0, "%s: expected subject algorithm %s, got NULL\n", header,
5299 expected->SubjectAlgorithm.pszObjId);
5300 if (expected->SubjectAlgorithm.pszObjId && got->SubjectAlgorithm.pszObjId)
5301 ok(!strcmp(expected->SubjectAlgorithm.pszObjId,
5302 got->SubjectAlgorithm.pszObjId),
5303 "%s: expected subject algorithm %s, got %s\n", header,
5304 expected->SubjectAlgorithm.pszObjId, got->SubjectAlgorithm.pszObjId);
5305 ok(expected->SubjectAlgorithm.Parameters.cbData ==
5306 got->SubjectAlgorithm.Parameters.cbData,
5307 "%s: expected subject algorithm parameters of %d bytes, got %d\n", header,
5308 expected->SubjectAlgorithm.Parameters.cbData,
5309 got->SubjectAlgorithm.Parameters.cbData);
5310 if (expected->SubjectAlgorithm.Parameters.cbData)
5311 ok(!memcmp(expected->SubjectAlgorithm.Parameters.pbData,
5312 got->SubjectAlgorithm.Parameters.pbData,
5313 expected->SubjectAlgorithm.Parameters.cbData),
5314 "%s: unexpected subject algorithm parameter value\n", header);
5315 ok(expected->cCTLEntry == got->cCTLEntry,
5316 "%s: expected %d CTL entries, got %d\n", header, expected->cCTLEntry,
5317 got->cCTLEntry);
5318 for (i = 0; i < expected->cCTLEntry; i++)
5320 ok(expected->rgCTLEntry[i].SubjectIdentifier.cbData ==
5321 got->rgCTLEntry[i].SubjectIdentifier.cbData,
5322 "%s[%d]: expected subject identifier of %d bytes, got %d\n",
5323 header, i, expected->rgCTLEntry[i].SubjectIdentifier.cbData,
5324 got->rgCTLEntry[i].SubjectIdentifier.cbData);
5325 if (expected->rgCTLEntry[i].SubjectIdentifier.cbData)
5326 ok(!memcmp(expected->rgCTLEntry[i].SubjectIdentifier.pbData,
5327 got->rgCTLEntry[i].SubjectIdentifier.pbData,
5328 expected->rgCTLEntry[i].SubjectIdentifier.cbData),
5329 "%s[%d]: unexpected subject identifier value\n",
5330 header, i);
5331 for (j = 0; j < expected->rgCTLEntry[i].cAttribute; j++)
5333 ok(!strcmp(expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5334 got->rgCTLEntry[i].rgAttribute[j].pszObjId),
5335 "%s[%d][%d]: expected attribute OID %s, got %s\n", header, i, j,
5336 expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5337 got->rgCTLEntry[i].rgAttribute[j].pszObjId);
5338 for (k = 0; k < expected->rgCTLEntry[i].rgAttribute[j].cValue; k++)
5340 ok(expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData ==
5341 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5342 "%s[%d][%d][%d]: expected value of %d bytes, got %d\n",
5343 header, i, j, k,
5344 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5345 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData);
5346 if (expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData)
5347 ok(!memcmp(
5348 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5349 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5350 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData),
5351 "%s[%d][%d][%d]: unexpected value\n",
5352 header, i, j, k);
5356 ok(expected->cExtension == got->cExtension,
5357 "%s: expected %d extensions, got %d\n", header, expected->cExtension,
5358 got->cExtension);
5359 for (i = 0; i < expected->cExtension; i++)
5361 ok(!strcmp(expected->rgExtension[i].pszObjId,
5362 got->rgExtension[i].pszObjId), "%s[%d]: expected %s, got %s\n",
5363 header, i, expected->rgExtension[i].pszObjId,
5364 got->rgExtension[i].pszObjId);
5365 ok(expected->rgExtension[i].fCritical == got->rgExtension[i].fCritical,
5366 "%s[%d]: expected fCritical = %d, got %d\n", header, i,
5367 expected->rgExtension[i].fCritical, got->rgExtension[i].fCritical);
5368 ok(expected->rgExtension[i].Value.cbData ==
5369 got->rgExtension[i].Value.cbData,
5370 "%s[%d]: expected extension value to have %d bytes, got %d\n",
5371 header, i, expected->rgExtension[i].Value.cbData,
5372 got->rgExtension[i].Value.cbData);
5373 if (expected->rgExtension[i].Value.cbData)
5374 ok(!memcmp(expected->rgExtension[i].Value.pbData,
5375 got->rgExtension[i].Value.pbData,
5376 expected->rgExtension[i].Value.cbData),
5377 "%s[%d]: unexpected extension value\n", header, i);
5381 static const BYTE signedCTL[] = {
5382 0x30,0x81,0xc7,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
5383 0x81,0xb9,0x30,0x81,0xb6,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
5384 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x28,0x06,0x09,0x2a,0x86,
5385 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x1b,0x04,0x19,0x30,0x17,0x30,0x00,
5386 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5387 0x30,0x5a,0x30,0x02,0x06,0x00,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
5388 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
5389 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
5390 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5391 0x00,0x04,0x40,0xca,0xd8,0x32,0xd1,0xbd,0x97,0x61,0x54,0xd6,0x80,0xcf,0x0d,
5392 0xbd,0xa2,0x42,0xc7,0xca,0x37,0x91,0x7d,0x9d,0xac,0x8c,0xdf,0x05,0x8a,0x39,
5393 0xc6,0x07,0xc1,0x37,0xe6,0xb9,0xd1,0x0d,0x26,0xec,0xa5,0xb0,0x8a,0x51,0x26,
5394 0x2b,0x4f,0x73,0x44,0x86,0x83,0x5e,0x2b,0x6e,0xcc,0xf8,0x1b,0x85,0x53,0xe9,
5395 0x7a,0x80,0x8f,0x6b,0x42,0x19,0x93 };
5396 static const BYTE signedCTLWithCTLInnerContent[] = {
5397 0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
5398 0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
5399 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
5400 0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
5401 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5402 0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
5403 0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
5404 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
5405 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
5406 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
5407 0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
5408 0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
5409 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
5410 0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5411 0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
5412 0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
5413 0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
5414 0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
5415 0x57,0x6c,0x0b,0x47,0xb8 };
5417 static void test_decodeCTL(DWORD dwEncoding)
5419 static char oid1[] = "1.2.3";
5420 static char oid2[] = "1.5.6";
5421 static BYTE nullData[] = { 5,0 };
5422 char *pOid1 = oid1;
5423 BOOL ret;
5424 BYTE *buf = NULL;
5425 DWORD size = 0;
5426 CTL_INFO info;
5427 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5428 CTL_ENTRY ctlEntry[2];
5429 CRYPT_ATTRIBUTE attr1, attr2;
5430 CRYPT_ATTR_BLOB value1, value2;
5432 memset(&info, 0, sizeof(info));
5433 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTL, sizeof(emptyCTL),
5434 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5435 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5436 if (buf)
5438 compareCTLInfo("empty CTL", &info, (CTL_INFO *)buf);
5439 LocalFree(buf);
5440 buf = NULL;
5442 info.dwVersion = 1;
5443 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTLWithVersion1,
5444 sizeof(emptyCTLWithVersion1), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
5445 &size);
5446 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5447 if (buf)
5449 compareCTLInfo("v1 CTL", &info, (CTL_INFO *)buf);
5450 LocalFree(buf);
5451 buf = NULL;
5453 info.dwVersion = 0;
5454 info.SubjectUsage.cUsageIdentifier = 1;
5455 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5456 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithUsageIdentifier,
5457 sizeof(ctlWithUsageIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5458 (BYTE *)&buf, &size);
5459 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5460 if (buf)
5462 compareCTLInfo("CTL with usage identifier", &info, (CTL_INFO *)buf);
5463 LocalFree(buf);
5464 buf = NULL;
5466 info.SubjectUsage.cUsageIdentifier = 0;
5467 info.ListIdentifier.cbData = sizeof(serialNum);
5468 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5469 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithListIdentifier,
5470 sizeof(ctlWithListIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5471 (BYTE *)&buf, &size);
5472 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5473 if (buf)
5475 compareCTLInfo("CTL with list identifier", &info, (CTL_INFO *)buf);
5476 LocalFree(buf);
5477 buf = NULL;
5479 info.ListIdentifier.cbData = 0;
5480 info.SequenceNumber.cbData = sizeof(serialNum);
5481 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5482 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithSequenceNumber,
5483 sizeof(ctlWithSequenceNumber), CRYPT_DECODE_ALLOC_FLAG, NULL,
5484 (BYTE *)&buf, &size);
5485 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5486 if (buf)
5488 compareCTLInfo("CTL with sequence number", &info, (CTL_INFO *)buf);
5489 LocalFree(buf);
5490 buf = NULL;
5492 info.SequenceNumber.cbData = 0;
5493 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5494 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisUpdate,
5495 sizeof(ctlWithThisUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5496 (BYTE *)&buf, &size);
5497 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5498 if (buf)
5500 compareCTLInfo("CTL with this update", &info, (CTL_INFO *)buf);
5501 LocalFree(buf);
5502 buf = NULL;
5504 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5505 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisAndNextUpdate,
5506 sizeof(ctlWithThisAndNextUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5507 (BYTE *)&buf, &size);
5508 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5509 if (buf)
5511 compareCTLInfo("CTL with this and next update", &info, (CTL_INFO *)buf);
5512 LocalFree(buf);
5513 buf = NULL;
5515 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5516 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5517 info.SubjectAlgorithm.pszObjId = oid2;
5518 info.SubjectAlgorithm.Parameters.cbData = sizeof(nullData);
5519 info.SubjectAlgorithm.Parameters.pbData = nullData;
5520 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithAlgId,
5521 sizeof(ctlWithAlgId), CRYPT_DECODE_ALLOC_FLAG, NULL,
5522 (BYTE *)&buf, &size);
5523 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5524 if (buf)
5526 compareCTLInfo("CTL with algorithm identifier", &info, (CTL_INFO *)buf);
5527 LocalFree(buf);
5528 buf = NULL;
5530 SetLastError(0xdeadbeef);
5531 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithBogusEntry,
5532 sizeof(ctlWithBogusEntry), CRYPT_DECODE_ALLOC_FLAG, NULL,
5533 (BYTE *)&buf, &size);
5534 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD || CRYPT_E_ASN1_CORRUPT),
5535 "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n",
5536 GetLastError());
5537 info.SubjectAlgorithm.Parameters.cbData = 0;
5538 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5539 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5540 info.SubjectAlgorithm.pszObjId = oid2;
5541 info.SubjectAlgorithm.pszObjId = NULL;
5542 value1.cbData = sizeof(emptySequence);
5543 value1.pbData = (LPBYTE)emptySequence;
5544 attr1.pszObjId = oid1;
5545 attr1.cValue = 1;
5546 attr1.rgValue = &value1;
5547 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5548 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5549 ctlEntry[0].cAttribute = 1;
5550 ctlEntry[0].rgAttribute = &attr1;
5551 info.cCTLEntry = 1;
5552 info.rgCTLEntry = ctlEntry;
5553 SetLastError(0xdeadbeef);
5554 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithOneEntry,
5555 sizeof(ctlWithOneEntry), CRYPT_DECODE_ALLOC_FLAG, NULL,
5556 (BYTE *)&buf, &size);
5557 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5558 if (buf)
5560 compareCTLInfo("CTL with one entry", &info, (CTL_INFO *)buf);
5561 LocalFree(buf);
5562 buf = NULL;
5564 value2.cbData = sizeof(encodedIPAddr);
5565 value2.pbData = (LPBYTE)encodedIPAddr;
5566 attr2.pszObjId = oid2;
5567 attr2.cValue = 1;
5568 attr2.rgValue = &value2;
5569 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5570 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5571 ctlEntry[1].cAttribute = 1;
5572 ctlEntry[1].rgAttribute = &attr2;
5573 info.cCTLEntry = 2;
5574 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithTwoEntries,
5575 sizeof(ctlWithTwoEntries), CRYPT_DECODE_ALLOC_FLAG, NULL,
5576 (BYTE *)&buf, &size);
5577 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5578 if (buf)
5580 compareCTLInfo("CTL with two entries", &info, (CTL_INFO *)buf);
5581 LocalFree(buf);
5582 buf = NULL;
5584 /* A signed CTL isn't decodable, even if the inner content is a CTL */
5585 SetLastError(0xdeadbeef);
5586 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, signedCTL,
5587 sizeof(signedCTL), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5588 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5589 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5590 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5591 GetLastError());
5592 SetLastError(0xdeadbeef);
5593 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL,
5594 signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent),
5595 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5596 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5597 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5598 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5599 GetLastError());
5602 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
5603 static const BYTE emptyPKCSContentInfoExtraBytes[] = { 0x30,0x04,0x06,0x02,0x2a,
5604 0x03,0,0,0,0,0,0 };
5605 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
5606 0xa0,0x01,0x01 };
5607 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
5608 0x03,0x02,0x01,0x01 };
5609 static BYTE bogusDER[] = { 1 };
5611 static void test_encodePKCSContentInfo(DWORD dwEncoding)
5613 BOOL ret;
5614 BYTE *buf = NULL;
5615 DWORD size = 0;
5616 CRYPT_CONTENT_INFO info = { 0 };
5617 char oid1[] = "1.2.3";
5619 if (0)
5621 /* Crashes on win9x */
5622 SetLastError(0xdeadbeef);
5623 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL,
5624 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5625 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5626 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5628 SetLastError(0xdeadbeef);
5629 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5630 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5631 ok(!ret && (GetLastError() == E_INVALIDARG ||
5632 GetLastError() == OSS_LIMITED /* Win9x */),
5633 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5634 info.pszObjId = oid1;
5635 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5636 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5637 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5638 if (buf)
5640 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size);
5641 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n");
5642 LocalFree(buf);
5644 info.Content.pbData = bogusDER;
5645 info.Content.cbData = sizeof(bogusDER);
5646 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5647 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5648 ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError());
5649 if (buf)
5651 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size);
5652 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n");
5653 LocalFree(buf);
5655 info.Content.pbData = (BYTE *)ints[0].encoded;
5656 info.Content.cbData = ints[0].encoded[1] + 2;
5657 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5658 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5659 if (buf)
5661 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size);
5662 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n");
5663 LocalFree(buf);
5667 static const BYTE indefiniteSignedPKCSContent[] = {
5668 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
5669 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
5670 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
5671 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
5672 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
5673 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
5674 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5675 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5676 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
5677 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5678 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5679 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
5680 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
5681 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
5682 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
5683 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
5684 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
5685 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
5686 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
5687 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5688 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5689 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
5690 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
5691 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
5692 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
5693 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
5694 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
5695 0x00,0x00,0x00,0x00,0x00,0x00 };
5697 static void test_decodePKCSContentInfo(DWORD dwEncoding)
5699 BOOL ret;
5700 LPBYTE buf = NULL;
5701 DWORD size = 0;
5702 CRYPT_CONTENT_INFO *info;
5704 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5705 emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo),
5706 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5707 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5708 if (buf)
5710 info = (CRYPT_CONTENT_INFO *)buf;
5712 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5713 info->pszObjId);
5714 ok(info->Content.cbData == 0, "Expected no data, got %d\n",
5715 info->Content.cbData);
5716 LocalFree(buf);
5718 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5719 emptyPKCSContentInfoExtraBytes, sizeof(emptyPKCSContentInfoExtraBytes),
5720 0, NULL, NULL, &size);
5721 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5722 SetLastError(0xdeadbeef);
5723 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5724 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo),
5725 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5726 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5727 * I doubt an app depends on that.
5729 ok((!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5730 GetLastError() == CRYPT_E_ASN1_CORRUPT)) || broken(ret),
5731 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5732 GetLastError());
5733 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5734 intPKCSContentInfo, sizeof(intPKCSContentInfo),
5735 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5736 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5737 if (buf)
5739 info = (CRYPT_CONTENT_INFO *)buf;
5741 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5742 info->pszObjId);
5743 ok(info->Content.cbData == ints[0].encoded[1] + 2,
5744 "Unexpected size %d\n", info->Content.cbData);
5745 ok(!memcmp(info->Content.pbData, ints[0].encoded,
5746 info->Content.cbData), "Unexpected value\n");
5747 LocalFree(buf);
5749 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5750 indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent),
5751 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5752 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5753 if (buf)
5755 info = (CRYPT_CONTENT_INFO *)buf;
5757 ok(!strcmp(info->pszObjId, szOID_RSA_signedData),
5758 "Expected %s, got %s\n", szOID_RSA_signedData, info->pszObjId);
5759 ok(info->Content.cbData == 392, "Expected 392, got %d\n",
5760 info->Content.cbData);
5761 LocalFree(buf);
5765 static const BYTE emptyPKCSAttr[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
5766 0x00 };
5767 static const BYTE bogusPKCSAttr[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
5768 0x01 };
5769 static const BYTE intPKCSAttr[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
5770 0x02,0x01,0x01 };
5772 static void test_encodePKCSAttribute(DWORD dwEncoding)
5774 CRYPT_ATTRIBUTE attr = { 0 };
5775 BOOL ret;
5776 LPBYTE buf = NULL;
5777 DWORD size = 0;
5778 CRYPT_ATTR_BLOB blob;
5779 char oid[] = "1.2.3";
5781 if (0)
5783 /* Crashes on win9x */
5784 SetLastError(0xdeadbeef);
5785 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, NULL,
5786 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5787 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5788 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5790 SetLastError(0xdeadbeef);
5791 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5792 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5793 ok(!ret && (GetLastError() == E_INVALIDARG ||
5794 GetLastError() == OSS_LIMITED /* Win9x */),
5795 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5796 attr.pszObjId = oid;
5797 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5798 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5799 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5800 if (buf)
5802 ok(size == sizeof(emptyPKCSAttr), "Unexpected size %d\n", size);
5803 ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n");
5804 LocalFree(buf);
5806 blob.cbData = sizeof(bogusDER);
5807 blob.pbData = bogusDER;
5808 attr.cValue = 1;
5809 attr.rgValue = &blob;
5810 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5811 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5812 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5813 if (buf)
5815 ok(size == sizeof(bogusPKCSAttr), "Unexpected size %d\n", size);
5816 ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n");
5817 LocalFree(buf);
5819 blob.pbData = (BYTE *)ints[0].encoded;
5820 blob.cbData = ints[0].encoded[1] + 2;
5821 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5822 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5823 if (buf)
5825 ok(size == sizeof(intPKCSAttr), "Unexpected size %d\n", size);
5826 ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n");
5827 LocalFree(buf);
5831 static void test_decodePKCSAttribute(DWORD dwEncoding)
5833 BOOL ret;
5834 LPBYTE buf = NULL;
5835 DWORD size = 0;
5836 CRYPT_ATTRIBUTE *attr;
5838 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5839 emptyPKCSAttr, sizeof(emptyPKCSAttr),
5840 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5841 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5842 if (buf)
5844 attr = (CRYPT_ATTRIBUTE *)buf;
5846 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5847 attr->pszObjId);
5848 ok(attr->cValue == 0, "Expected no value, got %d\n", attr->cValue);
5849 LocalFree(buf);
5851 SetLastError(0xdeadbeef);
5852 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5853 bogusPKCSAttr, sizeof(bogusPKCSAttr),
5854 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5855 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5856 * I doubt an app depends on that.
5858 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5859 GetLastError() == CRYPT_E_ASN1_CORRUPT || OSS_MORE_INPUT /* Win9x */),
5860 "Expected CRYPT_E_ASN1_EOD, CRYPT_E_ASN1_CORRUPT, or OSS_MORE_INPUT, got %x\n",
5861 GetLastError());
5862 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5863 intPKCSAttr, sizeof(intPKCSAttr),
5864 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5865 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5866 if (buf)
5868 attr = (CRYPT_ATTRIBUTE *)buf;
5870 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5871 attr->pszObjId);
5872 ok(attr->cValue == 1, "Expected 1 value, got %d\n", attr->cValue);
5873 ok(attr->rgValue[0].cbData == ints[0].encoded[1] + 2,
5874 "Unexpected size %d\n", attr->rgValue[0].cbData);
5875 ok(!memcmp(attr->rgValue[0].pbData, ints[0].encoded,
5876 attr->rgValue[0].cbData), "Unexpected value\n");
5877 LocalFree(buf);
5881 static const BYTE emptyPKCSAttributes[] = { 0x31,0x00 };
5882 static const BYTE singlePKCSAttributes[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
5883 0x2a,0x03,0x31,0x00 };
5884 static const BYTE doublePKCSAttributes[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
5885 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
5887 static void test_encodePKCSAttributes(DWORD dwEncoding)
5889 CRYPT_ATTRIBUTES attributes = { 0 };
5890 CRYPT_ATTRIBUTE attr[2] = { { 0 } };
5891 CRYPT_ATTR_BLOB blob;
5892 BOOL ret;
5893 LPBYTE buf = NULL;
5894 DWORD size = 0;
5895 char oid1[] = "1.2.3", oid2[] = "1.5.6";
5897 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5898 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5899 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5900 if (buf)
5902 ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %d\n", size);
5903 ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n");
5904 LocalFree(buf);
5906 attributes.cAttr = 1;
5907 attributes.rgAttr = attr;
5908 SetLastError(0xdeadbeef);
5909 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5910 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5911 ok(!ret && (GetLastError() == E_INVALIDARG ||
5912 GetLastError() == OSS_LIMITED /* Win9x */),
5913 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
5914 attr[0].pszObjId = oid1;
5915 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5916 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5917 if (buf)
5919 ok(size == sizeof(singlePKCSAttributes), "Unexpected size %d\n", size);
5920 ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n");
5921 LocalFree(buf);
5923 attr[1].pszObjId = oid2;
5924 attr[1].cValue = 1;
5925 attr[1].rgValue = &blob;
5926 blob.pbData = (BYTE *)ints[0].encoded;
5927 blob.cbData = ints[0].encoded[1] + 2;
5928 attributes.cAttr = 2;
5929 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5930 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5931 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5932 if (buf)
5934 ok(size == sizeof(doublePKCSAttributes), "Unexpected size %d\n", size);
5935 ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n");
5936 LocalFree(buf);
5940 static void test_decodePKCSAttributes(DWORD dwEncoding)
5942 BOOL ret;
5943 LPBYTE buf = NULL;
5944 DWORD size = 0;
5945 CRYPT_ATTRIBUTES *attributes;
5947 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5948 emptyPKCSAttributes, sizeof(emptyPKCSAttributes),
5949 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5950 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5951 if (buf)
5953 attributes = (CRYPT_ATTRIBUTES *)buf;
5954 ok(attributes->cAttr == 0, "Expected no attributes, got %d\n",
5955 attributes->cAttr);
5956 LocalFree(buf);
5958 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5959 singlePKCSAttributes, sizeof(singlePKCSAttributes),
5960 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5961 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5962 if (buf)
5964 attributes = (CRYPT_ATTRIBUTES *)buf;
5965 ok(attributes->cAttr == 1, "Expected 1 attribute, got %d\n",
5966 attributes->cAttr);
5967 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5968 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5969 ok(attributes->rgAttr[0].cValue == 0,
5970 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5971 LocalFree(buf);
5973 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5974 doublePKCSAttributes, sizeof(doublePKCSAttributes),
5975 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5976 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5977 if (buf)
5979 attributes = (CRYPT_ATTRIBUTES *)buf;
5980 ok(attributes->cAttr == 2, "Expected 2 attributes, got %d\n",
5981 attributes->cAttr);
5982 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5983 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5984 ok(attributes->rgAttr[0].cValue == 0,
5985 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5986 ok(!strcmp(attributes->rgAttr[1].pszObjId, "1.5.6"),
5987 "Expected 1.5.6, got %s\n", attributes->rgAttr[1].pszObjId);
5988 ok(attributes->rgAttr[1].cValue == 1,
5989 "Expected 1 attribute, got %d\n", attributes->rgAttr[1].cValue);
5990 ok(attributes->rgAttr[1].rgValue[0].cbData == ints[0].encoded[1] + 2,
5991 "Unexpected size %d\n", attributes->rgAttr[1].rgValue[0].cbData);
5992 ok(!memcmp(attributes->rgAttr[1].rgValue[0].pbData, ints[0].encoded,
5993 attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n");
5994 LocalFree(buf);
5998 static const BYTE singleCapability[] = {
5999 0x30,0x06,0x30,0x04,0x06,0x02,0x2d,0x06 };
6000 static const BYTE twoCapabilities[] = {
6001 0x30,0x0c,0x30,0x04,0x06,0x02,0x2d,0x06,0x30,0x04,0x06,0x02,0x2a,0x03 };
6002 static const BYTE singleCapabilitywithNULL[] = {
6003 0x30,0x08,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
6005 static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding)
6007 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6008 BOOL ret;
6009 LPBYTE buf = NULL;
6010 DWORD size = 0;
6011 CRYPT_SMIME_CAPABILITY capability[2];
6012 CRYPT_SMIME_CAPABILITIES capabilities;
6014 /* An empty capabilities is allowed */
6015 capabilities.cCapability = 0;
6016 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6017 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6018 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6019 if (buf)
6021 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
6022 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
6023 LocalFree(buf);
6025 /* A non-empty capabilities with an empty capability (lacking an OID) is
6026 * not allowed
6028 capability[0].pszObjId = NULL;
6029 capability[0].Parameters.cbData = 0;
6030 capabilities.cCapability = 1;
6031 capabilities.rgCapability = capability;
6032 SetLastError(0xdeadbeef);
6033 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6034 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6035 ok(!ret && (GetLastError() == E_INVALIDARG ||
6036 GetLastError() == OSS_LIMITED /* Win9x */),
6037 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6038 capability[0].pszObjId = oid1;
6039 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6040 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6041 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6042 if (buf)
6044 ok(size == sizeof(singleCapability), "unexpected size %d\n", size);
6045 ok(!memcmp(buf, singleCapability, size), "unexpected value\n");
6046 LocalFree(buf);
6048 capability[1].pszObjId = oid2;
6049 capability[1].Parameters.cbData = 0;
6050 capabilities.cCapability = 2;
6051 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6052 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6053 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6054 if (buf)
6056 ok(size == sizeof(twoCapabilities), "unexpected size %d\n", size);
6057 ok(!memcmp(buf, twoCapabilities, size), "unexpected value\n");
6058 LocalFree(buf);
6062 static void compareSMimeCapabilities(LPCSTR header,
6063 const CRYPT_SMIME_CAPABILITIES *expected, const CRYPT_SMIME_CAPABILITIES *got)
6065 DWORD i;
6067 ok(got->cCapability == expected->cCapability,
6068 "%s: expected %d capabilities, got %d\n", header, expected->cCapability,
6069 got->cCapability);
6070 for (i = 0; i < expected->cCapability; i++)
6072 ok(!strcmp(expected->rgCapability[i].pszObjId,
6073 got->rgCapability[i].pszObjId), "%s[%d]: expected %s, got %s\n",
6074 header, i, expected->rgCapability[i].pszObjId,
6075 got->rgCapability[i].pszObjId);
6076 ok(expected->rgCapability[i].Parameters.cbData ==
6077 got->rgCapability[i].Parameters.cbData,
6078 "%s[%d]: expected %d bytes, got %d\n", header, i,
6079 expected->rgCapability[i].Parameters.cbData,
6080 got->rgCapability[i].Parameters.cbData);
6081 if (expected->rgCapability[i].Parameters.cbData)
6082 ok(!memcmp(expected->rgCapability[i].Parameters.pbData,
6083 got->rgCapability[i].Parameters.pbData,
6084 expected->rgCapability[i].Parameters.cbData),
6085 "%s[%d]: unexpected value\n", header, i);
6089 static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding)
6091 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6092 BOOL ret;
6093 DWORD size = 0;
6094 CRYPT_SMIME_CAPABILITY capability[2];
6095 CRYPT_SMIME_CAPABILITIES capabilities, *ptr;
6097 SetLastError(0xdeadbeef);
6098 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6099 emptySequence, sizeof(emptySequence),
6100 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&ptr, &size);
6101 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6102 if (ret)
6104 capabilities.cCapability = 0;
6105 compareSMimeCapabilities("empty capabilities", &capabilities, ptr);
6106 LocalFree(ptr);
6108 SetLastError(0xdeadbeef);
6109 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6110 singleCapability, sizeof(singleCapability), CRYPT_DECODE_ALLOC_FLAG, NULL,
6111 (BYTE *)&ptr, &size);
6112 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6113 if (ret)
6115 capability[0].pszObjId = oid1;
6116 capability[0].Parameters.cbData = 0;
6117 capabilities.cCapability = 1;
6118 capabilities.rgCapability = capability;
6119 compareSMimeCapabilities("single capability", &capabilities, ptr);
6120 LocalFree(ptr);
6122 SetLastError(0xdeadbeef);
6123 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6124 singleCapabilitywithNULL, sizeof(singleCapabilitywithNULL),
6125 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&ptr, &size);
6126 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6127 if (ret)
6129 BYTE NULLparam[] = {0x05, 0x00};
6130 capability[0].pszObjId = oid1;
6131 capability[0].Parameters.cbData = 2;
6132 capability[0].Parameters.pbData = NULLparam;
6133 capabilities.cCapability = 1;
6134 capabilities.rgCapability = capability;
6135 compareSMimeCapabilities("single capability with NULL", &capabilities,
6136 ptr);
6137 LocalFree(ptr);
6139 SetLastError(0xdeadbeef);
6140 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6141 twoCapabilities, sizeof(twoCapabilities), CRYPT_DECODE_ALLOC_FLAG, NULL,
6142 (BYTE *)&ptr, &size);
6143 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6144 if (ret)
6146 capability[0].Parameters.cbData = 0;
6147 capability[1].pszObjId = oid2;
6148 capability[1].Parameters.cbData = 0;
6149 capabilities.cCapability = 2;
6150 compareSMimeCapabilities("two capabilities", &capabilities, ptr);
6151 LocalFree(ptr);
6155 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
6156 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
6157 0x67 };
6158 static const BYTE minimalPKCSSigner[] = {
6159 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6160 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6161 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6162 static const BYTE PKCSSignerWithSerial[] = {
6163 0x30,0x2c,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,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
6166 0x00 };
6167 static const BYTE PKCSSignerWithHashAlgo[] = {
6168 0x30,0x2e,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,0x04,0x06,0x00,0x05,
6171 0x00,0x04,0x00 };
6172 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = {
6173 0x30,0x30,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,0x00 };
6177 static const BYTE PKCSSignerWithHash[] = {
6178 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6179 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6180 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6181 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
6182 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6183 static const BYTE PKCSSignerWithAuthAttr[] = {
6184 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6185 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6186 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
6187 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
6188 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
6189 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
6190 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6192 static void test_encodePKCSSignerInfo(DWORD dwEncoding)
6194 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6195 BOOL ret;
6196 LPBYTE buf = NULL;
6197 DWORD size = 0;
6198 CMSG_SIGNER_INFO info = { 0 };
6199 char oid_common_name[] = szOID_COMMON_NAME;
6200 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
6201 (LPBYTE)encodedCommonName };
6202 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
6204 SetLastError(0xdeadbeef);
6205 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6206 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6207 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6209 skip("no PKCS7_SIGNER_INFO encode support\n");
6210 return;
6212 ok(!ret && (GetLastError() == E_INVALIDARG ||
6213 GetLastError() == OSS_LIMITED /* Win9x */),
6214 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6215 /* To be encoded, a signer must have an issuer at least, and the encoding
6216 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
6217 * see decoding tests.)
6219 info.Issuer.cbData = sizeof(encodedCommonNameNoNull);
6220 info.Issuer.pbData = encodedCommonNameNoNull;
6221 SetLastError(0xdeadbeef);
6222 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6223 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6224 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6225 ok(!ret && GetLastError() == E_INVALIDARG,
6226 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6227 else
6229 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6230 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6231 if (buf)
6233 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6234 if (size == sizeof(minimalPKCSSigner))
6235 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6236 else
6237 ok(0, "Unexpected value\n");
6238 LocalFree(buf);
6241 info.SerialNumber.cbData = sizeof(serialNum);
6242 info.SerialNumber.pbData = (BYTE *)serialNum;
6243 SetLastError(0xdeadbeef);
6244 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6245 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6246 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6247 ok(!ret && GetLastError() == E_INVALIDARG,
6248 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6249 else
6251 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6252 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6253 if (buf)
6255 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6256 size);
6257 if (size == sizeof(PKCSSignerWithSerial))
6258 ok(!memcmp(buf, PKCSSignerWithSerial, size),
6259 "Unexpected value\n");
6260 else
6261 ok(0, "Unexpected value\n");
6262 LocalFree(buf);
6265 info.HashAlgorithm.pszObjId = oid1;
6266 SetLastError(0xdeadbeef);
6267 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6268 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6269 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6270 ok(!ret && GetLastError() == E_INVALIDARG,
6271 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6272 else
6274 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6275 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6276 if (buf)
6278 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6279 size);
6280 if (size == sizeof(PKCSSignerWithHashAlgo))
6281 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6282 "Unexpected value\n");
6283 else
6284 ok(0, "Unexpected value\n");
6285 LocalFree(buf);
6288 info.HashEncryptionAlgorithm.pszObjId = oid2;
6289 SetLastError(0xdeadbeef);
6290 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6291 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6292 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6293 ok(!ret && GetLastError() == E_INVALIDARG,
6294 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6295 else
6297 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6298 if (buf)
6300 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6301 "Unexpected size %d\n", size);
6302 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo))
6303 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6304 "Unexpected value\n");
6305 else
6306 ok(0, "Unexpected value\n");
6307 LocalFree(buf);
6310 info.EncryptedHash.cbData = sizeof(hash);
6311 info.EncryptedHash.pbData = (BYTE *)hash;
6312 SetLastError(0xdeadbeef);
6313 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6314 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6315 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6316 ok(!ret && GetLastError() == E_INVALIDARG,
6317 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6318 else
6320 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6321 if (buf)
6323 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6324 size);
6325 if (size == sizeof(PKCSSignerWithHash))
6326 ok(!memcmp(buf, PKCSSignerWithHash, size),
6327 "Unexpected value\n");
6328 else
6329 ok(0, "Unexpected value\n");
6330 LocalFree(buf);
6333 info.AuthAttrs.cAttr = 1;
6334 info.AuthAttrs.rgAttr = &attr;
6335 SetLastError(0xdeadbeef);
6336 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6337 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6338 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6339 ok(!ret && GetLastError() == E_INVALIDARG,
6340 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6341 else
6343 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6344 if (buf)
6346 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
6347 size);
6348 if (size == sizeof(PKCSSignerWithAuthAttr))
6349 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
6350 "Unexpected value\n");
6351 else
6352 ok(0, "Unexpected value\n");
6353 LocalFree(buf);
6358 static void test_decodePKCSSignerInfo(DWORD dwEncoding)
6360 BOOL ret;
6361 LPBYTE buf = NULL;
6362 DWORD size = 0;
6363 CMSG_SIGNER_INFO *info;
6365 /* A PKCS signer can't be decoded without a serial number. */
6366 SetLastError(0xdeadbeef);
6367 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6368 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6369 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6370 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
6371 GetLastError() == OSS_DATA_ERROR /* Win9x */),
6372 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %x\n",
6373 GetLastError());
6374 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6375 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6376 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6377 ok(ret || broken(GetLastError() == OSS_DATA_ERROR),
6378 "CryptDecodeObjectEx failed: %x\n", GetLastError());
6379 if (buf)
6381 info = (CMSG_SIGNER_INFO *)buf;
6382 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6383 info->dwVersion);
6384 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6385 "Unexpected size %d\n", info->Issuer.cbData);
6386 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6387 info->Issuer.cbData), "Unexpected value\n");
6388 ok(info->SerialNumber.cbData == sizeof(serialNum),
6389 "Unexpected size %d\n", info->SerialNumber.cbData);
6390 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6391 "Unexpected value\n");
6392 LocalFree(buf);
6394 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6395 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6396 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6397 if (buf)
6399 info = (CMSG_SIGNER_INFO *)buf;
6400 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6401 info->dwVersion);
6402 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6403 "Unexpected size %d\n", info->Issuer.cbData);
6404 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6405 info->Issuer.cbData), "Unexpected value\n");
6406 ok(info->SerialNumber.cbData == sizeof(serialNum),
6407 "Unexpected size %d\n", info->SerialNumber.cbData);
6408 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6409 "Unexpected value\n");
6410 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6411 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6412 LocalFree(buf);
6414 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6415 PKCSSignerWithHashAndEncryptionAlgo,
6416 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6417 NULL, (BYTE *)&buf, &size);
6418 if (buf)
6420 info = (CMSG_SIGNER_INFO *)buf;
6421 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6422 info->dwVersion);
6423 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6424 "Unexpected size %d\n", info->Issuer.cbData);
6425 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6426 info->Issuer.cbData), "Unexpected value\n");
6427 ok(info->SerialNumber.cbData == sizeof(serialNum),
6428 "Unexpected size %d\n", info->SerialNumber.cbData);
6429 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6430 "Unexpected value\n");
6431 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6432 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6433 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6434 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6435 LocalFree(buf);
6437 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6438 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6439 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6440 if (buf)
6442 info = (CMSG_SIGNER_INFO *)buf;
6443 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6444 info->dwVersion);
6445 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6446 "Unexpected size %d\n", info->Issuer.cbData);
6447 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6448 info->Issuer.cbData), "Unexpected value\n");
6449 ok(info->SerialNumber.cbData == sizeof(serialNum),
6450 "Unexpected size %d\n", info->SerialNumber.cbData);
6451 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6452 "Unexpected value\n");
6453 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6454 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6455 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6456 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6457 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6458 info->EncryptedHash.cbData);
6459 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6460 "Unexpected value\n");
6461 LocalFree(buf);
6463 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6464 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
6465 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6466 if (buf)
6468 info = (CMSG_SIGNER_INFO *)buf;
6469 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n",
6470 info->AuthAttrs.cAttr);
6471 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
6472 "Expected %s, got %s\n", szOID_COMMON_NAME,
6473 info->AuthAttrs.rgAttr[0].pszObjId);
6474 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
6475 info->AuthAttrs.rgAttr[0].cValue);
6476 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
6477 sizeof(encodedCommonName), "Unexpected size %d\n",
6478 info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
6479 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
6480 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
6481 LocalFree(buf);
6485 static const BYTE CMSSignerWithKeyId[] = {
6486 0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,
6487 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6489 static void test_encodeCMSSignerInfo(DWORD dwEncoding)
6491 BOOL ret;
6492 LPBYTE buf = NULL;
6493 DWORD size = 0;
6494 CMSG_CMS_SIGNER_INFO info = { 0 };
6495 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6497 SetLastError(0xdeadbeef);
6498 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6499 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6500 ok(!ret, "Expected failure, got %d\n", ret);
6501 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6503 skip("no CMS_SIGNER_INFO encode support\n");
6504 return;
6506 ok(GetLastError() == E_INVALIDARG,
6507 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6508 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6509 SetLastError(0xdeadbeef);
6510 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6511 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6512 ok(!ret, "Expected failure, got %d\n", ret);
6513 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6515 skip("no CMS_SIGNER_INFO encode support\n");
6516 return;
6518 ok(GetLastError() == E_INVALIDARG,
6519 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6520 /* To be encoded, a signer must have a valid cert ID, where a valid ID may
6521 * be a key id or a issuer serial number with at least the issuer set, and
6522 * the encoding must include PKCS_7_ASN_ENCODING.
6523 * (That isn't enough to be decoded, see decoding tests.)
6525 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6526 sizeof(encodedCommonNameNoNull);
6527 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6528 SetLastError(0xdeadbeef);
6529 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6530 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6531 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6532 ok(!ret && GetLastError() == E_INVALIDARG,
6533 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6534 else
6536 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6537 if (buf)
6539 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6540 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6541 LocalFree(buf);
6544 U(info.SignerId).IssuerSerialNumber.SerialNumber.cbData = sizeof(serialNum);
6545 U(info.SignerId).IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
6546 SetLastError(0xdeadbeef);
6547 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6548 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6549 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6550 ok(!ret && GetLastError() == E_INVALIDARG,
6551 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6552 else
6554 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6555 if (buf)
6557 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6558 size);
6559 ok(!memcmp(buf, PKCSSignerWithSerial, size), "Unexpected value\n");
6560 LocalFree(buf);
6563 info.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
6564 U(info.SignerId).KeyId.cbData = sizeof(serialNum);
6565 U(info.SignerId).KeyId.pbData = (BYTE *)serialNum;
6566 SetLastError(0xdeadbeef);
6567 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6568 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6569 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6570 ok(!ret && GetLastError() == E_INVALIDARG,
6571 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6572 else
6574 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6575 if (buf)
6577 ok(size == sizeof(CMSSignerWithKeyId), "Unexpected size %d\n",
6578 size);
6579 ok(!memcmp(buf, CMSSignerWithKeyId, size), "Unexpected value\n");
6580 LocalFree(buf);
6583 /* While a CERT_ID can have a hash type, that's not allowed in CMS, where
6584 * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed
6585 * (see RFC 3852, section 5.3.)
6587 info.SignerId.dwIdChoice = CERT_ID_SHA1_HASH;
6588 U(info.SignerId).HashId.cbData = sizeof(hash);
6589 U(info.SignerId).HashId.pbData = (BYTE *)hash;
6590 SetLastError(0xdeadbeef);
6591 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6592 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6593 ok(!ret && GetLastError() == E_INVALIDARG,
6594 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6595 /* Now with a hash algo */
6596 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6597 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6598 sizeof(encodedCommonNameNoNull);
6599 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6600 info.HashAlgorithm.pszObjId = oid1;
6601 SetLastError(0xdeadbeef);
6602 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6603 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6604 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6605 ok(!ret && GetLastError() == E_INVALIDARG,
6606 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6607 else
6609 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6610 if (buf)
6612 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6613 size);
6614 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6615 "Unexpected value\n");
6616 LocalFree(buf);
6619 info.HashEncryptionAlgorithm.pszObjId = oid2;
6620 SetLastError(0xdeadbeef);
6621 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6622 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6623 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6624 ok(!ret && GetLastError() == E_INVALIDARG,
6625 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6626 else
6628 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6629 if (buf)
6631 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6632 "Unexpected size %d\n", size);
6633 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6634 "Unexpected value\n");
6635 LocalFree(buf);
6638 info.EncryptedHash.cbData = sizeof(hash);
6639 info.EncryptedHash.pbData = (BYTE *)hash;
6640 SetLastError(0xdeadbeef);
6641 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6642 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6643 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6644 ok(!ret && GetLastError() == E_INVALIDARG,
6645 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6646 else
6648 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6649 if (buf)
6651 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6652 size);
6653 ok(!memcmp(buf, PKCSSignerWithHash, size), "Unexpected value\n");
6654 LocalFree(buf);
6659 static void test_decodeCMSSignerInfo(DWORD dwEncoding)
6661 BOOL ret;
6662 LPBYTE buf = NULL;
6663 DWORD size = 0;
6664 CMSG_CMS_SIGNER_INFO *info;
6665 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6667 /* A CMS signer can't be decoded without a serial number. */
6668 SetLastError(0xdeadbeef);
6669 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6670 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6671 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6672 ok(!ret, "expected failure\n");
6673 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6675 skip("no CMS_SIGNER_INFO decode support\n");
6676 return;
6678 ok(GetLastError() == CRYPT_E_ASN1_CORRUPT,
6679 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
6680 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6681 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6682 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6683 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6684 if (buf)
6686 info = (CMSG_CMS_SIGNER_INFO *)buf;
6687 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6688 info->dwVersion);
6689 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6690 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6691 info->SignerId.dwIdChoice);
6692 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6693 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6694 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6695 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6696 encodedCommonNameNoNull,
6697 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6698 "Unexpected value\n");
6699 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6700 sizeof(serialNum), "Unexpected size %d\n",
6701 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6702 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6703 serialNum, sizeof(serialNum)), "Unexpected value\n");
6704 LocalFree(buf);
6706 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6707 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6708 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6709 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6710 if (buf)
6712 info = (CMSG_CMS_SIGNER_INFO *)buf;
6713 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6714 info->dwVersion);
6715 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6716 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6717 info->SignerId.dwIdChoice);
6718 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6719 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6720 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6721 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6722 encodedCommonNameNoNull,
6723 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6724 "Unexpected value\n");
6725 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6726 sizeof(serialNum), "Unexpected size %d\n",
6727 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6728 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6729 serialNum, sizeof(serialNum)), "Unexpected value\n");
6730 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6731 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6732 LocalFree(buf);
6734 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6735 PKCSSignerWithHashAndEncryptionAlgo,
6736 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6737 NULL, (BYTE *)&buf, &size);
6738 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6739 if (buf)
6741 info = (CMSG_CMS_SIGNER_INFO *)buf;
6742 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6743 info->dwVersion);
6744 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6745 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6746 info->SignerId.dwIdChoice);
6747 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6748 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6749 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6750 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6751 encodedCommonNameNoNull,
6752 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6753 "Unexpected value\n");
6754 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6755 sizeof(serialNum), "Unexpected size %d\n",
6756 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6757 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6758 serialNum, sizeof(serialNum)), "Unexpected value\n");
6759 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6760 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6761 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6762 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6763 LocalFree(buf);
6765 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6766 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6767 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6768 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6769 if (buf)
6771 info = (CMSG_CMS_SIGNER_INFO *)buf;
6772 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6773 info->dwVersion);
6774 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6775 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6776 info->SignerId.dwIdChoice);
6777 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6778 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6779 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6780 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6781 encodedCommonNameNoNull,
6782 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6783 "Unexpected value\n");
6784 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6785 sizeof(serialNum), "Unexpected size %d\n",
6786 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6787 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6788 serialNum, sizeof(serialNum)), "Unexpected value\n");
6789 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6790 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6791 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6792 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6793 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6794 info->EncryptedHash.cbData);
6795 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6796 "Unexpected value\n");
6797 LocalFree(buf);
6799 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6800 CMSSignerWithKeyId, sizeof(CMSSignerWithKeyId),
6801 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6802 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6803 if (buf)
6805 info = (CMSG_CMS_SIGNER_INFO *)buf;
6806 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6807 info->dwVersion);
6808 ok(info->SignerId.dwIdChoice == CERT_ID_KEY_IDENTIFIER,
6809 "Expected CERT_ID_KEY_IDENTIFIER, got %d\n",
6810 info->SignerId.dwIdChoice);
6811 ok(U(info->SignerId).KeyId.cbData == sizeof(serialNum),
6812 "Unexpected size %d\n", U(info->SignerId).KeyId.cbData);
6813 ok(!memcmp(U(info->SignerId).KeyId.pbData, serialNum, sizeof(serialNum)),
6814 "Unexpected value\n");
6815 LocalFree(buf);
6819 static BYTE emptyDNSPermittedConstraints[] = {
6820 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
6821 static BYTE emptyDNSExcludedConstraints[] = {
6822 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
6823 static BYTE DNSExcludedConstraints[] = {
6824 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
6825 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6826 static BYTE permittedAndExcludedConstraints[] = {
6827 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6828 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
6829 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6830 static BYTE permittedAndExcludedWithMinConstraints[] = {
6831 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6832 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
6833 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6834 static BYTE permittedAndExcludedWithMinMaxConstraints[] = {
6835 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6836 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
6837 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6839 static void test_encodeNameConstraints(DWORD dwEncoding)
6841 BOOL ret;
6842 CERT_NAME_CONSTRAINTS_INFO constraints = { 0 };
6843 CERT_GENERAL_SUBTREE permitted = { { 0 } };
6844 CERT_GENERAL_SUBTREE excluded = { { 0 } };
6845 LPBYTE buf;
6846 DWORD size;
6848 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6849 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6850 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6852 skip("no X509_NAME_CONSTRAINTS encode support\n");
6853 return;
6855 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6856 if (ret)
6858 ok(size == sizeof(emptySequence), "Unexpected size\n");
6859 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
6860 LocalFree(buf);
6862 constraints.cPermittedSubtree = 1;
6863 constraints.rgPermittedSubtree = &permitted;
6864 SetLastError(0xdeadbeef);
6865 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6866 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6867 ok(!ret && GetLastError() == E_INVALIDARG,
6868 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6869 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
6870 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6871 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6872 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6873 if (ret)
6875 ok(size == sizeof(emptyDNSPermittedConstraints), "Unexpected size\n");
6876 ok(!memcmp(buf, emptyDNSPermittedConstraints, size),
6877 "Unexpected value\n");
6878 LocalFree(buf);
6880 constraints.cPermittedSubtree = 0;
6881 constraints.cExcludedSubtree = 1;
6882 constraints.rgExcludedSubtree = &excluded;
6883 excluded.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
6884 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6885 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6886 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6887 if (ret)
6889 ok(size == sizeof(emptyDNSExcludedConstraints), "Unexpected size\n");
6890 ok(!memcmp(buf, emptyDNSExcludedConstraints, size),
6891 "Unexpected value\n");
6892 LocalFree(buf);
6894 U(excluded.Base).pwszURL = (LPWSTR)url;
6895 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6896 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6897 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6898 if (ret)
6900 ok(size == sizeof(DNSExcludedConstraints), "Unexpected size\n");
6901 ok(!memcmp(buf, DNSExcludedConstraints, size),
6902 "Unexpected value\n");
6903 LocalFree(buf);
6905 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
6906 U(permitted.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6907 U(permitted.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6908 constraints.cPermittedSubtree = 1;
6909 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6910 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6911 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6912 if (ret)
6914 ok(size == sizeof(permittedAndExcludedConstraints),
6915 "Unexpected size\n");
6916 ok(!memcmp(buf, permittedAndExcludedConstraints, size),
6917 "Unexpected value\n");
6918 LocalFree(buf);
6920 permitted.dwMinimum = 5;
6921 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6922 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6923 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6924 if (ret)
6926 ok(size == sizeof(permittedAndExcludedWithMinConstraints),
6927 "Unexpected size\n");
6928 ok(!memcmp(buf, permittedAndExcludedWithMinConstraints, size),
6929 "Unexpected value\n");
6930 LocalFree(buf);
6932 permitted.fMaximum = TRUE;
6933 permitted.dwMaximum = 3;
6934 SetLastError(0xdeadbeef);
6935 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6936 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6937 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6938 if (ret)
6940 ok(size == sizeof(permittedAndExcludedWithMinMaxConstraints),
6941 "Unexpected size\n");
6942 ok(!memcmp(buf, permittedAndExcludedWithMinMaxConstraints, size),
6943 "Unexpected value\n");
6944 LocalFree(buf);
6948 struct EncodedNameConstraints
6950 CRYPT_DATA_BLOB encoded;
6951 CERT_NAME_CONSTRAINTS_INFO constraints;
6954 static CERT_GENERAL_SUBTREE emptyDNSSubtree = {
6955 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
6956 static CERT_GENERAL_SUBTREE DNSSubtree = {
6957 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
6958 static CERT_GENERAL_SUBTREE IPAddressSubtree = {
6959 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 0 };
6960 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree = {
6961 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, 0 };
6962 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree = {
6963 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, TRUE, 3 };
6965 struct EncodedNameConstraints encodedNameConstraints[] = {
6966 { { sizeof(emptySequence), (LPBYTE)emptySequence }, { 0 } },
6967 { { sizeof(emptyDNSPermittedConstraints), emptyDNSPermittedConstraints },
6968 { 1, &emptyDNSSubtree, 0, NULL } },
6969 { { sizeof(emptyDNSExcludedConstraints), emptyDNSExcludedConstraints },
6970 { 0, NULL, 1, &emptyDNSSubtree } },
6971 { { sizeof(DNSExcludedConstraints), DNSExcludedConstraints },
6972 { 0, NULL, 1, &DNSSubtree } },
6973 { { sizeof(permittedAndExcludedConstraints), permittedAndExcludedConstraints },
6974 { 1, &IPAddressSubtree, 1, &DNSSubtree } },
6975 { { sizeof(permittedAndExcludedWithMinConstraints),
6976 permittedAndExcludedWithMinConstraints },
6977 { 1, &IPAddressWithMinSubtree, 1, &DNSSubtree } },
6978 { { sizeof(permittedAndExcludedWithMinMaxConstraints),
6979 permittedAndExcludedWithMinMaxConstraints },
6980 { 1, &IPAddressWithMinMaxSubtree, 1, &DNSSubtree } },
6983 static void test_decodeNameConstraints(DWORD dwEncoding)
6985 BOOL ret;
6986 DWORD i;
6987 CERT_NAME_CONSTRAINTS_INFO *constraints;
6989 U(DNSSubtree.Base).pwszURL = (LPWSTR)url;
6990 U(IPAddressSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6991 U(IPAddressSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6992 U(IPAddressWithMinSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6993 U(IPAddressWithMinSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6994 U(IPAddressWithMinMaxSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6995 U(IPAddressWithMinMaxSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6996 for (i = 0;
6997 i < sizeof(encodedNameConstraints) / sizeof(encodedNameConstraints[0]);
6998 i++)
7000 DWORD size;
7002 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS,
7003 encodedNameConstraints[i].encoded.pbData,
7004 encodedNameConstraints[i].encoded.cbData,
7005 CRYPT_DECODE_ALLOC_FLAG, NULL, &constraints, &size);
7006 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7008 skip("no X509_NAME_CONSTRAINTS decode support\n");
7009 return;
7011 ok(ret, "%d: CryptDecodeObjectEx failed: %08x\n", i, GetLastError());
7012 if (ret)
7014 DWORD j;
7016 if (constraints->cPermittedSubtree !=
7017 encodedNameConstraints[i].constraints.cPermittedSubtree)
7018 fprintf(stderr, "%d: expected %d permitted, got %d\n", i,
7019 encodedNameConstraints[i].constraints.cPermittedSubtree,
7020 constraints->cPermittedSubtree);
7021 if (constraints->cPermittedSubtree ==
7022 encodedNameConstraints[i].constraints.cPermittedSubtree)
7024 for (j = 0; j < constraints->cPermittedSubtree; j++)
7026 compareAltNameEntry(&constraints->rgPermittedSubtree[j].Base,
7027 &encodedNameConstraints[i].constraints.rgPermittedSubtree[j].Base);
7030 if (constraints->cExcludedSubtree !=
7031 encodedNameConstraints[i].constraints.cExcludedSubtree)
7032 fprintf(stderr, "%d: expected %d excluded, got %d\n", i,
7033 encodedNameConstraints[i].constraints.cExcludedSubtree,
7034 constraints->cExcludedSubtree);
7035 if (constraints->cExcludedSubtree ==
7036 encodedNameConstraints[i].constraints.cExcludedSubtree)
7038 for (j = 0; j < constraints->cExcludedSubtree; j++)
7040 compareAltNameEntry(&constraints->rgExcludedSubtree[j].Base,
7041 &encodedNameConstraints[i].constraints.rgExcludedSubtree[j].Base);
7044 LocalFree(constraints);
7049 static WCHAR noticeText[] = { 'T','h','i','s',' ','i','s',' ','a',' ',
7050 'n','o','t','i','c','e',0 };
7051 static const BYTE noticeWithDisplayText[] = {
7052 0x30,0x22,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,0x00,
7053 0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,0x74,
7054 0x00,0x69,0x00,0x63,0x00,0x65
7056 static char org[] = "Wine";
7057 static int noticeNumbers[] = { 2,3 };
7058 static BYTE noticeWithReference[] = {
7059 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7060 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7061 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7062 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7065 static void test_encodePolicyQualifierUserNotice(DWORD dwEncoding)
7067 BOOL ret;
7068 LPBYTE buf;
7069 DWORD size;
7070 CERT_POLICY_QUALIFIER_USER_NOTICE notice;
7071 CERT_POLICY_QUALIFIER_NOTICE_REFERENCE reference;
7073 memset(&notice, 0, sizeof(notice));
7074 ret = pCryptEncodeObjectEx(dwEncoding,
7075 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, &notice, CRYPT_ENCODE_ALLOC_FLAG,
7076 NULL, &buf, &size);
7077 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7079 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE encode support\n");
7080 return;
7082 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7083 if (ret)
7085 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size);
7086 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
7087 LocalFree(buf);
7089 notice.pszDisplayText = noticeText;
7090 ret = pCryptEncodeObjectEx(dwEncoding,
7091 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, &notice, CRYPT_ENCODE_ALLOC_FLAG,
7092 NULL, &buf, &size);
7093 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7094 if (ret)
7096 ok(sizeof(noticeWithDisplayText) == size, "unexpected size %d\n", size);
7097 ok(!memcmp(buf, noticeWithDisplayText, size), "unexpected value\n");
7098 LocalFree(buf);
7100 reference.pszOrganization = org;
7101 reference.cNoticeNumbers = 2;
7102 reference.rgNoticeNumbers = noticeNumbers;
7103 notice.pNoticeReference = &reference;
7104 ret = pCryptEncodeObjectEx(dwEncoding,
7105 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, &notice, CRYPT_ENCODE_ALLOC_FLAG,
7106 NULL, &buf, &size);
7107 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7108 if (ret)
7110 ok(sizeof(noticeWithReference) == size, "unexpected size %d\n", size);
7111 ok(!memcmp(buf, noticeWithReference, size), "unexpected value\n");
7112 LocalFree(buf);
7116 static void test_decodePolicyQualifierUserNotice(DWORD dwEncoding)
7118 BOOL ret;
7119 CERT_POLICY_QUALIFIER_USER_NOTICE *notice;
7120 DWORD size;
7122 ret = pCryptDecodeObjectEx(dwEncoding,
7123 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7124 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7125 &notice, &size);
7126 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7128 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE decode support\n");
7129 return;
7131 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7132 if (ret)
7134 ok(notice->pszDisplayText == NULL, "unexpected display text\n");
7135 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7136 LocalFree(notice);
7138 ret = pCryptDecodeObjectEx(dwEncoding,
7139 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7140 noticeWithDisplayText, sizeof(noticeWithDisplayText),
7141 CRYPT_DECODE_ALLOC_FLAG, NULL, &notice, &size);
7142 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7143 if (ret)
7145 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7146 "unexpected display text\n");
7147 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7148 LocalFree(notice);
7150 ret = pCryptDecodeObjectEx(dwEncoding,
7151 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7152 noticeWithReference, sizeof(noticeWithReference),
7153 CRYPT_DECODE_ALLOC_FLAG, NULL, &notice, &size);
7154 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7155 if (ret)
7157 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7158 "unexpected display text\n");
7159 ok(notice->pNoticeReference != NULL, "expected a notice reference\n");
7160 if (notice->pNoticeReference)
7162 ok(!strcmp(notice->pNoticeReference->pszOrganization, org),
7163 "unexpected organization %s\n",
7164 notice->pNoticeReference->pszOrganization);
7165 ok(notice->pNoticeReference->cNoticeNumbers == 2,
7166 "expected 2 notice numbers, got %d\n",
7167 notice->pNoticeReference->cNoticeNumbers);
7168 ok(notice->pNoticeReference->rgNoticeNumbers[0] == noticeNumbers[0],
7169 "unexpected notice number %d\n",
7170 notice->pNoticeReference->rgNoticeNumbers[0]);
7171 ok(notice->pNoticeReference->rgNoticeNumbers[1] == noticeNumbers[1],
7172 "unexpected notice number %d\n",
7173 notice->pNoticeReference->rgNoticeNumbers[1]);
7175 LocalFree(notice);
7179 static char oid_any_policy[] = "2.5.29.32.0";
7180 static const BYTE policiesWithAnyPolicy[] = {
7181 0x30,0x08,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00
7183 static char oid1[] = "1.2.3";
7184 static char oid_user_notice[] = "1.3.6.1.5.5.7.2.2";
7185 static const BYTE twoPolicies[] = {
7186 0x30,0x50,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00,0x30,0x46,0x06,0x02,0x2a,
7187 0x03,0x30,0x40,0x30,0x3e,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x02,
7188 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7189 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7190 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7191 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7194 static void test_encodeCertPolicies(DWORD dwEncoding)
7196 BOOL ret;
7197 CERT_POLICIES_INFO info;
7198 CERT_POLICY_INFO policy[2];
7199 CERT_POLICY_QUALIFIER_INFO qualifier;
7200 LPBYTE buf;
7201 DWORD size;
7203 memset(&info, 0, sizeof(info));
7204 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7205 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7206 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7207 if (ret)
7209 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size);
7210 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
7211 LocalFree(buf);
7213 memset(policy, 0, sizeof(policy));
7214 info.cPolicyInfo = 1;
7215 info.rgPolicyInfo = policy;
7216 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7217 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7218 ok(!ret && (GetLastError() == E_INVALIDARG ||
7219 GetLastError() == OSS_LIMITED /* Win9x/NT4 */),
7220 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
7221 policy[0].pszPolicyIdentifier = oid_any_policy;
7222 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7223 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7224 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7225 if (ret)
7227 ok(sizeof(policiesWithAnyPolicy) == size, "unexpected size %d\n", size);
7228 ok(!memcmp(buf, policiesWithAnyPolicy, size), "unexpected value\n");
7229 LocalFree(buf);
7231 policy[1].pszPolicyIdentifier = oid1;
7232 memset(&qualifier, 0, sizeof(qualifier));
7233 qualifier.pszPolicyQualifierId = oid_user_notice;
7234 qualifier.Qualifier.cbData = sizeof(noticeWithReference);
7235 qualifier.Qualifier.pbData = noticeWithReference;
7236 policy[1].cPolicyQualifier = 1;
7237 policy[1].rgPolicyQualifier = &qualifier;
7238 info.cPolicyInfo = 2;
7239 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7240 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7241 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7242 if (ret)
7244 ok(sizeof(twoPolicies) == size, "unexpected size %d\n", size);
7245 ok(!memcmp(buf, twoPolicies, size), "unexpected value\n");
7246 LocalFree(buf);
7250 static void test_decodeCertPolicies(DWORD dwEncoding)
7252 BOOL ret;
7253 CERT_POLICIES_INFO *info;
7254 DWORD size;
7256 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7257 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7258 &info, &size);
7259 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7260 if (ret)
7262 ok(info->cPolicyInfo == 0, "unexpected policy info %d\n",
7263 info->cPolicyInfo);
7264 LocalFree(info);
7266 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7267 policiesWithAnyPolicy, sizeof(policiesWithAnyPolicy),
7268 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7269 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7270 if (ret)
7272 ok(info->cPolicyInfo == 1, "unexpected policy info %d\n",
7273 info->cPolicyInfo);
7274 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy),
7275 "unexpected policy id %s\n",
7276 info->rgPolicyInfo[0].pszPolicyIdentifier);
7277 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0,
7278 "unexpected policy qualifier count %d\n",
7279 info->rgPolicyInfo[0].cPolicyQualifier);
7280 LocalFree(info);
7282 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7283 twoPolicies, sizeof(twoPolicies),
7284 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7285 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7286 if (ret)
7288 ok(info->cPolicyInfo == 2, "unexpected policy info %d\n",
7289 info->cPolicyInfo);
7290 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy),
7291 "unexpected policy id %s\n",
7292 info->rgPolicyInfo[0].pszPolicyIdentifier);
7293 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0,
7294 "unexpected policy qualifier count %d\n",
7295 info->rgPolicyInfo[0].cPolicyQualifier);
7296 ok(!strcmp(info->rgPolicyInfo[1].pszPolicyIdentifier, oid1),
7297 "unexpected policy id %s\n",
7298 info->rgPolicyInfo[1].pszPolicyIdentifier);
7299 ok(info->rgPolicyInfo[1].cPolicyQualifier == 1,
7300 "unexpected policy qualifier count %d\n",
7301 info->rgPolicyInfo[1].cPolicyQualifier);
7302 ok(!strcmp(
7303 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId,
7304 oid_user_notice), "unexpected policy qualifier id %s\n",
7305 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId);
7306 ok(info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData ==
7307 sizeof(noticeWithReference), "unexpected qualifier size %d\n",
7308 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData);
7309 ok(!memcmp(
7310 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.pbData,
7311 noticeWithReference, sizeof(noticeWithReference)),
7312 "unexpected qualifier value\n");
7313 LocalFree(info);
7317 /* Free *pInfo with HeapFree */
7318 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
7320 BOOL ret;
7321 DWORD size = 0;
7322 HCRYPTKEY key;
7324 /* This crashes
7325 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
7327 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size);
7328 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7329 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7330 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL,
7331 &size);
7332 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7333 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7334 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL,
7335 NULL, &size);
7336 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7337 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7338 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7339 0, NULL, NULL, &size);
7340 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7341 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7342 /* Test with no key */
7343 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7344 0, NULL, NULL, &size);
7345 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n",
7346 GetLastError());
7347 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
7348 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
7349 if (ret)
7351 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
7352 NULL, 0, NULL, NULL, &size);
7353 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
7354 *pInfo = HeapAlloc(GetProcessHeap(), 0, size);
7355 if (*pInfo)
7357 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
7358 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size);
7359 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n",
7360 GetLastError());
7361 if (ret)
7363 /* By default (we passed NULL as the OID) the OID is
7364 * szOID_RSA_RSA.
7366 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA),
7367 "Expected %s, got %s\n", szOID_RSA_RSA,
7368 (*pInfo)->Algorithm.pszObjId);
7372 CryptDestroyKey(key);
7375 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
7376 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
7377 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
7378 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 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, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
7382 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
7383 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7384 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7385 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7386 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
7387 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
7388 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
7389 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
7390 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
7391 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
7392 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
7393 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
7394 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
7395 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
7396 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
7397 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
7398 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
7399 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
7401 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info)
7403 BOOL ret;
7404 HCRYPTKEY key;
7405 PCCERT_CONTEXT context;
7406 DWORD dwSize;
7407 ALG_ID ai;
7409 /* These crash
7410 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
7411 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
7412 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
7413 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7414 NULL);
7416 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key);
7417 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7418 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7419 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key);
7420 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7421 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7422 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL,
7423 &key);
7424 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7425 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7427 /* Export key with standard algorithm (CALG_RSA_KEYX) */
7428 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7429 &key);
7430 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7432 dwSize = sizeof(ai);
7433 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7434 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7435 if(ret)
7437 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7438 ok(ai == CALG_RSA_KEYX, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai);
7441 CryptDestroyKey(key);
7443 /* Repeat with forced algorithm */
7444 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, CALG_RSA_SIGN, 0, NULL,
7445 &key);
7446 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7448 dwSize = sizeof(ai);
7449 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7450 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7451 if(ret)
7453 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7454 ok(ai == CALG_RSA_SIGN, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai);
7457 CryptDestroyKey(key);
7459 /* Test importing a public key from a certificate context */
7460 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert,
7461 sizeof(expiredCert));
7462 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
7463 GetLastError());
7464 if (context)
7466 ok(!strcmp(szOID_RSA_RSA,
7467 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId),
7468 "Expected %s, got %s\n", szOID_RSA_RSA,
7469 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
7470 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING,
7471 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
7472 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7473 CryptDestroyKey(key);
7474 CertFreeCertificateContext(context);
7478 static const char cspName[] = "WineCryptTemp";
7480 static void testPortPublicKeyInfo(void)
7482 HCRYPTPROV csp;
7483 BOOL ret;
7484 PCERT_PUBLIC_KEY_INFO info = NULL;
7486 /* Just in case a previous run failed, delete this thing */
7487 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7488 CRYPT_DELETEKEYSET);
7489 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7490 CRYPT_NEWKEYSET);
7492 testExportPublicKey(csp, &info);
7493 testImportPublicKey(csp, info);
7495 HeapFree(GetProcessHeap(), 0, info);
7496 CryptReleaseContext(csp, 0);
7497 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7498 CRYPT_DELETEKEYSET);
7501 START_TEST(encode)
7503 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
7504 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING };
7505 HMODULE hCrypt32;
7506 DWORD i;
7508 hCrypt32 = GetModuleHandleA("crypt32.dll");
7509 pCryptDecodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptDecodeObjectEx");
7510 pCryptEncodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptEncodeObjectEx");
7511 if (!pCryptDecodeObjectEx || !pCryptEncodeObjectEx)
7513 skip("CryptDecodeObjectEx() is not available\n");
7514 return;
7517 for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++)
7519 test_encodeInt(encodings[i]);
7520 test_decodeInt(encodings[i]);
7521 test_encodeEnumerated(encodings[i]);
7522 test_decodeEnumerated(encodings[i]);
7523 test_encodeFiletime(encodings[i]);
7524 test_decodeFiletime(encodings[i]);
7525 test_encodeName(encodings[i]);
7526 test_decodeName(encodings[i]);
7527 test_encodeUnicodeName(encodings[i]);
7528 test_decodeUnicodeName(encodings[i]);
7529 test_encodeNameValue(encodings[i]);
7530 test_decodeNameValue(encodings[i]);
7531 test_encodeUnicodeNameValue(encodings[i]);
7532 test_decodeUnicodeNameValue(encodings[i]);
7533 test_encodeAltName(encodings[i]);
7534 test_decodeAltName(encodings[i]);
7535 test_encodeOctets(encodings[i]);
7536 test_decodeOctets(encodings[i]);
7537 test_encodeBits(encodings[i]);
7538 test_decodeBits(encodings[i]);
7539 test_encodeBasicConstraints(encodings[i]);
7540 test_decodeBasicConstraints(encodings[i]);
7541 test_encodeRsaPublicKey(encodings[i]);
7542 test_decodeRsaPublicKey(encodings[i]);
7543 test_encodeSequenceOfAny(encodings[i]);
7544 test_decodeSequenceOfAny(encodings[i]);
7545 test_encodeExtensions(encodings[i]);
7546 test_decodeExtensions(encodings[i]);
7547 test_encodePublicKeyInfo(encodings[i]);
7548 test_decodePublicKeyInfo(encodings[i]);
7549 test_encodeCertToBeSigned(encodings[i]);
7550 test_decodeCertToBeSigned(encodings[i]);
7551 test_encodeCert(encodings[i]);
7552 test_decodeCert(encodings[i]);
7553 test_encodeCRLDistPoints(encodings[i]);
7554 test_decodeCRLDistPoints(encodings[i]);
7555 test_encodeCRLIssuingDistPoint(encodings[i]);
7556 test_decodeCRLIssuingDistPoint(encodings[i]);
7557 test_encodeCRLToBeSigned(encodings[i]);
7558 test_decodeCRLToBeSigned(encodings[i]);
7559 test_encodeEnhancedKeyUsage(encodings[i]);
7560 test_decodeEnhancedKeyUsage(encodings[i]);
7561 test_encodeAuthorityKeyId(encodings[i]);
7562 test_decodeAuthorityKeyId(encodings[i]);
7563 test_encodeAuthorityKeyId2(encodings[i]);
7564 test_decodeAuthorityKeyId2(encodings[i]);
7565 test_encodeAuthorityInfoAccess(encodings[i]);
7566 test_decodeAuthorityInfoAccess(encodings[i]);
7567 test_encodeCTL(encodings[i]);
7568 test_decodeCTL(encodings[i]);
7569 test_encodePKCSContentInfo(encodings[i]);
7570 test_decodePKCSContentInfo(encodings[i]);
7571 test_encodePKCSAttribute(encodings[i]);
7572 test_decodePKCSAttribute(encodings[i]);
7573 test_encodePKCSAttributes(encodings[i]);
7574 test_decodePKCSAttributes(encodings[i]);
7575 test_encodePKCSSMimeCapabilities(encodings[i]);
7576 test_decodePKCSSMimeCapabilities(encodings[i]);
7577 test_encodePKCSSignerInfo(encodings[i]);
7578 test_decodePKCSSignerInfo(encodings[i]);
7579 test_encodeCMSSignerInfo(encodings[i]);
7580 test_decodeCMSSignerInfo(encodings[i]);
7581 test_encodeNameConstraints(encodings[i]);
7582 test_decodeNameConstraints(encodings[i]);
7583 test_encodePolicyQualifierUserNotice(encodings[i]);
7584 test_decodePolicyQualifierUserNotice(encodings[i]);
7585 test_encodeCertPolicies(encodings[i]);
7586 test_decodeCertPolicies(encodings[i]);
7588 testPortPublicKeyInfo();