push b25f14be0dd3305724e1f1ef337bfe2a9ff59832
[wine/hacks.git] / dlls / crypt32 / tests / encode.c
blob108df0dc6c5f5a251c5ccd0b0a51cd14ad00824c
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 "Expected CRYPT_E_BAD_ENCODE, got 0x%08x\n", GetLastError());
476 static const char *printSystemTime(const SYSTEMTIME *st)
478 static char buf[25];
480 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st->wMonth, st->wDay,
481 st->wYear, st->wHour, st->wMinute, st->wSecond, st->wMilliseconds);
482 return buf;
485 static const char *printFileTime(const FILETIME *ft)
487 static char buf[25];
488 SYSTEMTIME st;
490 FileTimeToSystemTime(ft, &st);
491 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st.wMonth, st.wDay,
492 st.wYear, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
493 return buf;
496 static void compareTime(const SYSTEMTIME *expected, const FILETIME *got)
498 SYSTEMTIME st;
500 FileTimeToSystemTime(got, &st);
501 ok(expected->wYear == st.wYear &&
502 expected->wMonth == st.wMonth &&
503 expected->wDay == st.wDay &&
504 expected->wHour == st.wHour &&
505 expected->wMinute == st.wMinute &&
506 expected->wSecond == st.wSecond &&
507 abs(expected->wMilliseconds - st.wMilliseconds) <= 1,
508 "Got unexpected value for time decoding:\nexpected %s, got %s\n",
509 printSystemTime(expected), printFileTime(got));
512 static void testTimeDecoding(DWORD dwEncoding, LPCSTR structType,
513 const struct encodedFiletime *time)
515 FILETIME ft = { 0 };
516 DWORD size = sizeof(ft);
517 BOOL ret;
519 ret = pCryptDecodeObjectEx(dwEncoding, structType, time->encodedTime,
520 time->encodedTime[1] + 2, 0, NULL, &ft, &size);
521 /* years other than 1950-2050 are not allowed for encodings other than
522 * X509_CHOICE_OF_TIME.
524 if (structType == X509_CHOICE_OF_TIME ||
525 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050))
527 ok(ret, "CryptDecodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
528 GetLastError());
529 compareTime(&time->sysTime, &ft);
531 else
532 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
533 GetLastError() == OSS_PDU_MISMATCH /* Win9x */ ),
534 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %08x\n",
535 GetLastError());
538 static const BYTE bin20[] = {
539 0x17,0x0d,'0','5','0','6','0','6','1','6','1','0','0','0','Z'};
540 static const BYTE bin21[] = {
541 0x18,0x0f,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
542 static const BYTE bin22[] = {
543 0x18,0x0f,'2','1','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
545 static const struct encodedFiletime times[] = {
546 { { 2005, 6, 1, 6, 16, 10, 0, 0 }, bin20 },
547 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin21 },
548 { { 2145, 6, 1, 6, 16, 10, 0, 0 }, bin22 },
551 static void test_encodeFiletime(DWORD dwEncoding)
553 DWORD i;
555 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
557 testTimeEncoding(dwEncoding, X509_CHOICE_OF_TIME, &times[i]);
558 testTimeEncoding(dwEncoding, PKCS_UTC_TIME, &times[i]);
559 testTimeEncoding(dwEncoding, szOID_RSA_signingTime, &times[i]);
563 static const BYTE bin23[] = {
564 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','0','0','0','Z'};
565 static const BYTE bin24[] = {
566 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','9','9','9','Z'};
567 static const BYTE bin25[] = {
568 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','+','0','1','0','0'};
569 static const BYTE bin26[] = {
570 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','0','0'};
571 static const BYTE bin27[] = {
572 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','1','5'};
573 static const BYTE bin28[] = {
574 0x18,0x0a,'2','1','4','5','0','6','0','6','1','6'};
575 static const BYTE bin29[] = {
576 0x17,0x0a,'4','5','0','6','0','6','1','6','1','0'};
577 static const BYTE bin30[] = {
578 0x17,0x0b,'4','5','0','6','0','6','1','6','1','0','Z'};
579 static const BYTE bin31[] = {
580 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','+','0','1'};
581 static const BYTE bin32[] = {
582 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','-','0','1'};
583 static const BYTE bin33[] = {
584 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','+','0','1','0','0'};
585 static const BYTE bin34[] = {
586 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','-','0','1','0','0'};
587 static const BYTE bin35[] = {
588 0x17,0x08, '4','5','0','6','0','6','1','6'};
589 static const BYTE bin36[] = {
590 0x18,0x0f, 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','Z'};
591 static const BYTE bin37[] = {
592 0x18,0x04, '2','1','4','5'};
593 static const BYTE bin38[] = {
594 0x18,0x08, '2','1','4','5','0','6','0','6'};
596 static void test_decodeFiletime(DWORD dwEncoding)
598 static const struct encodedFiletime otherTimes[] = {
599 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin23 },
600 { { 1945, 6, 1, 6, 16, 10, 0, 999 }, bin24 },
601 { { 1945, 6, 1, 6, 17, 10, 0, 0 }, bin25 },
602 { { 1945, 6, 1, 6, 15, 10, 0, 0 }, bin26 },
603 { { 1945, 6, 1, 6, 14, 55, 0, 0 }, bin27 },
604 { { 2145, 6, 1, 6, 16, 0, 0, 0 }, bin28 },
605 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin29 },
606 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin30 },
607 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin31 },
608 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin32 },
609 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin33 },
610 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin34 },
612 /* An oddball case that succeeds in Windows, but doesn't seem correct
613 { { 2145, 6, 1, 2, 11, 31, 0, 0 }, "\x18" "\x13" "21450606161000-9999" },
615 static const unsigned char *bogusTimes[] = {
616 /* oddly, this succeeds on Windows, with year 2765
617 "\x18" "\x0f" "21r50606161000Z",
619 bin35,
620 bin36,
621 bin37,
622 bin38,
624 DWORD i, size;
625 FILETIME ft1 = { 0 }, ft2 = { 0 };
626 BOOL ret;
628 /* Check bogus length with non-NULL buffer */
629 ret = SystemTimeToFileTime(&times[0].sysTime, &ft1);
630 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
631 size = 1;
632 ret = pCryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
633 times[0].encodedTime, times[0].encodedTime[1] + 2, 0, NULL, &ft2, &size);
634 ok(!ret && GetLastError() == ERROR_MORE_DATA,
635 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
636 /* Normal tests */
637 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
639 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &times[i]);
640 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &times[i]);
641 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &times[i]);
643 for (i = 0; i < sizeof(otherTimes) / sizeof(otherTimes[0]); i++)
645 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &otherTimes[i]);
646 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &otherTimes[i]);
647 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &otherTimes[i]);
649 for (i = 0; i < sizeof(bogusTimes) / sizeof(bogusTimes[0]); i++)
651 size = sizeof(ft1);
652 ret = pCryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
653 bogusTimes[i], bogusTimes[i][1] + 2, 0, NULL, &ft1, &size);
654 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
655 GetLastError() == OSS_DATA_ERROR /* Win9x */),
656 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
657 GetLastError());
661 static const char commonName[] = "Juan Lang";
662 static const char surName[] = "Lang";
664 static const BYTE emptySequence[] = { 0x30, 0 };
665 static const BYTE emptyRDNs[] = { 0x30, 0x02, 0x31, 0 };
666 static const BYTE twoRDNs[] = {
667 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
668 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
669 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0};
670 static const BYTE encodedTwoRDNs[] = {
671 0x30,0x2e,0x31,0x2c,0x30,0x2a,0x06,0x03,0x55,0x04,0x03,0x30,0x23,0x31,0x21,
672 0x30,0x0c,0x06,0x03,0x55,0x04,0x04,0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,
673 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
674 0x6e,0x67,0x00,
677 static const BYTE us[] = { 0x55, 0x53 };
678 static const BYTE minnesota[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x73, 0x6f,
679 0x74, 0x61 };
680 static const BYTE minneapolis[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x61, 0x70,
681 0x6f, 0x6c, 0x69, 0x73 };
682 static const BYTE codeweavers[] = { 0x43, 0x6f, 0x64, 0x65, 0x57, 0x65, 0x61,
683 0x76, 0x65, 0x72, 0x73 };
684 static const BYTE wine[] = { 0x57, 0x69, 0x6e, 0x65, 0x20, 0x44, 0x65, 0x76,
685 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74 };
686 static const BYTE localhostAttr[] = { 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
687 0x73, 0x74 };
688 static const BYTE aric[] = { 0x61, 0x72, 0x69, 0x63, 0x40, 0x63, 0x6f, 0x64,
689 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d };
691 #define RDNA(arr) oid_ ## arr, CERT_RDN_PRINTABLE_STRING, { sizeof(arr), (LPBYTE)arr }
692 #define RDNIA5(arr) oid_ ## arr, CERT_RDN_IA5_STRING, { sizeof(arr), (LPBYTE)arr }
694 static CHAR oid_us[] = "2.5.4.6",
695 oid_minnesota[] = "2.5.4.8",
696 oid_minneapolis[] = "2.5.4.7",
697 oid_codeweavers[] = "2.5.4.10",
698 oid_wine[] = "2.5.4.11",
699 oid_localhostAttr[] = "2.5.4.3",
700 oid_aric[] = "1.2.840.113549.1.9.1";
701 static CERT_RDN_ATTR rdnAttrs[] = { { RDNA(us) },
702 { RDNA(minnesota) },
703 { RDNA(minneapolis) },
704 { RDNA(codeweavers) },
705 { RDNA(wine) },
706 { RDNA(localhostAttr) },
707 { RDNIA5(aric) } };
708 static CERT_RDN_ATTR decodedRdnAttrs[] = { { RDNA(us) },
709 { RDNA(localhostAttr) },
710 { RDNA(minnesota) },
711 { RDNA(minneapolis) },
712 { RDNA(codeweavers) },
713 { RDNA(wine) },
714 { RDNIA5(aric) } };
716 #undef RDNIA5
717 #undef RDNA
719 static const BYTE encodedRDNAttrs[] = {
720 0x30,0x81,0x96,0x31,0x81,0x93,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
721 0x53,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x68,
722 0x6f,0x73,0x74,0x30,0x10,0x06,0x03,0x55,0x04,0x08,0x13,0x09,0x4d,0x69,0x6e,0x6e,
723 0x65,0x73,0x6f,0x74,0x61,0x30,0x12,0x06,0x03,0x55,0x04,0x07,0x13,0x0b,0x4d,0x69,
724 0x6e,0x6e,0x65,0x61,0x70,0x6f,0x6c,0x69,0x73,0x30,0x12,0x06,0x03,0x55,0x04,0x0a,
725 0x13,0x0b,0x43,0x6f,0x64,0x65,0x57,0x65,0x61,0x76,0x65,0x72,0x73,0x30,0x17,0x06,
726 0x03,0x55,0x04,0x0b,0x13,0x10,0x57,0x69,0x6e,0x65,0x20,0x44,0x65,0x76,0x65,0x6c,
727 0x6f,0x70,0x6d,0x65,0x6e,0x74,0x30,0x21,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
728 0x01,0x09,0x01,0x16,0x14,0x61,0x72,0x69,0x63,0x40,0x63,0x6f,0x64,0x65,0x77,0x65,
729 0x61,0x76,0x65,0x72,0x73,0x2e,0x63,0x6f,0x6d
732 static void test_encodeName(DWORD dwEncoding)
734 CERT_RDN_ATTR attrs[2];
735 CERT_RDN rdn;
736 CERT_NAME_INFO info;
737 static CHAR oid_common_name[] = szOID_COMMON_NAME,
738 oid_sur_name[] = szOID_SUR_NAME;
739 BYTE *buf = NULL;
740 DWORD size = 0;
741 BOOL ret;
743 if (0)
745 /* Test with NULL pvStructInfo (crashes on win9x) */
746 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, NULL,
747 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
748 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
749 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
751 /* Test with empty CERT_NAME_INFO */
752 info.cRDN = 0;
753 info.rgRDN = NULL;
754 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
755 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
756 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
757 if (buf)
759 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
760 "Got unexpected encoding for empty name\n");
761 LocalFree(buf);
763 if (0)
765 /* Test with bogus CERT_RDN (crashes on win9x) */
766 info.cRDN = 1;
767 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
768 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
769 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
770 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
772 /* Test with empty CERT_RDN */
773 rdn.cRDNAttr = 0;
774 rdn.rgRDNAttr = NULL;
775 info.cRDN = 1;
776 info.rgRDN = &rdn;
777 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
778 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
779 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
780 if (buf)
782 ok(!memcmp(buf, emptyRDNs, sizeof(emptyRDNs)),
783 "Got unexpected encoding for empty RDN array\n");
784 LocalFree(buf);
786 if (0)
788 /* Test with bogus attr array (crashes on win9x) */
789 rdn.cRDNAttr = 1;
790 rdn.rgRDNAttr = NULL;
791 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
792 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
793 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
794 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
796 /* oddly, a bogus OID is accepted by Windows XP; not testing.
797 attrs[0].pszObjId = "bogus";
798 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
799 attrs[0].Value.cbData = sizeof(commonName);
800 attrs[0].Value.pbData = (BYTE *)commonName;
801 rdn.cRDNAttr = 1;
802 rdn.rgRDNAttr = attrs;
803 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
804 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
805 ok(!ret, "Expected failure, got success\n");
807 /* Check with two CERT_RDN_ATTRs. Note DER encoding forces the order of
808 * the encoded attributes to be swapped.
810 attrs[0].pszObjId = oid_common_name;
811 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
812 attrs[0].Value.cbData = sizeof(commonName);
813 attrs[0].Value.pbData = (BYTE *)commonName;
814 attrs[1].pszObjId = oid_sur_name;
815 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
816 attrs[1].Value.cbData = sizeof(surName);
817 attrs[1].Value.pbData = (BYTE *)surName;
818 rdn.cRDNAttr = 2;
819 rdn.rgRDNAttr = attrs;
820 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
821 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
822 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
823 if (buf)
825 ok(!memcmp(buf, twoRDNs, sizeof(twoRDNs)),
826 "Got unexpected encoding for two RDN array\n");
827 LocalFree(buf);
829 /* A name can be "encoded" with previously encoded RDN attrs. */
830 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
831 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
832 attrs[0].Value.cbData = sizeof(twoRDNs);
833 rdn.cRDNAttr = 1;
834 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
835 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
836 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
837 if (buf)
839 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
840 ok(!memcmp(buf, encodedTwoRDNs, size),
841 "Unexpected value for re-endoded two RDN array\n");
842 LocalFree(buf);
844 /* CERT_RDN_ANY_TYPE is too vague for X509_NAMEs, check the return */
845 rdn.cRDNAttr = 1;
846 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
847 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
848 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
849 ok(!ret && GetLastError() == E_INVALIDARG,
850 "Expected E_INVALIDARG, got %08x\n", GetLastError());
851 /* Test a more complex name */
852 rdn.cRDNAttr = sizeof(rdnAttrs) / sizeof(rdnAttrs[0]);
853 rdn.rgRDNAttr = (PCERT_RDN_ATTR)rdnAttrs;
854 info.cRDN = 1;
855 info.rgRDN = &rdn;
856 buf = NULL;
857 size = 0;
858 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, X509_NAME, &info,
859 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
860 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
861 if (ret)
863 ok(size == sizeof(encodedRDNAttrs), "Wrong size %d\n", size);
864 ok(!memcmp(buf, encodedRDNAttrs, size), "Unexpected value\n");
865 LocalFree(buf);
869 static WCHAR commonNameW[] = { 'J','u','a','n',' ','L','a','n','g',0 };
870 static WCHAR surNameW[] = { 'L','a','n','g',0 };
872 static const BYTE twoRDNsNoNull[] = {
873 0x30,0x21,0x31,0x1f,0x30,0x0b,0x06,0x03,0x55,0x04,0x04,0x13,0x04,0x4c,0x61,
874 0x6e,0x67,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,
875 0x20,0x4c,0x61,0x6e,0x67 };
876 static const BYTE anyType[] = {
877 0x30,0x2f,0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x1e,0x24,0x23,0x30,
878 0x21,0x31,0x0c,0x30,0x03,0x06,0x04,0x55,0x13,0x04,0x4c,0x05,0x6e,0x61,0x00,
879 0x67,0x11,0x30,0x03,0x06,0x04,0x55,0x13,0x03,0x4a,0x0a,0x61,0x75,0x20,0x6e,
880 0x61,0x4c,0x67,0x6e };
882 static void test_encodeUnicodeName(DWORD dwEncoding)
884 CERT_RDN_ATTR attrs[2];
885 CERT_RDN rdn;
886 CERT_NAME_INFO info;
887 static CHAR oid_common_name[] = szOID_COMMON_NAME,
888 oid_sur_name[] = szOID_SUR_NAME;
889 BYTE *buf = NULL;
890 DWORD size = 0;
891 BOOL ret;
893 if (0)
895 /* Test with NULL pvStructInfo (crashes on win9x) */
896 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, NULL,
897 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
898 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
899 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
901 /* Test with empty CERT_NAME_INFO */
902 info.cRDN = 0;
903 info.rgRDN = NULL;
904 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
905 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
906 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
907 if (buf)
909 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
910 "Got unexpected encoding for empty name\n");
911 LocalFree(buf);
913 /* Check with one CERT_RDN_ATTR, that has an invalid character for the
914 * encoding (the NULL).
916 attrs[0].pszObjId = oid_common_name;
917 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
918 attrs[0].Value.cbData = sizeof(commonNameW);
919 attrs[0].Value.pbData = (BYTE *)commonNameW;
920 rdn.cRDNAttr = 1;
921 rdn.rgRDNAttr = attrs;
922 info.cRDN = 1;
923 info.rgRDN = &rdn;
924 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
925 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
926 ok(!ret && GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING,
927 "Expected CRYPT_E_INVALID_PRINTABLE_STRING, got %08x\n", GetLastError());
928 ok(size == 9, "Unexpected error index %08x\n", size);
929 /* Check with two NULL-terminated CERT_RDN_ATTRs. Note DER encoding
930 * forces the order of the encoded attributes to be swapped.
932 attrs[0].pszObjId = oid_common_name;
933 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
934 attrs[0].Value.cbData = 0;
935 attrs[0].Value.pbData = (BYTE *)commonNameW;
936 attrs[1].pszObjId = oid_sur_name;
937 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
938 attrs[1].Value.cbData = 0;
939 attrs[1].Value.pbData = (BYTE *)surNameW;
940 rdn.cRDNAttr = 2;
941 rdn.rgRDNAttr = attrs;
942 info.cRDN = 1;
943 info.rgRDN = &rdn;
944 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
945 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
946 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
947 if (buf)
949 ok(!memcmp(buf, twoRDNsNoNull, sizeof(twoRDNsNoNull)),
950 "Got unexpected encoding for two RDN array\n");
951 LocalFree(buf);
953 /* A name can be "encoded" with previously encoded RDN attrs. */
954 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
955 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
956 attrs[0].Value.cbData = sizeof(twoRDNs);
957 rdn.cRDNAttr = 1;
958 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
959 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
960 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
961 if (buf)
963 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
964 ok(!memcmp(buf, encodedTwoRDNs, size),
965 "Unexpected value for re-endoded two RDN array\n");
966 LocalFree(buf);
968 /* Unicode names infer the type for CERT_RDN_ANY_TYPE */
969 rdn.cRDNAttr = 1;
970 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
971 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
972 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
973 todo_wine ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
974 if (buf)
976 ok(size == sizeof(anyType), "Unexpected size %d\n", size);
977 ok(!memcmp(buf, anyType, size), "Unexpected value\n");
978 LocalFree(buf);
982 static void compareNameValues(const CERT_NAME_VALUE *expected,
983 const CERT_NAME_VALUE *got)
985 ok(got->dwValueType == expected->dwValueType,
986 "Expected string type %d, got %d\n", expected->dwValueType,
987 got->dwValueType);
988 ok(got->Value.cbData == expected->Value.cbData,
989 "String type %d: unexpected data size, got %d, expected %d\n",
990 expected->dwValueType, got->Value.cbData, expected->Value.cbData);
991 if (got->Value.cbData && got->Value.pbData)
992 ok(!memcmp(got->Value.pbData, expected->Value.pbData,
993 min(got->Value.cbData, expected->Value.cbData)),
994 "String type %d: unexpected value\n", expected->dwValueType);
997 static void compareRDNAttrs(const CERT_RDN_ATTR *expected,
998 const CERT_RDN_ATTR *got)
1000 if (expected->pszObjId && strlen(expected->pszObjId))
1002 ok(got->pszObjId != NULL, "Expected OID %s, got NULL\n",
1003 expected->pszObjId);
1004 if (got->pszObjId)
1006 ok(!strcmp(got->pszObjId, expected->pszObjId),
1007 "Got unexpected OID %s, expected %s\n", got->pszObjId,
1008 expected->pszObjId);
1011 compareNameValues((const CERT_NAME_VALUE *)&expected->dwValueType,
1012 (const CERT_NAME_VALUE *)&got->dwValueType);
1015 static void compareRDNs(const CERT_RDN *expected, const CERT_RDN *got)
1017 ok(got->cRDNAttr == expected->cRDNAttr,
1018 "Expected %d RDN attrs, got %d\n", expected->cRDNAttr, got->cRDNAttr);
1019 if (got->cRDNAttr)
1021 DWORD i;
1023 for (i = 0; i < got->cRDNAttr; i++)
1024 compareRDNAttrs(&expected->rgRDNAttr[i], &got->rgRDNAttr[i]);
1028 static void compareNames(const CERT_NAME_INFO *expected,
1029 const CERT_NAME_INFO *got)
1031 ok(got->cRDN == expected->cRDN, "Expected %d RDNs, got %d\n",
1032 expected->cRDN, got->cRDN);
1033 if (got->cRDN)
1035 DWORD i;
1037 for (i = 0; i < got->cRDN; i++)
1038 compareRDNs(&expected->rgRDN[i], &got->rgRDN[i]);
1042 static const BYTE emptyIndefiniteSequence[] = { 0x30,0x80,0x00,0x00 };
1043 static const BYTE twoRDNsExtraBytes[] = {
1044 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
1045 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1046 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0,0,0,0,0,0};
1048 static void test_decodeName(DWORD dwEncoding)
1050 BYTE *buf = NULL;
1051 DWORD bufSize = 0;
1052 BOOL ret;
1053 CERT_RDN rdn;
1054 CERT_NAME_INFO info = { 1, &rdn };
1056 /* test empty name */
1057 bufSize = 0;
1058 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptySequence,
1059 emptySequence[1] + 2,
1060 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1061 (BYTE *)&buf, &bufSize);
1062 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1063 /* Interestingly, in Windows, if cRDN is 0, rgRGN may not be NULL. My
1064 * decoder works the same way, so only test the count.
1066 if (buf)
1068 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1069 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1070 "Expected 0 RDNs in empty info, got %d\n",
1071 ((CERT_NAME_INFO *)buf)->cRDN);
1072 LocalFree(buf);
1074 /* test empty name with indefinite-length encoding */
1075 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyIndefiniteSequence,
1076 sizeof(emptyIndefiniteSequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
1077 (BYTE *)&buf, &bufSize);
1078 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1079 if (ret)
1081 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1082 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1083 "Expected 0 RDNs in empty info, got %d\n",
1084 ((CERT_NAME_INFO *)buf)->cRDN);
1085 LocalFree(buf);
1087 /* test empty RDN */
1088 bufSize = 0;
1089 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyRDNs,
1090 emptyRDNs[1] + 2,
1091 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1092 (BYTE *)&buf, &bufSize);
1093 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1094 if (buf)
1096 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1098 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1099 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1100 "Got unexpected value for empty RDN\n");
1101 LocalFree(buf);
1103 /* test two RDN attrs */
1104 bufSize = 0;
1105 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNs,
1106 twoRDNs[1] + 2,
1107 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1108 (BYTE *)&buf, &bufSize);
1109 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1110 if (buf)
1112 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1113 oid_common_name[] = szOID_COMMON_NAME;
1115 CERT_RDN_ATTR attrs[] = {
1116 { oid_sur_name, CERT_RDN_PRINTABLE_STRING, { sizeof(surName),
1117 (BYTE *)surName } },
1118 { oid_common_name, CERT_RDN_PRINTABLE_STRING, { sizeof(commonName),
1119 (BYTE *)commonName } },
1122 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1123 rdn.rgRDNAttr = attrs;
1124 compareNames(&info, (CERT_NAME_INFO *)buf);
1125 LocalFree(buf);
1127 /* test that two RDN attrs with extra bytes succeeds */
1128 bufSize = 0;
1129 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNsExtraBytes,
1130 sizeof(twoRDNsExtraBytes), 0, NULL, NULL, &bufSize);
1131 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1132 /* And, a slightly more complicated name */
1133 buf = NULL;
1134 bufSize = 0;
1135 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME, encodedRDNAttrs,
1136 sizeof(encodedRDNAttrs), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1137 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1138 if (ret)
1140 rdn.cRDNAttr = sizeof(decodedRdnAttrs) / sizeof(decodedRdnAttrs[0]);
1141 rdn.rgRDNAttr = (PCERT_RDN_ATTR)decodedRdnAttrs;
1142 compareNames(&info, (CERT_NAME_INFO *)buf);
1143 LocalFree(buf);
1147 static void test_decodeUnicodeName(DWORD dwEncoding)
1149 BYTE *buf = NULL;
1150 DWORD bufSize = 0;
1151 BOOL ret;
1152 CERT_RDN rdn;
1153 CERT_NAME_INFO info = { 1, &rdn };
1155 /* test empty name */
1156 bufSize = 0;
1157 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptySequence,
1158 emptySequence[1] + 2,
1159 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1160 (BYTE *)&buf, &bufSize);
1161 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1162 if (buf)
1164 ok(bufSize == sizeof(CERT_NAME_INFO),
1165 "Got wrong bufSize %d\n", bufSize);
1166 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1167 "Expected 0 RDNs in empty info, got %d\n",
1168 ((CERT_NAME_INFO *)buf)->cRDN);
1169 LocalFree(buf);
1171 /* test empty RDN */
1172 bufSize = 0;
1173 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptyRDNs,
1174 emptyRDNs[1] + 2,
1175 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1176 (BYTE *)&buf, &bufSize);
1177 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1178 if (buf)
1180 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1182 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1183 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1184 "Got unexpected value for empty RDN\n");
1185 LocalFree(buf);
1187 /* test two RDN attrs */
1188 bufSize = 0;
1189 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, twoRDNsNoNull,
1190 sizeof(twoRDNsNoNull),
1191 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1192 (BYTE *)&buf, &bufSize);
1193 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1194 if (buf)
1196 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1197 oid_common_name[] = szOID_COMMON_NAME;
1199 CERT_RDN_ATTR attrs[] = {
1200 { oid_sur_name, CERT_RDN_PRINTABLE_STRING,
1201 { lstrlenW(surNameW) * sizeof(WCHAR), (BYTE *)surNameW } },
1202 { oid_common_name, CERT_RDN_PRINTABLE_STRING,
1203 { lstrlenW(commonNameW) * sizeof(WCHAR), (BYTE *)commonNameW } },
1206 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1207 rdn.rgRDNAttr = attrs;
1208 compareNames(&info, (CERT_NAME_INFO *)buf);
1209 LocalFree(buf);
1213 struct EncodedNameValue
1215 CERT_NAME_VALUE value;
1216 const BYTE *encoded;
1217 DWORD encodedSize;
1220 static const char bogusIA5[] = "\x80";
1221 static const char bogusPrintable[] = "~";
1222 static const char bogusNumeric[] = "A";
1223 static const BYTE bin42[] = { 0x16,0x02,0x80,0x00 };
1224 static const BYTE bin43[] = { 0x13,0x02,0x7e,0x00 };
1225 static const BYTE bin44[] = { 0x12,0x02,0x41,0x00 };
1226 static BYTE octetCommonNameValue[] = {
1227 0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1228 static BYTE numericCommonNameValue[] = {
1229 0x12,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1230 static BYTE printableCommonNameValue[] = {
1231 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1232 static BYTE t61CommonNameValue[] = {
1233 0x14,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1234 static BYTE videotexCommonNameValue[] = {
1235 0x15,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1236 static BYTE ia5CommonNameValue[] = {
1237 0x16,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1238 static BYTE graphicCommonNameValue[] = {
1239 0x19,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1240 static BYTE visibleCommonNameValue[] = {
1241 0x1a,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1242 static BYTE generalCommonNameValue[] = {
1243 0x1b,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1244 static BYTE bmpCommonNameValue[] = {
1245 0x1e,0x14,0x00,0x4a,0x00,0x75,0x00,0x61,0x00,0x6e,0x00,0x20,0x00,0x4c,0x00,
1246 0x61,0x00,0x6e,0x00,0x67,0x00,0x00 };
1247 static BYTE utf8CommonNameValue[] = {
1248 0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1250 static struct EncodedNameValue nameValues[] = {
1251 { { CERT_RDN_OCTET_STRING, { sizeof(commonName), (BYTE *)commonName } },
1252 octetCommonNameValue, sizeof(octetCommonNameValue) },
1253 { { CERT_RDN_NUMERIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1254 numericCommonNameValue, sizeof(numericCommonNameValue) },
1255 { { CERT_RDN_PRINTABLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1256 printableCommonNameValue, sizeof(printableCommonNameValue) },
1257 { { CERT_RDN_T61_STRING, { sizeof(commonName), (BYTE *)commonName } },
1258 t61CommonNameValue, sizeof(t61CommonNameValue) },
1259 { { CERT_RDN_VIDEOTEX_STRING, { sizeof(commonName), (BYTE *)commonName } },
1260 videotexCommonNameValue, sizeof(videotexCommonNameValue) },
1261 { { CERT_RDN_IA5_STRING, { sizeof(commonName), (BYTE *)commonName } },
1262 ia5CommonNameValue, sizeof(ia5CommonNameValue) },
1263 { { CERT_RDN_GRAPHIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1264 graphicCommonNameValue, sizeof(graphicCommonNameValue) },
1265 { { CERT_RDN_VISIBLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1266 visibleCommonNameValue, sizeof(visibleCommonNameValue) },
1267 { { CERT_RDN_GENERAL_STRING, { sizeof(commonName), (BYTE *)commonName } },
1268 generalCommonNameValue, sizeof(generalCommonNameValue) },
1269 { { CERT_RDN_BMP_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1270 bmpCommonNameValue, sizeof(bmpCommonNameValue) },
1271 { { CERT_RDN_UTF8_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1272 utf8CommonNameValue, sizeof(utf8CommonNameValue) },
1273 /* The following tests succeed under Windows, but really should fail,
1274 * they contain characters that are illegal for the encoding. I'm
1275 * including them to justify my lazy encoding.
1277 { { CERT_RDN_IA5_STRING, { sizeof(bogusIA5), (BYTE *)bogusIA5 } }, bin42,
1278 sizeof(bin42) },
1279 { { CERT_RDN_PRINTABLE_STRING, { sizeof(bogusPrintable),
1280 (BYTE *)bogusPrintable } }, bin43, sizeof(bin43) },
1281 { { CERT_RDN_NUMERIC_STRING, { sizeof(bogusNumeric), (BYTE *)bogusNumeric } },
1282 bin44, sizeof(bin44) },
1285 static void test_encodeNameValue(DWORD dwEncoding)
1287 BYTE *buf = NULL;
1288 DWORD size = 0, i;
1289 BOOL ret;
1290 CERT_NAME_VALUE value = { 0, { 0, NULL } };
1292 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1293 value.Value.pbData = printableCommonNameValue;
1294 value.Value.cbData = sizeof(printableCommonNameValue);
1295 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, &value,
1296 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1297 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1298 if (buf)
1300 ok(size == sizeof(printableCommonNameValue), "Unexpected size %d\n",
1301 size);
1302 ok(!memcmp(buf, printableCommonNameValue, size),
1303 "Unexpected encoding\n");
1304 LocalFree(buf);
1306 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1308 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE,
1309 &nameValues[i].value, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1310 &size);
1311 ok(ret, "Type %d: CryptEncodeObjectEx failed: %08x\n",
1312 nameValues[i].value.dwValueType, GetLastError());
1313 if (buf)
1315 ok(size == nameValues[i].encodedSize,
1316 "Expected size %d, got %d\n", nameValues[i].encodedSize, size);
1317 ok(!memcmp(buf, nameValues[i].encoded, size),
1318 "Got unexpected encoding\n");
1319 LocalFree(buf);
1324 static void test_decodeNameValue(DWORD dwEncoding)
1326 int i;
1327 BYTE *buf = NULL;
1328 DWORD bufSize = 0;
1329 BOOL ret;
1331 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1333 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE,
1334 nameValues[i].encoded, nameValues[i].encoded[1] + 2,
1335 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1336 (BYTE *)&buf, &bufSize);
1337 ok(ret, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
1338 nameValues[i].value.dwValueType, GetLastError());
1339 if (buf)
1341 compareNameValues(&nameValues[i].value,
1342 (const CERT_NAME_VALUE *)buf);
1343 LocalFree(buf);
1348 static const BYTE emptyURL[] = { 0x30, 0x02, 0x86, 0x00 };
1349 static const BYTE emptyURLExtraBytes[] = { 0x30, 0x02, 0x86, 0x00, 0, 0, 0 };
1350 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e',
1351 'h','q','.','o','r','g',0 };
1352 static const BYTE encodedURL[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74,
1353 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e,
1354 0x6f, 0x72, 0x67 };
1355 static const WCHAR nihongoURL[] = { 'h','t','t','p',':','/','/',0x226f,
1356 0x575b, 0 };
1357 static const WCHAR dnsName[] = { 'w','i','n','e','h','q','.','o','r','g',0 };
1358 static const BYTE encodedDnsName[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69,
1359 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
1360 static const BYTE localhost[] = { 127, 0, 0, 1 };
1361 static const BYTE encodedIPAddr[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00,
1362 0x01 };
1363 static const unsigned char encodedCommonName[] = {
1364 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0};
1365 static const BYTE encodedOidName[] = { 0x30,0x04,0x88,0x02,0x2a,0x03 };
1366 static const BYTE encodedDirectoryName[] = {
1367 0x30,0x19,0xa4,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1368 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1370 static void test_encodeAltName(DWORD dwEncoding)
1372 CERT_ALT_NAME_INFO info = { 0 };
1373 CERT_ALT_NAME_ENTRY entry = { 0 };
1374 BYTE *buf = NULL;
1375 DWORD size = 0;
1376 BOOL ret;
1377 char oid[] = "1.2.3";
1379 /* Test with empty info */
1380 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1381 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1382 if (buf)
1384 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
1385 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
1386 LocalFree(buf);
1388 /* Test with an empty entry */
1389 info.cAltEntry = 1;
1390 info.rgAltEntry = &entry;
1391 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1392 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1393 ok(!ret && GetLastError() == E_INVALIDARG,
1394 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1395 /* Test with an empty pointer */
1396 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
1397 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1398 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1399 if (buf)
1401 ok(size == sizeof(emptyURL), "Wrong size %d\n", size);
1402 ok(!memcmp(buf, emptyURL, size), "Unexpected value\n");
1403 LocalFree(buf);
1405 /* Test with a real URL */
1406 U(entry).pwszURL = (LPWSTR)url;
1407 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1408 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1409 if (buf)
1411 ok(size == sizeof(encodedURL), "Wrong size %d\n", size);
1412 ok(!memcmp(buf, encodedURL, size), "Unexpected value\n");
1413 LocalFree(buf);
1415 /* Now with the URL containing an invalid IA5 char */
1416 U(entry).pwszURL = (LPWSTR)nihongoURL;
1417 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1418 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1419 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
1420 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
1421 /* The first invalid character is at index 7 */
1422 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
1423 "Expected invalid char at index 7, got %d\n",
1424 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
1425 /* Now with the URL missing a scheme */
1426 U(entry).pwszURL = (LPWSTR)dnsName;
1427 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1428 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1429 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1430 if (buf)
1432 /* This succeeds, but it shouldn't, so don't worry about conforming */
1433 LocalFree(buf);
1435 /* Now with a DNS name */
1436 entry.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
1437 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1438 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1439 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1440 if (buf)
1442 ok(size == sizeof(encodedDnsName), "Wrong size %d\n", size);
1443 ok(!memcmp(buf, encodedDnsName, size), "Unexpected value\n");
1444 LocalFree(buf);
1446 /* Test with an IP address */
1447 entry.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
1448 U(entry).IPAddress.cbData = sizeof(localhost);
1449 U(entry).IPAddress.pbData = (LPBYTE)localhost;
1450 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1451 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1452 if (buf)
1454 ok(size == sizeof(encodedIPAddr), "Wrong size %d\n", size);
1455 ok(!memcmp(buf, encodedIPAddr, size), "Unexpected value\n");
1456 LocalFree(buf);
1458 /* Test with OID */
1459 entry.dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID;
1460 U(entry).pszRegisteredID = oid;
1461 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1462 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1463 if (buf)
1465 ok(size == sizeof(encodedOidName), "Wrong size %d\n", size);
1466 ok(!memcmp(buf, encodedOidName, size), "Unexpected value\n");
1467 LocalFree(buf);
1469 /* Test with directory name */
1470 entry.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
1471 U(entry).DirectoryName.cbData = sizeof(encodedCommonName);
1472 U(entry).DirectoryName.pbData = (LPBYTE)encodedCommonName;
1473 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1474 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1475 if (buf)
1477 ok(size == sizeof(encodedDirectoryName), "Wrong size %d\n", size);
1478 ok(!memcmp(buf, encodedDirectoryName, size), "Unexpected value\n");
1479 LocalFree(buf);
1483 static void test_decodeAltName(DWORD dwEncoding)
1485 static const BYTE unimplementedType[] = { 0x30, 0x06, 0x85, 0x04, 0x7f,
1486 0x00, 0x00, 0x01 };
1487 static const BYTE bogusType[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00,
1488 0x01 };
1489 BOOL ret;
1490 BYTE *buf = NULL;
1491 DWORD bufSize = 0;
1492 CERT_ALT_NAME_INFO *info;
1494 /* Test some bogus ones first */
1495 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1496 unimplementedType, sizeof(unimplementedType), CRYPT_DECODE_ALLOC_FLAG,
1497 NULL, (BYTE *)&buf, &bufSize);
1498 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
1499 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1500 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
1501 GetLastError());
1502 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1503 bogusType, sizeof(bogusType), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1504 &bufSize);
1505 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
1506 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1507 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
1508 GetLastError());
1509 /* Now expected cases */
1510 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptySequence,
1511 emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1512 &bufSize);
1513 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1514 if (buf)
1516 info = (CERT_ALT_NAME_INFO *)buf;
1518 ok(info->cAltEntry == 0, "Expected 0 entries, got %d\n",
1519 info->cAltEntry);
1520 LocalFree(buf);
1522 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptyURL,
1523 emptyURL[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 == 1, "Expected 1 entries, got %d\n",
1531 info->cAltEntry);
1532 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1533 "Expected CERT_ALT_NAME_URL, got %d\n",
1534 info->rgAltEntry[0].dwAltNameChoice);
1535 ok(U(info->rgAltEntry[0]).pwszURL == NULL || !*U(info->rgAltEntry[0]).pwszURL,
1536 "Expected empty URL\n");
1537 LocalFree(buf);
1539 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1540 emptyURLExtraBytes, sizeof(emptyURLExtraBytes), 0, NULL, NULL, &bufSize);
1541 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1542 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedURL,
1543 encodedURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1544 &bufSize);
1545 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1546 if (buf)
1548 info = (CERT_ALT_NAME_INFO *)buf;
1550 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1551 info->cAltEntry);
1552 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1553 "Expected CERT_ALT_NAME_URL, got %d\n",
1554 info->rgAltEntry[0].dwAltNameChoice);
1555 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszURL, url), "Unexpected URL\n");
1556 LocalFree(buf);
1558 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedDnsName,
1559 encodedDnsName[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1560 &bufSize);
1561 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1562 if (buf)
1564 info = (CERT_ALT_NAME_INFO *)buf;
1566 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1567 info->cAltEntry);
1568 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1569 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1570 info->rgAltEntry[0].dwAltNameChoice);
1571 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszDNSName, dnsName),
1572 "Unexpected DNS name\n");
1573 LocalFree(buf);
1575 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedIPAddr,
1576 encodedIPAddr[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1577 &bufSize);
1578 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1579 if (buf)
1581 info = (CERT_ALT_NAME_INFO *)buf;
1583 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1584 info->cAltEntry);
1585 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS,
1586 "Expected CERT_ALT_NAME_IP_ADDRESS, got %d\n",
1587 info->rgAltEntry[0].dwAltNameChoice);
1588 ok(U(info->rgAltEntry[0]).IPAddress.cbData == sizeof(localhost),
1589 "Unexpected IP address length %d\n",
1590 U(info->rgAltEntry[0]).IPAddress.cbData);
1591 ok(!memcmp(U(info->rgAltEntry[0]).IPAddress.pbData, localhost,
1592 sizeof(localhost)), "Unexpected IP address value\n");
1593 LocalFree(buf);
1595 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedOidName,
1596 sizeof(encodedOidName), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1597 &bufSize);
1598 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1599 if (buf)
1601 info = (CERT_ALT_NAME_INFO *)buf;
1603 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1604 info->cAltEntry);
1605 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_REGISTERED_ID,
1606 "Expected CERT_ALT_NAME_REGISTERED_ID, got %d\n",
1607 info->rgAltEntry[0].dwAltNameChoice);
1608 ok(!strcmp(U(info->rgAltEntry[0]).pszRegisteredID, "1.2.3"),
1609 "Expected OID 1.2.3, got %s\n", U(info->rgAltEntry[0]).pszRegisteredID);
1610 LocalFree(buf);
1612 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1613 encodedDirectoryName, sizeof(encodedDirectoryName),
1614 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1615 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1616 if (buf)
1618 info = (CERT_ALT_NAME_INFO *)buf;
1620 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1621 info->cAltEntry);
1622 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME,
1623 "Expected CERT_ALT_NAME_DIRECTORY_NAME, got %d\n",
1624 info->rgAltEntry[0].dwAltNameChoice);
1625 ok(U(info->rgAltEntry[0]).DirectoryName.cbData ==
1626 sizeof(encodedCommonName), "Unexpected directory name length %d\n",
1627 U(info->rgAltEntry[0]).DirectoryName.cbData);
1628 ok(!memcmp(U(info->rgAltEntry[0]).DirectoryName.pbData,
1629 encodedCommonName, sizeof(encodedCommonName)),
1630 "Unexpected directory name value\n");
1631 LocalFree(buf);
1635 struct UnicodeExpectedError
1637 DWORD valueType;
1638 LPCWSTR str;
1639 DWORD errorIndex;
1640 DWORD error;
1643 static const WCHAR oneW[] = { '1',0 };
1644 static const WCHAR aW[] = { 'a',0 };
1645 static const WCHAR quoteW[] = { '"', 0 };
1647 static struct UnicodeExpectedError unicodeErrors[] = {
1648 { CERT_RDN_ANY_TYPE, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1649 { CERT_RDN_ENCODED_BLOB, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1650 { CERT_RDN_OCTET_STRING, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1651 { CERT_RDN_NUMERIC_STRING, aW, 0, CRYPT_E_INVALID_NUMERIC_STRING },
1652 { CERT_RDN_PRINTABLE_STRING, quoteW, 0, CRYPT_E_INVALID_PRINTABLE_STRING },
1653 { CERT_RDN_IA5_STRING, nihongoURL, 7, CRYPT_E_INVALID_IA5_STRING },
1656 struct UnicodeExpectedResult
1658 DWORD valueType;
1659 LPCWSTR str;
1660 CRYPT_DATA_BLOB encoded;
1663 static BYTE oneNumeric[] = { 0x12, 0x01, 0x31 };
1664 static BYTE onePrintable[] = { 0x13, 0x01, 0x31 };
1665 static BYTE oneTeletex[] = { 0x14, 0x01, 0x31 };
1666 static BYTE oneVideotex[] = { 0x15, 0x01, 0x31 };
1667 static BYTE oneIA5[] = { 0x16, 0x01, 0x31 };
1668 static BYTE oneGraphic[] = { 0x19, 0x01, 0x31 };
1669 static BYTE oneVisible[] = { 0x1a, 0x01, 0x31 };
1670 static BYTE oneUniversal[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 };
1671 static BYTE oneGeneral[] = { 0x1b, 0x01, 0x31 };
1672 static BYTE oneBMP[] = { 0x1e, 0x02, 0x00, 0x31 };
1673 static BYTE oneUTF8[] = { 0x0c, 0x01, 0x31 };
1674 static BYTE nihongoT61[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,
1675 0x5b };
1676 static BYTE nihongoGeneral[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1677 0x6f,0x5b };
1678 static BYTE nihongoBMP[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,
1679 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
1680 static BYTE nihongoUTF8[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1681 0xe2,0x89,0xaf,0xe5,0x9d,0x9b };
1683 static struct UnicodeExpectedResult unicodeResults[] = {
1684 { CERT_RDN_NUMERIC_STRING, oneW, { sizeof(oneNumeric), oneNumeric } },
1685 { CERT_RDN_PRINTABLE_STRING, oneW, { sizeof(onePrintable), onePrintable } },
1686 { CERT_RDN_TELETEX_STRING, oneW, { sizeof(oneTeletex), oneTeletex } },
1687 { CERT_RDN_VIDEOTEX_STRING, oneW, { sizeof(oneVideotex), oneVideotex } },
1688 { CERT_RDN_IA5_STRING, oneW, { sizeof(oneIA5), oneIA5 } },
1689 { CERT_RDN_GRAPHIC_STRING, oneW, { sizeof(oneGraphic), oneGraphic } },
1690 { CERT_RDN_VISIBLE_STRING, oneW, { sizeof(oneVisible), oneVisible } },
1691 { CERT_RDN_UNIVERSAL_STRING, oneW, { sizeof(oneUniversal), oneUniversal } },
1692 { CERT_RDN_GENERAL_STRING, oneW, { sizeof(oneGeneral), oneGeneral } },
1693 { CERT_RDN_BMP_STRING, oneW, { sizeof(oneBMP), oneBMP } },
1694 { CERT_RDN_UTF8_STRING, oneW, { sizeof(oneUTF8), oneUTF8 } },
1695 { CERT_RDN_BMP_STRING, nihongoURL, { sizeof(nihongoBMP), nihongoBMP } },
1696 { CERT_RDN_UTF8_STRING, nihongoURL, { sizeof(nihongoUTF8), nihongoUTF8 } },
1699 static struct UnicodeExpectedResult unicodeWeirdness[] = {
1700 { CERT_RDN_TELETEX_STRING, nihongoURL, { sizeof(nihongoT61), nihongoT61 } },
1701 { CERT_RDN_GENERAL_STRING, nihongoURL, { sizeof(nihongoGeneral), nihongoGeneral } },
1704 static void test_encodeUnicodeNameValue(DWORD dwEncoding)
1706 BYTE *buf = NULL;
1707 DWORD size = 0, i;
1708 BOOL ret;
1709 CERT_NAME_VALUE value;
1711 if (0)
1713 /* Crashes on win9x */
1714 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, NULL,
1715 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1716 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1717 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1719 /* Have to have a string of some sort */
1720 value.dwValueType = 0; /* aka CERT_RDN_ANY_TYPE */
1721 value.Value.pbData = NULL;
1722 value.Value.cbData = 0;
1723 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1724 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1725 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1726 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1727 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1728 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1729 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1730 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1731 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1732 value.dwValueType = CERT_RDN_ANY_TYPE;
1733 value.Value.pbData = (LPBYTE)oneW;
1734 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1735 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1736 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1737 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1738 value.Value.cbData = sizeof(oneW);
1739 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1740 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1741 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1742 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1743 /* An encoded string with specified length isn't good enough either */
1744 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1745 value.Value.pbData = oneUniversal;
1746 value.Value.cbData = sizeof(oneUniversal);
1747 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1748 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1749 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1750 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1751 /* More failure checking */
1752 value.Value.cbData = 0;
1753 for (i = 0; i < sizeof(unicodeErrors) / sizeof(unicodeErrors[0]); i++)
1755 value.Value.pbData = (LPBYTE)unicodeErrors[i].str;
1756 value.dwValueType = unicodeErrors[i].valueType;
1757 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1758 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1759 ok(!ret && GetLastError() == unicodeErrors[i].error,
1760 "Value type %d: expected %08x, got %08x\n", value.dwValueType,
1761 unicodeErrors[i].error, GetLastError());
1762 ok(size == unicodeErrors[i].errorIndex,
1763 "Expected error index %d, got %d\n", unicodeErrors[i].errorIndex,
1764 size);
1766 /* cbData can be zero if the string is NULL-terminated */
1767 value.Value.cbData = 0;
1768 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1770 value.Value.pbData = (LPBYTE)unicodeResults[i].str;
1771 value.dwValueType = unicodeResults[i].valueType;
1772 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1773 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1774 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1775 if (buf)
1777 ok(size == unicodeResults[i].encoded.cbData,
1778 "Value type %d: expected size %d, got %d\n",
1779 value.dwValueType, unicodeResults[i].encoded.cbData, size);
1780 ok(!memcmp(unicodeResults[i].encoded.pbData, buf, size),
1781 "Value type %d: unexpected value\n", value.dwValueType);
1782 LocalFree(buf);
1785 /* These "encode," but they do so by truncating each unicode character
1786 * rather than properly encoding it. Kept separate from the proper results,
1787 * because the encoded forms won't decode to their original strings.
1789 for (i = 0; i < sizeof(unicodeWeirdness) / sizeof(unicodeWeirdness[0]); i++)
1791 value.Value.pbData = (LPBYTE)unicodeWeirdness[i].str;
1792 value.dwValueType = unicodeWeirdness[i].valueType;
1793 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1794 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1795 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1796 if (buf)
1798 ok(size == unicodeWeirdness[i].encoded.cbData,
1799 "Value type %d: expected size %d, got %d\n",
1800 value.dwValueType, unicodeWeirdness[i].encoded.cbData, size);
1801 ok(!memcmp(unicodeWeirdness[i].encoded.pbData, buf, size),
1802 "Value type %d: unexpected value\n", value.dwValueType);
1803 LocalFree(buf);
1808 static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
1810 if (n <= 0) return 0;
1811 while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
1812 return *str1 - *str2;
1815 static void test_decodeUnicodeNameValue(DWORD dwEncoding)
1817 DWORD i;
1819 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1821 BYTE *buf = NULL;
1822 BOOL ret;
1823 DWORD size = 0;
1825 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE,
1826 unicodeResults[i].encoded.pbData, unicodeResults[i].encoded.cbData,
1827 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1828 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1829 if (ret && buf)
1831 PCERT_NAME_VALUE value = (PCERT_NAME_VALUE)buf;
1833 ok(value->dwValueType == unicodeResults[i].valueType,
1834 "Expected value type %d, got %d\n", unicodeResults[i].valueType,
1835 value->dwValueType);
1836 ok(!strncmpW((LPWSTR)value->Value.pbData, unicodeResults[i].str,
1837 value->Value.cbData / sizeof(WCHAR)),
1838 "Unexpected decoded value for index %d (value type %d)\n", i,
1839 unicodeResults[i].valueType);
1840 LocalFree(buf);
1845 struct encodedOctets
1847 const BYTE *val;
1848 const BYTE *encoded;
1851 static const unsigned char bin46[] = { 'h','i',0 };
1852 static const unsigned char bin47[] = { 0x04,0x02,'h','i',0 };
1853 static const unsigned char bin48[] = {
1854 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1855 static const unsigned char bin49[] = {
1856 0x04,0x0f,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1857 static const unsigned char bin50[] = { 0 };
1858 static const unsigned char bin51[] = { 0x04,0x00,0 };
1860 static const struct encodedOctets octets[] = {
1861 { bin46, bin47 },
1862 { bin48, bin49 },
1863 { bin50, bin51 },
1866 static void test_encodeOctets(DWORD dwEncoding)
1868 CRYPT_DATA_BLOB blob;
1869 DWORD i;
1871 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1873 BYTE *buf = NULL;
1874 BOOL ret;
1875 DWORD bufSize = 0;
1877 blob.cbData = strlen((const char*)octets[i].val);
1878 blob.pbData = (BYTE*)octets[i].val;
1879 ret = pCryptEncodeObjectEx(dwEncoding, X509_OCTET_STRING, &blob,
1880 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1881 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
1882 if (buf)
1884 ok(buf[0] == 4,
1885 "Got unexpected type %d for octet string (expected 4)\n", buf[0]);
1886 ok(buf[1] == octets[i].encoded[1], "Got length %d, expected %d\n",
1887 buf[1], octets[i].encoded[1]);
1888 ok(!memcmp(buf + 1, octets[i].encoded + 1,
1889 octets[i].encoded[1] + 1), "Got unexpected value\n");
1890 LocalFree(buf);
1895 static void test_decodeOctets(DWORD dwEncoding)
1897 DWORD i;
1899 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1901 BYTE *buf = NULL;
1902 BOOL ret;
1903 DWORD bufSize = 0;
1905 ret = pCryptDecodeObjectEx(dwEncoding, X509_OCTET_STRING,
1906 (BYTE *)octets[i].encoded, octets[i].encoded[1] + 2,
1907 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1908 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1909 ok(bufSize >= sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1],
1910 "Expected size >= %d, got %d\n",
1911 (int)sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1], bufSize);
1912 ok(buf != NULL, "Expected allocated buffer\n");
1913 if (buf)
1915 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)buf;
1917 if (blob->cbData)
1918 ok(!memcmp(blob->pbData, octets[i].val, blob->cbData),
1919 "Unexpected value\n");
1920 LocalFree(buf);
1925 static const BYTE bytesToEncode[] = { 0xff, 0xff };
1927 struct encodedBits
1929 DWORD cUnusedBits;
1930 const BYTE *encoded;
1931 DWORD cbDecoded;
1932 const BYTE *decoded;
1935 static const unsigned char bin52[] = { 0x03,0x03,0x00,0xff,0xff };
1936 static const unsigned char bin53[] = { 0xff,0xff };
1937 static const unsigned char bin54[] = { 0x03,0x03,0x01,0xff,0xfe };
1938 static const unsigned char bin55[] = { 0xff,0xfe };
1939 static const unsigned char bin56[] = { 0x03,0x02,0x01,0xfe };
1940 static const unsigned char bin57[] = { 0xfe };
1941 static const unsigned char bin58[] = { 0x03,0x01,0x00 };
1943 static const struct encodedBits bits[] = {
1944 /* normal test cases */
1945 { 0, bin52, 2, bin53 },
1946 { 1, bin54, 2, bin55 },
1947 /* strange test case, showing cUnusedBits >= 8 is allowed */
1948 { 9, bin56, 1, bin57 },
1949 /* even stranger test case, showing cUnusedBits > cbData * 8 is allowed */
1950 { 17, bin58, 0, NULL },
1953 static void test_encodeBits(DWORD dwEncoding)
1955 DWORD i;
1957 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
1959 CRYPT_BIT_BLOB blob;
1960 BOOL ret;
1961 BYTE *buf = NULL;
1962 DWORD bufSize = 0;
1964 blob.cbData = sizeof(bytesToEncode);
1965 blob.pbData = (BYTE *)bytesToEncode;
1966 blob.cUnusedBits = bits[i].cUnusedBits;
1967 ret = pCryptEncodeObjectEx(dwEncoding, X509_BITS, &blob,
1968 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1969 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1970 if (buf)
1972 ok(bufSize == bits[i].encoded[1] + 2,
1973 "Got unexpected size %d, expected %d\n", bufSize,
1974 bits[i].encoded[1] + 2);
1975 ok(!memcmp(buf, bits[i].encoded, bits[i].encoded[1] + 2),
1976 "Unexpected value\n");
1977 LocalFree(buf);
1982 static void test_decodeBits(DWORD dwEncoding)
1984 static const BYTE ber[] = "\x03\x02\x01\xff";
1985 static const BYTE berDecoded = 0xfe;
1986 DWORD i;
1987 BOOL ret;
1988 BYTE *buf = NULL;
1989 DWORD bufSize = 0;
1991 /* normal cases */
1992 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
1994 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, bits[i].encoded,
1995 bits[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1996 &bufSize);
1997 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1998 if (buf)
2000 CRYPT_BIT_BLOB *blob;
2002 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + bits[i].cbDecoded,
2003 "Got unexpected size %d\n", bufSize);
2004 blob = (CRYPT_BIT_BLOB *)buf;
2005 ok(blob->cbData == bits[i].cbDecoded,
2006 "Got unexpected length %d, expected %d\n", blob->cbData,
2007 bits[i].cbDecoded);
2008 if (blob->cbData && bits[i].cbDecoded)
2009 ok(!memcmp(blob->pbData, bits[i].decoded, bits[i].cbDecoded),
2010 "Unexpected value\n");
2011 LocalFree(buf);
2014 /* special case: check that something that's valid in BER but not in DER
2015 * decodes successfully
2017 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, ber, ber[1] + 2,
2018 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2019 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2020 if (buf)
2022 CRYPT_BIT_BLOB *blob;
2024 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + sizeof(berDecoded),
2025 "Got unexpected size %d\n", bufSize);
2026 blob = (CRYPT_BIT_BLOB *)buf;
2027 ok(blob->cbData == sizeof(berDecoded),
2028 "Got unexpected length %d\n", blob->cbData);
2029 if (blob->cbData)
2030 ok(*blob->pbData == berDecoded, "Unexpected value\n");
2031 LocalFree(buf);
2035 struct Constraints2
2037 CERT_BASIC_CONSTRAINTS2_INFO info;
2038 const BYTE *encoded;
2041 static const unsigned char bin59[] = { 0x30,0x00 };
2042 static const unsigned char bin60[] = { 0x30,0x03,0x01,0x01,0xff };
2043 static const unsigned char bin61[] = { 0x30,0x03,0x02,0x01,0x00 };
2044 static const unsigned char bin62[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2045 static const struct Constraints2 constraints2[] = {
2046 /* empty constraints */
2047 { { FALSE, FALSE, 0}, bin59 },
2048 /* can be a CA */
2049 { { TRUE, FALSE, 0}, bin60 },
2050 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well,
2051 * but that's not the case
2053 { { FALSE, TRUE, 0}, bin61 },
2054 /* can be a CA and has path length constraints set */
2055 { { TRUE, TRUE, 1}, bin62 },
2058 static const BYTE emptyConstraint[] = { 0x30, 0x03, 0x03, 0x01, 0x00 };
2059 static const BYTE encodedDomainName[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11,
2060 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
2061 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
2062 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2063 static const BYTE constraintWithDomainName[] = { 0x30, 0x32, 0x03, 0x01, 0x00,
2064 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
2065 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30,
2066 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
2067 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2069 static void test_encodeBasicConstraints(DWORD dwEncoding)
2071 DWORD i, bufSize = 0;
2072 CERT_BASIC_CONSTRAINTS_INFO info = { { 0 } };
2073 CERT_NAME_BLOB nameBlob = { sizeof(encodedDomainName),
2074 (LPBYTE)encodedDomainName };
2075 BOOL ret;
2076 BYTE *buf = NULL;
2078 /* First test with the simpler info2 */
2079 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2081 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2082 &constraints2[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2083 &bufSize);
2084 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2085 if (buf)
2087 ok(bufSize == constraints2[i].encoded[1] + 2,
2088 "Expected %d bytes, got %d\n", constraints2[i].encoded[1] + 2,
2089 bufSize);
2090 ok(!memcmp(buf, constraints2[i].encoded,
2091 constraints2[i].encoded[1] + 2), "Unexpected value\n");
2092 LocalFree(buf);
2095 /* Now test with more complex basic constraints */
2096 info.SubjectType.cbData = 0;
2097 info.fPathLenConstraint = FALSE;
2098 info.cSubtreesConstraint = 0;
2099 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2100 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2101 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2102 if (buf)
2104 ok(bufSize == sizeof(emptyConstraint), "Wrong size %d\n", bufSize);
2105 ok(!memcmp(buf, emptyConstraint, sizeof(emptyConstraint)),
2106 "Unexpected value\n");
2107 LocalFree(buf);
2109 /* None of the certs I examined had any subtree constraint, but I test one
2110 * anyway just in case.
2112 info.cSubtreesConstraint = 1;
2113 info.rgSubtreesConstraint = &nameBlob;
2114 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2115 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2116 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2117 if (buf)
2119 ok(bufSize == sizeof(constraintWithDomainName), "Wrong size %d\n", bufSize);
2120 ok(!memcmp(buf, constraintWithDomainName,
2121 sizeof(constraintWithDomainName)), "Unexpected value\n");
2122 LocalFree(buf);
2124 /* FIXME: test encoding with subject type. */
2127 static const unsigned char bin63[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 };
2129 static void test_decodeBasicConstraints(DWORD dwEncoding)
2131 static const BYTE inverted[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01,
2132 0xff };
2133 static const struct Constraints2 badBool = { { TRUE, TRUE, 1 }, bin63 };
2134 DWORD i;
2135 BOOL ret;
2136 BYTE *buf = NULL;
2137 DWORD bufSize = 0;
2139 /* First test with simpler info2 */
2140 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2142 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2143 constraints2[i].encoded, constraints2[i].encoded[1] + 2,
2144 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2145 ok(ret, "CryptDecodeObjectEx failed for item %d: %08x\n", i,
2146 GetLastError());
2147 if (buf)
2149 CERT_BASIC_CONSTRAINTS2_INFO *info =
2150 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2152 ok(!memcmp(info, &constraints2[i].info, sizeof(*info)),
2153 "Unexpected value for item %d\n", i);
2154 LocalFree(buf);
2157 /* Check with the order of encoded elements inverted */
2158 buf = (PBYTE)1;
2159 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2160 inverted, inverted[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2161 &bufSize);
2162 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2163 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2164 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2165 GetLastError());
2166 ok(!buf, "Expected buf to be set to NULL\n");
2167 /* Check with a non-DER bool */
2168 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2169 badBool.encoded, badBool.encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2170 (BYTE *)&buf, &bufSize);
2171 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2172 if (buf)
2174 CERT_BASIC_CONSTRAINTS2_INFO *info =
2175 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2177 ok(!memcmp(info, &badBool.info, sizeof(*info)), "Unexpected value\n");
2178 LocalFree(buf);
2180 /* Check with a non-basic constraints value */
2181 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2182 (LPBYTE)encodedCommonName, encodedCommonName[1] + 2,
2183 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2184 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2185 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2186 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2187 GetLastError());
2188 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */
2189 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2190 emptyConstraint, sizeof(emptyConstraint), CRYPT_DECODE_ALLOC_FLAG, NULL,
2191 (BYTE *)&buf, &bufSize);
2192 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2193 if (buf)
2195 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2197 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2198 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2199 ok(info->cSubtreesConstraint == 0, "Expected no subtree constraints\n");
2200 LocalFree(buf);
2202 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2203 constraintWithDomainName, sizeof(constraintWithDomainName),
2204 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2205 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2206 if (buf)
2208 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2210 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2211 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2212 ok(info->cSubtreesConstraint == 1, "Expected a subtree constraint\n");
2213 if (info->cSubtreesConstraint && info->rgSubtreesConstraint)
2215 ok(info->rgSubtreesConstraint[0].cbData ==
2216 sizeof(encodedDomainName), "Wrong size %d\n",
2217 info->rgSubtreesConstraint[0].cbData);
2218 ok(!memcmp(info->rgSubtreesConstraint[0].pbData, encodedDomainName,
2219 sizeof(encodedDomainName)), "Unexpected value\n");
2221 LocalFree(buf);
2225 /* These are terrible public keys of course, I'm just testing encoding */
2226 static const BYTE modulus1[] = { 0,0,0,1,1,1,1,1 };
2227 static const BYTE modulus2[] = { 1,1,1,1,1,0,0,0 };
2228 static const BYTE modulus3[] = { 0x80,1,1,1,1,0,0,0 };
2229 static const BYTE modulus4[] = { 1,1,1,1,1,0,0,0x80 };
2230 static const BYTE mod1_encoded[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 };
2231 static const BYTE mod2_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2232 static const BYTE mod3_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 };
2233 static const BYTE mod4_encoded[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2235 struct EncodedRSAPubKey
2237 const BYTE *modulus;
2238 size_t modulusLen;
2239 const BYTE *encoded;
2240 size_t decodedModulusLen;
2243 struct EncodedRSAPubKey rsaPubKeys[] = {
2244 { modulus1, sizeof(modulus1), mod1_encoded, sizeof(modulus1) },
2245 { modulus2, sizeof(modulus2), mod2_encoded, 5 },
2246 { modulus3, sizeof(modulus3), mod3_encoded, 5 },
2247 { modulus4, sizeof(modulus4), mod4_encoded, 8 },
2250 static void test_encodeRsaPublicKey(DWORD dwEncoding)
2252 BYTE toEncode[sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + sizeof(modulus1)];
2253 BLOBHEADER *hdr = (BLOBHEADER *)toEncode;
2254 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(toEncode + sizeof(BLOBHEADER));
2255 BOOL ret;
2256 BYTE *buf = NULL;
2257 DWORD bufSize = 0, i;
2259 /* Try with a bogus blob type */
2260 hdr->bType = 2;
2261 hdr->bVersion = CUR_BLOB_VERSION;
2262 hdr->reserved = 0;
2263 hdr->aiKeyAlg = CALG_RSA_KEYX;
2264 rsaPubKey->magic = 0x31415352;
2265 rsaPubKey->bitlen = sizeof(modulus1) * 8;
2266 rsaPubKey->pubexp = 65537;
2267 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), modulus1,
2268 sizeof(modulus1));
2270 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2271 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2272 &bufSize);
2273 ok(!ret && GetLastError() == E_INVALIDARG,
2274 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2275 /* Now with a bogus reserved field */
2276 hdr->bType = PUBLICKEYBLOB;
2277 hdr->reserved = 1;
2278 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2279 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2280 &bufSize);
2281 if (buf)
2283 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2284 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2285 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2286 LocalFree(buf);
2288 /* Now with a bogus blob version */
2289 hdr->reserved = 0;
2290 hdr->bVersion = 0;
2291 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2292 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2293 &bufSize);
2294 if (buf)
2296 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2297 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2298 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2299 LocalFree(buf);
2301 /* And with a bogus alg ID */
2302 hdr->bVersion = CUR_BLOB_VERSION;
2303 hdr->aiKeyAlg = CALG_DES;
2304 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2305 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2306 &bufSize);
2307 if (buf)
2309 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2310 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2311 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2312 LocalFree(buf);
2314 /* Check a couple of RSA-related OIDs */
2315 hdr->aiKeyAlg = CALG_RSA_KEYX;
2316 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_RSA,
2317 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2318 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2319 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2320 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2321 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2322 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2323 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2324 /* Finally, all valid */
2325 hdr->aiKeyAlg = CALG_RSA_KEYX;
2326 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2328 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2329 rsaPubKeys[i].modulus, rsaPubKeys[i].modulusLen);
2330 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2331 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2332 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2333 if (buf)
2335 ok(bufSize == rsaPubKeys[i].encoded[1] + 2,
2336 "Expected size %d, got %d\n", rsaPubKeys[i].encoded[1] + 2,
2337 bufSize);
2338 ok(!memcmp(buf, rsaPubKeys[i].encoded, bufSize),
2339 "Unexpected value\n");
2340 LocalFree(buf);
2345 static void test_decodeRsaPublicKey(DWORD dwEncoding)
2347 DWORD i;
2348 LPBYTE buf = NULL;
2349 DWORD bufSize = 0;
2350 BOOL ret;
2352 /* Try with a bad length */
2353 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2354 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1],
2355 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2356 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2357 "Expected CRYPT_E_ASN1_EOD, got %08x\n", CRYPT_E_ASN1_EOD);
2358 /* Try with a couple of RSA-related OIDs */
2359 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_RSA,
2360 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2361 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2362 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2363 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2364 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2365 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2366 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2367 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2368 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2369 /* Now try success cases */
2370 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2372 bufSize = 0;
2373 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2374 rsaPubKeys[i].encoded, rsaPubKeys[i].encoded[1] + 2,
2375 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2376 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2377 if (buf)
2379 BLOBHEADER *hdr = (BLOBHEADER *)buf;
2380 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER));
2382 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2383 rsaPubKeys[i].decodedModulusLen,
2384 "Wrong size %d\n", bufSize);
2385 ok(hdr->bType == PUBLICKEYBLOB,
2386 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB,
2387 hdr->bType);
2388 ok(hdr->bVersion == CUR_BLOB_VERSION,
2389 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
2390 CUR_BLOB_VERSION, hdr->bVersion);
2391 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n",
2392 hdr->reserved);
2393 ok(hdr->aiKeyAlg == CALG_RSA_KEYX,
2394 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg);
2395 ok(rsaPubKey->magic == 0x31415352,
2396 "Expected magic RSA1, got %08x\n", rsaPubKey->magic);
2397 ok(rsaPubKey->bitlen == rsaPubKeys[i].decodedModulusLen * 8,
2398 "Wrong bit len %d\n", rsaPubKey->bitlen);
2399 ok(rsaPubKey->pubexp == 65537, "Expected pubexp 65537, got %d\n",
2400 rsaPubKey->pubexp);
2401 ok(!memcmp(buf + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2402 rsaPubKeys[i].modulus, rsaPubKeys[i].decodedModulusLen),
2403 "Unexpected modulus\n");
2404 LocalFree(buf);
2409 static const BYTE intSequence[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01,
2410 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02,
2411 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2413 static const BYTE mixedSequence[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
2414 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f,
2415 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02,
2416 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2418 static void test_encodeSequenceOfAny(DWORD dwEncoding)
2420 CRYPT_DER_BLOB blobs[sizeof(ints) / sizeof(ints[0])];
2421 CRYPT_SEQUENCE_OF_ANY seq;
2422 DWORD i;
2423 BOOL ret;
2424 BYTE *buf = NULL;
2425 DWORD bufSize = 0;
2427 /* Encode a homogeneous sequence */
2428 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
2430 blobs[i].cbData = ints[i].encoded[1] + 2;
2431 blobs[i].pbData = (BYTE *)ints[i].encoded;
2433 seq.cValue = sizeof(ints) / sizeof(ints[0]);
2434 seq.rgValue = blobs;
2436 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2437 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2438 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2439 if (buf)
2441 ok(bufSize == sizeof(intSequence), "Wrong size %d\n", bufSize);
2442 ok(!memcmp(buf, intSequence, intSequence[1] + 2), "Unexpected value\n");
2443 LocalFree(buf);
2445 /* Change the type of the first element in the sequence, and give it
2446 * another go
2448 blobs[0].cbData = times[0].encodedTime[1] + 2;
2449 blobs[0].pbData = (BYTE *)times[0].encodedTime;
2450 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2451 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2452 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2453 if (buf)
2455 ok(bufSize == sizeof(mixedSequence), "Wrong size %d\n", bufSize);
2456 ok(!memcmp(buf, mixedSequence, mixedSequence[1] + 2),
2457 "Unexpected value\n");
2458 LocalFree(buf);
2462 static void test_decodeSequenceOfAny(DWORD dwEncoding)
2464 BOOL ret;
2465 BYTE *buf = NULL;
2466 DWORD bufSize = 0;
2468 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, intSequence,
2469 intSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2470 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2471 if (buf)
2473 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2474 DWORD i;
2476 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2477 "Wrong elements %d\n", seq->cValue);
2478 for (i = 0; i < min(seq->cValue, sizeof(ints) / sizeof(ints[0])); i++)
2480 ok(seq->rgValue[i].cbData == ints[i].encoded[1] + 2,
2481 "Expected %d bytes, got %d\n", ints[i].encoded[1] + 2,
2482 seq->rgValue[i].cbData);
2483 ok(!memcmp(seq->rgValue[i].pbData, ints[i].encoded,
2484 ints[i].encoded[1] + 2), "Unexpected value\n");
2486 LocalFree(buf);
2488 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, mixedSequence,
2489 mixedSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2490 &bufSize);
2491 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2492 if (buf)
2494 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2496 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2497 "Wrong elements %d\n", seq->cValue);
2498 /* Just check the first element since it's all that changed */
2499 ok(seq->rgValue[0].cbData == times[0].encodedTime[1] + 2,
2500 "Expected %d bytes, got %d\n", times[0].encodedTime[1] + 2,
2501 seq->rgValue[0].cbData);
2502 ok(!memcmp(seq->rgValue[0].pbData, times[0].encodedTime,
2503 times[0].encodedTime[1] + 2), "Unexpected value\n");
2504 LocalFree(buf);
2508 struct encodedExtensions
2510 CERT_EXTENSIONS exts;
2511 const BYTE *encoded;
2514 static BYTE crit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2515 static BYTE noncrit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2516 static CHAR oid_basic_constraints2[] = szOID_BASIC_CONSTRAINTS2;
2517 static CERT_EXTENSION criticalExt =
2518 { oid_basic_constraints2, TRUE, { 8, crit_ext_data } };
2519 static CERT_EXTENSION nonCriticalExt =
2520 { oid_basic_constraints2, FALSE, { 8, noncrit_ext_data } };
2522 static const BYTE ext0[] = { 0x30,0x00 };
2523 static const BYTE ext1[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2524 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2525 static const BYTE ext2[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2526 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2528 static const struct encodedExtensions exts[] = {
2529 { { 0, NULL }, ext0 },
2530 { { 1, &criticalExt }, ext1 },
2531 { { 1, &nonCriticalExt }, ext2 },
2534 static void test_encodeExtensions(DWORD dwEncoding)
2536 DWORD i;
2538 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2540 BOOL ret;
2541 BYTE *buf = NULL;
2542 DWORD bufSize = 0;
2544 ret = pCryptEncodeObjectEx(dwEncoding, X509_EXTENSIONS, &exts[i].exts,
2545 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2546 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2547 if (buf)
2549 ok(bufSize == exts[i].encoded[1] + 2,
2550 "Expected %d bytes, got %d\n", exts[i].encoded[1] + 2, bufSize);
2551 ok(!memcmp(buf, exts[i].encoded, exts[i].encoded[1] + 2),
2552 "Unexpected value\n");
2553 LocalFree(buf);
2558 static void test_decodeExtensions(DWORD dwEncoding)
2560 DWORD i;
2562 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2564 BOOL ret;
2565 BYTE *buf = NULL;
2566 DWORD bufSize = 0;
2568 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS,
2569 exts[i].encoded, exts[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2570 NULL, (BYTE *)&buf, &bufSize);
2571 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2572 if (buf)
2574 CERT_EXTENSIONS *ext = (CERT_EXTENSIONS *)buf;
2575 DWORD j;
2577 ok(ext->cExtension == exts[i].exts.cExtension,
2578 "Expected %d extensions, see %d\n", exts[i].exts.cExtension,
2579 ext->cExtension);
2580 for (j = 0; j < min(ext->cExtension, exts[i].exts.cExtension); j++)
2582 ok(!strcmp(ext->rgExtension[j].pszObjId,
2583 exts[i].exts.rgExtension[j].pszObjId),
2584 "Expected OID %s, got %s\n",
2585 exts[i].exts.rgExtension[j].pszObjId,
2586 ext->rgExtension[j].pszObjId);
2587 ok(!memcmp(ext->rgExtension[j].Value.pbData,
2588 exts[i].exts.rgExtension[j].Value.pbData,
2589 exts[i].exts.rgExtension[j].Value.cbData),
2590 "Unexpected value\n");
2592 LocalFree(buf);
2597 /* MS encodes public key info with a NULL if the algorithm identifier's
2598 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2599 * it encodes them by omitting the algorithm parameters. This latter approach
2600 * seems more correct, so accept either form.
2602 struct encodedPublicKey
2604 CERT_PUBLIC_KEY_INFO info;
2605 const BYTE *encoded;
2606 const BYTE *encodedNoNull;
2607 CERT_PUBLIC_KEY_INFO decoded;
2610 static const BYTE aKey[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2611 0xe, 0xf };
2612 static const BYTE params[] = { 0x02, 0x01, 0x01 };
2614 static const unsigned char bin64[] = {
2615 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2616 static const unsigned char bin65[] = {
2617 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2618 static const unsigned char bin66[] = {
2619 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2620 static const unsigned char bin67[] = {
2621 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2622 static const unsigned char bin68[] = {
2623 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01,
2624 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2625 static const unsigned char bin69[] = {
2626 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2627 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2628 static const unsigned char bin70[] = {
2629 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2630 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2631 0x0f};
2632 static const unsigned char bin71[] = {
2633 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2634 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2635 0x0f};
2636 static unsigned char bin72[] = { 0x05,0x00};
2638 static CHAR oid_bogus[] = "1.2.3",
2639 oid_rsa[] = szOID_RSA;
2641 static const struct encodedPublicKey pubKeys[] = {
2642 /* with a bogus OID */
2643 { { { oid_bogus, { 0, NULL } }, { 0, NULL, 0 } },
2644 bin64, bin65,
2645 { { oid_bogus, { 2, bin72 } }, { 0, NULL, 0 } } },
2646 /* some normal keys */
2647 { { { oid_rsa, { 0, NULL } }, { 0, NULL, 0} },
2648 bin66, bin67,
2649 { { oid_rsa, { 2, bin72 } }, { 0, NULL, 0 } } },
2650 { { { oid_rsa, { 0, NULL } }, { sizeof(aKey), (BYTE *)aKey, 0} },
2651 bin68, bin69,
2652 { { oid_rsa, { 2, bin72 } }, { sizeof(aKey), (BYTE *)aKey, 0} } },
2653 /* with add'l parameters--note they must be DER-encoded */
2654 { { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2655 (BYTE *)aKey, 0 } },
2656 bin70, bin71,
2657 { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2658 (BYTE *)aKey, 0 } } },
2661 static void test_encodePublicKeyInfo(DWORD dwEncoding)
2663 DWORD i;
2665 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2667 BOOL ret;
2668 BYTE *buf = NULL;
2669 DWORD bufSize = 0;
2671 ret = pCryptEncodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2672 &pubKeys[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2673 &bufSize);
2674 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2675 if (buf)
2677 ok(bufSize == pubKeys[i].encoded[1] + 2 ||
2678 bufSize == pubKeys[i].encodedNoNull[1] + 2,
2679 "Expected %d or %d bytes, got %d\n", pubKeys[i].encoded[1] + 2,
2680 pubKeys[i].encodedNoNull[1] + 2, bufSize);
2681 if (bufSize == pubKeys[i].encoded[1] + 2)
2682 ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2),
2683 "Unexpected value\n");
2684 else if (bufSize == pubKeys[i].encodedNoNull[1] + 2)
2685 ok(!memcmp(buf, pubKeys[i].encodedNoNull,
2686 pubKeys[i].encodedNoNull[1] + 2), "Unexpected value\n");
2687 LocalFree(buf);
2692 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO *expected,
2693 const CERT_PUBLIC_KEY_INFO *got)
2695 ok(!strcmp(expected->Algorithm.pszObjId, got->Algorithm.pszObjId),
2696 "Expected OID %s, got %s\n", expected->Algorithm.pszObjId,
2697 got->Algorithm.pszObjId);
2698 ok(expected->Algorithm.Parameters.cbData ==
2699 got->Algorithm.Parameters.cbData,
2700 "Expected parameters of %d bytes, got %d\n",
2701 expected->Algorithm.Parameters.cbData, got->Algorithm.Parameters.cbData);
2702 if (expected->Algorithm.Parameters.cbData)
2703 ok(!memcmp(expected->Algorithm.Parameters.pbData,
2704 got->Algorithm.Parameters.pbData, got->Algorithm.Parameters.cbData),
2705 "Unexpected algorithm parameters\n");
2706 ok(expected->PublicKey.cbData == got->PublicKey.cbData,
2707 "Expected public key of %d bytes, got %d\n",
2708 expected->PublicKey.cbData, got->PublicKey.cbData);
2709 if (expected->PublicKey.cbData)
2710 ok(!memcmp(expected->PublicKey.pbData, got->PublicKey.pbData,
2711 got->PublicKey.cbData), "Unexpected public key value\n");
2714 static void test_decodePublicKeyInfo(DWORD dwEncoding)
2716 static const BYTE bogusPubKeyInfo[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
2717 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
2718 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
2719 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2720 DWORD i;
2721 BOOL ret;
2722 BYTE *buf = NULL;
2723 DWORD bufSize = 0;
2725 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2727 /* The NULL form decodes to the decoded member */
2728 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2729 pubKeys[i].encoded, pubKeys[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2730 NULL, (BYTE *)&buf, &bufSize);
2731 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2732 if (buf)
2734 comparePublicKeyInfo(&pubKeys[i].decoded,
2735 (CERT_PUBLIC_KEY_INFO *)buf);
2736 LocalFree(buf);
2738 /* The non-NULL form decodes to the original */
2739 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2740 pubKeys[i].encodedNoNull, pubKeys[i].encodedNoNull[1] + 2,
2741 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2742 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2743 if (buf)
2745 comparePublicKeyInfo(&pubKeys[i].info, (CERT_PUBLIC_KEY_INFO *)buf);
2746 LocalFree(buf);
2749 /* Test with bogus (not valid DER) parameters */
2750 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2751 bogusPubKeyInfo, bogusPubKeyInfo[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2752 NULL, (BYTE *)&buf, &bufSize);
2753 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
2754 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2757 static const BYTE v1Cert[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
2758 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2759 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
2760 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
2761 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2762 static const BYTE v2Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02,
2763 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2764 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2765 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2766 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2767 static const BYTE v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2768 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2769 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2770 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2771 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2772 static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
2773 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2774 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2775 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2776 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2777 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2778 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2779 static const BYTE v1CertWithSerial[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
2780 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2781 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2782 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2783 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2784 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2785 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2786 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2787 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
2788 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
2789 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
2790 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
2791 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
2792 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
2793 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
2794 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
2795 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2796 static const BYTE v1CertWithPubKey[] = {
2797 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2798 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2799 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2800 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2801 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2802 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2803 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2804 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2805 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
2806 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
2807 0x01,0x01 };
2808 static const BYTE v1CertWithPubKeyNoNull[] = {
2809 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2810 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2811 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2812 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2813 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2814 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2815 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2816 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2817 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
2818 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2819 static const BYTE v1CertWithSubjectKeyId[] = {
2820 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2821 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2822 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2823 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2824 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2825 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2826 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
2827 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2828 0x4c,0x61,0x6e,0x67,0x00 };
2830 static const BYTE serialNum[] = { 0x01 };
2832 static void test_encodeCertToBeSigned(DWORD dwEncoding)
2834 BOOL ret;
2835 BYTE *buf = NULL;
2836 DWORD size = 0;
2837 CERT_INFO info = { 0 };
2838 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2839 static char oid_subject_key_identifier[] = szOID_SUBJECT_KEY_IDENTIFIER;
2840 CERT_EXTENSION ext;
2842 if (0)
2844 /* Test with NULL pvStructInfo (crashes on win9x) */
2845 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL,
2846 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2847 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2848 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2850 /* Test with a V1 cert */
2851 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2852 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2853 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2854 if (buf)
2856 ok(size == v1Cert[1] + 2, "Expected size %d, got %d\n",
2857 v1Cert[1] + 2, size);
2858 ok(!memcmp(buf, v1Cert, size), "Got unexpected value\n");
2859 LocalFree(buf);
2861 /* Test v2 cert */
2862 info.dwVersion = CERT_V2;
2863 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2864 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2865 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2866 if (buf)
2868 ok(size == sizeof(v2Cert), "Wrong size %d\n", size);
2869 ok(!memcmp(buf, v2Cert, size), "Got unexpected value\n");
2870 LocalFree(buf);
2872 /* Test v3 cert */
2873 info.dwVersion = CERT_V3;
2874 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2875 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2876 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2877 if (buf)
2879 ok(size == sizeof(v3Cert), "Wrong size %d\n", size);
2880 ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n");
2881 LocalFree(buf);
2883 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
2884 * API doesn't prevent it)
2886 info.dwVersion = CERT_V1;
2887 info.cExtension = 1;
2888 info.rgExtension = &criticalExt;
2889 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2890 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2891 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2892 if (buf)
2894 ok(size == sizeof(v1CertWithConstraints), "Wrong size %d\n", size);
2895 ok(!memcmp(buf, v1CertWithConstraints, size), "Got unexpected value\n");
2896 LocalFree(buf);
2898 /* test v1 cert with a serial number */
2899 info.SerialNumber.cbData = sizeof(serialNum);
2900 info.SerialNumber.pbData = (BYTE *)serialNum;
2901 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2902 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2903 if (buf)
2905 ok(size == sizeof(v1CertWithSerial), "Wrong size %d\n", size);
2906 ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n");
2907 LocalFree(buf);
2909 /* Test v1 cert with an issuer name, a subject name, and a serial number */
2910 info.Issuer.cbData = sizeof(encodedCommonName);
2911 info.Issuer.pbData = (BYTE *)encodedCommonName;
2912 info.Subject.cbData = sizeof(encodedCommonName);
2913 info.Subject.pbData = (BYTE *)encodedCommonName;
2914 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2915 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2916 if (buf)
2918 ok(size == sizeof(bigCert), "Wrong size %d\n", size);
2919 ok(!memcmp(buf, bigCert, size), "Got unexpected value\n");
2920 LocalFree(buf);
2922 /* Add a public key */
2923 info.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2924 info.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2925 info.SubjectPublicKeyInfo.PublicKey.pbData = (LPBYTE)aKey;
2926 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2927 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2928 if (buf)
2930 ok(size == sizeof(v1CertWithPubKey) ||
2931 size == sizeof(v1CertWithPubKeyNoNull), "Wrong size %d\n", size);
2932 if (size == sizeof(v1CertWithPubKey))
2933 ok(!memcmp(buf, v1CertWithPubKey, size), "Got unexpected value\n");
2934 else if (size == sizeof(v1CertWithPubKeyNoNull))
2935 ok(!memcmp(buf, v1CertWithPubKeyNoNull, size),
2936 "Got unexpected value\n");
2937 LocalFree(buf);
2939 /* Remove the public key, and add a subject key identifier extension */
2940 info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2941 info.SubjectPublicKeyInfo.PublicKey.cbData = 0;
2942 info.SubjectPublicKeyInfo.PublicKey.pbData = NULL;
2943 ext.pszObjId = oid_subject_key_identifier;
2944 ext.fCritical = FALSE;
2945 ext.Value.cbData = sizeof(octetCommonNameValue);
2946 ext.Value.pbData = (BYTE *)octetCommonNameValue;
2947 info.cExtension = 1;
2948 info.rgExtension = &ext;
2949 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2950 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2951 if (buf)
2953 ok(size == sizeof(v1CertWithSubjectKeyId), "Wrong size %d\n", size);
2954 ok(!memcmp(buf, v1CertWithSubjectKeyId, size), "Unexpected value\n");
2955 LocalFree(buf);
2959 static void test_decodeCertToBeSigned(DWORD dwEncoding)
2961 static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert,
2962 v1CertWithConstraints, v1CertWithSerial };
2963 BOOL ret;
2964 BYTE *buf = NULL;
2965 DWORD size = 0, i;
2967 /* Test with NULL pbEncoded */
2968 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 0,
2969 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2970 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2971 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2972 if (0)
2974 /* Crashes on win9x */
2975 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 1,
2976 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2977 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2978 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2980 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT, because at a
2981 * minimum a cert must have a non-zero serial number, an issuer, and a
2982 * subject.
2984 for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++)
2986 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
2987 corruptCerts[i], corruptCerts[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2988 (BYTE *)&buf, &size);
2989 ok(!ret, "Expected failure\n");
2991 /* Now check with serial number, subject and issuer specified */
2992 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert,
2993 sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2994 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2995 if (buf)
2997 CERT_INFO *info = (CERT_INFO *)buf;
2999 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3000 ok(info->SerialNumber.cbData == 1,
3001 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3002 ok(*info->SerialNumber.pbData == *serialNum,
3003 "Expected serial number %d, got %d\n", *serialNum,
3004 *info->SerialNumber.pbData);
3005 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3006 "Wrong size %d\n", info->Issuer.cbData);
3007 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3008 "Unexpected issuer\n");
3009 ok(info->Subject.cbData == sizeof(encodedCommonName),
3010 "Wrong size %d\n", info->Subject.cbData);
3011 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3012 info->Subject.cbData), "Unexpected subject\n");
3013 LocalFree(buf);
3015 /* Check again with pub key specified */
3016 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3017 v1CertWithPubKey, sizeof(v1CertWithPubKey), CRYPT_DECODE_ALLOC_FLAG, NULL,
3018 (BYTE *)&buf, &size);
3019 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3020 if (buf)
3022 CERT_INFO *info = (CERT_INFO *)buf;
3024 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3025 ok(info->SerialNumber.cbData == 1,
3026 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3027 ok(*info->SerialNumber.pbData == *serialNum,
3028 "Expected serial number %d, got %d\n", *serialNum,
3029 *info->SerialNumber.pbData);
3030 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3031 "Wrong size %d\n", info->Issuer.cbData);
3032 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3033 "Unexpected issuer\n");
3034 ok(info->Subject.cbData == sizeof(encodedCommonName),
3035 "Wrong size %d\n", info->Subject.cbData);
3036 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3037 info->Subject.cbData), "Unexpected subject\n");
3038 ok(!strcmp(info->SubjectPublicKeyInfo.Algorithm.pszObjId,
3039 szOID_RSA_RSA), "Expected szOID_RSA_RSA, got %s\n",
3040 info->SubjectPublicKeyInfo.Algorithm.pszObjId);
3041 ok(info->SubjectPublicKeyInfo.PublicKey.cbData == sizeof(aKey),
3042 "Wrong size %d\n", info->SubjectPublicKeyInfo.PublicKey.cbData);
3043 ok(!memcmp(info->SubjectPublicKeyInfo.PublicKey.pbData, aKey,
3044 sizeof(aKey)), "Unexpected public key\n");
3045 LocalFree(buf);
3049 static const BYTE hash[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
3050 0xe, 0xf };
3052 static const BYTE signedBigCert[] = {
3053 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
3054 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
3055 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
3056 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3057 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
3058 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
3059 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
3060 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
3061 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
3062 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3063 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
3064 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
3066 static void test_encodeCert(DWORD dwEncoding)
3068 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
3069 * also that bigCert is a NULL-terminated string, so don't count its
3070 * last byte (otherwise the signed cert won't decode.)
3072 CERT_SIGNED_CONTENT_INFO info = { { sizeof(bigCert), (BYTE *)bigCert },
3073 { NULL, { 0, NULL } }, { sizeof(hash), (BYTE *)hash, 0 } };
3074 BOOL ret;
3075 BYTE *buf = NULL;
3076 DWORD bufSize = 0;
3078 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT, &info,
3079 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
3080 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3081 if (buf)
3083 ok(bufSize == sizeof(signedBigCert), "Wrong size %d\n", bufSize);
3084 ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n");
3085 LocalFree(buf);
3089 static void test_decodeCert(DWORD dwEncoding)
3091 BOOL ret;
3092 BYTE *buf = NULL;
3093 DWORD size = 0;
3095 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert,
3096 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3097 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3098 if (buf)
3100 CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf;
3102 ok(info->ToBeSigned.cbData == sizeof(bigCert),
3103 "Wrong cert size %d\n", info->ToBeSigned.cbData);
3104 ok(!memcmp(info->ToBeSigned.pbData, bigCert, info->ToBeSigned.cbData),
3105 "Unexpected cert\n");
3106 ok(info->Signature.cbData == sizeof(hash),
3107 "Wrong signature size %d\n", info->Signature.cbData);
3108 ok(!memcmp(info->Signature.pbData, hash, info->Signature.cbData),
3109 "Unexpected signature\n");
3110 LocalFree(buf);
3112 /* A signed cert decodes as a CERT_INFO too */
3113 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCert,
3114 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3115 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3116 if (buf)
3118 CERT_INFO *info = (CERT_INFO *)buf;
3120 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3121 ok(info->SerialNumber.cbData == 1,
3122 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3123 ok(*info->SerialNumber.pbData == *serialNum,
3124 "Expected serial number %d, got %d\n", *serialNum,
3125 *info->SerialNumber.pbData);
3126 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3127 "Wrong size %d\n", info->Issuer.cbData);
3128 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3129 "Unexpected issuer\n");
3130 ok(info->Subject.cbData == sizeof(encodedCommonName),
3131 "Wrong size %d\n", info->Subject.cbData);
3132 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3133 info->Subject.cbData), "Unexpected subject\n");
3134 LocalFree(buf);
3138 static const BYTE emptyDistPoint[] = { 0x30, 0x02, 0x30, 0x00 };
3139 static const BYTE distPointWithUrl[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3140 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3141 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3142 static const BYTE distPointWithReason[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3143 0x00, 0x03 };
3144 static const BYTE distPointWithIssuer[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3145 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3146 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3147 static const BYTE distPointWithUrlAndIssuer[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3148 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3149 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3150 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3151 0x2e, 0x6f, 0x72, 0x67 };
3152 static const BYTE crlReason = CRL_REASON_KEY_COMPROMISE |
3153 CRL_REASON_AFFILIATION_CHANGED;
3155 static void test_encodeCRLDistPoints(DWORD dwEncoding)
3157 CRL_DIST_POINTS_INFO info = { 0 };
3158 CRL_DIST_POINT point = { { 0 } };
3159 CERT_ALT_NAME_ENTRY entry = { 0 };
3160 BOOL ret;
3161 BYTE *buf = NULL;
3162 DWORD size = 0;
3164 /* Test with an empty info */
3165 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3166 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3167 ok(!ret && GetLastError() == E_INVALIDARG,
3168 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3169 /* Test with one empty dist point */
3170 info.cDistPoint = 1;
3171 info.rgDistPoint = &point;
3172 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3173 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3174 if (buf)
3176 ok(size == sizeof(emptyDistPoint), "Wrong size %d\n", size);
3177 ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n");
3178 LocalFree(buf);
3180 /* A dist point with an invalid name */
3181 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3182 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3183 U(entry).pwszURL = (LPWSTR)nihongoURL;
3184 U(point.DistPointName).FullName.cAltEntry = 1;
3185 U(point.DistPointName).FullName.rgAltEntry = &entry;
3186 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3187 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3188 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
3189 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
3190 /* The first invalid character is at index 7 */
3191 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
3192 "Expected invalid char at index 7, got %d\n",
3193 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
3194 /* A dist point with (just) a valid name */
3195 U(entry).pwszURL = (LPWSTR)url;
3196 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3197 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3198 if (buf)
3200 ok(size == sizeof(distPointWithUrl), "Wrong size %d\n", size);
3201 ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n");
3202 LocalFree(buf);
3204 /* A dist point with (just) reason flags */
3205 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3206 point.ReasonFlags.cbData = sizeof(crlReason);
3207 point.ReasonFlags.pbData = (LPBYTE)&crlReason;
3208 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3209 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3210 if (buf)
3212 ok(size == sizeof(distPointWithReason), "Wrong size %d\n", size);
3213 ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n");
3214 LocalFree(buf);
3216 /* A dist point with just an issuer */
3217 point.ReasonFlags.cbData = 0;
3218 point.CRLIssuer.cAltEntry = 1;
3219 point.CRLIssuer.rgAltEntry = &entry;
3220 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3221 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3222 if (buf)
3224 ok(size == sizeof(distPointWithIssuer), "Wrong size %d\n", size);
3225 ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n");
3226 LocalFree(buf);
3228 /* A dist point with both a name and an issuer */
3229 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3230 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3231 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3232 if (buf)
3234 ok(size == sizeof(distPointWithUrlAndIssuer),
3235 "Wrong size %d\n", size);
3236 ok(!memcmp(buf, distPointWithUrlAndIssuer, size), "Unexpected value\n");
3237 LocalFree(buf);
3241 static void test_decodeCRLDistPoints(DWORD dwEncoding)
3243 BOOL ret;
3244 BYTE *buf = NULL;
3245 DWORD size = 0;
3246 PCRL_DIST_POINTS_INFO info;
3247 PCRL_DIST_POINT point;
3248 PCERT_ALT_NAME_ENTRY entry;
3250 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3251 emptyDistPoint, emptyDistPoint[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3252 (BYTE *)&buf, &size);
3253 if (ret)
3255 info = (PCRL_DIST_POINTS_INFO)buf;
3256 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3257 "Wrong size %d\n", size);
3258 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3259 info->cDistPoint);
3260 point = info->rgDistPoint;
3261 ok(point->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_NO_NAME,
3262 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3263 point->DistPointName.dwDistPointNameChoice);
3264 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3265 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3266 LocalFree(buf);
3268 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3269 distPointWithUrl, distPointWithUrl[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3270 (BYTE *)&buf, &size);
3271 if (ret)
3273 info = (PCRL_DIST_POINTS_INFO)buf;
3274 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3275 "Wrong size %d\n", size);
3276 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3277 info->cDistPoint);
3278 point = info->rgDistPoint;
3279 ok(point->DistPointName.dwDistPointNameChoice ==
3280 CRL_DIST_POINT_FULL_NAME,
3281 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3282 point->DistPointName.dwDistPointNameChoice);
3283 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3284 "Expected 1 name entry, got %d\n",
3285 U(point->DistPointName).FullName.cAltEntry);
3286 entry = U(point->DistPointName).FullName.rgAltEntry;
3287 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3288 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3289 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3290 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3291 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3292 LocalFree(buf);
3294 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3295 distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
3296 NULL, (BYTE *)&buf, &size);
3297 if (ret)
3299 info = (PCRL_DIST_POINTS_INFO)buf;
3300 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3301 "Wrong size %d\n", size);
3302 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3303 info->cDistPoint);
3304 point = info->rgDistPoint;
3305 ok(point->DistPointName.dwDistPointNameChoice ==
3306 CRL_DIST_POINT_NO_NAME,
3307 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3308 point->DistPointName.dwDistPointNameChoice);
3309 ok(point->ReasonFlags.cbData == sizeof(crlReason),
3310 "Expected reason length\n");
3311 ok(!memcmp(point->ReasonFlags.pbData, &crlReason, sizeof(crlReason)),
3312 "Unexpected reason\n");
3313 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3314 LocalFree(buf);
3316 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3317 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2,
3318 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3319 if (ret)
3321 info = (PCRL_DIST_POINTS_INFO)buf;
3322 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3323 "Wrong size %d\n", size);
3324 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3325 info->cDistPoint);
3326 point = info->rgDistPoint;
3327 ok(point->DistPointName.dwDistPointNameChoice ==
3328 CRL_DIST_POINT_FULL_NAME,
3329 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3330 point->DistPointName.dwDistPointNameChoice);
3331 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3332 "Expected 1 name entry, got %d\n",
3333 U(point->DistPointName).FullName.cAltEntry);
3334 entry = U(point->DistPointName).FullName.rgAltEntry;
3335 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3336 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3337 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3338 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3339 ok(point->CRLIssuer.cAltEntry == 1,
3340 "Expected 1 issuer entry, got %d\n", point->CRLIssuer.cAltEntry);
3341 entry = point->CRLIssuer.rgAltEntry;
3342 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3343 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3344 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3345 LocalFree(buf);
3349 static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3350 static const BYTE emptyNameIDP[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3351 static const BYTE urlIDP[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3352 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3353 0x67 };
3355 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding)
3357 BOOL ret;
3358 BYTE *buf = NULL;
3359 DWORD size = 0;
3360 CRL_ISSUING_DIST_POINT point = { { 0 } };
3361 CERT_ALT_NAME_ENTRY entry;
3363 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, NULL,
3364 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3365 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3367 skip("no X509_ISSUING_DIST_POINT encode support\n");
3368 return;
3370 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3371 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3372 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3373 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3374 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3375 if (buf)
3377 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
3378 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
3379 LocalFree(buf);
3381 /* nonsensical flags */
3382 point.fOnlyContainsUserCerts = TRUE;
3383 point.fOnlyContainsCACerts = TRUE;
3384 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3385 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3386 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3387 if (buf)
3389 ok(size == sizeof(badFlagsIDP), "Unexpected size %d\n", size);
3390 ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n");
3391 LocalFree(buf);
3393 /* unimplemented name type */
3394 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3395 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_ISSUER_RDN_NAME;
3396 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3397 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3398 ok(!ret && GetLastError() == E_INVALIDARG,
3399 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3400 /* empty name */
3401 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3402 U(point.DistPointName).FullName.cAltEntry = 0;
3403 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3404 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3405 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3406 if (buf)
3408 ok(size == sizeof(emptyNameIDP), "Unexpected size %d\n", size);
3409 ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n");
3410 LocalFree(buf);
3412 /* name with URL entry */
3413 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3414 U(entry).pwszURL = (LPWSTR)url;
3415 U(point.DistPointName).FullName.cAltEntry = 1;
3416 U(point.DistPointName).FullName.rgAltEntry = &entry;
3417 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3418 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3419 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3420 if (buf)
3422 ok(size == sizeof(urlIDP), "Unexpected size %d\n", size);
3423 ok(!memcmp(buf, urlIDP, size), "Unexpected value\n");
3424 LocalFree(buf);
3428 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY *expected,
3429 const CERT_ALT_NAME_ENTRY *got)
3431 ok(expected->dwAltNameChoice == got->dwAltNameChoice,
3432 "Expected name choice %d, got %d\n", expected->dwAltNameChoice,
3433 got->dwAltNameChoice);
3434 if (expected->dwAltNameChoice == got->dwAltNameChoice)
3436 switch (got->dwAltNameChoice)
3438 case CERT_ALT_NAME_RFC822_NAME:
3439 case CERT_ALT_NAME_DNS_NAME:
3440 case CERT_ALT_NAME_EDI_PARTY_NAME:
3441 case CERT_ALT_NAME_URL:
3442 case CERT_ALT_NAME_REGISTERED_ID:
3443 ok((!U(*expected).pwszURL && !U(*got).pwszURL) ||
3444 (!U(*expected).pwszURL && !lstrlenW(U(*got).pwszURL)) ||
3445 (!U(*got).pwszURL && !lstrlenW(U(*expected).pwszURL)) ||
3446 !lstrcmpW(U(*expected).pwszURL, U(*got).pwszURL),
3447 "Unexpected name\n");
3448 break;
3449 case CERT_ALT_NAME_X400_ADDRESS:
3450 case CERT_ALT_NAME_DIRECTORY_NAME:
3451 case CERT_ALT_NAME_IP_ADDRESS:
3452 ok(U(*got).IPAddress.cbData == U(*expected).IPAddress.cbData,
3453 "Unexpected IP address length %d\n", U(*got).IPAddress.cbData);
3454 ok(!memcmp(U(*got).IPAddress.pbData, U(*got).IPAddress.pbData,
3455 U(*got).IPAddress.cbData), "Unexpected value\n");
3456 break;
3461 static void compareAltNameInfo(const CERT_ALT_NAME_INFO *expected,
3462 const CERT_ALT_NAME_INFO *got)
3464 DWORD i;
3466 ok(expected->cAltEntry == got->cAltEntry, "Expected %d entries, got %d\n",
3467 expected->cAltEntry, got->cAltEntry);
3468 for (i = 0; i < min(expected->cAltEntry, got->cAltEntry); i++)
3469 compareAltNameEntry(&expected->rgAltEntry[i], &got->rgAltEntry[i]);
3472 static void compareDistPointName(const CRL_DIST_POINT_NAME *expected,
3473 const CRL_DIST_POINT_NAME *got)
3475 ok(got->dwDistPointNameChoice == expected->dwDistPointNameChoice,
3476 "Unexpected name choice %d\n", got->dwDistPointNameChoice);
3477 if (got->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME)
3478 compareAltNameInfo(&(U(*expected).FullName), &(U(*got).FullName));
3481 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT *expected,
3482 const CRL_ISSUING_DIST_POINT *got)
3484 compareDistPointName(&expected->DistPointName, &got->DistPointName);
3485 ok(got->fOnlyContainsUserCerts == expected->fOnlyContainsUserCerts,
3486 "Unexpected fOnlyContainsUserCerts\n");
3487 ok(got->fOnlyContainsCACerts == expected->fOnlyContainsCACerts,
3488 "Unexpected fOnlyContainsCACerts\n");
3489 ok(got->OnlySomeReasonFlags.cbData == expected->OnlySomeReasonFlags.cbData,
3490 "Unexpected reason flags\n");
3491 ok(got->fIndirectCRL == expected->fIndirectCRL,
3492 "Unexpected fIndirectCRL\n");
3495 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding)
3497 BOOL ret;
3498 BYTE *buf = NULL;
3499 DWORD size = 0;
3500 CRL_ISSUING_DIST_POINT point = { { 0 } };
3502 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3503 emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3504 (BYTE *)&buf, &size);
3505 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3507 skip("no X509_ISSUING_DIST_POINT decode support\n");
3508 return;
3510 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3511 if (ret)
3513 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3514 LocalFree(buf);
3516 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3517 badFlagsIDP, badFlagsIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3518 (BYTE *)&buf, &size);
3519 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3520 if (ret)
3522 point.fOnlyContainsUserCerts = point.fOnlyContainsCACerts = TRUE;
3523 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3524 LocalFree(buf);
3526 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3527 emptyNameIDP, emptyNameIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3528 (BYTE *)&buf, &size);
3529 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3530 if (ret)
3532 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3533 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3534 U(point.DistPointName).FullName.cAltEntry = 0;
3535 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3536 LocalFree(buf);
3538 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3539 urlIDP, urlIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3540 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3541 if (ret)
3543 CERT_ALT_NAME_ENTRY entry;
3545 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3546 U(entry).pwszURL = (LPWSTR)url;
3547 U(point.DistPointName).FullName.cAltEntry = 1;
3548 U(point.DistPointName).FullName.rgAltEntry = &entry;
3549 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3550 LocalFree(buf);
3554 static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3555 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3556 0x30, 0x5a };
3557 static const BYTE v2CRL[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3558 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3559 0x30, 0x30, 0x30, 0x30, 0x5a };
3560 static const BYTE v1CRLWithIssuer[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3561 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3562 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3563 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3564 0x5a };
3565 static const BYTE v1CRLWithIssuerAndEmptyEntry[] = { 0x30, 0x43, 0x30, 0x02,
3566 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3567 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3568 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3569 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3570 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3571 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3572 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3573 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3574 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3575 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3576 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3577 static const BYTE v1CRLWithEntryExt[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3578 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3579 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3580 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3581 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3582 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3583 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3584 static const BYTE v1CRLWithExt[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3585 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3586 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3587 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
3588 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3589 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
3590 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3591 static const BYTE v2CRLWithExt[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
3592 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
3593 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
3594 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
3595 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
3596 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
3597 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3598 static const BYTE v2CRLWithIssuingDistPoint[] = { 0x30,0x5c,0x02,0x01,0x01,
3599 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
3600 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
3601 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
3602 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3603 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
3604 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3606 static void test_encodeCRLToBeSigned(DWORD dwEncoding)
3608 BOOL ret;
3609 BYTE *buf = NULL;
3610 static CHAR oid_issuing_dist_point[] = szOID_ISSUING_DIST_POINT;
3611 DWORD size = 0;
3612 CRL_INFO info = { 0 };
3613 CRL_ENTRY entry = { { 0 }, { 0 }, 0, 0 };
3614 CERT_EXTENSION ext;
3616 /* Test with a V1 CRL */
3617 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3618 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3619 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3620 if (buf)
3622 ok(size == sizeof(v1CRL), "Wrong size %d\n", size);
3623 ok(!memcmp(buf, v1CRL, size), "Got unexpected value\n");
3624 LocalFree(buf);
3626 /* Test v2 CRL */
3627 info.dwVersion = CRL_V2;
3628 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3629 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3630 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3631 if (buf)
3633 ok(size == v2CRL[1] + 2, "Expected size %d, got %d\n",
3634 v2CRL[1] + 2, size);
3635 ok(!memcmp(buf, v2CRL, size), "Got unexpected value\n");
3636 LocalFree(buf);
3638 /* v1 CRL with a name */
3639 info.dwVersion = CRL_V1;
3640 info.Issuer.cbData = sizeof(encodedCommonName);
3641 info.Issuer.pbData = (BYTE *)encodedCommonName;
3642 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3643 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3644 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3645 if (buf)
3647 ok(size == sizeof(v1CRLWithIssuer), "Wrong size %d\n", size);
3648 ok(!memcmp(buf, v1CRLWithIssuer, size), "Got unexpected value\n");
3649 LocalFree(buf);
3651 if (0)
3653 /* v1 CRL with a name and a NULL entry pointer (crashes on win9x) */
3654 info.cCRLEntry = 1;
3655 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3656 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3657 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3658 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3660 /* now set an empty entry */
3661 info.cCRLEntry = 1;
3662 info.rgCRLEntry = &entry;
3663 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3664 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3665 if (buf)
3667 ok(size == sizeof(v1CRLWithIssuerAndEmptyEntry),
3668 "Wrong size %d\n", size);
3669 ok(!memcmp(buf, v1CRLWithIssuerAndEmptyEntry, size),
3670 "Got unexpected value\n");
3671 LocalFree(buf);
3673 /* an entry with a serial number */
3674 entry.SerialNumber.cbData = sizeof(serialNum);
3675 entry.SerialNumber.pbData = (BYTE *)serialNum;
3676 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3677 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3678 if (buf)
3680 ok(size == sizeof(v1CRLWithIssuerAndEntry),
3681 "Wrong size %d\n", size);
3682 ok(!memcmp(buf, v1CRLWithIssuerAndEntry, size),
3683 "Got unexpected value\n");
3684 LocalFree(buf);
3686 /* an entry with an extension */
3687 entry.cExtension = 1;
3688 entry.rgExtension = &criticalExt;
3689 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3690 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3691 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3692 if (buf)
3694 ok(size == sizeof(v1CRLWithEntryExt), "Wrong size %d\n", size);
3695 ok(!memcmp(buf, v1CRLWithEntryExt, size), "Got unexpected value\n");
3696 LocalFree(buf);
3698 /* a CRL with an extension */
3699 entry.cExtension = 0;
3700 info.cExtension = 1;
3701 info.rgExtension = &criticalExt;
3702 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3703 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3704 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3705 if (buf)
3707 ok(size == sizeof(v1CRLWithExt), "Wrong size %d\n", size);
3708 ok(!memcmp(buf, v1CRLWithExt, size), "Got unexpected value\n");
3709 LocalFree(buf);
3711 /* a v2 CRL with an extension, this time non-critical */
3712 info.dwVersion = CRL_V2;
3713 info.rgExtension = &nonCriticalExt;
3714 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3715 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3716 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3717 if (buf)
3719 ok(size == sizeof(v2CRLWithExt), "Wrong size %d\n", size);
3720 ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n");
3721 LocalFree(buf);
3723 /* a v2 CRL with an issuing dist point extension */
3724 ext.pszObjId = oid_issuing_dist_point;
3725 ext.fCritical = TRUE;
3726 ext.Value.cbData = sizeof(urlIDP);
3727 ext.Value.pbData = (LPBYTE)urlIDP;
3728 entry.rgExtension = &ext;
3729 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3730 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3731 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3732 if (buf)
3734 ok(size == sizeof(v2CRLWithIssuingDistPoint), "Wrong size %d\n", size);
3735 ok(!memcmp(buf, v2CRLWithIssuingDistPoint, size), "Unexpected value\n");
3736 LocalFree(buf);
3740 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
3741 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
3742 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
3743 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
3744 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
3745 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
3746 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
3747 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
3748 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
3749 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
3750 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
3751 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
3752 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
3753 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
3754 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
3755 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
3756 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
3757 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
3758 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
3759 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
3760 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
3761 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
3762 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
3763 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
3764 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
3765 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
3766 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
3767 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
3768 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
3769 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
3770 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
3771 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
3772 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
3773 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
3774 0xcd };
3775 static const BYTE verisignCRLWithLotsOfEntries[] = {
3776 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
3777 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
3778 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
3779 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
3780 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
3781 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
3782 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
3783 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
3784 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
3785 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
3786 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
3787 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
3788 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
3789 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
3790 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
3791 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
3792 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3793 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
3794 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
3795 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3796 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
3797 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
3798 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
3799 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
3800 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
3801 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
3802 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
3803 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
3804 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
3805 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
3806 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3807 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
3808 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
3809 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3810 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
3811 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
3812 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
3813 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
3814 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
3815 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
3816 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
3817 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
3818 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
3819 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
3820 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
3821 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
3822 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
3823 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
3824 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
3825 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
3826 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
3827 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
3828 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
3829 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
3830 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3831 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
3832 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
3833 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
3834 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
3835 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
3836 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
3837 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
3838 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
3839 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
3840 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
3841 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
3842 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
3843 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
3844 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
3845 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
3846 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
3847 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
3848 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
3849 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
3850 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
3851 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
3852 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
3853 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
3854 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
3855 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
3856 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
3857 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
3858 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3859 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
3860 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
3861 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
3862 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
3863 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
3864 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
3865 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
3866 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
3867 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
3868 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
3869 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
3870 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
3871 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
3872 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
3873 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
3874 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
3875 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
3876 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
3877 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
3878 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
3879 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
3880 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
3881 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
3882 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
3883 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
3884 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
3885 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
3886 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3887 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
3888 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
3889 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
3890 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
3891 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
3892 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
3893 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
3894 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
3895 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
3896 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
3897 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
3898 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
3899 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
3900 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3901 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
3902 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
3903 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
3904 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
3905 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
3906 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
3907 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
3908 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
3909 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
3910 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
3911 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
3912 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
3913 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
3914 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
3915 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
3916 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
3917 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
3918 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
3919 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
3920 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
3921 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
3922 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
3923 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
3924 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
3925 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
3926 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
3927 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
3928 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
3929 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
3930 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
3931 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
3932 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
3933 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
3934 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
3935 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
3936 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
3937 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
3938 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
3939 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
3940 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
3941 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
3942 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
3943 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
3944 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
3945 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
3946 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
3947 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
3948 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
3949 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
3950 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
3951 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
3952 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
3953 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
3954 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
3955 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
3956 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
3957 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
3958 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
3959 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
3960 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
3961 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
3962 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
3963 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
3964 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
3965 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
3966 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
3967 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
3968 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
3969 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
3970 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
3971 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
3972 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
3973 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
3974 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
3975 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
3976 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
3977 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
3978 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
3979 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
3980 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
3981 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
3982 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
3983 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
3984 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
3985 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
3986 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
3987 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
3988 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
3989 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
3990 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
3991 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
3992 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
3993 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
3994 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
3995 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
3996 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
3997 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
3998 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
3999 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
4000 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
4001 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
4002 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
4003 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
4004 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
4005 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
4006 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
4007 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
4008 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
4009 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
4010 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
4011 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
4012 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
4013 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
4014 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
4015 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
4016 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
4017 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
4018 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
4019 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
4020 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
4021 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
4022 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
4023 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
4024 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
4025 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
4026 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
4027 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
4028 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
4029 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
4030 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
4031 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
4032 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
4033 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
4034 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
4035 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
4036 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
4037 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
4038 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
4039 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
4040 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
4041 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
4042 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
4043 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
4044 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
4045 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
4046 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
4047 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
4048 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
4049 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
4050 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
4051 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
4052 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
4053 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
4054 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
4055 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
4056 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
4057 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
4058 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
4059 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
4060 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
4061 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
4062 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
4063 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
4064 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
4065 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
4066 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
4067 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
4068 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
4069 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
4070 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
4071 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
4072 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
4073 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
4074 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
4075 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
4076 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
4077 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
4078 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
4079 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4080 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4081 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4082 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4083 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4084 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4085 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4086 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4087 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4088 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4089 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4090 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4091 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4092 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4093 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4094 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4095 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4096 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4097 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4098 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4099 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4100 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4101 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4102 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4103 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4104 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4105 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4106 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4107 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4108 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4109 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4110 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4111 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4112 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4113 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4114 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4115 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4116 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4117 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4118 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4119 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4120 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4121 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4122 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4123 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4124 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4125 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4126 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4127 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4128 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4129 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4130 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4131 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4132 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4133 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4134 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4135 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4136 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4137 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4138 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4139 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4140 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4141 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4142 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4143 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4144 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4145 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4146 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4147 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4148 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4149 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4150 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4151 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4152 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4153 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4154 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4155 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4156 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4157 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4158 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4159 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4160 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4161 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4162 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4163 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4164 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4165 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4166 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4167 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4168 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4169 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4170 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4171 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4172 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4173 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4174 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4175 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4176 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4177 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4178 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4179 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4180 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4181 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4182 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4183 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4184 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4185 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4186 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4187 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4188 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4189 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4190 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4191 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4192 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4193 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4194 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4195 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4196 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4197 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4198 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4199 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4200 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4201 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4202 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4203 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4204 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4205 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4206 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4207 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4208 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4209 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4210 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4211 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4212 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4213 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4214 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4215 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4216 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4217 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4218 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4219 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4220 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4221 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4222 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4223 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4224 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4225 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4226 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4227 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4228 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4229 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4230 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4231 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4232 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4233 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4234 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4235 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4236 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4237 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4238 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4239 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4240 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4241 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4242 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4243 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4244 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4245 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4246 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4247 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4248 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4249 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4250 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4251 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4252 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4253 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4254 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4255 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4256 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4257 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4258 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4259 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4260 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4261 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4262 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4263 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4264 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4265 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4266 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4267 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4268 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4269 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4270 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4271 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4272 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4273 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4274 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4275 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4276 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4277 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4278 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4279 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4280 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4281 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4282 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4283 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4285 static void test_decodeCRLToBeSigned(DWORD dwEncoding)
4287 static const BYTE *corruptCRLs[] = { v1CRL, v2CRL };
4288 BOOL ret;
4289 BYTE *buf = NULL;
4290 DWORD size = 0, i;
4292 for (i = 0; i < sizeof(corruptCRLs) / sizeof(corruptCRLs[0]); i++)
4294 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4295 corruptCRLs[i], corruptCRLs[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4296 (BYTE *)&buf, &size);
4297 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT),
4298 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
4300 /* at a minimum, a CRL must contain an issuer: */
4301 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4302 v1CRLWithIssuer, v1CRLWithIssuer[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4303 (BYTE *)&buf, &size);
4304 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4305 if (buf)
4307 CRL_INFO *info = (CRL_INFO *)buf;
4309 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4310 ok(info->cCRLEntry == 0, "Expected 0 CRL entries, got %d\n",
4311 info->cCRLEntry);
4312 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4313 "Wrong issuer size %d\n", info->Issuer.cbData);
4314 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4315 "Unexpected issuer\n");
4316 LocalFree(buf);
4318 /* check decoding with an empty CRL entry */
4319 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4320 v1CRLWithIssuerAndEmptyEntry, v1CRLWithIssuerAndEmptyEntry[1] + 2,
4321 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4322 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
4323 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
4324 /* with a real CRL entry */
4325 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4326 v1CRLWithIssuerAndEntry, v1CRLWithIssuerAndEntry[1] + 2,
4327 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4328 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4329 if (buf)
4331 CRL_INFO *info = (CRL_INFO *)buf;
4332 CRL_ENTRY *entry;
4334 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4335 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4336 info->cCRLEntry);
4337 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4338 entry = info->rgCRLEntry;
4339 ok(entry->SerialNumber.cbData == 1,
4340 "Expected serial number size 1, got %d\n",
4341 entry->SerialNumber.cbData);
4342 ok(*entry->SerialNumber.pbData == *serialNum,
4343 "Expected serial number %d, got %d\n", *serialNum,
4344 *entry->SerialNumber.pbData);
4345 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4346 "Wrong issuer size %d\n", info->Issuer.cbData);
4347 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4348 "Unexpected issuer\n");
4349 LocalFree(buf);
4351 /* a real CRL from verisign that has extensions */
4352 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4353 verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG,
4354 NULL, (BYTE *)&buf, &size);
4355 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4356 if (buf)
4358 CRL_INFO *info = (CRL_INFO *)buf;
4359 CRL_ENTRY *entry;
4361 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4362 ok(info->cCRLEntry == 3, "Expected 3 CRL entries, got %d\n",
4363 info->cCRLEntry);
4364 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4365 entry = info->rgCRLEntry;
4366 ok(info->cExtension == 2, "Expected 2 extensions, got %d\n",
4367 info->cExtension);
4368 LocalFree(buf);
4370 /* another real CRL from verisign that has lots of entries */
4371 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4372 verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries),
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;
4379 ok(size >= sizeof(CRL_INFO), "Got size %d\n", size);
4380 ok(info->cCRLEntry == 209, "Expected 209 CRL entries, got %d\n",
4381 info->cCRLEntry);
4382 ok(info->cExtension == 0, "Expected 0 extensions, got %d\n",
4383 info->cExtension);
4384 LocalFree(buf);
4386 /* and finally, with an extension */
4387 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4388 v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4389 NULL, (BYTE *)&buf, &size);
4390 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4391 if (buf)
4393 CRL_INFO *info = (CRL_INFO *)buf;
4394 CRL_ENTRY *entry;
4396 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4397 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4398 info->cCRLEntry);
4399 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4400 entry = info->rgCRLEntry;
4401 ok(entry->SerialNumber.cbData == 1,
4402 "Expected serial number size 1, got %d\n",
4403 entry->SerialNumber.cbData);
4404 ok(*entry->SerialNumber.pbData == *serialNum,
4405 "Expected serial number %d, got %d\n", *serialNum,
4406 *entry->SerialNumber.pbData);
4407 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4408 "Wrong issuer size %d\n", info->Issuer.cbData);
4409 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4410 "Unexpected issuer\n");
4411 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4412 info->cExtension);
4413 LocalFree(buf);
4415 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4416 v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4417 NULL, (BYTE *)&buf, &size);
4418 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4419 if (buf)
4421 CRL_INFO *info = (CRL_INFO *)buf;
4423 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4424 info->cExtension);
4425 LocalFree(buf);
4427 /* And again, with an issuing dist point */
4428 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4429 v2CRLWithIssuingDistPoint, sizeof(v2CRLWithIssuingDistPoint),
4430 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4431 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4432 if (buf)
4434 CRL_INFO *info = (CRL_INFO *)buf;
4436 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4437 info->cExtension);
4438 LocalFree(buf);
4442 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
4443 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
4444 static const BYTE encodedUsage[] = {
4445 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4446 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4447 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4449 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding)
4451 BOOL ret;
4452 BYTE *buf = NULL;
4453 DWORD size = 0;
4454 CERT_ENHKEY_USAGE usage;
4456 /* Test with empty usage */
4457 usage.cUsageIdentifier = 0;
4458 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4459 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4460 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4461 if (buf)
4463 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
4464 ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n");
4465 LocalFree(buf);
4467 /* Test with a few usages */
4468 usage.cUsageIdentifier = sizeof(keyUsages) / sizeof(keyUsages[0]);
4469 usage.rgpszUsageIdentifier = (LPSTR *)keyUsages;
4470 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4471 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4472 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4473 if (buf)
4475 ok(size == sizeof(encodedUsage), "Wrong size %d\n", size);
4476 ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n");
4477 LocalFree(buf);
4481 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding)
4483 BOOL ret;
4484 LPBYTE buf = NULL;
4485 DWORD size = 0;
4487 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4488 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4489 (BYTE *)&buf, &size);
4490 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4491 if (buf)
4493 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4495 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4496 "Wrong size %d\n", size);
4497 ok(usage->cUsageIdentifier == 0, "Expected 0 CRL entries, got %d\n",
4498 usage->cUsageIdentifier);
4499 LocalFree(buf);
4501 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4502 encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL,
4503 (BYTE *)&buf, &size);
4504 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4505 if (buf)
4507 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4508 DWORD i;
4510 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4511 "Wrong size %d\n", size);
4512 ok(usage->cUsageIdentifier == sizeof(keyUsages) / sizeof(keyUsages[0]),
4513 "Wrong CRL entries count %d\n", usage->cUsageIdentifier);
4514 for (i = 0; i < usage->cUsageIdentifier; i++)
4515 ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]),
4516 "Expected OID %s, got %s\n", keyUsages[i],
4517 usage->rgpszUsageIdentifier[i]);
4518 LocalFree(buf);
4522 static BYTE keyId[] = { 1,2,3,4 };
4523 static const BYTE authorityKeyIdWithId[] = {
4524 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4525 static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4526 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4527 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4528 static const BYTE authorityKeyIdWithSerial[] = { 0x30,0x03,0x82,0x01,0x01 };
4530 static void test_encodeAuthorityKeyId(DWORD dwEncoding)
4532 CERT_AUTHORITY_KEY_ID_INFO info = { { 0 } };
4533 BOOL ret;
4534 BYTE *buf = NULL;
4535 DWORD size = 0;
4537 /* Test with empty id */
4538 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4539 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4540 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4541 if (buf)
4543 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4544 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4545 LocalFree(buf);
4547 /* With just a key id */
4548 info.KeyId.cbData = sizeof(keyId);
4549 info.KeyId.pbData = keyId;
4550 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4551 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4552 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4553 if (buf)
4555 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", size);
4556 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4557 LocalFree(buf);
4559 /* With just an issuer */
4560 info.KeyId.cbData = 0;
4561 info.CertIssuer.cbData = sizeof(encodedCommonName);
4562 info.CertIssuer.pbData = (BYTE *)encodedCommonName;
4563 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4564 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4565 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4566 if (buf)
4568 ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %d\n",
4569 size);
4570 ok(!memcmp(buf, authorityKeyIdWithIssuer, size), "Unexpected value\n");
4571 LocalFree(buf);
4573 /* With just a serial number */
4574 info.CertIssuer.cbData = 0;
4575 info.CertSerialNumber.cbData = sizeof(serialNum);
4576 info.CertSerialNumber.pbData = (BYTE *)serialNum;
4577 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4578 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4579 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4580 if (buf)
4582 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4583 size);
4584 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4585 LocalFree(buf);
4589 static void test_decodeAuthorityKeyId(DWORD dwEncoding)
4591 BOOL ret;
4592 LPBYTE buf = NULL;
4593 DWORD size = 0;
4595 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4596 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4597 (BYTE *)&buf, &size);
4598 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4599 if (buf)
4601 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4603 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4604 size);
4605 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4606 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4607 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4608 LocalFree(buf);
4610 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4611 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4612 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4613 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4614 if (buf)
4616 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4618 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4619 size);
4620 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4621 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4622 "Unexpected key id\n");
4623 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4624 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4625 LocalFree(buf);
4627 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4628 authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer),
4629 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4630 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4631 if (buf)
4633 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4635 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4636 size);
4637 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4638 ok(info->CertIssuer.cbData == sizeof(encodedCommonName),
4639 "Unexpected issuer len\n");
4640 ok(!memcmp(info->CertIssuer.pbData, encodedCommonName,
4641 sizeof(encodedCommonName)), "Unexpected issuer\n");
4642 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4643 LocalFree(buf);
4645 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4646 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4647 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4648 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4649 if (buf)
4651 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4653 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4654 size);
4655 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4656 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4657 ok(info->CertSerialNumber.cbData == sizeof(serialNum),
4658 "Unexpected serial number len\n");
4659 ok(!memcmp(info->CertSerialNumber.pbData, serialNum, sizeof(serialNum)),
4660 "Unexpected serial number\n");
4661 LocalFree(buf);
4665 static const BYTE authorityKeyIdWithIssuerUrl[] = { 0x30,0x15,0xa1,0x13,0x86,
4666 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
4667 0x6f,0x72,0x67 };
4669 static void test_encodeAuthorityKeyId2(DWORD dwEncoding)
4671 CERT_AUTHORITY_KEY_ID2_INFO info = { { 0 } };
4672 CERT_ALT_NAME_ENTRY entry = { 0 };
4673 BOOL ret;
4674 BYTE *buf = NULL;
4675 DWORD size = 0;
4677 /* Test with empty id */
4678 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4679 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4680 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4681 if (buf)
4683 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4684 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4685 LocalFree(buf);
4687 /* With just a key id */
4688 info.KeyId.cbData = sizeof(keyId);
4689 info.KeyId.pbData = keyId;
4690 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4691 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4692 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4693 if (buf)
4695 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n",
4696 size);
4697 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4698 LocalFree(buf);
4700 /* With a bogus issuer name */
4701 info.KeyId.cbData = 0;
4702 info.AuthorityCertIssuer.cAltEntry = 1;
4703 info.AuthorityCertIssuer.rgAltEntry = &entry;
4704 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4705 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4706 ok(!ret && GetLastError() == E_INVALIDARG,
4707 "Expected E_INVALIDARG, got %08x\n", GetLastError());
4708 /* With an issuer name */
4709 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
4710 U(entry).pwszURL = (LPWSTR)url;
4711 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4712 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4713 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4714 if (buf)
4716 ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %d\n",
4717 size);
4718 ok(!memcmp(buf, authorityKeyIdWithIssuerUrl, size),
4719 "Unexpected value\n");
4720 LocalFree(buf);
4722 /* With just a serial number */
4723 info.AuthorityCertIssuer.cAltEntry = 0;
4724 info.AuthorityCertSerialNumber.cbData = sizeof(serialNum);
4725 info.AuthorityCertSerialNumber.pbData = (BYTE *)serialNum;
4726 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4727 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4728 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4729 if (buf)
4731 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4732 size);
4733 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4734 LocalFree(buf);
4738 static void test_decodeAuthorityKeyId2(DWORD dwEncoding)
4740 BOOL ret;
4741 LPBYTE buf = NULL;
4742 DWORD size = 0;
4744 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4745 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4746 (BYTE *)&buf, &size);
4747 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4748 if (buf)
4750 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4752 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4753 size);
4754 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4755 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4756 "Expected no issuer name entries\n");
4757 ok(info->AuthorityCertSerialNumber.cbData == 0,
4758 "Expected no serial number\n");
4759 LocalFree(buf);
4761 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4762 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4763 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4764 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4765 if (buf)
4767 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4769 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4770 size);
4771 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4772 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4773 "Unexpected key id\n");
4774 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4775 "Expected no issuer name entries\n");
4776 ok(info->AuthorityCertSerialNumber.cbData == 0,
4777 "Expected no serial number\n");
4778 LocalFree(buf);
4780 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4781 authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl),
4782 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4783 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4784 if (buf)
4786 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4788 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4789 size);
4790 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4791 ok(info->AuthorityCertIssuer.cAltEntry == 1,
4792 "Expected 1 issuer entry, got %d\n",
4793 info->AuthorityCertIssuer.cAltEntry);
4794 ok(info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice ==
4795 CERT_ALT_NAME_URL, "Expected CERT_ALT_NAME_URL, got %d\n",
4796 info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice);
4797 ok(!lstrcmpW(U(info->AuthorityCertIssuer.rgAltEntry[0]).pwszURL,
4798 url), "Unexpected URL\n");
4799 ok(info->AuthorityCertSerialNumber.cbData == 0,
4800 "Expected no serial number\n");
4801 LocalFree(buf);
4803 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4804 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4805 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4806 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4807 if (buf)
4809 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4811 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4812 size);
4813 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4814 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4815 "Expected no issuer name entries\n");
4816 ok(info->AuthorityCertSerialNumber.cbData == sizeof(serialNum),
4817 "Unexpected serial number len\n");
4818 ok(!memcmp(info->AuthorityCertSerialNumber.pbData, serialNum,
4819 sizeof(serialNum)), "Unexpected serial number\n");
4820 LocalFree(buf);
4824 static const BYTE authorityInfoAccessWithUrl[] = {
4825 0x30,0x19,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
4826 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
4827 static const BYTE authorityInfoAccessWithUrlAndIPAddr[] = {
4828 0x30,0x29,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
4829 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x0e,0x06,
4830 0x02,0x2d,0x06,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
4832 static void test_encodeAuthorityInfoAccess(DWORD dwEncoding)
4834 static char oid1[] = "1.2.3";
4835 static char oid2[] = "1.5.6";
4836 BOOL ret;
4837 BYTE *buf = NULL;
4838 DWORD size = 0;
4839 CERT_ACCESS_DESCRIPTION accessDescription[2];
4840 CERT_AUTHORITY_INFO_ACCESS aia;
4842 memset(accessDescription, 0, sizeof(accessDescription));
4843 aia.cAccDescr = 0;
4844 aia.rgAccDescr = NULL;
4845 /* Having no access descriptions is allowed */
4846 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4847 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4848 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4849 if (buf)
4851 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
4852 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
4853 LocalFree(buf);
4854 buf = NULL;
4856 /* It can't have an empty access method */
4857 aia.cAccDescr = 1;
4858 aia.rgAccDescr = accessDescription;
4859 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4860 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4861 ok(!ret && GetLastError() == E_INVALIDARG,
4862 "expected E_INVALIDARG, got %08x\n", GetLastError());
4863 /* It can't have an empty location */
4864 accessDescription[0].pszAccessMethod = oid1;
4865 SetLastError(0xdeadbeef);
4866 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4867 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4868 ok(!ret && GetLastError() == E_INVALIDARG,
4869 "expected E_INVALIDARG, got %08x\n", GetLastError());
4870 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
4871 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
4872 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4873 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4874 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4875 if (buf)
4877 ok(size == sizeof(authorityInfoAccessWithUrl), "unexpected size %d\n",
4878 size);
4879 ok(!memcmp(buf, authorityInfoAccessWithUrl, size),
4880 "unexpected value\n");
4881 LocalFree(buf);
4882 buf = NULL;
4884 accessDescription[1].pszAccessMethod = oid2;
4885 accessDescription[1].AccessLocation.dwAltNameChoice =
4886 CERT_ALT_NAME_IP_ADDRESS;
4887 U(accessDescription[1].AccessLocation).IPAddress.cbData =
4888 sizeof(encodedIPAddr);
4889 U(accessDescription[1].AccessLocation).IPAddress.pbData =
4890 (LPBYTE)encodedIPAddr;
4891 aia.cAccDescr = 2;
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(authorityInfoAccessWithUrlAndIPAddr),
4898 "unexpected size %d\n", size);
4899 ok(!memcmp(buf, authorityInfoAccessWithUrlAndIPAddr, size),
4900 "unexpected value\n");
4901 LocalFree(buf);
4902 buf = NULL;
4906 static void compareAuthorityInfoAccess(LPCSTR header,
4907 const CERT_AUTHORITY_INFO_ACCESS *expected,
4908 const CERT_AUTHORITY_INFO_ACCESS *got)
4910 DWORD i;
4912 ok(expected->cAccDescr == got->cAccDescr,
4913 "%s: expected %d access descriptions, got %d\n", header,
4914 expected->cAccDescr, got->cAccDescr);
4915 for (i = 0; i < expected->cAccDescr; i++)
4917 ok(!strcmp(expected->rgAccDescr[i].pszAccessMethod,
4918 got->rgAccDescr[i].pszAccessMethod), "%s[%d]: expected %s, got %s\n",
4919 header, i, expected->rgAccDescr[i].pszAccessMethod,
4920 got->rgAccDescr[i].pszAccessMethod);
4921 compareAltNameEntry(&expected->rgAccDescr[i].AccessLocation,
4922 &got->rgAccDescr[i].AccessLocation);
4926 static void test_decodeAuthorityInfoAccess(DWORD dwEncoding)
4928 static char oid1[] = "1.2.3";
4929 static char oid2[] = "1.5.6";
4930 BOOL ret;
4931 LPBYTE buf = NULL;
4932 DWORD size = 0;
4934 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
4935 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4936 (BYTE *)&buf, &size);
4937 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4938 if (buf)
4940 CERT_AUTHORITY_INFO_ACCESS aia = { 0, NULL };
4942 compareAuthorityInfoAccess("empty AIA", &aia,
4943 (CERT_AUTHORITY_INFO_ACCESS *)buf);
4944 LocalFree(buf);
4945 buf = NULL;
4947 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
4948 authorityInfoAccessWithUrl, sizeof(authorityInfoAccessWithUrl),
4949 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4950 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4951 if (buf)
4953 CERT_ACCESS_DESCRIPTION accessDescription;
4954 CERT_AUTHORITY_INFO_ACCESS aia;
4956 accessDescription.pszAccessMethod = oid1;
4957 accessDescription.AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
4958 U(accessDescription.AccessLocation).pwszURL = (LPWSTR)url;
4959 aia.cAccDescr = 1;
4960 aia.rgAccDescr = &accessDescription;
4961 compareAuthorityInfoAccess("AIA with URL", &aia,
4962 (CERT_AUTHORITY_INFO_ACCESS *)buf);
4963 LocalFree(buf);
4964 buf = NULL;
4966 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
4967 authorityInfoAccessWithUrlAndIPAddr,
4968 sizeof(authorityInfoAccessWithUrlAndIPAddr), CRYPT_DECODE_ALLOC_FLAG,
4969 NULL, (BYTE *)&buf, &size);
4970 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4971 if (buf)
4973 CERT_ACCESS_DESCRIPTION accessDescription[2];
4974 CERT_AUTHORITY_INFO_ACCESS aia;
4976 accessDescription[0].pszAccessMethod = oid1;
4977 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
4978 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
4979 accessDescription[1].pszAccessMethod = oid2;
4980 accessDescription[1].AccessLocation.dwAltNameChoice =
4981 CERT_ALT_NAME_IP_ADDRESS;
4982 U(accessDescription[1].AccessLocation).IPAddress.cbData =
4983 sizeof(encodedIPAddr);
4984 U(accessDescription[1].AccessLocation).IPAddress.pbData =
4985 (LPBYTE)encodedIPAddr;
4986 aia.cAccDescr = 2;
4987 aia.rgAccDescr = accessDescription;
4988 compareAuthorityInfoAccess("AIA with URL and IP addr", &aia,
4989 (CERT_AUTHORITY_INFO_ACCESS *)buf);
4990 LocalFree(buf);
4991 buf = NULL;
4995 static const BYTE emptyCTL[] = {
4996 0x30,0x17,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
4997 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
4998 static const BYTE emptyCTLWithVersion1[] = {
4999 0x30,0x1a,0x02,0x01,0x01,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5000 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5001 static const BYTE ctlWithUsageIdentifier[] = {
5002 0x30,0x1b,0x30,0x04,0x06,0x02,0x2a,0x03,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
5003 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5004 static const BYTE ctlWithListIdentifier[] = {
5005 0x30,0x1a,0x30,0x00,0x04,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5006 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5007 static const BYTE ctlWithSequenceNumber[] = {
5008 0x30,0x1a,0x30,0x00,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5009 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5010 static const BYTE ctlWithThisUpdate[] = {
5011 0x30,0x15,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5012 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5013 static const BYTE ctlWithThisAndNextUpdate[] = {
5014 0x30,0x24,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5015 0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5016 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5017 static const BYTE ctlWithAlgId[] = {
5018 0x30,0x1b,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5019 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5020 static const BYTE ctlWithBogusEntry[] = {
5021 0x30,0x29,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5022 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x10,0x30,0x0e,0x04,
5023 0x01,0x01,0x31,0x09,0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,0x01 };
5024 static const BYTE ctlWithOneEntry[] = {
5025 0x30,0x2a,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5026 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x11,0x30,0x0f,0x04,
5027 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00 };
5028 static const BYTE ctlWithTwoEntries[] = {
5029 0x30,0x41,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5030 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x28,0x30,0x0f,0x04,
5031 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00,0x30,
5032 0x15,0x04,0x01,0x01,0x31,0x10,0x30,0x0e,0x06,0x02,0x2d,0x06,0x31,0x08,0x30,
5033 0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5035 static void test_encodeCTL(DWORD dwEncoding)
5037 static char oid1[] = "1.2.3";
5038 static char oid2[] = "1.5.6";
5039 char *pOid1 = oid1;
5040 BOOL ret;
5041 BYTE *buf = NULL;
5042 DWORD size = 0;
5043 CTL_INFO info;
5044 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5045 CTL_ENTRY ctlEntry[2];
5046 CRYPT_ATTRIBUTE attr1, attr2;
5047 CRYPT_ATTR_BLOB value1, value2;
5049 memset(&info, 0, sizeof(info));
5050 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5051 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5052 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5053 if (buf)
5055 ok(size == sizeof(emptyCTL), "unexpected size %d\n", size);
5056 ok(!memcmp(buf, emptyCTL, size), "unexpected value\n");
5057 LocalFree(buf);
5058 buf = NULL;
5060 info.dwVersion = 1;
5061 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5062 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5063 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5064 if (buf)
5066 ok(size == sizeof(emptyCTLWithVersion1), "unexpected size %d\n", size);
5067 ok(!memcmp(buf, emptyCTLWithVersion1, size), "unexpected value\n");
5068 LocalFree(buf);
5069 buf = NULL;
5071 info.dwVersion = 0;
5072 info.SubjectUsage.cUsageIdentifier = 1;
5073 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5074 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5075 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5076 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5077 if (buf)
5079 ok(size == sizeof(ctlWithUsageIdentifier), "unexpected size %d\n",
5080 size);
5081 ok(!memcmp(buf, ctlWithUsageIdentifier, size), "unexpected value\n");
5082 LocalFree(buf);
5083 buf = NULL;
5085 info.SubjectUsage.cUsageIdentifier = 0;
5086 info.ListIdentifier.cbData = sizeof(serialNum);
5087 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5088 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5089 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5090 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5091 if (buf)
5093 ok(size == sizeof(ctlWithListIdentifier), "unexpected size %d\n", size);
5094 ok(!memcmp(buf, ctlWithListIdentifier, size), "unexpected value\n");
5095 LocalFree(buf);
5096 buf = NULL;
5098 info.ListIdentifier.cbData = 0;
5099 info.SequenceNumber.cbData = sizeof(serialNum);
5100 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5101 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5102 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5103 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5104 if (buf)
5106 ok(size == sizeof(ctlWithSequenceNumber), "unexpected size %d\n",
5107 size);
5108 ok(!memcmp(buf, ctlWithSequenceNumber, size), "unexpected value\n");
5109 LocalFree(buf);
5110 buf = NULL;
5112 info.SequenceNumber.cbData = 0;
5113 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5114 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5115 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5116 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5117 if (buf)
5119 ok(size == sizeof(ctlWithThisUpdate), "unexpected size %d\n", size);
5120 ok(!memcmp(buf, ctlWithThisUpdate, size), "unexpected value\n");
5121 LocalFree(buf);
5122 buf = NULL;
5124 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5125 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5126 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5127 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5128 if (buf)
5130 ok(size == sizeof(ctlWithThisAndNextUpdate), "unexpected size %d\n",
5131 size);
5132 ok(!memcmp(buf, ctlWithThisAndNextUpdate, size), "unexpected value\n");
5133 LocalFree(buf);
5134 buf = NULL;
5136 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5137 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5138 info.SubjectAlgorithm.pszObjId = oid2;
5139 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5140 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5141 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5142 if (buf)
5144 ok(size == sizeof(ctlWithAlgId), "unexpected size %d\n", size);
5145 ok(!memcmp(buf, ctlWithAlgId, size), "unexpected value\n");
5146 LocalFree(buf);
5147 buf = NULL;
5149 /* The value is supposed to be asn.1 encoded, so this'll fail to decode
5150 * (see tests below) but it'll encode fine.
5152 info.SubjectAlgorithm.pszObjId = NULL;
5153 value1.cbData = sizeof(serialNum);
5154 value1.pbData = (LPBYTE)serialNum;
5155 attr1.pszObjId = oid1;
5156 attr1.cValue = 1;
5157 attr1.rgValue = &value1;
5158 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5159 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5160 ctlEntry[0].cAttribute = 1;
5161 ctlEntry[0].rgAttribute = &attr1;
5162 info.cCTLEntry = 1;
5163 info.rgCTLEntry = ctlEntry;
5164 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5165 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5166 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5167 if (buf)
5169 ok(size == sizeof(ctlWithBogusEntry), "unexpected size %d\n", size);
5170 ok(!memcmp(buf, ctlWithBogusEntry, size), "unexpected value\n");
5171 LocalFree(buf);
5172 buf = NULL;
5174 value1.cbData = sizeof(emptySequence);
5175 value1.pbData = (LPBYTE)emptySequence;
5176 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5177 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5178 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5179 if (buf)
5181 ok(size == sizeof(ctlWithOneEntry), "unexpected size %d\n", size);
5182 ok(!memcmp(buf, ctlWithOneEntry, size), "unexpected value\n");
5183 LocalFree(buf);
5184 buf = NULL;
5186 value2.cbData = sizeof(encodedIPAddr);
5187 value2.pbData = (LPBYTE)encodedIPAddr;
5188 attr2.pszObjId = oid2;
5189 attr2.cValue = 1;
5190 attr2.rgValue = &value2;
5191 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5192 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5193 ctlEntry[1].cAttribute = 1;
5194 ctlEntry[1].rgAttribute = &attr2;
5195 info.cCTLEntry = 2;
5196 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5197 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5198 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5199 if (buf)
5201 ok(size == sizeof(ctlWithTwoEntries), "unexpected size %d\n", size);
5202 ok(!memcmp(buf, ctlWithTwoEntries, size), "unexpected value\n");
5203 LocalFree(buf);
5204 buf = NULL;
5208 static void compareCTLInfo(LPCSTR header, const CTL_INFO *expected,
5209 const CTL_INFO *got)
5211 DWORD i, j, k;
5213 ok(expected->dwVersion == got->dwVersion,
5214 "%s: expected version %d, got %d\n", header, expected->dwVersion,
5215 got->dwVersion);
5216 ok(expected->SubjectUsage.cUsageIdentifier ==
5217 got->SubjectUsage.cUsageIdentifier,
5218 "%s: expected %d usage identifiers, got %d\n", header,
5219 expected->SubjectUsage.cUsageIdentifier,
5220 got->SubjectUsage.cUsageIdentifier);
5221 for (i = 0; i < expected->SubjectUsage.cUsageIdentifier; i++)
5222 ok(!strcmp(expected->SubjectUsage.rgpszUsageIdentifier[i],
5223 got->SubjectUsage.rgpszUsageIdentifier[i]),
5224 "%s[%d]: expected %s, got %s\n", header, i,
5225 expected->SubjectUsage.rgpszUsageIdentifier[i],
5226 got->SubjectUsage.rgpszUsageIdentifier[i]);
5227 ok(expected->ListIdentifier.cbData == got->ListIdentifier.cbData,
5228 "%s: expected list identifier of %d bytes, got %d\n", header,
5229 expected->ListIdentifier.cbData, got->ListIdentifier.cbData);
5230 if (expected->ListIdentifier.cbData)
5231 ok(!memcmp(expected->ListIdentifier.pbData, got->ListIdentifier.pbData,
5232 expected->ListIdentifier.cbData),
5233 "%s: unexpected list identifier value\n", header);
5234 ok(expected->SequenceNumber.cbData == got->SequenceNumber.cbData,
5235 "%s: expected sequence number of %d bytes, got %d\n", header,
5236 expected->SequenceNumber.cbData, got->SequenceNumber.cbData);
5237 if (expected->SequenceNumber.cbData)
5238 ok(!memcmp(expected->SequenceNumber.pbData, got->SequenceNumber.pbData,
5239 expected->SequenceNumber.cbData),
5240 "%s: unexpected sequence number value\n", header);
5241 ok(!memcmp(&expected->ThisUpdate, &got->ThisUpdate, sizeof(FILETIME)),
5242 "%s: expected this update = (%d, %d), got (%d, %d)\n", header,
5243 expected->ThisUpdate.dwLowDateTime, expected->ThisUpdate.dwHighDateTime,
5244 got->ThisUpdate.dwLowDateTime, got->ThisUpdate.dwHighDateTime);
5245 ok(!memcmp(&expected->NextUpdate, &got->NextUpdate, sizeof(FILETIME)),
5246 "%s: expected next update = (%d, %d), got (%d, %d)\n", header,
5247 expected->NextUpdate.dwLowDateTime, expected->NextUpdate.dwHighDateTime,
5248 got->NextUpdate.dwLowDateTime, got->NextUpdate.dwHighDateTime);
5249 if (expected->SubjectAlgorithm.pszObjId &&
5250 *expected->SubjectAlgorithm.pszObjId && !got->SubjectAlgorithm.pszObjId)
5251 ok(0, "%s: expected subject algorithm %s, got NULL\n", header,
5252 expected->SubjectAlgorithm.pszObjId);
5253 if (expected->SubjectAlgorithm.pszObjId && got->SubjectAlgorithm.pszObjId)
5254 ok(!strcmp(expected->SubjectAlgorithm.pszObjId,
5255 got->SubjectAlgorithm.pszObjId),
5256 "%s: expected subject algorithm %s, got %s\n", header,
5257 expected->SubjectAlgorithm.pszObjId, got->SubjectAlgorithm.pszObjId);
5258 ok(expected->SubjectAlgorithm.Parameters.cbData ==
5259 got->SubjectAlgorithm.Parameters.cbData,
5260 "%s: expected subject algorithm parameters of %d bytes, got %d\n", header,
5261 expected->SubjectAlgorithm.Parameters.cbData,
5262 got->SubjectAlgorithm.Parameters.cbData);
5263 if (expected->SubjectAlgorithm.Parameters.cbData)
5264 ok(!memcmp(expected->SubjectAlgorithm.Parameters.pbData,
5265 got->SubjectAlgorithm.Parameters.pbData,
5266 expected->SubjectAlgorithm.Parameters.cbData),
5267 "%s: unexpected subject algorithm parameter value\n", header);
5268 ok(expected->cCTLEntry == got->cCTLEntry,
5269 "%s: expected %d CTL entries, got %d\n", header, expected->cCTLEntry,
5270 got->cCTLEntry);
5271 for (i = 0; i < expected->cCTLEntry; i++)
5273 ok(expected->rgCTLEntry[i].SubjectIdentifier.cbData ==
5274 got->rgCTLEntry[i].SubjectIdentifier.cbData,
5275 "%s[%d]: expected subject identifier of %d bytes, got %d\n",
5276 header, i, expected->rgCTLEntry[i].SubjectIdentifier.cbData,
5277 got->rgCTLEntry[i].SubjectIdentifier.cbData);
5278 if (expected->rgCTLEntry[i].SubjectIdentifier.cbData)
5279 ok(!memcmp(expected->rgCTLEntry[i].SubjectIdentifier.pbData,
5280 got->rgCTLEntry[i].SubjectIdentifier.pbData,
5281 expected->rgCTLEntry[i].SubjectIdentifier.cbData),
5282 "%s[%d]: unexpected subject identifier value\n",
5283 header, i);
5284 for (j = 0; j < expected->rgCTLEntry[i].cAttribute; j++)
5286 ok(!strcmp(expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5287 got->rgCTLEntry[i].rgAttribute[j].pszObjId),
5288 "%s[%d][%d]: expected attribute OID %s, got %s\n", header, i, j,
5289 expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5290 got->rgCTLEntry[i].rgAttribute[j].pszObjId);
5291 for (k = 0; k < expected->rgCTLEntry[i].rgAttribute[j].cValue; k++)
5293 ok(expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData ==
5294 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5295 "%s[%d][%d][%d]: expected value of %d bytes, got %d\n",
5296 header, i, j, k,
5297 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5298 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData);
5299 if (expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData)
5300 ok(!memcmp(
5301 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5302 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5303 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData),
5304 "%s[%d][%d][%d]: unexpected value\n",
5305 header, i, j, k);
5309 ok(expected->cExtension == got->cExtension,
5310 "%s: expected %d extensions, got %d\n", header, expected->cExtension,
5311 got->cExtension);
5312 for (i = 0; i < expected->cExtension; i++)
5314 ok(!strcmp(expected->rgExtension[i].pszObjId,
5315 got->rgExtension[i].pszObjId), "%s[%d]: expected %s, got %s\n",
5316 header, i, expected->rgExtension[i].pszObjId,
5317 got->rgExtension[i].pszObjId);
5318 ok(expected->rgExtension[i].fCritical == got->rgExtension[i].fCritical,
5319 "%s[%d]: expected fCritical = %d, got %d\n", header, i,
5320 expected->rgExtension[i].fCritical, got->rgExtension[i].fCritical);
5321 ok(expected->rgExtension[i].Value.cbData ==
5322 got->rgExtension[i].Value.cbData,
5323 "%s[%d]: expected extension value to have %d bytes, got %d\n",
5324 header, i, expected->rgExtension[i].Value.cbData,
5325 got->rgExtension[i].Value.cbData);
5326 if (expected->rgExtension[i].Value.cbData)
5327 ok(!memcmp(expected->rgExtension[i].Value.pbData,
5328 got->rgExtension[i].Value.pbData,
5329 expected->rgExtension[i].Value.cbData),
5330 "%s[%d]: unexpected extension value\n", header, i);
5334 static const BYTE signedCTL[] = {
5335 0x30,0x81,0xc7,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
5336 0x81,0xb9,0x30,0x81,0xb6,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
5337 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x28,0x06,0x09,0x2a,0x86,
5338 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x1b,0x04,0x19,0x30,0x17,0x30,0x00,
5339 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5340 0x30,0x5a,0x30,0x02,0x06,0x00,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
5341 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
5342 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
5343 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5344 0x00,0x04,0x40,0xca,0xd8,0x32,0xd1,0xbd,0x97,0x61,0x54,0xd6,0x80,0xcf,0x0d,
5345 0xbd,0xa2,0x42,0xc7,0xca,0x37,0x91,0x7d,0x9d,0xac,0x8c,0xdf,0x05,0x8a,0x39,
5346 0xc6,0x07,0xc1,0x37,0xe6,0xb9,0xd1,0x0d,0x26,0xec,0xa5,0xb0,0x8a,0x51,0x26,
5347 0x2b,0x4f,0x73,0x44,0x86,0x83,0x5e,0x2b,0x6e,0xcc,0xf8,0x1b,0x85,0x53,0xe9,
5348 0x7a,0x80,0x8f,0x6b,0x42,0x19,0x93 };
5349 static const BYTE signedCTLWithCTLInnerContent[] = {
5350 0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
5351 0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
5352 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
5353 0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
5354 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5355 0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
5356 0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
5357 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
5358 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
5359 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
5360 0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
5361 0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
5362 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
5363 0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5364 0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
5365 0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
5366 0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
5367 0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
5368 0x57,0x6c,0x0b,0x47,0xb8 };
5370 static void test_decodeCTL(DWORD dwEncoding)
5372 static char oid1[] = "1.2.3";
5373 static char oid2[] = "1.5.6";
5374 static BYTE nullData[] = { 5,0 };
5375 char *pOid1 = oid1;
5376 BOOL ret;
5377 BYTE *buf = NULL;
5378 DWORD size = 0;
5379 CTL_INFO info;
5380 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5381 CTL_ENTRY ctlEntry[2];
5382 CRYPT_ATTRIBUTE attr1, attr2;
5383 CRYPT_ATTR_BLOB value1, value2;
5385 memset(&info, 0, sizeof(info));
5386 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTL, sizeof(emptyCTL),
5387 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5388 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5389 if (buf)
5391 compareCTLInfo("empty CTL", &info, (CTL_INFO *)buf);
5392 LocalFree(buf);
5393 buf = NULL;
5395 info.dwVersion = 1;
5396 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTLWithVersion1,
5397 sizeof(emptyCTLWithVersion1), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
5398 &size);
5399 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5400 if (buf)
5402 compareCTLInfo("v1 CTL", &info, (CTL_INFO *)buf);
5403 LocalFree(buf);
5404 buf = NULL;
5406 info.dwVersion = 0;
5407 info.SubjectUsage.cUsageIdentifier = 1;
5408 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5409 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithUsageIdentifier,
5410 sizeof(ctlWithUsageIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5411 (BYTE *)&buf, &size);
5412 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5413 if (buf)
5415 compareCTLInfo("CTL with usage identifier", &info, (CTL_INFO *)buf);
5416 LocalFree(buf);
5417 buf = NULL;
5419 info.SubjectUsage.cUsageIdentifier = 0;
5420 info.ListIdentifier.cbData = sizeof(serialNum);
5421 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5422 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithListIdentifier,
5423 sizeof(ctlWithListIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5424 (BYTE *)&buf, &size);
5425 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5426 if (buf)
5428 compareCTLInfo("CTL with list identifier", &info, (CTL_INFO *)buf);
5429 LocalFree(buf);
5430 buf = NULL;
5432 info.ListIdentifier.cbData = 0;
5433 info.SequenceNumber.cbData = sizeof(serialNum);
5434 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5435 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithSequenceNumber,
5436 sizeof(ctlWithSequenceNumber), CRYPT_DECODE_ALLOC_FLAG, NULL,
5437 (BYTE *)&buf, &size);
5438 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5439 if (buf)
5441 compareCTLInfo("CTL with sequence number", &info, (CTL_INFO *)buf);
5442 LocalFree(buf);
5443 buf = NULL;
5445 info.SequenceNumber.cbData = 0;
5446 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5447 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisUpdate,
5448 sizeof(ctlWithThisUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5449 (BYTE *)&buf, &size);
5450 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5451 if (buf)
5453 compareCTLInfo("CTL with this update", &info, (CTL_INFO *)buf);
5454 LocalFree(buf);
5455 buf = NULL;
5457 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5458 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisAndNextUpdate,
5459 sizeof(ctlWithThisAndNextUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5460 (BYTE *)&buf, &size);
5461 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5462 if (buf)
5464 compareCTLInfo("CTL with this and next update", &info, (CTL_INFO *)buf);
5465 LocalFree(buf);
5466 buf = NULL;
5468 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5469 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5470 info.SubjectAlgorithm.pszObjId = oid2;
5471 info.SubjectAlgorithm.Parameters.cbData = sizeof(nullData);
5472 info.SubjectAlgorithm.Parameters.pbData = nullData;
5473 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithAlgId,
5474 sizeof(ctlWithAlgId), CRYPT_DECODE_ALLOC_FLAG, NULL,
5475 (BYTE *)&buf, &size);
5476 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5477 if (buf)
5479 compareCTLInfo("CTL with algorithm identifier", &info, (CTL_INFO *)buf);
5480 LocalFree(buf);
5481 buf = NULL;
5483 SetLastError(0xdeadbeef);
5484 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithBogusEntry,
5485 sizeof(ctlWithBogusEntry), CRYPT_DECODE_ALLOC_FLAG, NULL,
5486 (BYTE *)&buf, &size);
5487 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD || CRYPT_E_ASN1_CORRUPT),
5488 "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n",
5489 GetLastError());
5490 info.SubjectAlgorithm.Parameters.cbData = 0;
5491 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5492 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5493 info.SubjectAlgorithm.pszObjId = oid2;
5494 info.SubjectAlgorithm.pszObjId = NULL;
5495 value1.cbData = sizeof(emptySequence);
5496 value1.pbData = (LPBYTE)emptySequence;
5497 attr1.pszObjId = oid1;
5498 attr1.cValue = 1;
5499 attr1.rgValue = &value1;
5500 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5501 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5502 ctlEntry[0].cAttribute = 1;
5503 ctlEntry[0].rgAttribute = &attr1;
5504 info.cCTLEntry = 1;
5505 info.rgCTLEntry = ctlEntry;
5506 SetLastError(0xdeadbeef);
5507 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithOneEntry,
5508 sizeof(ctlWithOneEntry), CRYPT_DECODE_ALLOC_FLAG, NULL,
5509 (BYTE *)&buf, &size);
5510 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5511 if (buf)
5513 compareCTLInfo("CTL with one entry", &info, (CTL_INFO *)buf);
5514 LocalFree(buf);
5515 buf = NULL;
5517 value2.cbData = sizeof(encodedIPAddr);
5518 value2.pbData = (LPBYTE)encodedIPAddr;
5519 attr2.pszObjId = oid2;
5520 attr2.cValue = 1;
5521 attr2.rgValue = &value2;
5522 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5523 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5524 ctlEntry[1].cAttribute = 1;
5525 ctlEntry[1].rgAttribute = &attr2;
5526 info.cCTLEntry = 2;
5527 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithTwoEntries,
5528 sizeof(ctlWithTwoEntries), CRYPT_DECODE_ALLOC_FLAG, NULL,
5529 (BYTE *)&buf, &size);
5530 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5531 if (buf)
5533 compareCTLInfo("CTL with two entries", &info, (CTL_INFO *)buf);
5534 LocalFree(buf);
5535 buf = NULL;
5537 /* A signed CTL isn't decodable, even if the inner content is a CTL */
5538 SetLastError(0xdeadbeef);
5539 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, signedCTL,
5540 sizeof(signedCTL), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5541 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
5542 "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
5543 SetLastError(0xdeadbeef);
5544 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL,
5545 signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent),
5546 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5547 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
5548 "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
5551 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
5552 static const BYTE emptyPKCSContentInfoExtraBytes[] = { 0x30,0x04,0x06,0x02,0x2a,
5553 0x03,0,0,0,0,0,0 };
5554 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
5555 0xa0,0x01,0x01 };
5556 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
5557 0x03,0x02,0x01,0x01 };
5558 static BYTE bogusDER[] = { 1 };
5560 static void test_encodePKCSContentInfo(DWORD dwEncoding)
5562 BOOL ret;
5563 BYTE *buf = NULL;
5564 DWORD size = 0;
5565 CRYPT_CONTENT_INFO info = { 0 };
5566 char oid1[] = "1.2.3";
5568 if (0)
5570 /* Crashes on win9x */
5571 SetLastError(0xdeadbeef);
5572 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL,
5573 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5574 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5575 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5577 SetLastError(0xdeadbeef);
5578 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5579 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5580 ok(!ret && GetLastError() == E_INVALIDARG,
5581 "Expected E_INVALIDARG, got %x\n", GetLastError());
5582 info.pszObjId = oid1;
5583 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5584 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5585 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5586 if (buf)
5588 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size);
5589 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n");
5590 LocalFree(buf);
5592 info.Content.pbData = bogusDER;
5593 info.Content.cbData = sizeof(bogusDER);
5594 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5595 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5596 ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError());
5597 if (buf)
5599 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size);
5600 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n");
5601 LocalFree(buf);
5603 info.Content.pbData = (BYTE *)ints[0].encoded;
5604 info.Content.cbData = ints[0].encoded[1] + 2;
5605 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5606 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5607 if (buf)
5609 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size);
5610 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n");
5611 LocalFree(buf);
5615 static const BYTE indefiniteSignedPKCSContent[] = {
5616 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
5617 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
5618 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
5619 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
5620 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
5621 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
5622 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5623 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5624 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
5625 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5626 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5627 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
5628 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
5629 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
5630 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
5631 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
5632 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
5633 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
5634 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
5635 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5636 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5637 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
5638 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
5639 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
5640 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
5641 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
5642 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
5643 0x00,0x00,0x00,0x00,0x00,0x00 };
5645 static void test_decodePKCSContentInfo(DWORD dwEncoding)
5647 BOOL ret;
5648 LPBYTE buf = NULL;
5649 DWORD size = 0;
5650 CRYPT_CONTENT_INFO *info;
5652 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5653 emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo),
5654 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5655 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5656 if (buf)
5658 info = (CRYPT_CONTENT_INFO *)buf;
5660 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5661 info->pszObjId);
5662 ok(info->Content.cbData == 0, "Expected no data, got %d\n",
5663 info->Content.cbData);
5664 LocalFree(buf);
5666 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5667 emptyPKCSContentInfoExtraBytes, sizeof(emptyPKCSContentInfoExtraBytes),
5668 0, NULL, NULL, &size);
5669 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5670 SetLastError(0xdeadbeef);
5671 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5672 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo),
5673 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5674 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5675 * I doubt an app depends on that.
5677 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5678 GetLastError() == CRYPT_E_ASN1_CORRUPT),
5679 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5680 GetLastError());
5681 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5682 intPKCSContentInfo, sizeof(intPKCSContentInfo),
5683 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5684 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5685 if (buf)
5687 info = (CRYPT_CONTENT_INFO *)buf;
5689 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5690 info->pszObjId);
5691 ok(info->Content.cbData == ints[0].encoded[1] + 2,
5692 "Unexpected size %d\n", info->Content.cbData);
5693 ok(!memcmp(info->Content.pbData, ints[0].encoded,
5694 info->Content.cbData), "Unexpected value\n");
5695 LocalFree(buf);
5697 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5698 indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent),
5699 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5700 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5701 if (buf)
5703 info = (CRYPT_CONTENT_INFO *)buf;
5705 ok(!strcmp(info->pszObjId, szOID_RSA_signedData),
5706 "Expected %s, got %s\n", szOID_RSA_signedData, info->pszObjId);
5707 ok(info->Content.cbData == 392, "Expected 392, got %d\n",
5708 info->Content.cbData);
5709 LocalFree(buf);
5713 static const BYTE emptyPKCSAttr[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
5714 0x00 };
5715 static const BYTE bogusPKCSAttr[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
5716 0x01 };
5717 static const BYTE intPKCSAttr[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
5718 0x02,0x01,0x01 };
5720 static void test_encodePKCSAttribute(DWORD dwEncoding)
5722 CRYPT_ATTRIBUTE attr = { 0 };
5723 BOOL ret;
5724 LPBYTE buf = NULL;
5725 DWORD size = 0;
5726 CRYPT_ATTR_BLOB blob;
5727 char oid[] = "1.2.3";
5729 if (0)
5731 /* Crashes on win9x */
5732 SetLastError(0xdeadbeef);
5733 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, NULL,
5734 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5735 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5736 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5738 SetLastError(0xdeadbeef);
5739 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5740 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5741 ok(!ret && GetLastError() == E_INVALIDARG,
5742 "Expected E_INVALIDARG, got %x\n", GetLastError());
5743 attr.pszObjId = oid;
5744 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5745 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5746 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5747 if (buf)
5749 ok(size == sizeof(emptyPKCSAttr), "Unexpected size %d\n", size);
5750 ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n");
5751 LocalFree(buf);
5753 blob.cbData = sizeof(bogusDER);
5754 blob.pbData = bogusDER;
5755 attr.cValue = 1;
5756 attr.rgValue = &blob;
5757 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5758 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5759 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5760 if (buf)
5762 ok(size == sizeof(bogusPKCSAttr), "Unexpected size %d\n", size);
5763 ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n");
5764 LocalFree(buf);
5766 blob.pbData = (BYTE *)ints[0].encoded;
5767 blob.cbData = ints[0].encoded[1] + 2;
5768 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5769 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5770 if (buf)
5772 ok(size == sizeof(intPKCSAttr), "Unexpected size %d\n", size);
5773 ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n");
5774 LocalFree(buf);
5778 static void test_decodePKCSAttribute(DWORD dwEncoding)
5780 BOOL ret;
5781 LPBYTE buf = NULL;
5782 DWORD size = 0;
5783 CRYPT_ATTRIBUTE *attr;
5785 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5786 emptyPKCSAttr, sizeof(emptyPKCSAttr),
5787 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5788 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5789 if (buf)
5791 attr = (CRYPT_ATTRIBUTE *)buf;
5793 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5794 attr->pszObjId);
5795 ok(attr->cValue == 0, "Expected no value, got %d\n", attr->cValue);
5796 LocalFree(buf);
5798 SetLastError(0xdeadbeef);
5799 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5800 bogusPKCSAttr, sizeof(bogusPKCSAttr),
5801 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5802 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5803 * I doubt an app depends on that.
5805 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5806 GetLastError() == CRYPT_E_ASN1_CORRUPT),
5807 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5808 GetLastError());
5809 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5810 intPKCSAttr, sizeof(intPKCSAttr),
5811 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5812 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5813 if (buf)
5815 attr = (CRYPT_ATTRIBUTE *)buf;
5817 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5818 attr->pszObjId);
5819 ok(attr->cValue == 1, "Expected 1 value, got %d\n", attr->cValue);
5820 ok(attr->rgValue[0].cbData == ints[0].encoded[1] + 2,
5821 "Unexpected size %d\n", attr->rgValue[0].cbData);
5822 ok(!memcmp(attr->rgValue[0].pbData, ints[0].encoded,
5823 attr->rgValue[0].cbData), "Unexpected value\n");
5824 LocalFree(buf);
5828 static const BYTE emptyPKCSAttributes[] = { 0x31,0x00 };
5829 static const BYTE singlePKCSAttributes[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
5830 0x2a,0x03,0x31,0x00 };
5831 static const BYTE doublePKCSAttributes[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
5832 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
5834 static void test_encodePKCSAttributes(DWORD dwEncoding)
5836 CRYPT_ATTRIBUTES attributes = { 0 };
5837 CRYPT_ATTRIBUTE attr[2] = { { 0 } };
5838 CRYPT_ATTR_BLOB blob;
5839 BOOL ret;
5840 LPBYTE buf = NULL;
5841 DWORD size = 0;
5842 char oid1[] = "1.2.3", oid2[] = "1.5.6";
5844 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5845 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5846 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5847 if (buf)
5849 ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %d\n", size);
5850 ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n");
5851 LocalFree(buf);
5853 attributes.cAttr = 1;
5854 attributes.rgAttr = attr;
5855 SetLastError(0xdeadbeef);
5856 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5857 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5858 ok(!ret && GetLastError() == E_INVALIDARG,
5859 "Expected E_INVALIDARG, got %x\n", GetLastError());
5860 attr[0].pszObjId = oid1;
5861 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5862 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5863 if (buf)
5865 ok(size == sizeof(singlePKCSAttributes), "Unexpected size %d\n", size);
5866 ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n");
5867 LocalFree(buf);
5869 attr[1].pszObjId = oid2;
5870 attr[1].cValue = 1;
5871 attr[1].rgValue = &blob;
5872 blob.pbData = (BYTE *)ints[0].encoded;
5873 blob.cbData = ints[0].encoded[1] + 2;
5874 attributes.cAttr = 2;
5875 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5876 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5877 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5878 if (buf)
5880 ok(size == sizeof(doublePKCSAttributes), "Unexpected size %d\n", size);
5881 ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n");
5882 LocalFree(buf);
5886 static void test_decodePKCSAttributes(DWORD dwEncoding)
5888 BOOL ret;
5889 LPBYTE buf = NULL;
5890 DWORD size = 0;
5891 CRYPT_ATTRIBUTES *attributes;
5893 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5894 emptyPKCSAttributes, sizeof(emptyPKCSAttributes),
5895 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5896 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5897 if (buf)
5899 attributes = (CRYPT_ATTRIBUTES *)buf;
5900 ok(attributes->cAttr == 0, "Expected no attributes, got %d\n",
5901 attributes->cAttr);
5902 LocalFree(buf);
5904 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5905 singlePKCSAttributes, sizeof(singlePKCSAttributes),
5906 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5907 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5908 if (buf)
5910 attributes = (CRYPT_ATTRIBUTES *)buf;
5911 ok(attributes->cAttr == 1, "Expected 1 attribute, got %d\n",
5912 attributes->cAttr);
5913 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5914 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5915 ok(attributes->rgAttr[0].cValue == 0,
5916 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5917 LocalFree(buf);
5919 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5920 doublePKCSAttributes, sizeof(doublePKCSAttributes),
5921 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5922 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5923 if (buf)
5925 attributes = (CRYPT_ATTRIBUTES *)buf;
5926 ok(attributes->cAttr == 2, "Expected 2 attributes, got %d\n",
5927 attributes->cAttr);
5928 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5929 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5930 ok(attributes->rgAttr[0].cValue == 0,
5931 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5932 ok(!strcmp(attributes->rgAttr[1].pszObjId, "1.5.6"),
5933 "Expected 1.5.6, got %s\n", attributes->rgAttr[1].pszObjId);
5934 ok(attributes->rgAttr[1].cValue == 1,
5935 "Expected 1 attribute, got %d\n", attributes->rgAttr[1].cValue);
5936 ok(attributes->rgAttr[1].rgValue[0].cbData == ints[0].encoded[1] + 2,
5937 "Unexpected size %d\n", attributes->rgAttr[1].rgValue[0].cbData);
5938 ok(!memcmp(attributes->rgAttr[1].rgValue[0].pbData, ints[0].encoded,
5939 attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n");
5940 LocalFree(buf);
5944 static const BYTE singleCapability[] = {
5945 0x30,0x06,0x30,0x04,0x06,0x02,0x2d,0x06 };
5946 static const BYTE twoCapabilities[] = {
5947 0x30,0x0c,0x30,0x04,0x06,0x02,0x2d,0x06,0x30,0x04,0x06,0x02,0x2a,0x03 };
5948 static const BYTE singleCapabilitywithNULL[] = {
5949 0x30,0x08,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5951 static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding)
5953 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
5954 BOOL ret;
5955 LPBYTE buf = NULL;
5956 DWORD size = 0;
5957 CRYPT_SMIME_CAPABILITY capability[2];
5958 CRYPT_SMIME_CAPABILITIES capabilities;
5960 /* An empty capabilities is allowed */
5961 capabilities.cCapability = 0;
5962 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
5963 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5964 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5965 if (buf)
5967 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
5968 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
5969 LocalFree(buf);
5971 /* A non-empty capabilities with an empty capability (lacking an OID) is
5972 * not allowed
5974 capability[0].pszObjId = NULL;
5975 capability[0].Parameters.cbData = 0;
5976 capabilities.cCapability = 1;
5977 capabilities.rgCapability = capability;
5978 SetLastError(0xdeadbeef);
5979 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
5980 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5981 ok(!ret && GetLastError() == E_INVALIDARG,
5982 "expected E_INVALIDARG, got %08x\n", GetLastError());
5983 capability[0].pszObjId = oid1;
5984 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
5985 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5986 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5987 if (buf)
5989 ok(size == sizeof(singleCapability), "unexpected size %d\n", size);
5990 ok(!memcmp(buf, singleCapability, size), "unexpected value\n");
5991 LocalFree(buf);
5993 capability[1].pszObjId = oid2;
5994 capability[1].Parameters.cbData = 0;
5995 capabilities.cCapability = 2;
5996 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
5997 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5998 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5999 if (buf)
6001 ok(size == sizeof(twoCapabilities), "unexpected size %d\n", size);
6002 ok(!memcmp(buf, twoCapabilities, size), "unexpected value\n");
6003 LocalFree(buf);
6007 static void compareSMimeCapabilities(LPCSTR header,
6008 const CRYPT_SMIME_CAPABILITIES *expected, const CRYPT_SMIME_CAPABILITIES *got)
6010 DWORD i;
6012 ok(got->cCapability == expected->cCapability,
6013 "%s: expected %d capabilities, got %d\n", header, expected->cCapability,
6014 got->cCapability);
6015 for (i = 0; i < expected->cCapability; i++)
6017 ok(!strcmp(expected->rgCapability[i].pszObjId,
6018 got->rgCapability[i].pszObjId), "%s[%d]: expected %s, got %s\n",
6019 header, i, expected->rgCapability[i].pszObjId,
6020 got->rgCapability[i].pszObjId);
6021 ok(expected->rgCapability[i].Parameters.cbData ==
6022 got->rgCapability[i].Parameters.cbData,
6023 "%s[%d]: expected %d bytes, got %d\n", header, i,
6024 expected->rgCapability[i].Parameters.cbData,
6025 got->rgCapability[i].Parameters.cbData);
6026 if (expected->rgCapability[i].Parameters.cbData)
6027 ok(!memcmp(expected->rgCapability[i].Parameters.pbData,
6028 got->rgCapability[i].Parameters.pbData,
6029 expected->rgCapability[i].Parameters.cbData),
6030 "%s[%d]: unexpected value\n", header, i);
6034 static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding)
6036 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6037 BOOL ret;
6038 DWORD size = 0;
6039 CRYPT_SMIME_CAPABILITY capability[2];
6040 CRYPT_SMIME_CAPABILITIES capabilities, *ptr;
6042 SetLastError(0xdeadbeef);
6043 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6044 emptySequence, sizeof(emptySequence),
6045 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&ptr, &size);
6046 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6047 if (ret)
6049 capabilities.cCapability = 0;
6050 compareSMimeCapabilities("empty capabilities", &capabilities, ptr);
6051 LocalFree(ptr);
6053 SetLastError(0xdeadbeef);
6054 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6055 singleCapability, sizeof(singleCapability), CRYPT_DECODE_ALLOC_FLAG, NULL,
6056 (BYTE *)&ptr, &size);
6057 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6058 if (ret)
6060 capability[0].pszObjId = oid1;
6061 capability[0].Parameters.cbData = 0;
6062 capabilities.cCapability = 1;
6063 capabilities.rgCapability = capability;
6064 compareSMimeCapabilities("single capability", &capabilities, ptr);
6065 LocalFree(ptr);
6067 SetLastError(0xdeadbeef);
6068 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6069 singleCapabilitywithNULL, sizeof(singleCapabilitywithNULL),
6070 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&ptr, &size);
6071 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6072 if (ret)
6074 BYTE NULLparam[] = {0x05, 0x00};
6075 capability[0].pszObjId = oid1;
6076 capability[0].Parameters.cbData = 2;
6077 capability[0].Parameters.pbData = NULLparam;
6078 capabilities.cCapability = 1;
6079 capabilities.rgCapability = capability;
6080 compareSMimeCapabilities("single capability with NULL", &capabilities,
6081 ptr);
6082 LocalFree(ptr);
6084 SetLastError(0xdeadbeef);
6085 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6086 twoCapabilities, sizeof(twoCapabilities), CRYPT_DECODE_ALLOC_FLAG, NULL,
6087 (BYTE *)&ptr, &size);
6088 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6089 if (ret)
6091 capability[0].Parameters.cbData = 0;
6092 capability[1].pszObjId = oid2;
6093 capability[1].Parameters.cbData = 0;
6094 capabilities.cCapability = 2;
6095 compareSMimeCapabilities("two capabilities", &capabilities, ptr);
6096 LocalFree(ptr);
6100 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
6101 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
6102 0x67 };
6103 static const BYTE minimalPKCSSigner[] = {
6104 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6105 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6106 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6107 static const BYTE PKCSSignerWithSerial[] = {
6108 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6109 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6110 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
6111 0x00 };
6112 static const BYTE PKCSSignerWithHashAlgo[] = {
6113 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6114 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6115 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
6116 0x00,0x04,0x00 };
6117 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = {
6118 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6119 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6120 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6121 0x06,0x05,0x00,0x04,0x00 };
6122 static const BYTE PKCSSignerWithHash[] = {
6123 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6124 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6125 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6126 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
6127 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6128 static const BYTE PKCSSignerWithAuthAttr[] = {
6129 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6130 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6131 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
6132 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
6133 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
6134 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
6135 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6137 static void test_encodePKCSSignerInfo(DWORD dwEncoding)
6139 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6140 BOOL ret;
6141 LPBYTE buf = NULL;
6142 DWORD size = 0;
6143 CMSG_SIGNER_INFO info = { 0 };
6144 char oid_common_name[] = szOID_COMMON_NAME;
6145 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
6146 (LPBYTE)encodedCommonName };
6147 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
6149 SetLastError(0xdeadbeef);
6150 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6151 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6152 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6154 skip("no PKCS7_SIGNER_INFO encode support\n");
6155 return;
6157 ok(!ret && GetLastError() == E_INVALIDARG,
6158 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6159 /* To be encoded, a signer must have an issuer at least, and the encoding
6160 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
6161 * see decoding tests.)
6163 info.Issuer.cbData = sizeof(encodedCommonNameNoNull);
6164 info.Issuer.pbData = encodedCommonNameNoNull;
6165 SetLastError(0xdeadbeef);
6166 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6167 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6168 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6169 ok(!ret && GetLastError() == E_INVALIDARG,
6170 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6171 else
6173 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6174 if (buf)
6176 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6177 if (size == sizeof(minimalPKCSSigner))
6178 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6179 else
6180 ok(0, "Unexpected value\n");
6181 LocalFree(buf);
6184 info.SerialNumber.cbData = sizeof(serialNum);
6185 info.SerialNumber.pbData = (BYTE *)serialNum;
6186 SetLastError(0xdeadbeef);
6187 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6188 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6189 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6190 ok(!ret && GetLastError() == E_INVALIDARG,
6191 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6192 else
6194 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6195 if (buf)
6197 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6198 size);
6199 if (size == sizeof(PKCSSignerWithSerial))
6200 ok(!memcmp(buf, PKCSSignerWithSerial, size),
6201 "Unexpected value\n");
6202 else
6203 ok(0, "Unexpected value\n");
6204 LocalFree(buf);
6207 info.HashAlgorithm.pszObjId = oid1;
6208 SetLastError(0xdeadbeef);
6209 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6210 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6211 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6212 ok(!ret && GetLastError() == E_INVALIDARG,
6213 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6214 else
6216 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6217 if (buf)
6219 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6220 size);
6221 if (size == sizeof(PKCSSignerWithHashAlgo))
6222 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6223 "Unexpected value\n");
6224 else
6225 ok(0, "Unexpected value\n");
6226 LocalFree(buf);
6229 info.HashEncryptionAlgorithm.pszObjId = oid2;
6230 SetLastError(0xdeadbeef);
6231 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6232 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6233 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6234 ok(!ret && GetLastError() == E_INVALIDARG,
6235 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6236 else
6238 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6239 if (buf)
6241 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6242 "Unexpected size %d\n", size);
6243 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo))
6244 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6245 "Unexpected value\n");
6246 else
6247 ok(0, "Unexpected value\n");
6248 LocalFree(buf);
6251 info.EncryptedHash.cbData = sizeof(hash);
6252 info.EncryptedHash.pbData = (BYTE *)hash;
6253 SetLastError(0xdeadbeef);
6254 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6255 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6256 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6257 ok(!ret && GetLastError() == E_INVALIDARG,
6258 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6259 else
6261 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6262 if (buf)
6264 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6265 size);
6266 if (size == sizeof(PKCSSignerWithHash))
6267 ok(!memcmp(buf, PKCSSignerWithHash, size),
6268 "Unexpected value\n");
6269 else
6270 ok(0, "Unexpected value\n");
6271 LocalFree(buf);
6274 info.AuthAttrs.cAttr = 1;
6275 info.AuthAttrs.rgAttr = &attr;
6276 SetLastError(0xdeadbeef);
6277 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6278 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6279 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6280 ok(!ret && GetLastError() == E_INVALIDARG,
6281 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6282 else
6284 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6285 if (buf)
6287 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
6288 size);
6289 if (size == sizeof(PKCSSignerWithAuthAttr))
6290 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
6291 "Unexpected value\n");
6292 else
6293 ok(0, "Unexpected value\n");
6294 LocalFree(buf);
6299 static void test_decodePKCSSignerInfo(DWORD dwEncoding)
6301 BOOL ret;
6302 LPBYTE buf = NULL;
6303 DWORD size = 0;
6304 CMSG_SIGNER_INFO *info;
6306 /* A PKCS signer can't be decoded without a serial number. */
6307 SetLastError(0xdeadbeef);
6308 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6309 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6310 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6311 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
6312 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
6313 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6314 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6315 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6316 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6317 if (buf)
6319 info = (CMSG_SIGNER_INFO *)buf;
6320 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6321 info->dwVersion);
6322 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6323 "Unexpected size %d\n", info->Issuer.cbData);
6324 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6325 info->Issuer.cbData), "Unexpected value\n");
6326 ok(info->SerialNumber.cbData == sizeof(serialNum),
6327 "Unexpected size %d\n", info->SerialNumber.cbData);
6328 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6329 "Unexpected value\n");
6330 LocalFree(buf);
6332 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6333 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6334 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6335 if (buf)
6337 info = (CMSG_SIGNER_INFO *)buf;
6338 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6339 info->dwVersion);
6340 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6341 "Unexpected size %d\n", info->Issuer.cbData);
6342 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6343 info->Issuer.cbData), "Unexpected value\n");
6344 ok(info->SerialNumber.cbData == sizeof(serialNum),
6345 "Unexpected size %d\n", info->SerialNumber.cbData);
6346 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6347 "Unexpected value\n");
6348 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6349 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6350 LocalFree(buf);
6352 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6353 PKCSSignerWithHashAndEncryptionAlgo,
6354 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6355 NULL, (BYTE *)&buf, &size);
6356 if (buf)
6358 info = (CMSG_SIGNER_INFO *)buf;
6359 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6360 info->dwVersion);
6361 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6362 "Unexpected size %d\n", info->Issuer.cbData);
6363 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6364 info->Issuer.cbData), "Unexpected value\n");
6365 ok(info->SerialNumber.cbData == sizeof(serialNum),
6366 "Unexpected size %d\n", info->SerialNumber.cbData);
6367 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6368 "Unexpected value\n");
6369 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6370 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6371 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6372 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6373 LocalFree(buf);
6375 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6376 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6377 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6378 if (buf)
6380 info = (CMSG_SIGNER_INFO *)buf;
6381 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6382 info->dwVersion);
6383 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6384 "Unexpected size %d\n", info->Issuer.cbData);
6385 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6386 info->Issuer.cbData), "Unexpected value\n");
6387 ok(info->SerialNumber.cbData == sizeof(serialNum),
6388 "Unexpected size %d\n", info->SerialNumber.cbData);
6389 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6390 "Unexpected value\n");
6391 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6392 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6393 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6394 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6395 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6396 info->EncryptedHash.cbData);
6397 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6398 "Unexpected value\n");
6399 LocalFree(buf);
6401 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6402 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
6403 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6404 if (buf)
6406 info = (CMSG_SIGNER_INFO *)buf;
6407 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n",
6408 info->AuthAttrs.cAttr);
6409 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
6410 "Expected %s, got %s\n", szOID_COMMON_NAME,
6411 info->AuthAttrs.rgAttr[0].pszObjId);
6412 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
6413 info->AuthAttrs.rgAttr[0].cValue);
6414 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
6415 sizeof(encodedCommonName), "Unexpected size %d\n",
6416 info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
6417 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
6418 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
6419 LocalFree(buf);
6423 static const BYTE CMSSignerWithKeyId[] = {
6424 0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,
6425 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6427 static void test_encodeCMSSignerInfo(DWORD dwEncoding)
6429 BOOL ret;
6430 LPBYTE buf = NULL;
6431 DWORD size = 0;
6432 CMSG_CMS_SIGNER_INFO info = { 0 };
6433 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6435 SetLastError(0xdeadbeef);
6436 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6437 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6438 ok(!ret && GetLastError() == E_INVALIDARG,
6439 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6440 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6441 SetLastError(0xdeadbeef);
6442 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6443 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6444 ok(!ret, "Expected failure, got %d\n", ret);
6445 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6447 skip("no CMS_SIGNER_INFO encode support\n");
6448 return;
6450 ok(GetLastError() == E_INVALIDARG,
6451 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6452 /* To be encoded, a signer must have a valid cert ID, where a valid ID may
6453 * be a key id or a issuer serial number with at least the issuer set, and
6454 * the encoding must include PKCS_7_ASN_ENCODING.
6455 * (That isn't enough to be decoded, see decoding tests.)
6457 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6458 sizeof(encodedCommonNameNoNull);
6459 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6460 SetLastError(0xdeadbeef);
6461 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6462 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6463 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6464 ok(!ret && GetLastError() == E_INVALIDARG,
6465 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6466 else
6468 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6469 if (buf)
6471 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6472 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6473 LocalFree(buf);
6476 U(info.SignerId).IssuerSerialNumber.SerialNumber.cbData = sizeof(serialNum);
6477 U(info.SignerId).IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
6478 SetLastError(0xdeadbeef);
6479 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6480 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6481 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6482 ok(!ret && GetLastError() == E_INVALIDARG,
6483 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6484 else
6486 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6487 if (buf)
6489 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6490 size);
6491 ok(!memcmp(buf, PKCSSignerWithSerial, size), "Unexpected value\n");
6492 LocalFree(buf);
6495 info.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
6496 U(info.SignerId).KeyId.cbData = sizeof(serialNum);
6497 U(info.SignerId).KeyId.pbData = (BYTE *)serialNum;
6498 SetLastError(0xdeadbeef);
6499 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6500 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6501 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6502 ok(!ret && GetLastError() == E_INVALIDARG,
6503 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6504 else
6506 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6507 if (buf)
6509 ok(size == sizeof(CMSSignerWithKeyId), "Unexpected size %d\n",
6510 size);
6511 ok(!memcmp(buf, CMSSignerWithKeyId, size), "Unexpected value\n");
6512 LocalFree(buf);
6515 /* While a CERT_ID can have a hash type, that's not allowed in CMS, where
6516 * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed
6517 * (see RFC 3852, section 5.3.)
6519 info.SignerId.dwIdChoice = CERT_ID_SHA1_HASH;
6520 U(info.SignerId).HashId.cbData = sizeof(hash);
6521 U(info.SignerId).HashId.pbData = (BYTE *)hash;
6522 SetLastError(0xdeadbeef);
6523 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6524 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6525 ok(!ret && GetLastError() == E_INVALIDARG,
6526 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6527 /* Now with a hash algo */
6528 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6529 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6530 sizeof(encodedCommonNameNoNull);
6531 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6532 info.HashAlgorithm.pszObjId = oid1;
6533 SetLastError(0xdeadbeef);
6534 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6535 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6536 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6537 ok(!ret && GetLastError() == E_INVALIDARG,
6538 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6539 else
6541 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6542 if (buf)
6544 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6545 size);
6546 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6547 "Unexpected value\n");
6548 LocalFree(buf);
6551 info.HashEncryptionAlgorithm.pszObjId = oid2;
6552 SetLastError(0xdeadbeef);
6553 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6554 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6555 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6556 ok(!ret && GetLastError() == E_INVALIDARG,
6557 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6558 else
6560 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6561 if (buf)
6563 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6564 "Unexpected size %d\n", size);
6565 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6566 "Unexpected value\n");
6567 LocalFree(buf);
6570 info.EncryptedHash.cbData = sizeof(hash);
6571 info.EncryptedHash.pbData = (BYTE *)hash;
6572 SetLastError(0xdeadbeef);
6573 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6574 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6575 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6576 ok(!ret && GetLastError() == E_INVALIDARG,
6577 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6578 else
6580 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6581 if (buf)
6583 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6584 size);
6585 ok(!memcmp(buf, PKCSSignerWithHash, size), "Unexpected value\n");
6586 LocalFree(buf);
6591 static void test_decodeCMSSignerInfo(DWORD dwEncoding)
6593 BOOL ret;
6594 LPBYTE buf = NULL;
6595 DWORD size = 0;
6596 CMSG_CMS_SIGNER_INFO *info;
6597 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6599 /* A CMS signer can't be decoded without a serial number. */
6600 SetLastError(0xdeadbeef);
6601 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6602 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6603 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6604 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
6605 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
6606 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6607 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6608 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6609 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6610 if (buf)
6612 info = (CMSG_CMS_SIGNER_INFO *)buf;
6613 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6614 info->dwVersion);
6615 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6616 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6617 info->SignerId.dwIdChoice);
6618 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6619 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6620 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6621 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6622 encodedCommonNameNoNull,
6623 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6624 "Unexpected value\n");
6625 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6626 sizeof(serialNum), "Unexpected size %d\n",
6627 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6628 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6629 serialNum, sizeof(serialNum)), "Unexpected value\n");
6630 LocalFree(buf);
6632 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6633 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6634 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6635 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6636 if (buf)
6638 info = (CMSG_CMS_SIGNER_INFO *)buf;
6639 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6640 info->dwVersion);
6641 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6642 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6643 info->SignerId.dwIdChoice);
6644 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6645 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6646 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6647 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6648 encodedCommonNameNoNull,
6649 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6650 "Unexpected value\n");
6651 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6652 sizeof(serialNum), "Unexpected size %d\n",
6653 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6654 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6655 serialNum, sizeof(serialNum)), "Unexpected value\n");
6656 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6657 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6658 LocalFree(buf);
6660 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6661 PKCSSignerWithHashAndEncryptionAlgo,
6662 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6663 NULL, (BYTE *)&buf, &size);
6664 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6665 if (buf)
6667 info = (CMSG_CMS_SIGNER_INFO *)buf;
6668 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6669 info->dwVersion);
6670 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6671 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6672 info->SignerId.dwIdChoice);
6673 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6674 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6675 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6676 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6677 encodedCommonNameNoNull,
6678 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6679 "Unexpected value\n");
6680 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6681 sizeof(serialNum), "Unexpected size %d\n",
6682 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6683 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6684 serialNum, sizeof(serialNum)), "Unexpected value\n");
6685 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6686 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6687 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6688 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6689 LocalFree(buf);
6691 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6692 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6693 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6694 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6695 if (buf)
6697 info = (CMSG_CMS_SIGNER_INFO *)buf;
6698 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6699 info->dwVersion);
6700 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6701 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6702 info->SignerId.dwIdChoice);
6703 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6704 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6705 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6706 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6707 encodedCommonNameNoNull,
6708 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6709 "Unexpected value\n");
6710 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6711 sizeof(serialNum), "Unexpected size %d\n",
6712 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6713 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6714 serialNum, sizeof(serialNum)), "Unexpected value\n");
6715 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6716 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6717 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6718 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6719 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6720 info->EncryptedHash.cbData);
6721 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6722 "Unexpected value\n");
6723 LocalFree(buf);
6725 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6726 CMSSignerWithKeyId, sizeof(CMSSignerWithKeyId),
6727 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6728 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6729 if (buf)
6731 info = (CMSG_CMS_SIGNER_INFO *)buf;
6732 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6733 info->dwVersion);
6734 ok(info->SignerId.dwIdChoice == CERT_ID_KEY_IDENTIFIER,
6735 "Expected CERT_ID_KEY_IDENTIFIER, got %d\n",
6736 info->SignerId.dwIdChoice);
6737 ok(U(info->SignerId).KeyId.cbData == sizeof(serialNum),
6738 "Unexpected size %d\n", U(info->SignerId).KeyId.cbData);
6739 ok(!memcmp(U(info->SignerId).KeyId.pbData, serialNum, sizeof(serialNum)),
6740 "Unexpected value\n");
6741 LocalFree(buf);
6745 static BYTE emptyDNSPermittedConstraints[] = {
6746 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
6747 static BYTE emptyDNSExcludedConstraints[] = {
6748 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
6749 static BYTE DNSExcludedConstraints[] = {
6750 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
6751 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6752 static BYTE permittedAndExcludedConstraints[] = {
6753 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6754 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
6755 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6756 static BYTE permittedAndExcludedWithMinConstraints[] = {
6757 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6758 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
6759 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6760 static BYTE permittedAndExcludedWithMinMaxConstraints[] = {
6761 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6762 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
6763 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6765 static void test_encodeNameConstraints(DWORD dwEncoding)
6767 BOOL ret;
6768 CERT_NAME_CONSTRAINTS_INFO constraints = { 0 };
6769 CERT_GENERAL_SUBTREE permitted = { { 0 } };
6770 CERT_GENERAL_SUBTREE excluded = { { 0 } };
6771 LPBYTE buf;
6772 DWORD size;
6774 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6775 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6776 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6778 skip("no X509_NAME_CONSTRAINTS encode support\n");
6779 return;
6781 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6782 if (ret)
6784 ok(size == sizeof(emptySequence), "Unexpected size\n");
6785 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
6786 LocalFree(buf);
6788 constraints.cPermittedSubtree = 1;
6789 constraints.rgPermittedSubtree = &permitted;
6790 SetLastError(0xdeadbeef);
6791 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6792 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6793 ok(!ret && GetLastError() == E_INVALIDARG,
6794 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6795 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
6796 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6797 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6798 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6799 if (ret)
6801 ok(size == sizeof(emptyDNSPermittedConstraints), "Unexpected size\n");
6802 ok(!memcmp(buf, emptyDNSPermittedConstraints, size),
6803 "Unexpected value\n");
6804 LocalFree(buf);
6806 constraints.cPermittedSubtree = 0;
6807 constraints.cExcludedSubtree = 1;
6808 constraints.rgExcludedSubtree = &excluded;
6809 excluded.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
6810 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6811 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6812 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6813 if (ret)
6815 ok(size == sizeof(emptyDNSExcludedConstraints), "Unexpected size\n");
6816 ok(!memcmp(buf, emptyDNSExcludedConstraints, size),
6817 "Unexpected value\n");
6818 LocalFree(buf);
6820 U(excluded.Base).pwszURL = (LPWSTR)url;
6821 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6822 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6823 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6824 if (ret)
6826 ok(size == sizeof(DNSExcludedConstraints), "Unexpected size\n");
6827 ok(!memcmp(buf, DNSExcludedConstraints, size),
6828 "Unexpected value\n");
6829 LocalFree(buf);
6831 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
6832 U(permitted.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6833 U(permitted.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6834 constraints.cPermittedSubtree = 1;
6835 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6836 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6837 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6838 if (ret)
6840 ok(size == sizeof(permittedAndExcludedConstraints),
6841 "Unexpected size\n");
6842 ok(!memcmp(buf, permittedAndExcludedConstraints, size),
6843 "Unexpected value\n");
6844 LocalFree(buf);
6846 permitted.dwMinimum = 5;
6847 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6848 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6849 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6850 if (ret)
6852 ok(size == sizeof(permittedAndExcludedWithMinConstraints),
6853 "Unexpected size\n");
6854 ok(!memcmp(buf, permittedAndExcludedWithMinConstraints, size),
6855 "Unexpected value\n");
6856 LocalFree(buf);
6858 permitted.fMaximum = TRUE;
6859 permitted.dwMaximum = 3;
6860 SetLastError(0xdeadbeef);
6861 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6862 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6863 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6864 if (ret)
6866 ok(size == sizeof(permittedAndExcludedWithMinMaxConstraints),
6867 "Unexpected size\n");
6868 ok(!memcmp(buf, permittedAndExcludedWithMinMaxConstraints, size),
6869 "Unexpected value\n");
6870 LocalFree(buf);
6874 struct EncodedNameConstraints
6876 CRYPT_DATA_BLOB encoded;
6877 CERT_NAME_CONSTRAINTS_INFO constraints;
6880 static CERT_GENERAL_SUBTREE emptyDNSSubtree = {
6881 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
6882 static CERT_GENERAL_SUBTREE DNSSubtree = {
6883 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
6884 static CERT_GENERAL_SUBTREE IPAddressSubtree = {
6885 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 0 };
6886 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree = {
6887 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, 0 };
6888 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree = {
6889 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, TRUE, 3 };
6891 struct EncodedNameConstraints encodedNameConstraints[] = {
6892 { { sizeof(emptySequence), (LPBYTE)emptySequence }, { 0 } },
6893 { { sizeof(emptyDNSPermittedConstraints), emptyDNSPermittedConstraints },
6894 { 1, &emptyDNSSubtree, 0, NULL } },
6895 { { sizeof(emptyDNSExcludedConstraints), emptyDNSExcludedConstraints },
6896 { 0, NULL, 1, &emptyDNSSubtree } },
6897 { { sizeof(DNSExcludedConstraints), DNSExcludedConstraints },
6898 { 0, NULL, 1, &DNSSubtree } },
6899 { { sizeof(permittedAndExcludedConstraints), permittedAndExcludedConstraints },
6900 { 1, &IPAddressSubtree, 1, &DNSSubtree } },
6901 { { sizeof(permittedAndExcludedWithMinConstraints),
6902 permittedAndExcludedWithMinConstraints },
6903 { 1, &IPAddressWithMinSubtree, 1, &DNSSubtree } },
6904 { { sizeof(permittedAndExcludedWithMinMaxConstraints),
6905 permittedAndExcludedWithMinMaxConstraints },
6906 { 1, &IPAddressWithMinMaxSubtree, 1, &DNSSubtree } },
6909 static void test_decodeNameConstraints(DWORD dwEncoding)
6911 BOOL ret;
6912 DWORD i;
6913 CERT_NAME_CONSTRAINTS_INFO *constraints;
6915 U(DNSSubtree.Base).pwszURL = (LPWSTR)url;
6916 U(IPAddressSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6917 U(IPAddressSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6918 U(IPAddressWithMinSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6919 U(IPAddressWithMinSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6920 U(IPAddressWithMinMaxSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6921 U(IPAddressWithMinMaxSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6922 for (i = 0;
6923 i < sizeof(encodedNameConstraints) / sizeof(encodedNameConstraints[0]);
6924 i++)
6926 DWORD size;
6928 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS,
6929 encodedNameConstraints[i].encoded.pbData,
6930 encodedNameConstraints[i].encoded.cbData,
6931 CRYPT_DECODE_ALLOC_FLAG, NULL, &constraints, &size);
6932 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6934 skip("no X509_NAME_CONSTRAINTS decode support\n");
6935 return;
6937 ok(ret, "%d: CryptDecodeObjectEx failed: %08x\n", i, GetLastError());
6938 if (ret)
6940 DWORD j;
6942 if (constraints->cPermittedSubtree !=
6943 encodedNameConstraints[i].constraints.cPermittedSubtree)
6944 fprintf(stderr, "%d: expected %d permitted, got %d\n", i,
6945 encodedNameConstraints[i].constraints.cPermittedSubtree,
6946 constraints->cPermittedSubtree);
6947 if (constraints->cPermittedSubtree ==
6948 encodedNameConstraints[i].constraints.cPermittedSubtree)
6950 for (j = 0; j < constraints->cPermittedSubtree; j++)
6952 compareAltNameEntry(&constraints->rgPermittedSubtree[j].Base,
6953 &encodedNameConstraints[i].constraints.rgPermittedSubtree[j].Base);
6956 if (constraints->cExcludedSubtree !=
6957 encodedNameConstraints[i].constraints.cExcludedSubtree)
6958 fprintf(stderr, "%d: expected %d excluded, got %d\n", i,
6959 encodedNameConstraints[i].constraints.cExcludedSubtree,
6960 constraints->cExcludedSubtree);
6961 if (constraints->cExcludedSubtree ==
6962 encodedNameConstraints[i].constraints.cExcludedSubtree)
6964 for (j = 0; j < constraints->cExcludedSubtree; j++)
6966 compareAltNameEntry(&constraints->rgExcludedSubtree[j].Base,
6967 &encodedNameConstraints[i].constraints.rgExcludedSubtree[j].Base);
6970 LocalFree(constraints);
6975 /* Free *pInfo with HeapFree */
6976 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
6978 BOOL ret;
6979 DWORD size = 0;
6980 HCRYPTKEY key;
6982 /* This crashes
6983 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
6985 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size);
6986 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
6987 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
6988 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL,
6989 &size);
6990 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
6991 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
6992 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL,
6993 NULL, &size);
6994 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
6995 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
6996 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
6997 0, NULL, NULL, &size);
6998 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
6999 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7000 /* Test with no key */
7001 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7002 0, NULL, NULL, &size);
7003 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n",
7004 GetLastError());
7005 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
7006 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
7007 if (ret)
7009 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
7010 NULL, 0, NULL, NULL, &size);
7011 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
7012 *pInfo = HeapAlloc(GetProcessHeap(), 0, size);
7013 if (*pInfo)
7015 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
7016 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size);
7017 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n",
7018 GetLastError());
7019 if (ret)
7021 /* By default (we passed NULL as the OID) the OID is
7022 * szOID_RSA_RSA.
7024 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA),
7025 "Expected %s, got %s\n", szOID_RSA_RSA,
7026 (*pInfo)->Algorithm.pszObjId);
7030 CryptDestroyKey(key);
7033 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
7034 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
7035 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
7036 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7037 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7038 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7039 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
7040 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
7041 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7042 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7043 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7044 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
7045 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
7046 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
7047 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
7048 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
7049 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
7050 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
7051 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
7052 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
7053 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
7054 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
7055 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
7056 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
7057 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
7059 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info)
7061 BOOL ret;
7062 HCRYPTKEY key;
7063 PCCERT_CONTEXT context;
7064 DWORD dwSize;
7065 ALG_ID ai;
7067 /* These crash
7068 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
7069 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
7070 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
7071 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7072 NULL);
7074 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key);
7075 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7076 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7077 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key);
7078 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7079 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7080 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL,
7081 &key);
7082 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7083 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7085 /* Export key with standard algorithm (CALG_RSA_KEYX) */
7086 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7087 &key);
7088 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7090 dwSize = sizeof(ai);
7091 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7092 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7093 if(ret)
7095 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7096 ok(ai == CALG_RSA_KEYX, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai);
7099 CryptDestroyKey(key);
7101 /* Repeat with forced algorithm */
7102 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, CALG_RSA_SIGN, 0, NULL,
7103 &key);
7104 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7106 dwSize = sizeof(ai);
7107 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7108 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7109 if(ret)
7111 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7112 ok(ai == CALG_RSA_SIGN, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai);
7115 CryptDestroyKey(key);
7117 /* Test importing a public key from a certificate context */
7118 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert,
7119 sizeof(expiredCert));
7120 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
7121 GetLastError());
7122 if (context)
7124 ok(!strcmp(szOID_RSA_RSA,
7125 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId),
7126 "Expected %s, got %s\n", szOID_RSA_RSA,
7127 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
7128 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING,
7129 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
7130 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7131 CryptDestroyKey(key);
7132 CertFreeCertificateContext(context);
7136 static const char cspName[] = "WineCryptTemp";
7138 static void testPortPublicKeyInfo(void)
7140 HCRYPTPROV csp;
7141 BOOL ret;
7142 PCERT_PUBLIC_KEY_INFO info = NULL;
7144 /* Just in case a previous run failed, delete this thing */
7145 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7146 CRYPT_DELETEKEYSET);
7147 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7148 CRYPT_NEWKEYSET);
7150 testExportPublicKey(csp, &info);
7151 testImportPublicKey(csp, info);
7153 HeapFree(GetProcessHeap(), 0, info);
7154 CryptReleaseContext(csp, 0);
7155 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7156 CRYPT_DELETEKEYSET);
7159 START_TEST(encode)
7161 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
7162 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING };
7163 HMODULE hCrypt32;
7164 DWORD i;
7166 hCrypt32 = GetModuleHandleA("crypt32.dll");
7167 pCryptDecodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptDecodeObjectEx");
7168 pCryptEncodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptEncodeObjectEx");
7169 if (!pCryptDecodeObjectEx || !pCryptEncodeObjectEx)
7171 skip("CryptDecodeObjectEx() is not available\n");
7172 return;
7175 for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++)
7177 test_encodeInt(encodings[i]);
7178 test_decodeInt(encodings[i]);
7179 test_encodeEnumerated(encodings[i]);
7180 test_decodeEnumerated(encodings[i]);
7181 test_encodeFiletime(encodings[i]);
7182 test_decodeFiletime(encodings[i]);
7183 test_encodeName(encodings[i]);
7184 test_decodeName(encodings[i]);
7185 test_encodeUnicodeName(encodings[i]);
7186 test_decodeUnicodeName(encodings[i]);
7187 test_encodeNameValue(encodings[i]);
7188 test_decodeNameValue(encodings[i]);
7189 test_encodeUnicodeNameValue(encodings[i]);
7190 test_decodeUnicodeNameValue(encodings[i]);
7191 test_encodeAltName(encodings[i]);
7192 test_decodeAltName(encodings[i]);
7193 test_encodeOctets(encodings[i]);
7194 test_decodeOctets(encodings[i]);
7195 test_encodeBits(encodings[i]);
7196 test_decodeBits(encodings[i]);
7197 test_encodeBasicConstraints(encodings[i]);
7198 test_decodeBasicConstraints(encodings[i]);
7199 test_encodeRsaPublicKey(encodings[i]);
7200 test_decodeRsaPublicKey(encodings[i]);
7201 test_encodeSequenceOfAny(encodings[i]);
7202 test_decodeSequenceOfAny(encodings[i]);
7203 test_encodeExtensions(encodings[i]);
7204 test_decodeExtensions(encodings[i]);
7205 test_encodePublicKeyInfo(encodings[i]);
7206 test_decodePublicKeyInfo(encodings[i]);
7207 test_encodeCertToBeSigned(encodings[i]);
7208 test_decodeCertToBeSigned(encodings[i]);
7209 test_encodeCert(encodings[i]);
7210 test_decodeCert(encodings[i]);
7211 test_encodeCRLDistPoints(encodings[i]);
7212 test_decodeCRLDistPoints(encodings[i]);
7213 test_encodeCRLIssuingDistPoint(encodings[i]);
7214 test_decodeCRLIssuingDistPoint(encodings[i]);
7215 test_encodeCRLToBeSigned(encodings[i]);
7216 test_decodeCRLToBeSigned(encodings[i]);
7217 test_encodeEnhancedKeyUsage(encodings[i]);
7218 test_decodeEnhancedKeyUsage(encodings[i]);
7219 test_encodeAuthorityKeyId(encodings[i]);
7220 test_decodeAuthorityKeyId(encodings[i]);
7221 test_encodeAuthorityKeyId2(encodings[i]);
7222 test_decodeAuthorityKeyId2(encodings[i]);
7223 test_encodeAuthorityInfoAccess(encodings[i]);
7224 test_decodeAuthorityInfoAccess(encodings[i]);
7225 test_encodeCTL(encodings[i]);
7226 test_decodeCTL(encodings[i]);
7227 test_encodePKCSContentInfo(encodings[i]);
7228 test_decodePKCSContentInfo(encodings[i]);
7229 test_encodePKCSAttribute(encodings[i]);
7230 test_decodePKCSAttribute(encodings[i]);
7231 test_encodePKCSAttributes(encodings[i]);
7232 test_decodePKCSAttributes(encodings[i]);
7233 test_encodePKCSSMimeCapabilities(encodings[i]);
7234 test_decodePKCSSMimeCapabilities(encodings[i]);
7235 test_encodePKCSSignerInfo(encodings[i]);
7236 test_decodePKCSSignerInfo(encodings[i]);
7237 test_encodeCMSSignerInfo(encodings[i]);
7238 test_decodeCMSSignerInfo(encodings[i]);
7239 test_encodeNameConstraints(encodings[i]);
7240 test_decodeNameConstraints(encodings[i]);
7242 testPortPublicKeyInfo();