crypt32: Implement decoding CERT_POLICY_QUALIFIER_USER_NOTICE.
[wine/wine64.git] / dlls / crypt32 / tests / encode.c
blob4adba05d63671e846efb1a5e67c234aa353d1aa7
1 /*
2 * Unit test suite for crypt32.dll's CryptEncodeObjectEx/CryptDecodeObjectEx
4 * Copyright 2005 Juan Lang
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include <stdio.h>
21 #include <stdarg.h>
22 #include <windef.h>
23 #include <winbase.h>
24 #include <winerror.h>
25 #include <wincrypt.h>
27 #include "wine/test.h"
30 static BOOL (WINAPI *pCryptDecodeObjectEx)(DWORD,LPCSTR,const BYTE*,DWORD,DWORD,PCRYPT_DECODE_PARA,void*,DWORD*);
31 static BOOL (WINAPI *pCryptEncodeObjectEx)(DWORD,LPCSTR,const void*,DWORD,PCRYPT_ENCODE_PARA,void*,DWORD*);
33 struct encodedInt
35 int val;
36 const BYTE *encoded;
39 static const BYTE bin1[] = {0x02,0x01,0x01};
40 static const BYTE bin2[] = {0x02,0x01,0x7f};
41 static const BYTE bin3[] = {0x02,0x02,0x00,0x80};
42 static const BYTE bin4[] = {0x02,0x02,0x01,0x00};
43 static const BYTE bin5[] = {0x02,0x01,0x80};
44 static const BYTE bin6[] = {0x02,0x02,0xff,0x7f};
45 static const BYTE bin7[] = {0x02,0x04,0xba,0xdd,0xf0,0x0d};
47 static const struct encodedInt ints[] = {
48 { 1, bin1 },
49 { 127, bin2 },
50 { 128, bin3 },
51 { 256, bin4 },
52 { -128, bin5 },
53 { -129, bin6 },
54 { 0xbaddf00d, bin7 },
57 struct encodedBigInt
59 const BYTE *val;
60 const BYTE *encoded;
61 const BYTE *decoded;
64 static const BYTE bin8[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
65 static const BYTE bin9[] = {0x02,0x0a,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0};
66 static const BYTE bin10[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
68 static const BYTE bin11[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0xff,0};
69 static const BYTE bin12[] = {0x02,0x09,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
70 static const BYTE bin13[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0};
72 static const struct encodedBigInt bigInts[] = {
73 { bin8, bin9, bin10 },
74 { bin11, bin12, bin13 },
77 static const BYTE bin14[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
78 static const BYTE bin15[] = {0x02,0x0a,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0};
79 static const BYTE bin16[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0xff,0};
80 static const BYTE bin17[] = {0x02,0x0c,0x00,0xff,0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
82 /* Decoded is the same as original, so don't bother storing a separate copy */
83 static const struct encodedBigInt bigUInts[] = {
84 { bin14, bin15, NULL },
85 { bin16, bin17, NULL },
88 static void test_encodeInt(DWORD dwEncoding)
90 DWORD bufSize = 0;
91 int i;
92 BOOL ret;
93 CRYPT_INTEGER_BLOB blob;
94 BYTE *buf = NULL;
96 /* CryptEncodeObjectEx with NULL bufSize crashes..
97 ret = pCryptEncodeObjectEx(3, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
98 NULL);
100 /* check bogus encoding */
101 ret = pCryptEncodeObjectEx(0, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
102 &bufSize);
103 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
104 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
105 if (0)
107 /* check with NULL integer buffer. Windows XP incorrectly returns an
108 * NTSTATUS (crashes on win9x).
110 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, NULL, 0, NULL, NULL,
111 &bufSize);
112 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
113 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
115 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
117 /* encode as normal integer */
118 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, &ints[i].val, 0,
119 NULL, NULL, &bufSize);
120 ok(ret, "Expected success, got %d\n", GetLastError());
121 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, &ints[i].val,
122 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
123 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
124 if (buf)
126 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
127 buf[0]);
128 ok(buf[1] == ints[i].encoded[1], "Got length %d, expected %d\n",
129 buf[1], ints[i].encoded[1]);
130 ok(!memcmp(buf + 1, ints[i].encoded + 1, ints[i].encoded[1] + 1),
131 "Encoded value of 0x%08x didn't match expected\n", ints[i].val);
132 LocalFree(buf);
134 /* encode as multibyte integer */
135 blob.cbData = sizeof(ints[i].val);
136 blob.pbData = (BYTE *)&ints[i].val;
137 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
138 0, NULL, NULL, &bufSize);
139 ok(ret, "Expected success, got %d\n", GetLastError());
140 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
141 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
142 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
143 if (buf)
145 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
146 buf[0]);
147 ok(buf[1] == ints[i].encoded[1], "Got length %d, expected %d\n",
148 buf[1], ints[i].encoded[1]);
149 ok(!memcmp(buf + 1, ints[i].encoded + 1, ints[i].encoded[1] + 1),
150 "Encoded value of 0x%08x didn't match expected\n", ints[i].val);
151 LocalFree(buf);
154 /* encode a couple bigger ints, just to show it's little-endian and leading
155 * sign bytes are dropped
157 for (i = 0; i < sizeof(bigInts) / sizeof(bigInts[0]); i++)
159 blob.cbData = strlen((const char*)bigInts[i].val);
160 blob.pbData = (BYTE *)bigInts[i].val;
161 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
162 0, NULL, NULL, &bufSize);
163 ok(ret, "Expected success, got %d\n", GetLastError());
164 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
165 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
166 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
167 if (buf)
169 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
170 buf[0]);
171 ok(buf[1] == bigInts[i].encoded[1], "Got length %d, expected %d\n",
172 buf[1], bigInts[i].encoded[1]);
173 ok(!memcmp(buf + 1, bigInts[i].encoded + 1,
174 bigInts[i].encoded[1] + 1),
175 "Encoded value didn't match expected\n");
176 LocalFree(buf);
179 /* and, encode some uints */
180 for (i = 0; i < sizeof(bigUInts) / sizeof(bigUInts[0]); i++)
182 blob.cbData = strlen((const char*)bigUInts[i].val);
183 blob.pbData = (BYTE*)bigUInts[i].val;
184 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, &blob,
185 0, NULL, NULL, &bufSize);
186 ok(ret, "Expected success, got %d\n", GetLastError());
187 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, &blob,
188 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
189 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
190 if (buf)
192 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
193 buf[0]);
194 ok(buf[1] == bigUInts[i].encoded[1], "Got length %d, expected %d\n",
195 buf[1], bigUInts[i].encoded[1]);
196 ok(!memcmp(buf + 1, bigUInts[i].encoded + 1,
197 bigUInts[i].encoded[1] + 1),
198 "Encoded value didn't match expected\n");
199 LocalFree(buf);
204 static void test_decodeInt(DWORD dwEncoding)
206 static const BYTE bigInt[] = { 2, 5, 0xff, 0xfe, 0xff, 0xfe, 0xff };
207 static const BYTE testStr[] = { 0x16, 4, 't', 'e', 's', 't' };
208 static const BYTE longForm[] = { 2, 0x81, 0x01, 0x01 };
209 static const BYTE bigBogus[] = { 0x02, 0x84, 0x01, 0xff, 0xff, 0xf9 };
210 static const BYTE extraBytes[] = { 2, 1, 1, 0, 0, 0, 0 };
211 BYTE *buf = NULL;
212 DWORD bufSize = 0;
213 int i;
214 BOOL ret;
216 /* CryptDecodeObjectEx with NULL bufSize crashes..
217 ret = pCryptDecodeObjectEx(3, X509_INTEGER, &ints[0].encoded,
218 ints[0].encoded[1] + 2, 0, NULL, NULL, NULL);
220 /* check bogus encoding */
221 ret = pCryptDecodeObjectEx(3, X509_INTEGER, (BYTE *)&ints[0].encoded,
222 ints[0].encoded[1] + 2, 0, NULL, NULL, &bufSize);
223 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
224 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
225 /* check with NULL integer buffer */
226 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, NULL, 0, 0, NULL, NULL,
227 &bufSize);
228 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
229 GetLastError() == OSS_BAD_ARG /* Win9x */),
230 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
231 /* check with a valid, but too large, integer */
232 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, bigInt, bigInt[1] + 2,
233 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
234 ok((!ret && GetLastError() == CRYPT_E_ASN1_LARGE) ||
235 broken(ret) /* Win9x */,
236 "Expected CRYPT_E_ASN1_LARGE, got %d\n", GetLastError());
237 /* check with a DER-encoded string */
238 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, testStr, testStr[1] + 2,
239 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
240 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
241 GetLastError() == OSS_PDU_MISMATCH /* Win9x */ ),
242 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %08x\n",
243 GetLastError());
244 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
246 /* When the output buffer is NULL, this always succeeds */
247 SetLastError(0xdeadbeef);
248 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER,
249 ints[i].encoded, ints[i].encoded[1] + 2, 0, NULL, NULL,
250 &bufSize);
251 ok(ret && GetLastError() == NOERROR,
252 "Expected success and NOERROR, got %d\n", GetLastError());
253 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER,
254 ints[i].encoded, ints[i].encoded[1] + 2,
255 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
256 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
257 ok(bufSize == sizeof(int), "Wrong size %d\n", bufSize);
258 ok(buf != NULL, "Expected allocated buffer\n");
259 if (buf)
261 ok(!memcmp(buf, &ints[i].val, bufSize), "Expected %d, got %d\n",
262 ints[i].val, *(int *)buf);
263 LocalFree(buf);
266 for (i = 0; i < sizeof(bigInts) / sizeof(bigInts[0]); i++)
268 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER,
269 bigInts[i].encoded, bigInts[i].encoded[1] + 2, 0, NULL, NULL,
270 &bufSize);
271 ok(ret && GetLastError() == NOERROR,
272 "Expected success and NOERROR, got %d\n", GetLastError());
273 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER,
274 bigInts[i].encoded, bigInts[i].encoded[1] + 2,
275 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
276 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
277 ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %d\n", bufSize);
278 ok(buf != NULL, "Expected allocated buffer\n");
279 if (buf)
281 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
283 ok(blob->cbData == strlen((const char*)bigInts[i].decoded),
284 "Expected len %d, got %d\n", lstrlenA((const char*)bigInts[i].decoded),
285 blob->cbData);
286 ok(!memcmp(blob->pbData, bigInts[i].decoded, blob->cbData),
287 "Unexpected value\n");
288 LocalFree(buf);
291 for (i = 0; i < sizeof(bigUInts) / sizeof(bigUInts[0]); i++)
293 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT,
294 bigUInts[i].encoded, bigUInts[i].encoded[1] + 2, 0, NULL, NULL,
295 &bufSize);
296 ok(ret && GetLastError() == NOERROR,
297 "Expected success and NOERROR, got %d\n", GetLastError());
298 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT,
299 bigUInts[i].encoded, bigUInts[i].encoded[1] + 2,
300 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
301 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
302 ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %d\n", bufSize);
303 ok(buf != NULL, "Expected allocated buffer\n");
304 if (buf)
306 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
308 ok(blob->cbData == strlen((const char*)bigUInts[i].val),
309 "Expected len %d, got %d\n", lstrlenA((const char*)bigUInts[i].val),
310 blob->cbData);
311 ok(!memcmp(blob->pbData, bigUInts[i].val, blob->cbData),
312 "Unexpected value\n");
313 LocalFree(buf);
316 /* Decode the value 1 with long-form length */
317 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, longForm,
318 sizeof(longForm), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
319 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
320 if (buf)
322 ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf);
323 LocalFree(buf);
325 /* check with extra bytes at the end */
326 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, extraBytes,
327 sizeof(extraBytes), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
328 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
329 if (buf)
331 ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf);
332 LocalFree(buf);
334 /* Try to decode some bogus large items */
335 /* The buffer size is smaller than the encoded length, so this should fail
336 * with CRYPT_E_ASN1_EOD if it's being decoded.
337 * Under XP it fails with CRYPT_E_ASN1_LARGE, which means there's a limit
338 * on the size decoded, but in ME it fails with CRYPT_E_ASN1_EOD or crashes.
339 * So this test unfortunately isn't useful.
340 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, tooBig,
341 0x7fffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
342 ok(!ret && GetLastError() == CRYPT_E_ASN1_LARGE,
343 "Expected CRYPT_E_ASN1_LARGE, got %08x\n", GetLastError());
345 /* This will try to decode the buffer and overflow it, check that it's
346 * caught.
348 if (0)
350 /* a large buffer isn't guaranteed to crash, it depends on memory allocation order */
351 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, bigBogus,
352 0x01ffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
353 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
354 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
358 static const BYTE bin18[] = {0x0a,0x01,0x01};
359 static const BYTE bin19[] = {0x0a,0x05,0x00,0xff,0xff,0xff,0x80};
361 /* These are always encoded unsigned, and aren't constrained to be any
362 * particular value
364 static const struct encodedInt enums[] = {
365 { 1, bin18 },
366 { -128, bin19 },
369 /* X509_CRL_REASON_CODE is also an enumerated type, but it's #defined to
370 * X509_ENUMERATED.
372 static const LPCSTR enumeratedTypes[] = { X509_ENUMERATED,
373 szOID_CRL_REASON_CODE };
375 static void test_encodeEnumerated(DWORD dwEncoding)
377 DWORD i, j;
379 for (i = 0; i < sizeof(enumeratedTypes) / sizeof(enumeratedTypes[0]); i++)
381 for (j = 0; j < sizeof(enums) / sizeof(enums[0]); j++)
383 BOOL ret;
384 BYTE *buf = NULL;
385 DWORD bufSize = 0;
387 ret = pCryptEncodeObjectEx(dwEncoding, enumeratedTypes[i],
388 &enums[j].val, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
389 &bufSize);
390 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
391 if (buf)
393 ok(buf[0] == 0xa,
394 "Got unexpected type %d for enumerated (expected 0xa)\n",
395 buf[0]);
396 ok(buf[1] == enums[j].encoded[1],
397 "Got length %d, expected %d\n", buf[1], enums[j].encoded[1]);
398 ok(!memcmp(buf + 1, enums[j].encoded + 1,
399 enums[j].encoded[1] + 1),
400 "Encoded value of 0x%08x didn't match expected\n",
401 enums[j].val);
402 LocalFree(buf);
408 static void test_decodeEnumerated(DWORD dwEncoding)
410 DWORD i, j;
412 for (i = 0; i < sizeof(enumeratedTypes) / sizeof(enumeratedTypes[0]); i++)
414 for (j = 0; j < sizeof(enums) / sizeof(enums[0]); j++)
416 BOOL ret;
417 DWORD bufSize = sizeof(int);
418 int val;
420 ret = pCryptDecodeObjectEx(dwEncoding, enumeratedTypes[i],
421 enums[j].encoded, enums[j].encoded[1] + 2, 0, NULL,
422 (BYTE *)&val, &bufSize);
423 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
424 ok(bufSize == sizeof(int),
425 "Got unexpected size %d for enumerated\n", bufSize);
426 ok(val == enums[j].val, "Unexpected value %d, expected %d\n",
427 val, enums[j].val);
432 struct encodedFiletime
434 SYSTEMTIME sysTime;
435 const BYTE *encodedTime;
438 static void testTimeEncoding(DWORD dwEncoding, LPCSTR structType,
439 const struct encodedFiletime *time)
441 FILETIME ft = { 0 };
442 BYTE *buf = NULL;
443 DWORD bufSize = 0;
444 BOOL ret;
446 ret = SystemTimeToFileTime(&time->sysTime, &ft);
447 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
448 ret = pCryptEncodeObjectEx(dwEncoding, structType, &ft,
449 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
450 /* years other than 1950-2050 are not allowed for encodings other than
451 * X509_CHOICE_OF_TIME.
453 if (structType == X509_CHOICE_OF_TIME ||
454 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050))
456 ok(ret, "CryptEncodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
457 GetLastError());
458 ok(buf != NULL, "Expected an allocated buffer\n");
459 if (buf)
461 ok(buf[0] == time->encodedTime[0],
462 "Expected type 0x%02x, got 0x%02x\n", time->encodedTime[0],
463 buf[0]);
464 ok(buf[1] == time->encodedTime[1], "Expected %d bytes, got %d\n",
465 time->encodedTime[1], bufSize);
466 ok(!memcmp(time->encodedTime + 2, buf + 2, time->encodedTime[1]),
467 "Got unexpected value for time encoding\n");
468 LocalFree(buf);
471 else
472 ok((!ret && GetLastError() == CRYPT_E_BAD_ENCODE) ||
473 broken(GetLastError() == ERROR_SUCCESS),
474 "Expected CRYPT_E_BAD_ENCODE, got 0x%08x\n", GetLastError());
477 static const char *printSystemTime(const SYSTEMTIME *st)
479 static char buf[25];
481 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st->wMonth, st->wDay,
482 st->wYear, st->wHour, st->wMinute, st->wSecond, st->wMilliseconds);
483 return buf;
486 static const char *printFileTime(const FILETIME *ft)
488 static char buf[25];
489 SYSTEMTIME st;
491 FileTimeToSystemTime(ft, &st);
492 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st.wMonth, st.wDay,
493 st.wYear, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
494 return buf;
497 static void compareTime(const SYSTEMTIME *expected, const FILETIME *got)
499 SYSTEMTIME st;
501 FileTimeToSystemTime(got, &st);
502 ok((expected->wYear == st.wYear &&
503 expected->wMonth == st.wMonth &&
504 expected->wDay == st.wDay &&
505 expected->wHour == st.wHour &&
506 expected->wMinute == st.wMinute &&
507 expected->wSecond == st.wSecond &&
508 abs(expected->wMilliseconds - st.wMilliseconds) <= 1) ||
509 /* Some Windows systems only seem to be accurate in their time decoding to
510 * within about an hour.
512 broken(expected->wYear == st.wYear &&
513 expected->wMonth == st.wMonth &&
514 expected->wDay == st.wDay &&
515 abs(expected->wHour - st.wHour) <= 1),
516 "Got unexpected value for time decoding:\nexpected %s, got %s\n",
517 printSystemTime(expected), printFileTime(got));
520 static void testTimeDecoding(DWORD dwEncoding, LPCSTR structType,
521 const struct encodedFiletime *time)
523 FILETIME ft = { 0 };
524 DWORD size = sizeof(ft);
525 BOOL ret;
527 ret = pCryptDecodeObjectEx(dwEncoding, structType, time->encodedTime,
528 time->encodedTime[1] + 2, 0, NULL, &ft, &size);
529 /* years other than 1950-2050 are not allowed for encodings other than
530 * X509_CHOICE_OF_TIME.
532 if (structType == X509_CHOICE_OF_TIME ||
533 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050))
535 ok(ret || broken(GetLastError() == OSS_DATA_ERROR),
536 "CryptDecodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
537 GetLastError());
538 if (ret)
539 compareTime(&time->sysTime, &ft);
541 else
542 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
543 GetLastError() == OSS_PDU_MISMATCH /* Win9x */ ),
544 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %08x\n",
545 GetLastError());
548 static const BYTE bin20[] = {
549 0x17,0x0d,'0','5','0','6','0','6','1','6','1','0','0','0','Z'};
550 static const BYTE bin21[] = {
551 0x18,0x0f,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
552 static const BYTE bin22[] = {
553 0x18,0x0f,'2','1','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
555 static const struct encodedFiletime times[] = {
556 { { 2005, 6, 1, 6, 16, 10, 0, 0 }, bin20 },
557 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin21 },
558 { { 2145, 6, 1, 6, 16, 10, 0, 0 }, bin22 },
561 static void test_encodeFiletime(DWORD dwEncoding)
563 DWORD i;
565 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
567 testTimeEncoding(dwEncoding, X509_CHOICE_OF_TIME, &times[i]);
568 testTimeEncoding(dwEncoding, PKCS_UTC_TIME, &times[i]);
569 testTimeEncoding(dwEncoding, szOID_RSA_signingTime, &times[i]);
573 static const BYTE bin23[] = {
574 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','0','0','0','Z'};
575 static const BYTE bin24[] = {
576 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','9','9','9','Z'};
577 static const BYTE bin25[] = {
578 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','+','0','1','0','0'};
579 static const BYTE bin26[] = {
580 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','0','0'};
581 static const BYTE bin27[] = {
582 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','1','5'};
583 static const BYTE bin28[] = {
584 0x18,0x0a,'2','1','4','5','0','6','0','6','1','6'};
585 static const BYTE bin29[] = {
586 0x17,0x0a,'4','5','0','6','0','6','1','6','1','0'};
587 static const BYTE bin30[] = {
588 0x17,0x0b,'4','5','0','6','0','6','1','6','1','0','Z'};
589 static const BYTE bin31[] = {
590 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','+','0','1'};
591 static const BYTE bin32[] = {
592 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','-','0','1'};
593 static const BYTE bin33[] = {
594 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','+','0','1','0','0'};
595 static const BYTE bin34[] = {
596 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','-','0','1','0','0'};
597 static const BYTE bin35[] = {
598 0x17,0x08, '4','5','0','6','0','6','1','6'};
599 static const BYTE bin36[] = {
600 0x18,0x0f, 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','Z'};
601 static const BYTE bin37[] = {
602 0x18,0x04, '2','1','4','5'};
603 static const BYTE bin38[] = {
604 0x18,0x08, '2','1','4','5','0','6','0','6'};
606 static void test_decodeFiletime(DWORD dwEncoding)
608 static const struct encodedFiletime otherTimes[] = {
609 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin23 },
610 { { 1945, 6, 1, 6, 16, 10, 0, 999 }, bin24 },
611 { { 1945, 6, 1, 6, 17, 10, 0, 0 }, bin25 },
612 { { 1945, 6, 1, 6, 15, 10, 0, 0 }, bin26 },
613 { { 1945, 6, 1, 6, 14, 55, 0, 0 }, bin27 },
614 { { 2145, 6, 1, 6, 16, 0, 0, 0 }, bin28 },
615 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin29 },
616 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin30 },
617 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin31 },
618 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin32 },
619 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin33 },
620 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin34 },
622 /* An oddball case that succeeds in Windows, but doesn't seem correct
623 { { 2145, 6, 1, 2, 11, 31, 0, 0 }, "\x18" "\x13" "21450606161000-9999" },
625 static const unsigned char *bogusTimes[] = {
626 /* oddly, this succeeds on Windows, with year 2765
627 "\x18" "\x0f" "21r50606161000Z",
629 bin35,
630 bin36,
631 bin37,
632 bin38,
634 DWORD i, size;
635 FILETIME ft1 = { 0 }, ft2 = { 0 };
636 BOOL ret;
638 /* Check bogus length with non-NULL buffer */
639 ret = SystemTimeToFileTime(&times[0].sysTime, &ft1);
640 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
641 size = 1;
642 ret = pCryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
643 times[0].encodedTime, times[0].encodedTime[1] + 2, 0, NULL, &ft2, &size);
644 ok(!ret && GetLastError() == ERROR_MORE_DATA,
645 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
646 /* Normal tests */
647 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
649 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &times[i]);
650 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &times[i]);
651 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &times[i]);
653 for (i = 0; i < sizeof(otherTimes) / sizeof(otherTimes[0]); i++)
655 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &otherTimes[i]);
656 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &otherTimes[i]);
657 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &otherTimes[i]);
659 for (i = 0; i < sizeof(bogusTimes) / sizeof(bogusTimes[0]); i++)
661 size = sizeof(ft1);
662 ret = pCryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
663 bogusTimes[i], bogusTimes[i][1] + 2, 0, NULL, &ft1, &size);
664 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
665 GetLastError() == OSS_DATA_ERROR /* Win9x */),
666 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
667 GetLastError());
671 static const char commonName[] = "Juan Lang";
672 static const char surName[] = "Lang";
674 static const BYTE emptySequence[] = { 0x30, 0 };
675 static const BYTE emptyRDNs[] = { 0x30, 0x02, 0x31, 0 };
676 static const BYTE twoRDNs[] = {
677 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
678 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
679 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0};
680 static const BYTE encodedTwoRDNs[] = {
681 0x30,0x2e,0x31,0x2c,0x30,0x2a,0x06,0x03,0x55,0x04,0x03,0x30,0x23,0x31,0x21,
682 0x30,0x0c,0x06,0x03,0x55,0x04,0x04,0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,
683 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
684 0x6e,0x67,0x00,
687 static const BYTE us[] = { 0x55, 0x53 };
688 static const BYTE minnesota[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x73, 0x6f,
689 0x74, 0x61 };
690 static const BYTE minneapolis[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x61, 0x70,
691 0x6f, 0x6c, 0x69, 0x73 };
692 static const BYTE codeweavers[] = { 0x43, 0x6f, 0x64, 0x65, 0x57, 0x65, 0x61,
693 0x76, 0x65, 0x72, 0x73 };
694 static const BYTE wine[] = { 0x57, 0x69, 0x6e, 0x65, 0x20, 0x44, 0x65, 0x76,
695 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74 };
696 static const BYTE localhostAttr[] = { 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
697 0x73, 0x74 };
698 static const BYTE aric[] = { 0x61, 0x72, 0x69, 0x63, 0x40, 0x63, 0x6f, 0x64,
699 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d };
701 #define RDNA(arr) oid_ ## arr, CERT_RDN_PRINTABLE_STRING, { sizeof(arr), (LPBYTE)arr }
702 #define RDNIA5(arr) oid_ ## arr, CERT_RDN_IA5_STRING, { sizeof(arr), (LPBYTE)arr }
704 static CHAR oid_us[] = "2.5.4.6",
705 oid_minnesota[] = "2.5.4.8",
706 oid_minneapolis[] = "2.5.4.7",
707 oid_codeweavers[] = "2.5.4.10",
708 oid_wine[] = "2.5.4.11",
709 oid_localhostAttr[] = "2.5.4.3",
710 oid_aric[] = "1.2.840.113549.1.9.1";
711 static CERT_RDN_ATTR rdnAttrs[] = { { RDNA(us) },
712 { RDNA(minnesota) },
713 { RDNA(minneapolis) },
714 { RDNA(codeweavers) },
715 { RDNA(wine) },
716 { RDNA(localhostAttr) },
717 { RDNIA5(aric) } };
718 static CERT_RDN_ATTR decodedRdnAttrs[] = { { RDNA(us) },
719 { RDNA(localhostAttr) },
720 { RDNA(minnesota) },
721 { RDNA(minneapolis) },
722 { RDNA(codeweavers) },
723 { RDNA(wine) },
724 { RDNIA5(aric) } };
726 #undef RDNIA5
727 #undef RDNA
729 static const BYTE encodedRDNAttrs[] = {
730 0x30,0x81,0x96,0x31,0x81,0x93,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
731 0x53,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x68,
732 0x6f,0x73,0x74,0x30,0x10,0x06,0x03,0x55,0x04,0x08,0x13,0x09,0x4d,0x69,0x6e,0x6e,
733 0x65,0x73,0x6f,0x74,0x61,0x30,0x12,0x06,0x03,0x55,0x04,0x07,0x13,0x0b,0x4d,0x69,
734 0x6e,0x6e,0x65,0x61,0x70,0x6f,0x6c,0x69,0x73,0x30,0x12,0x06,0x03,0x55,0x04,0x0a,
735 0x13,0x0b,0x43,0x6f,0x64,0x65,0x57,0x65,0x61,0x76,0x65,0x72,0x73,0x30,0x17,0x06,
736 0x03,0x55,0x04,0x0b,0x13,0x10,0x57,0x69,0x6e,0x65,0x20,0x44,0x65,0x76,0x65,0x6c,
737 0x6f,0x70,0x6d,0x65,0x6e,0x74,0x30,0x21,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
738 0x01,0x09,0x01,0x16,0x14,0x61,0x72,0x69,0x63,0x40,0x63,0x6f,0x64,0x65,0x77,0x65,
739 0x61,0x76,0x65,0x72,0x73,0x2e,0x63,0x6f,0x6d
742 static void test_encodeName(DWORD dwEncoding)
744 CERT_RDN_ATTR attrs[2];
745 CERT_RDN rdn;
746 CERT_NAME_INFO info;
747 static CHAR oid_common_name[] = szOID_COMMON_NAME,
748 oid_sur_name[] = szOID_SUR_NAME;
749 BYTE *buf = NULL;
750 DWORD size = 0;
751 BOOL ret;
753 if (0)
755 /* Test with NULL pvStructInfo (crashes on win9x) */
756 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, NULL,
757 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
758 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
759 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
761 /* Test with empty CERT_NAME_INFO */
762 info.cRDN = 0;
763 info.rgRDN = NULL;
764 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
765 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
766 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
767 if (buf)
769 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
770 "Got unexpected encoding for empty name\n");
771 LocalFree(buf);
773 if (0)
775 /* Test with bogus CERT_RDN (crashes on win9x) */
776 info.cRDN = 1;
777 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
778 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
779 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
780 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
782 /* Test with empty CERT_RDN */
783 rdn.cRDNAttr = 0;
784 rdn.rgRDNAttr = NULL;
785 info.cRDN = 1;
786 info.rgRDN = &rdn;
787 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
788 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
789 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
790 if (buf)
792 ok(!memcmp(buf, emptyRDNs, sizeof(emptyRDNs)),
793 "Got unexpected encoding for empty RDN array\n");
794 LocalFree(buf);
796 if (0)
798 /* Test with bogus attr array (crashes on win9x) */
799 rdn.cRDNAttr = 1;
800 rdn.rgRDNAttr = NULL;
801 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
802 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
803 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
804 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
806 /* oddly, a bogus OID is accepted by Windows XP; not testing.
807 attrs[0].pszObjId = "bogus";
808 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
809 attrs[0].Value.cbData = sizeof(commonName);
810 attrs[0].Value.pbData = (BYTE *)commonName;
811 rdn.cRDNAttr = 1;
812 rdn.rgRDNAttr = attrs;
813 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
814 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
815 ok(!ret, "Expected failure, got success\n");
817 /* Check with two CERT_RDN_ATTRs. Note DER encoding forces the order of
818 * the encoded attributes to be swapped.
820 attrs[0].pszObjId = oid_common_name;
821 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
822 attrs[0].Value.cbData = sizeof(commonName);
823 attrs[0].Value.pbData = (BYTE *)commonName;
824 attrs[1].pszObjId = oid_sur_name;
825 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
826 attrs[1].Value.cbData = sizeof(surName);
827 attrs[1].Value.pbData = (BYTE *)surName;
828 rdn.cRDNAttr = 2;
829 rdn.rgRDNAttr = attrs;
830 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
831 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
832 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
833 if (buf)
835 ok(!memcmp(buf, twoRDNs, sizeof(twoRDNs)),
836 "Got unexpected encoding for two RDN array\n");
837 LocalFree(buf);
839 /* A name can be "encoded" with previously encoded RDN attrs. */
840 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
841 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
842 attrs[0].Value.cbData = sizeof(twoRDNs);
843 rdn.cRDNAttr = 1;
844 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
845 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
846 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
847 if (buf)
849 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
850 ok(!memcmp(buf, encodedTwoRDNs, size),
851 "Unexpected value for re-endoded two RDN array\n");
852 LocalFree(buf);
854 /* CERT_RDN_ANY_TYPE is too vague for X509_NAMEs, check the return */
855 rdn.cRDNAttr = 1;
856 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
857 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
858 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
859 ok(!ret && GetLastError() == E_INVALIDARG,
860 "Expected E_INVALIDARG, got %08x\n", GetLastError());
861 /* Test a more complex name */
862 rdn.cRDNAttr = sizeof(rdnAttrs) / sizeof(rdnAttrs[0]);
863 rdn.rgRDNAttr = (PCERT_RDN_ATTR)rdnAttrs;
864 info.cRDN = 1;
865 info.rgRDN = &rdn;
866 buf = NULL;
867 size = 0;
868 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, X509_NAME, &info,
869 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
870 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
871 if (ret)
873 ok(size == sizeof(encodedRDNAttrs), "Wrong size %d\n", size);
874 ok(!memcmp(buf, encodedRDNAttrs, size), "Unexpected value\n");
875 LocalFree(buf);
879 static WCHAR commonNameW[] = { 'J','u','a','n',' ','L','a','n','g',0 };
880 static WCHAR surNameW[] = { 'L','a','n','g',0 };
882 static const BYTE twoRDNsNoNull[] = {
883 0x30,0x21,0x31,0x1f,0x30,0x0b,0x06,0x03,0x55,0x04,0x04,0x13,0x04,0x4c,0x61,
884 0x6e,0x67,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,
885 0x20,0x4c,0x61,0x6e,0x67 };
886 static const BYTE anyType[] = {
887 0x30,0x2f,0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x1e,0x24,0x23,0x30,
888 0x21,0x31,0x0c,0x30,0x03,0x06,0x04,0x55,0x13,0x04,0x4c,0x05,0x6e,0x61,0x00,
889 0x67,0x11,0x30,0x03,0x06,0x04,0x55,0x13,0x03,0x4a,0x0a,0x61,0x75,0x20,0x6e,
890 0x61,0x4c,0x67,0x6e };
892 static void test_encodeUnicodeName(DWORD dwEncoding)
894 CERT_RDN_ATTR attrs[2];
895 CERT_RDN rdn;
896 CERT_NAME_INFO info;
897 static CHAR oid_common_name[] = szOID_COMMON_NAME,
898 oid_sur_name[] = szOID_SUR_NAME;
899 BYTE *buf = NULL;
900 DWORD size = 0;
901 BOOL ret;
903 if (0)
905 /* Test with NULL pvStructInfo (crashes on win9x) */
906 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, NULL,
907 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
908 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
909 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
911 /* Test with empty CERT_NAME_INFO */
912 info.cRDN = 0;
913 info.rgRDN = NULL;
914 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
915 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
916 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
917 if (buf)
919 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
920 "Got unexpected encoding for empty name\n");
921 LocalFree(buf);
923 /* Check with one CERT_RDN_ATTR, that has an invalid character for the
924 * encoding (the NULL).
926 attrs[0].pszObjId = oid_common_name;
927 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
928 attrs[0].Value.cbData = sizeof(commonNameW);
929 attrs[0].Value.pbData = (BYTE *)commonNameW;
930 rdn.cRDNAttr = 1;
931 rdn.rgRDNAttr = attrs;
932 info.cRDN = 1;
933 info.rgRDN = &rdn;
934 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
935 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
936 ok(!ret && GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING,
937 "Expected CRYPT_E_INVALID_PRINTABLE_STRING, got %08x\n", GetLastError());
938 ok(size == 9, "Unexpected error index %08x\n", size);
939 /* Check with two NULL-terminated CERT_RDN_ATTRs. Note DER encoding
940 * forces the order of the encoded attributes to be swapped.
942 attrs[0].pszObjId = oid_common_name;
943 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
944 attrs[0].Value.cbData = 0;
945 attrs[0].Value.pbData = (BYTE *)commonNameW;
946 attrs[1].pszObjId = oid_sur_name;
947 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
948 attrs[1].Value.cbData = 0;
949 attrs[1].Value.pbData = (BYTE *)surNameW;
950 rdn.cRDNAttr = 2;
951 rdn.rgRDNAttr = attrs;
952 info.cRDN = 1;
953 info.rgRDN = &rdn;
954 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
955 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
956 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
957 if (buf)
959 ok(!memcmp(buf, twoRDNsNoNull, sizeof(twoRDNsNoNull)),
960 "Got unexpected encoding for two RDN array\n");
961 LocalFree(buf);
963 /* A name can be "encoded" with previously encoded RDN attrs. */
964 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
965 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
966 attrs[0].Value.cbData = sizeof(twoRDNs);
967 rdn.cRDNAttr = 1;
968 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
969 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
970 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
971 if (buf)
973 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
974 ok(!memcmp(buf, encodedTwoRDNs, size),
975 "Unexpected value for re-endoded two RDN array\n");
976 LocalFree(buf);
978 /* Unicode names infer the type for CERT_RDN_ANY_TYPE */
979 rdn.cRDNAttr = 1;
980 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
981 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
982 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
983 todo_wine ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
984 if (buf)
986 ok(size == sizeof(anyType), "Unexpected size %d\n", size);
987 ok(!memcmp(buf, anyType, size), "Unexpected value\n");
988 LocalFree(buf);
992 static void compareNameValues(const CERT_NAME_VALUE *expected,
993 const CERT_NAME_VALUE *got)
995 ok(got->dwValueType == expected->dwValueType,
996 "Expected string type %d, got %d\n", expected->dwValueType,
997 got->dwValueType);
998 ok(got->Value.cbData == expected->Value.cbData,
999 "String type %d: unexpected data size, got %d, expected %d\n",
1000 expected->dwValueType, got->Value.cbData, expected->Value.cbData);
1001 if (got->Value.cbData && got->Value.pbData)
1002 ok(!memcmp(got->Value.pbData, expected->Value.pbData,
1003 min(got->Value.cbData, expected->Value.cbData)),
1004 "String type %d: unexpected value\n", expected->dwValueType);
1007 static void compareRDNAttrs(const CERT_RDN_ATTR *expected,
1008 const CERT_RDN_ATTR *got)
1010 if (expected->pszObjId && strlen(expected->pszObjId))
1012 ok(got->pszObjId != NULL, "Expected OID %s, got NULL\n",
1013 expected->pszObjId);
1014 if (got->pszObjId)
1016 ok(!strcmp(got->pszObjId, expected->pszObjId),
1017 "Got unexpected OID %s, expected %s\n", got->pszObjId,
1018 expected->pszObjId);
1021 compareNameValues((const CERT_NAME_VALUE *)&expected->dwValueType,
1022 (const CERT_NAME_VALUE *)&got->dwValueType);
1025 static void compareRDNs(const CERT_RDN *expected, const CERT_RDN *got)
1027 ok(got->cRDNAttr == expected->cRDNAttr,
1028 "Expected %d RDN attrs, got %d\n", expected->cRDNAttr, got->cRDNAttr);
1029 if (got->cRDNAttr)
1031 DWORD i;
1033 for (i = 0; i < got->cRDNAttr; i++)
1034 compareRDNAttrs(&expected->rgRDNAttr[i], &got->rgRDNAttr[i]);
1038 static void compareNames(const CERT_NAME_INFO *expected,
1039 const CERT_NAME_INFO *got)
1041 ok(got->cRDN == expected->cRDN, "Expected %d RDNs, got %d\n",
1042 expected->cRDN, got->cRDN);
1043 if (got->cRDN)
1045 DWORD i;
1047 for (i = 0; i < got->cRDN; i++)
1048 compareRDNs(&expected->rgRDN[i], &got->rgRDN[i]);
1052 static const BYTE emptyIndefiniteSequence[] = { 0x30,0x80,0x00,0x00 };
1053 static const BYTE twoRDNsExtraBytes[] = {
1054 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
1055 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1056 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0,0,0,0,0,0};
1058 static void test_decodeName(DWORD dwEncoding)
1060 BYTE *buf = NULL;
1061 DWORD bufSize = 0;
1062 BOOL ret;
1063 CERT_RDN rdn;
1064 CERT_NAME_INFO info = { 1, &rdn };
1066 /* test empty name */
1067 bufSize = 0;
1068 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptySequence,
1069 emptySequence[1] + 2,
1070 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1071 (BYTE *)&buf, &bufSize);
1072 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1073 /* Interestingly, in Windows, if cRDN is 0, rgRGN may not be NULL. My
1074 * decoder works the same way, so only test the count.
1076 if (buf)
1078 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1079 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1080 "Expected 0 RDNs in empty info, got %d\n",
1081 ((CERT_NAME_INFO *)buf)->cRDN);
1082 LocalFree(buf);
1084 /* test empty name with indefinite-length encoding */
1085 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyIndefiniteSequence,
1086 sizeof(emptyIndefiniteSequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
1087 (BYTE *)&buf, &bufSize);
1088 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1089 if (ret)
1091 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1092 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1093 "Expected 0 RDNs in empty info, got %d\n",
1094 ((CERT_NAME_INFO *)buf)->cRDN);
1095 LocalFree(buf);
1097 /* test empty RDN */
1098 bufSize = 0;
1099 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyRDNs,
1100 emptyRDNs[1] + 2,
1101 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1102 (BYTE *)&buf, &bufSize);
1103 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1104 if (buf)
1106 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1108 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1109 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1110 "Got unexpected value for empty RDN\n");
1111 LocalFree(buf);
1113 /* test two RDN attrs */
1114 bufSize = 0;
1115 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNs,
1116 twoRDNs[1] + 2,
1117 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1118 (BYTE *)&buf, &bufSize);
1119 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1120 if (buf)
1122 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1123 oid_common_name[] = szOID_COMMON_NAME;
1125 CERT_RDN_ATTR attrs[] = {
1126 { oid_sur_name, CERT_RDN_PRINTABLE_STRING, { sizeof(surName),
1127 (BYTE *)surName } },
1128 { oid_common_name, CERT_RDN_PRINTABLE_STRING, { sizeof(commonName),
1129 (BYTE *)commonName } },
1132 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1133 rdn.rgRDNAttr = attrs;
1134 compareNames(&info, (CERT_NAME_INFO *)buf);
1135 LocalFree(buf);
1137 /* test that two RDN attrs with extra bytes succeeds */
1138 bufSize = 0;
1139 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNsExtraBytes,
1140 sizeof(twoRDNsExtraBytes), 0, NULL, NULL, &bufSize);
1141 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1142 /* And, a slightly more complicated name */
1143 buf = NULL;
1144 bufSize = 0;
1145 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME, encodedRDNAttrs,
1146 sizeof(encodedRDNAttrs), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1147 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1148 if (ret)
1150 rdn.cRDNAttr = sizeof(decodedRdnAttrs) / sizeof(decodedRdnAttrs[0]);
1151 rdn.rgRDNAttr = (PCERT_RDN_ATTR)decodedRdnAttrs;
1152 compareNames(&info, (CERT_NAME_INFO *)buf);
1153 LocalFree(buf);
1157 static void test_decodeUnicodeName(DWORD dwEncoding)
1159 BYTE *buf = NULL;
1160 DWORD bufSize = 0;
1161 BOOL ret;
1162 CERT_RDN rdn;
1163 CERT_NAME_INFO info = { 1, &rdn };
1165 /* test empty name */
1166 bufSize = 0;
1167 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptySequence,
1168 emptySequence[1] + 2,
1169 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1170 (BYTE *)&buf, &bufSize);
1171 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1172 if (buf)
1174 ok(bufSize == sizeof(CERT_NAME_INFO),
1175 "Got wrong bufSize %d\n", bufSize);
1176 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1177 "Expected 0 RDNs in empty info, got %d\n",
1178 ((CERT_NAME_INFO *)buf)->cRDN);
1179 LocalFree(buf);
1181 /* test empty RDN */
1182 bufSize = 0;
1183 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptyRDNs,
1184 emptyRDNs[1] + 2,
1185 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1186 (BYTE *)&buf, &bufSize);
1187 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1188 if (buf)
1190 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1192 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1193 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1194 "Got unexpected value for empty RDN\n");
1195 LocalFree(buf);
1197 /* test two RDN attrs */
1198 bufSize = 0;
1199 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, twoRDNsNoNull,
1200 sizeof(twoRDNsNoNull),
1201 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1202 (BYTE *)&buf, &bufSize);
1203 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1204 if (buf)
1206 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1207 oid_common_name[] = szOID_COMMON_NAME;
1209 CERT_RDN_ATTR attrs[] = {
1210 { oid_sur_name, CERT_RDN_PRINTABLE_STRING,
1211 { lstrlenW(surNameW) * sizeof(WCHAR), (BYTE *)surNameW } },
1212 { oid_common_name, CERT_RDN_PRINTABLE_STRING,
1213 { lstrlenW(commonNameW) * sizeof(WCHAR), (BYTE *)commonNameW } },
1216 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1217 rdn.rgRDNAttr = attrs;
1218 compareNames(&info, (CERT_NAME_INFO *)buf);
1219 LocalFree(buf);
1223 struct EncodedNameValue
1225 CERT_NAME_VALUE value;
1226 const BYTE *encoded;
1227 DWORD encodedSize;
1230 static const char bogusIA5[] = "\x80";
1231 static const char bogusPrintable[] = "~";
1232 static const char bogusNumeric[] = "A";
1233 static const BYTE bin42[] = { 0x16,0x02,0x80,0x00 };
1234 static const BYTE bin43[] = { 0x13,0x02,0x7e,0x00 };
1235 static const BYTE bin44[] = { 0x12,0x02,0x41,0x00 };
1236 static BYTE octetCommonNameValue[] = {
1237 0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1238 static BYTE numericCommonNameValue[] = {
1239 0x12,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1240 static BYTE printableCommonNameValue[] = {
1241 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1242 static BYTE t61CommonNameValue[] = {
1243 0x14,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1244 static BYTE videotexCommonNameValue[] = {
1245 0x15,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1246 static BYTE ia5CommonNameValue[] = {
1247 0x16,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1248 static BYTE graphicCommonNameValue[] = {
1249 0x19,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1250 static BYTE visibleCommonNameValue[] = {
1251 0x1a,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1252 static BYTE generalCommonNameValue[] = {
1253 0x1b,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1254 static BYTE bmpCommonNameValue[] = {
1255 0x1e,0x14,0x00,0x4a,0x00,0x75,0x00,0x61,0x00,0x6e,0x00,0x20,0x00,0x4c,0x00,
1256 0x61,0x00,0x6e,0x00,0x67,0x00,0x00 };
1257 static BYTE utf8CommonNameValue[] = {
1258 0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1260 static struct EncodedNameValue nameValues[] = {
1261 { { CERT_RDN_OCTET_STRING, { sizeof(commonName), (BYTE *)commonName } },
1262 octetCommonNameValue, sizeof(octetCommonNameValue) },
1263 { { CERT_RDN_NUMERIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1264 numericCommonNameValue, sizeof(numericCommonNameValue) },
1265 { { CERT_RDN_PRINTABLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1266 printableCommonNameValue, sizeof(printableCommonNameValue) },
1267 { { CERT_RDN_T61_STRING, { sizeof(commonName), (BYTE *)commonName } },
1268 t61CommonNameValue, sizeof(t61CommonNameValue) },
1269 { { CERT_RDN_VIDEOTEX_STRING, { sizeof(commonName), (BYTE *)commonName } },
1270 videotexCommonNameValue, sizeof(videotexCommonNameValue) },
1271 { { CERT_RDN_IA5_STRING, { sizeof(commonName), (BYTE *)commonName } },
1272 ia5CommonNameValue, sizeof(ia5CommonNameValue) },
1273 { { CERT_RDN_GRAPHIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1274 graphicCommonNameValue, sizeof(graphicCommonNameValue) },
1275 { { CERT_RDN_VISIBLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1276 visibleCommonNameValue, sizeof(visibleCommonNameValue) },
1277 { { CERT_RDN_GENERAL_STRING, { sizeof(commonName), (BYTE *)commonName } },
1278 generalCommonNameValue, sizeof(generalCommonNameValue) },
1279 { { CERT_RDN_BMP_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1280 bmpCommonNameValue, sizeof(bmpCommonNameValue) },
1281 { { CERT_RDN_UTF8_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1282 utf8CommonNameValue, sizeof(utf8CommonNameValue) },
1283 /* The following tests succeed under Windows, but really should fail,
1284 * they contain characters that are illegal for the encoding. I'm
1285 * including them to justify my lazy encoding.
1287 { { CERT_RDN_IA5_STRING, { sizeof(bogusIA5), (BYTE *)bogusIA5 } }, bin42,
1288 sizeof(bin42) },
1289 { { CERT_RDN_PRINTABLE_STRING, { sizeof(bogusPrintable),
1290 (BYTE *)bogusPrintable } }, bin43, sizeof(bin43) },
1291 { { CERT_RDN_NUMERIC_STRING, { sizeof(bogusNumeric), (BYTE *)bogusNumeric } },
1292 bin44, sizeof(bin44) },
1295 static void test_encodeNameValue(DWORD dwEncoding)
1297 BYTE *buf = NULL;
1298 DWORD size = 0, i;
1299 BOOL ret;
1300 CERT_NAME_VALUE value = { 0, { 0, NULL } };
1302 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1303 value.Value.pbData = printableCommonNameValue;
1304 value.Value.cbData = sizeof(printableCommonNameValue);
1305 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, &value,
1306 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1307 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1308 if (buf)
1310 ok(size == sizeof(printableCommonNameValue), "Unexpected size %d\n",
1311 size);
1312 ok(!memcmp(buf, printableCommonNameValue, size),
1313 "Unexpected encoding\n");
1314 LocalFree(buf);
1316 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1318 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE,
1319 &nameValues[i].value, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1320 &size);
1321 ok(ret, "Type %d: CryptEncodeObjectEx failed: %08x\n",
1322 nameValues[i].value.dwValueType, GetLastError());
1323 if (buf)
1325 ok(size == nameValues[i].encodedSize,
1326 "Expected size %d, got %d\n", nameValues[i].encodedSize, size);
1327 ok(!memcmp(buf, nameValues[i].encoded, size),
1328 "Got unexpected encoding\n");
1329 LocalFree(buf);
1334 static void test_decodeNameValue(DWORD dwEncoding)
1336 int i;
1337 BYTE *buf = NULL;
1338 DWORD bufSize = 0;
1339 BOOL ret;
1341 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1343 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE,
1344 nameValues[i].encoded, nameValues[i].encoded[1] + 2,
1345 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1346 (BYTE *)&buf, &bufSize);
1347 ok(ret, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
1348 nameValues[i].value.dwValueType, GetLastError());
1349 if (buf)
1351 compareNameValues(&nameValues[i].value,
1352 (const CERT_NAME_VALUE *)buf);
1353 LocalFree(buf);
1358 static const BYTE emptyURL[] = { 0x30, 0x02, 0x86, 0x00 };
1359 static const BYTE emptyURLExtraBytes[] = { 0x30, 0x02, 0x86, 0x00, 0, 0, 0 };
1360 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e',
1361 'h','q','.','o','r','g',0 };
1362 static const BYTE encodedURL[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74,
1363 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e,
1364 0x6f, 0x72, 0x67 };
1365 static const WCHAR nihongoURL[] = { 'h','t','t','p',':','/','/',0x226f,
1366 0x575b, 0 };
1367 static const WCHAR dnsName[] = { 'w','i','n','e','h','q','.','o','r','g',0 };
1368 static const BYTE encodedDnsName[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69,
1369 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
1370 static const BYTE localhost[] = { 127, 0, 0, 1 };
1371 static const BYTE encodedIPAddr[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00,
1372 0x01 };
1373 static const unsigned char encodedCommonName[] = {
1374 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0};
1375 static const BYTE encodedOidName[] = { 0x30,0x04,0x88,0x02,0x2a,0x03 };
1376 static const BYTE encodedDirectoryName[] = {
1377 0x30,0x19,0xa4,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1378 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1380 static void test_encodeAltName(DWORD dwEncoding)
1382 CERT_ALT_NAME_INFO info = { 0 };
1383 CERT_ALT_NAME_ENTRY entry = { 0 };
1384 BYTE *buf = NULL;
1385 DWORD size = 0;
1386 BOOL ret;
1387 char oid[] = "1.2.3";
1389 /* Test with empty info */
1390 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1391 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1392 if (buf)
1394 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
1395 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
1396 LocalFree(buf);
1398 /* Test with an empty entry */
1399 info.cAltEntry = 1;
1400 info.rgAltEntry = &entry;
1401 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1402 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1403 ok(!ret && GetLastError() == E_INVALIDARG,
1404 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1405 /* Test with an empty pointer */
1406 entry.dwAltNameChoice = CERT_ALT_NAME_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(emptyURL), "Wrong size %d\n", size);
1412 ok(!memcmp(buf, emptyURL, size), "Unexpected value\n");
1413 LocalFree(buf);
1415 /* Test with a real URL */
1416 U(entry).pwszURL = (LPWSTR)url;
1417 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1418 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1419 if (buf)
1421 ok(size == sizeof(encodedURL), "Wrong size %d\n", size);
1422 ok(!memcmp(buf, encodedURL, size), "Unexpected value\n");
1423 LocalFree(buf);
1425 /* Now with the URL containing an invalid IA5 char */
1426 U(entry).pwszURL = (LPWSTR)nihongoURL;
1427 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1428 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1429 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
1430 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
1431 /* The first invalid character is at index 7 */
1432 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
1433 "Expected invalid char at index 7, got %d\n",
1434 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
1435 /* Now with the URL missing a scheme */
1436 U(entry).pwszURL = (LPWSTR)dnsName;
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 /* This succeeds, but it shouldn't, so don't worry about conforming */
1443 LocalFree(buf);
1445 /* Now with a DNS name */
1446 entry.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
1447 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1448 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1449 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1450 if (buf)
1452 ok(size == sizeof(encodedDnsName), "Wrong size %d\n", size);
1453 ok(!memcmp(buf, encodedDnsName, size), "Unexpected value\n");
1454 LocalFree(buf);
1456 /* Test with an IP address */
1457 entry.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
1458 U(entry).IPAddress.cbData = sizeof(localhost);
1459 U(entry).IPAddress.pbData = (LPBYTE)localhost;
1460 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1461 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1462 if (buf)
1464 ok(size == sizeof(encodedIPAddr), "Wrong size %d\n", size);
1465 ok(!memcmp(buf, encodedIPAddr, size), "Unexpected value\n");
1466 LocalFree(buf);
1468 /* Test with OID */
1469 entry.dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID;
1470 U(entry).pszRegisteredID = oid;
1471 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1472 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1473 if (buf)
1475 ok(size == sizeof(encodedOidName), "Wrong size %d\n", size);
1476 ok(!memcmp(buf, encodedOidName, size), "Unexpected value\n");
1477 LocalFree(buf);
1479 /* Test with directory name */
1480 entry.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
1481 U(entry).DirectoryName.cbData = sizeof(encodedCommonName);
1482 U(entry).DirectoryName.pbData = (LPBYTE)encodedCommonName;
1483 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1484 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1485 if (buf)
1487 ok(size == sizeof(encodedDirectoryName), "Wrong size %d\n", size);
1488 ok(!memcmp(buf, encodedDirectoryName, size), "Unexpected value\n");
1489 LocalFree(buf);
1493 static void test_decodeAltName(DWORD dwEncoding)
1495 static const BYTE unimplementedType[] = { 0x30, 0x06, 0x85, 0x04, 0x7f,
1496 0x00, 0x00, 0x01 };
1497 static const BYTE bogusType[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00,
1498 0x01 };
1499 BOOL ret;
1500 BYTE *buf = NULL;
1501 DWORD bufSize = 0;
1502 CERT_ALT_NAME_INFO *info;
1504 /* Test some bogus ones first */
1505 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1506 unimplementedType, sizeof(unimplementedType), CRYPT_DECODE_ALLOC_FLAG,
1507 NULL, (BYTE *)&buf, &bufSize);
1508 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
1509 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1510 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
1511 GetLastError());
1512 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1513 bogusType, sizeof(bogusType), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1514 &bufSize);
1515 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
1516 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1517 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
1518 GetLastError());
1519 /* Now expected cases */
1520 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptySequence,
1521 emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1522 &bufSize);
1523 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1524 if (buf)
1526 info = (CERT_ALT_NAME_INFO *)buf;
1528 ok(info->cAltEntry == 0, "Expected 0 entries, got %d\n",
1529 info->cAltEntry);
1530 LocalFree(buf);
1532 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptyURL,
1533 emptyURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1534 &bufSize);
1535 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1536 if (buf)
1538 info = (CERT_ALT_NAME_INFO *)buf;
1540 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1541 info->cAltEntry);
1542 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1543 "Expected CERT_ALT_NAME_URL, got %d\n",
1544 info->rgAltEntry[0].dwAltNameChoice);
1545 ok(U(info->rgAltEntry[0]).pwszURL == NULL || !*U(info->rgAltEntry[0]).pwszURL,
1546 "Expected empty URL\n");
1547 LocalFree(buf);
1549 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1550 emptyURLExtraBytes, sizeof(emptyURLExtraBytes), 0, NULL, NULL, &bufSize);
1551 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1552 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedURL,
1553 encodedURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1554 &bufSize);
1555 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1556 if (buf)
1558 info = (CERT_ALT_NAME_INFO *)buf;
1560 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1561 info->cAltEntry);
1562 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1563 "Expected CERT_ALT_NAME_URL, got %d\n",
1564 info->rgAltEntry[0].dwAltNameChoice);
1565 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszURL, url), "Unexpected URL\n");
1566 LocalFree(buf);
1568 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedDnsName,
1569 encodedDnsName[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1570 &bufSize);
1571 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1572 if (buf)
1574 info = (CERT_ALT_NAME_INFO *)buf;
1576 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1577 info->cAltEntry);
1578 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1579 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1580 info->rgAltEntry[0].dwAltNameChoice);
1581 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszDNSName, dnsName),
1582 "Unexpected DNS name\n");
1583 LocalFree(buf);
1585 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedIPAddr,
1586 encodedIPAddr[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1587 &bufSize);
1588 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1589 if (buf)
1591 info = (CERT_ALT_NAME_INFO *)buf;
1593 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1594 info->cAltEntry);
1595 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS,
1596 "Expected CERT_ALT_NAME_IP_ADDRESS, got %d\n",
1597 info->rgAltEntry[0].dwAltNameChoice);
1598 ok(U(info->rgAltEntry[0]).IPAddress.cbData == sizeof(localhost),
1599 "Unexpected IP address length %d\n",
1600 U(info->rgAltEntry[0]).IPAddress.cbData);
1601 ok(!memcmp(U(info->rgAltEntry[0]).IPAddress.pbData, localhost,
1602 sizeof(localhost)), "Unexpected IP address value\n");
1603 LocalFree(buf);
1605 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedOidName,
1606 sizeof(encodedOidName), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1607 &bufSize);
1608 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1609 if (buf)
1611 info = (CERT_ALT_NAME_INFO *)buf;
1613 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1614 info->cAltEntry);
1615 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_REGISTERED_ID,
1616 "Expected CERT_ALT_NAME_REGISTERED_ID, got %d\n",
1617 info->rgAltEntry[0].dwAltNameChoice);
1618 ok(!strcmp(U(info->rgAltEntry[0]).pszRegisteredID, "1.2.3"),
1619 "Expected OID 1.2.3, got %s\n", U(info->rgAltEntry[0]).pszRegisteredID);
1620 LocalFree(buf);
1622 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1623 encodedDirectoryName, sizeof(encodedDirectoryName),
1624 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1625 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1626 if (buf)
1628 info = (CERT_ALT_NAME_INFO *)buf;
1630 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1631 info->cAltEntry);
1632 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME,
1633 "Expected CERT_ALT_NAME_DIRECTORY_NAME, got %d\n",
1634 info->rgAltEntry[0].dwAltNameChoice);
1635 ok(U(info->rgAltEntry[0]).DirectoryName.cbData ==
1636 sizeof(encodedCommonName), "Unexpected directory name length %d\n",
1637 U(info->rgAltEntry[0]).DirectoryName.cbData);
1638 ok(!memcmp(U(info->rgAltEntry[0]).DirectoryName.pbData,
1639 encodedCommonName, sizeof(encodedCommonName)),
1640 "Unexpected directory name value\n");
1641 LocalFree(buf);
1645 struct UnicodeExpectedError
1647 DWORD valueType;
1648 LPCWSTR str;
1649 DWORD errorIndex;
1650 DWORD error;
1653 static const WCHAR oneW[] = { '1',0 };
1654 static const WCHAR aW[] = { 'a',0 };
1655 static const WCHAR quoteW[] = { '"', 0 };
1657 static struct UnicodeExpectedError unicodeErrors[] = {
1658 { CERT_RDN_ANY_TYPE, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1659 { CERT_RDN_ENCODED_BLOB, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1660 { CERT_RDN_OCTET_STRING, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1661 { CERT_RDN_NUMERIC_STRING, aW, 0, CRYPT_E_INVALID_NUMERIC_STRING },
1662 { CERT_RDN_PRINTABLE_STRING, quoteW, 0, CRYPT_E_INVALID_PRINTABLE_STRING },
1663 { CERT_RDN_IA5_STRING, nihongoURL, 7, CRYPT_E_INVALID_IA5_STRING },
1666 struct UnicodeExpectedResult
1668 DWORD valueType;
1669 LPCWSTR str;
1670 CRYPT_DATA_BLOB encoded;
1673 static BYTE oneNumeric[] = { 0x12, 0x01, 0x31 };
1674 static BYTE onePrintable[] = { 0x13, 0x01, 0x31 };
1675 static BYTE oneTeletex[] = { 0x14, 0x01, 0x31 };
1676 static BYTE oneVideotex[] = { 0x15, 0x01, 0x31 };
1677 static BYTE oneIA5[] = { 0x16, 0x01, 0x31 };
1678 static BYTE oneGraphic[] = { 0x19, 0x01, 0x31 };
1679 static BYTE oneVisible[] = { 0x1a, 0x01, 0x31 };
1680 static BYTE oneUniversal[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 };
1681 static BYTE oneGeneral[] = { 0x1b, 0x01, 0x31 };
1682 static BYTE oneBMP[] = { 0x1e, 0x02, 0x00, 0x31 };
1683 static BYTE oneUTF8[] = { 0x0c, 0x01, 0x31 };
1684 static BYTE nihongoT61[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,
1685 0x5b };
1686 static BYTE nihongoGeneral[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1687 0x6f,0x5b };
1688 static BYTE nihongoBMP[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,
1689 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
1690 static BYTE nihongoUTF8[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1691 0xe2,0x89,0xaf,0xe5,0x9d,0x9b };
1693 static struct UnicodeExpectedResult unicodeResults[] = {
1694 { CERT_RDN_NUMERIC_STRING, oneW, { sizeof(oneNumeric), oneNumeric } },
1695 { CERT_RDN_PRINTABLE_STRING, oneW, { sizeof(onePrintable), onePrintable } },
1696 { CERT_RDN_TELETEX_STRING, oneW, { sizeof(oneTeletex), oneTeletex } },
1697 { CERT_RDN_VIDEOTEX_STRING, oneW, { sizeof(oneVideotex), oneVideotex } },
1698 { CERT_RDN_IA5_STRING, oneW, { sizeof(oneIA5), oneIA5 } },
1699 { CERT_RDN_GRAPHIC_STRING, oneW, { sizeof(oneGraphic), oneGraphic } },
1700 { CERT_RDN_VISIBLE_STRING, oneW, { sizeof(oneVisible), oneVisible } },
1701 { CERT_RDN_UNIVERSAL_STRING, oneW, { sizeof(oneUniversal), oneUniversal } },
1702 { CERT_RDN_GENERAL_STRING, oneW, { sizeof(oneGeneral), oneGeneral } },
1703 { CERT_RDN_BMP_STRING, oneW, { sizeof(oneBMP), oneBMP } },
1704 { CERT_RDN_UTF8_STRING, oneW, { sizeof(oneUTF8), oneUTF8 } },
1705 { CERT_RDN_BMP_STRING, nihongoURL, { sizeof(nihongoBMP), nihongoBMP } },
1706 { CERT_RDN_UTF8_STRING, nihongoURL, { sizeof(nihongoUTF8), nihongoUTF8 } },
1709 static struct UnicodeExpectedResult unicodeWeirdness[] = {
1710 { CERT_RDN_TELETEX_STRING, nihongoURL, { sizeof(nihongoT61), nihongoT61 } },
1711 { CERT_RDN_GENERAL_STRING, nihongoURL, { sizeof(nihongoGeneral), nihongoGeneral } },
1714 static void test_encodeUnicodeNameValue(DWORD dwEncoding)
1716 BYTE *buf = NULL;
1717 DWORD size = 0, i;
1718 BOOL ret;
1719 CERT_NAME_VALUE value;
1721 if (0)
1723 /* Crashes on win9x */
1724 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, NULL,
1725 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1726 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1727 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1729 /* Have to have a string of some sort */
1730 value.dwValueType = 0; /* aka CERT_RDN_ANY_TYPE */
1731 value.Value.pbData = NULL;
1732 value.Value.cbData = 0;
1733 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1734 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1735 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1736 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1737 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1738 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1739 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1740 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1741 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1742 value.dwValueType = CERT_RDN_ANY_TYPE;
1743 value.Value.pbData = (LPBYTE)oneW;
1744 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1745 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1746 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1747 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1748 value.Value.cbData = sizeof(oneW);
1749 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1750 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1751 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1752 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1753 /* An encoded string with specified length isn't good enough either */
1754 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1755 value.Value.pbData = oneUniversal;
1756 value.Value.cbData = sizeof(oneUniversal);
1757 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1758 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1759 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1760 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1761 /* More failure checking */
1762 value.Value.cbData = 0;
1763 for (i = 0; i < sizeof(unicodeErrors) / sizeof(unicodeErrors[0]); i++)
1765 value.Value.pbData = (LPBYTE)unicodeErrors[i].str;
1766 value.dwValueType = unicodeErrors[i].valueType;
1767 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1768 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1769 ok(!ret && GetLastError() == unicodeErrors[i].error,
1770 "Value type %d: expected %08x, got %08x\n", value.dwValueType,
1771 unicodeErrors[i].error, GetLastError());
1772 ok(size == unicodeErrors[i].errorIndex,
1773 "Expected error index %d, got %d\n", unicodeErrors[i].errorIndex,
1774 size);
1776 /* cbData can be zero if the string is NULL-terminated */
1777 value.Value.cbData = 0;
1778 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1780 value.Value.pbData = (LPBYTE)unicodeResults[i].str;
1781 value.dwValueType = unicodeResults[i].valueType;
1782 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1783 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1784 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
1785 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1786 if (buf)
1788 ok(size == unicodeResults[i].encoded.cbData,
1789 "Value type %d: expected size %d, got %d\n",
1790 value.dwValueType, unicodeResults[i].encoded.cbData, size);
1791 ok(!memcmp(unicodeResults[i].encoded.pbData, buf, size),
1792 "Value type %d: unexpected value\n", value.dwValueType);
1793 LocalFree(buf);
1796 /* These "encode," but they do so by truncating each unicode character
1797 * rather than properly encoding it. Kept separate from the proper results,
1798 * because the encoded forms won't decode to their original strings.
1800 for (i = 0; i < sizeof(unicodeWeirdness) / sizeof(unicodeWeirdness[0]); i++)
1802 value.Value.pbData = (LPBYTE)unicodeWeirdness[i].str;
1803 value.dwValueType = unicodeWeirdness[i].valueType;
1804 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1805 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1806 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1807 if (buf)
1809 ok(size == unicodeWeirdness[i].encoded.cbData,
1810 "Value type %d: expected size %d, got %d\n",
1811 value.dwValueType, unicodeWeirdness[i].encoded.cbData, size);
1812 ok(!memcmp(unicodeWeirdness[i].encoded.pbData, buf, size),
1813 "Value type %d: unexpected value\n", value.dwValueType);
1814 LocalFree(buf);
1819 static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
1821 if (n <= 0) return 0;
1822 while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
1823 return *str1 - *str2;
1826 static void test_decodeUnicodeNameValue(DWORD dwEncoding)
1828 DWORD i;
1830 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1832 BYTE *buf = NULL;
1833 BOOL ret;
1834 DWORD size = 0;
1836 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE,
1837 unicodeResults[i].encoded.pbData, unicodeResults[i].encoded.cbData,
1838 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1839 ok(ret || broken(GetLastError() == CRYPT_E_NOT_CHAR_STRING /* Win9x */),
1840 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1841 if (ret && buf)
1843 PCERT_NAME_VALUE value = (PCERT_NAME_VALUE)buf;
1845 ok(value->dwValueType == unicodeResults[i].valueType,
1846 "Expected value type %d, got %d\n", unicodeResults[i].valueType,
1847 value->dwValueType);
1848 ok(!strncmpW((LPWSTR)value->Value.pbData, unicodeResults[i].str,
1849 value->Value.cbData / sizeof(WCHAR)),
1850 "Unexpected decoded value for index %d (value type %d)\n", i,
1851 unicodeResults[i].valueType);
1852 LocalFree(buf);
1857 struct encodedOctets
1859 const BYTE *val;
1860 const BYTE *encoded;
1863 static const unsigned char bin46[] = { 'h','i',0 };
1864 static const unsigned char bin47[] = { 0x04,0x02,'h','i',0 };
1865 static const unsigned char bin48[] = {
1866 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1867 static const unsigned char bin49[] = {
1868 0x04,0x0f,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1869 static const unsigned char bin50[] = { 0 };
1870 static const unsigned char bin51[] = { 0x04,0x00,0 };
1872 static const struct encodedOctets octets[] = {
1873 { bin46, bin47 },
1874 { bin48, bin49 },
1875 { bin50, bin51 },
1878 static void test_encodeOctets(DWORD dwEncoding)
1880 CRYPT_DATA_BLOB blob;
1881 DWORD i;
1883 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1885 BYTE *buf = NULL;
1886 BOOL ret;
1887 DWORD bufSize = 0;
1889 blob.cbData = strlen((const char*)octets[i].val);
1890 blob.pbData = (BYTE*)octets[i].val;
1891 ret = pCryptEncodeObjectEx(dwEncoding, X509_OCTET_STRING, &blob,
1892 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1893 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
1894 if (buf)
1896 ok(buf[0] == 4,
1897 "Got unexpected type %d for octet string (expected 4)\n", buf[0]);
1898 ok(buf[1] == octets[i].encoded[1], "Got length %d, expected %d\n",
1899 buf[1], octets[i].encoded[1]);
1900 ok(!memcmp(buf + 1, octets[i].encoded + 1,
1901 octets[i].encoded[1] + 1), "Got unexpected value\n");
1902 LocalFree(buf);
1907 static void test_decodeOctets(DWORD dwEncoding)
1909 DWORD i;
1911 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1913 BYTE *buf = NULL;
1914 BOOL ret;
1915 DWORD bufSize = 0;
1917 ret = pCryptDecodeObjectEx(dwEncoding, X509_OCTET_STRING,
1918 (BYTE *)octets[i].encoded, octets[i].encoded[1] + 2,
1919 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1920 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1921 ok(bufSize >= sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1],
1922 "Expected size >= %d, got %d\n",
1923 (int)sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1], bufSize);
1924 ok(buf != NULL, "Expected allocated buffer\n");
1925 if (buf)
1927 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)buf;
1929 if (blob->cbData)
1930 ok(!memcmp(blob->pbData, octets[i].val, blob->cbData),
1931 "Unexpected value\n");
1932 LocalFree(buf);
1937 static const BYTE bytesToEncode[] = { 0xff, 0xff };
1939 struct encodedBits
1941 DWORD cUnusedBits;
1942 const BYTE *encoded;
1943 DWORD cbDecoded;
1944 const BYTE *decoded;
1947 static const unsigned char bin52[] = { 0x03,0x03,0x00,0xff,0xff };
1948 static const unsigned char bin53[] = { 0xff,0xff };
1949 static const unsigned char bin54[] = { 0x03,0x03,0x01,0xff,0xfe };
1950 static const unsigned char bin55[] = { 0xff,0xfe };
1951 static const unsigned char bin56[] = { 0x03,0x02,0x01,0xfe };
1952 static const unsigned char bin57[] = { 0xfe };
1953 static const unsigned char bin58[] = { 0x03,0x01,0x00 };
1955 static const struct encodedBits bits[] = {
1956 /* normal test cases */
1957 { 0, bin52, 2, bin53 },
1958 { 1, bin54, 2, bin55 },
1959 /* strange test case, showing cUnusedBits >= 8 is allowed */
1960 { 9, bin56, 1, bin57 },
1961 /* even stranger test case, showing cUnusedBits > cbData * 8 is allowed */
1962 { 17, bin58, 0, NULL },
1965 static void test_encodeBits(DWORD dwEncoding)
1967 DWORD i;
1969 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
1971 CRYPT_BIT_BLOB blob;
1972 BOOL ret;
1973 BYTE *buf = NULL;
1974 DWORD bufSize = 0;
1976 blob.cbData = sizeof(bytesToEncode);
1977 blob.pbData = (BYTE *)bytesToEncode;
1978 blob.cUnusedBits = bits[i].cUnusedBits;
1979 ret = pCryptEncodeObjectEx(dwEncoding, X509_BITS, &blob,
1980 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1981 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1982 if (buf)
1984 ok(bufSize == bits[i].encoded[1] + 2,
1985 "Got unexpected size %d, expected %d\n", bufSize,
1986 bits[i].encoded[1] + 2);
1987 ok(!memcmp(buf, bits[i].encoded, bits[i].encoded[1] + 2),
1988 "Unexpected value\n");
1989 LocalFree(buf);
1994 static void test_decodeBits(DWORD dwEncoding)
1996 static const BYTE ber[] = "\x03\x02\x01\xff";
1997 static const BYTE berDecoded = 0xfe;
1998 DWORD i;
1999 BOOL ret;
2000 BYTE *buf = NULL;
2001 DWORD bufSize = 0;
2003 /* normal cases */
2004 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
2006 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, bits[i].encoded,
2007 bits[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2008 &bufSize);
2009 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2010 if (buf)
2012 CRYPT_BIT_BLOB *blob;
2014 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + bits[i].cbDecoded,
2015 "Got unexpected size %d\n", bufSize);
2016 blob = (CRYPT_BIT_BLOB *)buf;
2017 ok(blob->cbData == bits[i].cbDecoded,
2018 "Got unexpected length %d, expected %d\n", blob->cbData,
2019 bits[i].cbDecoded);
2020 if (blob->cbData && bits[i].cbDecoded)
2021 ok(!memcmp(blob->pbData, bits[i].decoded, bits[i].cbDecoded),
2022 "Unexpected value\n");
2023 LocalFree(buf);
2026 /* special case: check that something that's valid in BER but not in DER
2027 * decodes successfully
2029 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, ber, ber[1] + 2,
2030 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2031 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2032 if (buf)
2034 CRYPT_BIT_BLOB *blob;
2036 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + sizeof(berDecoded),
2037 "Got unexpected size %d\n", bufSize);
2038 blob = (CRYPT_BIT_BLOB *)buf;
2039 ok(blob->cbData == sizeof(berDecoded),
2040 "Got unexpected length %d\n", blob->cbData);
2041 if (blob->cbData)
2042 ok(*blob->pbData == berDecoded, "Unexpected value\n");
2043 LocalFree(buf);
2047 struct Constraints2
2049 CERT_BASIC_CONSTRAINTS2_INFO info;
2050 const BYTE *encoded;
2053 static const unsigned char bin59[] = { 0x30,0x00 };
2054 static const unsigned char bin60[] = { 0x30,0x03,0x01,0x01,0xff };
2055 static const unsigned char bin61[] = { 0x30,0x03,0x02,0x01,0x00 };
2056 static const unsigned char bin62[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2057 static const struct Constraints2 constraints2[] = {
2058 /* empty constraints */
2059 { { FALSE, FALSE, 0}, bin59 },
2060 /* can be a CA */
2061 { { TRUE, FALSE, 0}, bin60 },
2062 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well,
2063 * but that's not the case
2065 { { FALSE, TRUE, 0}, bin61 },
2066 /* can be a CA and has path length constraints set */
2067 { { TRUE, TRUE, 1}, bin62 },
2070 static const BYTE emptyConstraint[] = { 0x30, 0x03, 0x03, 0x01, 0x00 };
2071 static const BYTE encodedDomainName[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11,
2072 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
2073 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
2074 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2075 static const BYTE constraintWithDomainName[] = { 0x30, 0x32, 0x03, 0x01, 0x00,
2076 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
2077 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30,
2078 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
2079 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2081 static void test_encodeBasicConstraints(DWORD dwEncoding)
2083 DWORD i, bufSize = 0;
2084 CERT_BASIC_CONSTRAINTS_INFO info = { { 0 } };
2085 CERT_NAME_BLOB nameBlob = { sizeof(encodedDomainName),
2086 (LPBYTE)encodedDomainName };
2087 BOOL ret;
2088 BYTE *buf = NULL;
2090 /* First test with the simpler info2 */
2091 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2093 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2094 &constraints2[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2095 &bufSize);
2096 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2097 if (buf)
2099 ok(bufSize == constraints2[i].encoded[1] + 2,
2100 "Expected %d bytes, got %d\n", constraints2[i].encoded[1] + 2,
2101 bufSize);
2102 ok(!memcmp(buf, constraints2[i].encoded,
2103 constraints2[i].encoded[1] + 2), "Unexpected value\n");
2104 LocalFree(buf);
2107 /* Now test with more complex basic constraints */
2108 info.SubjectType.cbData = 0;
2109 info.fPathLenConstraint = FALSE;
2110 info.cSubtreesConstraint = 0;
2111 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2112 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2113 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2114 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2115 if (buf)
2117 ok(bufSize == sizeof(emptyConstraint), "Wrong size %d\n", bufSize);
2118 ok(!memcmp(buf, emptyConstraint, sizeof(emptyConstraint)),
2119 "Unexpected value\n");
2120 LocalFree(buf);
2122 /* None of the certs I examined had any subtree constraint, but I test one
2123 * anyway just in case.
2125 info.cSubtreesConstraint = 1;
2126 info.rgSubtreesConstraint = &nameBlob;
2127 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2128 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2129 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2130 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2131 if (buf)
2133 ok(bufSize == sizeof(constraintWithDomainName), "Wrong size %d\n", bufSize);
2134 ok(!memcmp(buf, constraintWithDomainName,
2135 sizeof(constraintWithDomainName)), "Unexpected value\n");
2136 LocalFree(buf);
2138 /* FIXME: test encoding with subject type. */
2141 static const unsigned char bin63[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 };
2143 static void test_decodeBasicConstraints(DWORD dwEncoding)
2145 static const BYTE inverted[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01,
2146 0xff };
2147 static const struct Constraints2 badBool = { { TRUE, TRUE, 1 }, bin63 };
2148 DWORD i;
2149 BOOL ret;
2150 BYTE *buf = NULL;
2151 DWORD bufSize = 0;
2153 /* First test with simpler info2 */
2154 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2156 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2157 constraints2[i].encoded, constraints2[i].encoded[1] + 2,
2158 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2159 ok(ret, "CryptDecodeObjectEx failed for item %d: %08x\n", i,
2160 GetLastError());
2161 if (buf)
2163 CERT_BASIC_CONSTRAINTS2_INFO *info =
2164 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2166 ok(!memcmp(info, &constraints2[i].info, sizeof(*info)),
2167 "Unexpected value for item %d\n", i);
2168 LocalFree(buf);
2171 /* Check with the order of encoded elements inverted */
2172 buf = (PBYTE)1;
2173 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2174 inverted, inverted[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2175 &bufSize);
2176 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2177 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2178 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2179 GetLastError());
2180 ok(!buf, "Expected buf to be set to NULL\n");
2181 /* Check with a non-DER bool */
2182 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2183 badBool.encoded, badBool.encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2184 (BYTE *)&buf, &bufSize);
2185 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2186 if (buf)
2188 CERT_BASIC_CONSTRAINTS2_INFO *info =
2189 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2191 ok(!memcmp(info, &badBool.info, sizeof(*info)), "Unexpected value\n");
2192 LocalFree(buf);
2194 /* Check with a non-basic constraints value */
2195 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2196 (LPBYTE)encodedCommonName, encodedCommonName[1] + 2,
2197 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2198 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2199 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2200 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2201 GetLastError());
2202 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */
2203 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2204 emptyConstraint, sizeof(emptyConstraint), CRYPT_DECODE_ALLOC_FLAG, NULL,
2205 (BYTE *)&buf, &bufSize);
2206 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2207 if (buf)
2209 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2211 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2212 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2213 ok(info->cSubtreesConstraint == 0, "Expected no subtree constraints\n");
2214 LocalFree(buf);
2216 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2217 constraintWithDomainName, sizeof(constraintWithDomainName),
2218 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2219 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2220 if (buf)
2222 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2224 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2225 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2226 ok(info->cSubtreesConstraint == 1, "Expected a subtree constraint\n");
2227 if (info->cSubtreesConstraint && info->rgSubtreesConstraint)
2229 ok(info->rgSubtreesConstraint[0].cbData ==
2230 sizeof(encodedDomainName), "Wrong size %d\n",
2231 info->rgSubtreesConstraint[0].cbData);
2232 ok(!memcmp(info->rgSubtreesConstraint[0].pbData, encodedDomainName,
2233 sizeof(encodedDomainName)), "Unexpected value\n");
2235 LocalFree(buf);
2239 /* These are terrible public keys of course, I'm just testing encoding */
2240 static const BYTE modulus1[] = { 0,0,0,1,1,1,1,1 };
2241 static const BYTE modulus2[] = { 1,1,1,1,1,0,0,0 };
2242 static const BYTE modulus3[] = { 0x80,1,1,1,1,0,0,0 };
2243 static const BYTE modulus4[] = { 1,1,1,1,1,0,0,0x80 };
2244 static const BYTE mod1_encoded[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 };
2245 static const BYTE mod2_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2246 static const BYTE mod3_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 };
2247 static const BYTE mod4_encoded[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2249 struct EncodedRSAPubKey
2251 const BYTE *modulus;
2252 size_t modulusLen;
2253 const BYTE *encoded;
2254 size_t decodedModulusLen;
2257 struct EncodedRSAPubKey rsaPubKeys[] = {
2258 { modulus1, sizeof(modulus1), mod1_encoded, sizeof(modulus1) },
2259 { modulus2, sizeof(modulus2), mod2_encoded, 5 },
2260 { modulus3, sizeof(modulus3), mod3_encoded, 5 },
2261 { modulus4, sizeof(modulus4), mod4_encoded, 8 },
2264 static void test_encodeRsaPublicKey(DWORD dwEncoding)
2266 BYTE toEncode[sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + sizeof(modulus1)];
2267 BLOBHEADER *hdr = (BLOBHEADER *)toEncode;
2268 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(toEncode + sizeof(BLOBHEADER));
2269 BOOL ret;
2270 BYTE *buf = NULL;
2271 DWORD bufSize = 0, i;
2273 /* Try with a bogus blob type */
2274 hdr->bType = 2;
2275 hdr->bVersion = CUR_BLOB_VERSION;
2276 hdr->reserved = 0;
2277 hdr->aiKeyAlg = CALG_RSA_KEYX;
2278 rsaPubKey->magic = 0x31415352;
2279 rsaPubKey->bitlen = sizeof(modulus1) * 8;
2280 rsaPubKey->pubexp = 65537;
2281 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), modulus1,
2282 sizeof(modulus1));
2284 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2285 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2286 &bufSize);
2287 ok(!ret && GetLastError() == E_INVALIDARG,
2288 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2289 /* Now with a bogus reserved field */
2290 hdr->bType = PUBLICKEYBLOB;
2291 hdr->reserved = 1;
2292 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2293 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2294 &bufSize);
2295 if (buf)
2297 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2298 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2299 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2300 LocalFree(buf);
2302 /* Now with a bogus blob version */
2303 hdr->reserved = 0;
2304 hdr->bVersion = 0;
2305 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2306 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2307 &bufSize);
2308 if (buf)
2310 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2311 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2312 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2313 LocalFree(buf);
2315 /* And with a bogus alg ID */
2316 hdr->bVersion = CUR_BLOB_VERSION;
2317 hdr->aiKeyAlg = CALG_DES;
2318 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2319 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2320 &bufSize);
2321 if (buf)
2323 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2324 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2325 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2326 LocalFree(buf);
2328 /* Check a couple of RSA-related OIDs */
2329 hdr->aiKeyAlg = CALG_RSA_KEYX;
2330 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_RSA,
2331 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2332 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2333 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2334 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2335 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2336 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2337 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2338 /* Finally, all valid */
2339 hdr->aiKeyAlg = CALG_RSA_KEYX;
2340 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2342 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2343 rsaPubKeys[i].modulus, rsaPubKeys[i].modulusLen);
2344 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2345 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2346 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2347 if (buf)
2349 ok(bufSize == rsaPubKeys[i].encoded[1] + 2,
2350 "Expected size %d, got %d\n", rsaPubKeys[i].encoded[1] + 2,
2351 bufSize);
2352 ok(!memcmp(buf, rsaPubKeys[i].encoded, bufSize),
2353 "Unexpected value\n");
2354 LocalFree(buf);
2359 static void test_decodeRsaPublicKey(DWORD dwEncoding)
2361 DWORD i;
2362 LPBYTE buf = NULL;
2363 DWORD bufSize = 0;
2364 BOOL ret;
2366 /* Try with a bad length */
2367 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2368 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1],
2369 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2370 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2371 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2372 /* Try with a couple of RSA-related OIDs */
2373 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_RSA,
2374 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2375 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2376 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2377 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2378 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2379 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2380 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2381 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2382 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2383 /* Now try success cases */
2384 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2386 bufSize = 0;
2387 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2388 rsaPubKeys[i].encoded, rsaPubKeys[i].encoded[1] + 2,
2389 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2390 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2391 if (buf)
2393 BLOBHEADER *hdr = (BLOBHEADER *)buf;
2394 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER));
2396 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2397 rsaPubKeys[i].decodedModulusLen,
2398 "Wrong size %d\n", bufSize);
2399 ok(hdr->bType == PUBLICKEYBLOB,
2400 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB,
2401 hdr->bType);
2402 ok(hdr->bVersion == CUR_BLOB_VERSION,
2403 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
2404 CUR_BLOB_VERSION, hdr->bVersion);
2405 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n",
2406 hdr->reserved);
2407 ok(hdr->aiKeyAlg == CALG_RSA_KEYX,
2408 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg);
2409 ok(rsaPubKey->magic == 0x31415352,
2410 "Expected magic RSA1, got %08x\n", rsaPubKey->magic);
2411 ok(rsaPubKey->bitlen == rsaPubKeys[i].decodedModulusLen * 8,
2412 "Wrong bit len %d\n", rsaPubKey->bitlen);
2413 ok(rsaPubKey->pubexp == 65537, "Expected pubexp 65537, got %d\n",
2414 rsaPubKey->pubexp);
2415 ok(!memcmp(buf + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2416 rsaPubKeys[i].modulus, rsaPubKeys[i].decodedModulusLen),
2417 "Unexpected modulus\n");
2418 LocalFree(buf);
2423 static const BYTE intSequence[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01,
2424 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02,
2425 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2427 static const BYTE mixedSequence[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
2428 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f,
2429 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02,
2430 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2432 static void test_encodeSequenceOfAny(DWORD dwEncoding)
2434 CRYPT_DER_BLOB blobs[sizeof(ints) / sizeof(ints[0])];
2435 CRYPT_SEQUENCE_OF_ANY seq;
2436 DWORD i;
2437 BOOL ret;
2438 BYTE *buf = NULL;
2439 DWORD bufSize = 0;
2441 /* Encode a homogeneous sequence */
2442 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
2444 blobs[i].cbData = ints[i].encoded[1] + 2;
2445 blobs[i].pbData = (BYTE *)ints[i].encoded;
2447 seq.cValue = sizeof(ints) / sizeof(ints[0]);
2448 seq.rgValue = blobs;
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(intSequence), "Wrong size %d\n", bufSize);
2456 ok(!memcmp(buf, intSequence, intSequence[1] + 2), "Unexpected value\n");
2457 LocalFree(buf);
2459 /* Change the type of the first element in the sequence, and give it
2460 * another go
2462 blobs[0].cbData = times[0].encodedTime[1] + 2;
2463 blobs[0].pbData = (BYTE *)times[0].encodedTime;
2464 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2465 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2466 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2467 if (buf)
2469 ok(bufSize == sizeof(mixedSequence), "Wrong size %d\n", bufSize);
2470 ok(!memcmp(buf, mixedSequence, mixedSequence[1] + 2),
2471 "Unexpected value\n");
2472 LocalFree(buf);
2476 static void test_decodeSequenceOfAny(DWORD dwEncoding)
2478 BOOL ret;
2479 BYTE *buf = NULL;
2480 DWORD bufSize = 0;
2482 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, intSequence,
2483 intSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2484 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2485 if (buf)
2487 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2488 DWORD i;
2490 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2491 "Wrong elements %d\n", seq->cValue);
2492 for (i = 0; i < min(seq->cValue, sizeof(ints) / sizeof(ints[0])); i++)
2494 ok(seq->rgValue[i].cbData == ints[i].encoded[1] + 2,
2495 "Expected %d bytes, got %d\n", ints[i].encoded[1] + 2,
2496 seq->rgValue[i].cbData);
2497 ok(!memcmp(seq->rgValue[i].pbData, ints[i].encoded,
2498 ints[i].encoded[1] + 2), "Unexpected value\n");
2500 LocalFree(buf);
2502 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, mixedSequence,
2503 mixedSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2504 &bufSize);
2505 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2506 if (buf)
2508 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2510 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2511 "Wrong elements %d\n", seq->cValue);
2512 /* Just check the first element since it's all that changed */
2513 ok(seq->rgValue[0].cbData == times[0].encodedTime[1] + 2,
2514 "Expected %d bytes, got %d\n", times[0].encodedTime[1] + 2,
2515 seq->rgValue[0].cbData);
2516 ok(!memcmp(seq->rgValue[0].pbData, times[0].encodedTime,
2517 times[0].encodedTime[1] + 2), "Unexpected value\n");
2518 LocalFree(buf);
2522 struct encodedExtensions
2524 CERT_EXTENSIONS exts;
2525 const BYTE *encoded;
2528 static BYTE crit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2529 static BYTE noncrit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2530 static CHAR oid_basic_constraints2[] = szOID_BASIC_CONSTRAINTS2;
2531 static CERT_EXTENSION criticalExt =
2532 { oid_basic_constraints2, TRUE, { 8, crit_ext_data } };
2533 static CERT_EXTENSION nonCriticalExt =
2534 { oid_basic_constraints2, FALSE, { 8, noncrit_ext_data } };
2536 static const BYTE ext0[] = { 0x30,0x00 };
2537 static const BYTE ext1[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2538 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2539 static const BYTE ext2[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2540 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2542 static const struct encodedExtensions exts[] = {
2543 { { 0, NULL }, ext0 },
2544 { { 1, &criticalExt }, ext1 },
2545 { { 1, &nonCriticalExt }, ext2 },
2548 static void test_encodeExtensions(DWORD dwEncoding)
2550 DWORD i;
2552 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2554 BOOL ret;
2555 BYTE *buf = NULL;
2556 DWORD bufSize = 0;
2558 ret = pCryptEncodeObjectEx(dwEncoding, X509_EXTENSIONS, &exts[i].exts,
2559 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2560 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2561 if (buf)
2563 ok(bufSize == exts[i].encoded[1] + 2,
2564 "Expected %d bytes, got %d\n", exts[i].encoded[1] + 2, bufSize);
2565 ok(!memcmp(buf, exts[i].encoded, exts[i].encoded[1] + 2),
2566 "Unexpected value\n");
2567 LocalFree(buf);
2572 static void test_decodeExtensions(DWORD dwEncoding)
2574 DWORD i;
2576 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2578 BOOL ret;
2579 BYTE *buf = NULL;
2580 DWORD bufSize = 0;
2582 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS,
2583 exts[i].encoded, exts[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2584 NULL, (BYTE *)&buf, &bufSize);
2585 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2586 if (buf)
2588 CERT_EXTENSIONS *ext = (CERT_EXTENSIONS *)buf;
2589 DWORD j;
2591 ok(ext->cExtension == exts[i].exts.cExtension,
2592 "Expected %d extensions, see %d\n", exts[i].exts.cExtension,
2593 ext->cExtension);
2594 for (j = 0; j < min(ext->cExtension, exts[i].exts.cExtension); j++)
2596 ok(!strcmp(ext->rgExtension[j].pszObjId,
2597 exts[i].exts.rgExtension[j].pszObjId),
2598 "Expected OID %s, got %s\n",
2599 exts[i].exts.rgExtension[j].pszObjId,
2600 ext->rgExtension[j].pszObjId);
2601 ok(!memcmp(ext->rgExtension[j].Value.pbData,
2602 exts[i].exts.rgExtension[j].Value.pbData,
2603 exts[i].exts.rgExtension[j].Value.cbData),
2604 "Unexpected value\n");
2606 LocalFree(buf);
2611 /* MS encodes public key info with a NULL if the algorithm identifier's
2612 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2613 * it encodes them by omitting the algorithm parameters. This latter approach
2614 * seems more correct, so accept either form.
2616 struct encodedPublicKey
2618 CERT_PUBLIC_KEY_INFO info;
2619 const BYTE *encoded;
2620 const BYTE *encodedNoNull;
2621 CERT_PUBLIC_KEY_INFO decoded;
2624 static const BYTE aKey[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2625 0xe, 0xf };
2626 static const BYTE params[] = { 0x02, 0x01, 0x01 };
2628 static const unsigned char bin64[] = {
2629 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2630 static const unsigned char bin65[] = {
2631 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2632 static const unsigned char bin66[] = {
2633 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2634 static const unsigned char bin67[] = {
2635 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2636 static const unsigned char bin68[] = {
2637 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01,
2638 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2639 static const unsigned char bin69[] = {
2640 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2641 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2642 static const unsigned char bin70[] = {
2643 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2644 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2645 0x0f};
2646 static const unsigned char bin71[] = {
2647 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2648 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2649 0x0f};
2650 static unsigned char bin72[] = { 0x05,0x00};
2652 static CHAR oid_bogus[] = "1.2.3",
2653 oid_rsa[] = szOID_RSA;
2655 static const struct encodedPublicKey pubKeys[] = {
2656 /* with a bogus OID */
2657 { { { oid_bogus, { 0, NULL } }, { 0, NULL, 0 } },
2658 bin64, bin65,
2659 { { oid_bogus, { 2, bin72 } }, { 0, NULL, 0 } } },
2660 /* some normal keys */
2661 { { { oid_rsa, { 0, NULL } }, { 0, NULL, 0} },
2662 bin66, bin67,
2663 { { oid_rsa, { 2, bin72 } }, { 0, NULL, 0 } } },
2664 { { { oid_rsa, { 0, NULL } }, { sizeof(aKey), (BYTE *)aKey, 0} },
2665 bin68, bin69,
2666 { { oid_rsa, { 2, bin72 } }, { sizeof(aKey), (BYTE *)aKey, 0} } },
2667 /* with add'l parameters--note they must be DER-encoded */
2668 { { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2669 (BYTE *)aKey, 0 } },
2670 bin70, bin71,
2671 { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2672 (BYTE *)aKey, 0 } } },
2675 static void test_encodePublicKeyInfo(DWORD dwEncoding)
2677 DWORD i;
2679 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2681 BOOL ret;
2682 BYTE *buf = NULL;
2683 DWORD bufSize = 0;
2685 ret = pCryptEncodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2686 &pubKeys[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2687 &bufSize);
2688 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2689 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2690 if (buf)
2692 ok(bufSize == pubKeys[i].encoded[1] + 2 ||
2693 bufSize == pubKeys[i].encodedNoNull[1] + 2,
2694 "Expected %d or %d bytes, got %d\n", pubKeys[i].encoded[1] + 2,
2695 pubKeys[i].encodedNoNull[1] + 2, bufSize);
2696 if (bufSize == pubKeys[i].encoded[1] + 2)
2697 ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2),
2698 "Unexpected value\n");
2699 else if (bufSize == pubKeys[i].encodedNoNull[1] + 2)
2700 ok(!memcmp(buf, pubKeys[i].encodedNoNull,
2701 pubKeys[i].encodedNoNull[1] + 2), "Unexpected value\n");
2702 LocalFree(buf);
2707 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO *expected,
2708 const CERT_PUBLIC_KEY_INFO *got)
2710 ok(!strcmp(expected->Algorithm.pszObjId, got->Algorithm.pszObjId),
2711 "Expected OID %s, got %s\n", expected->Algorithm.pszObjId,
2712 got->Algorithm.pszObjId);
2713 ok(expected->Algorithm.Parameters.cbData ==
2714 got->Algorithm.Parameters.cbData,
2715 "Expected parameters of %d bytes, got %d\n",
2716 expected->Algorithm.Parameters.cbData, got->Algorithm.Parameters.cbData);
2717 if (expected->Algorithm.Parameters.cbData)
2718 ok(!memcmp(expected->Algorithm.Parameters.pbData,
2719 got->Algorithm.Parameters.pbData, got->Algorithm.Parameters.cbData),
2720 "Unexpected algorithm parameters\n");
2721 ok(expected->PublicKey.cbData == got->PublicKey.cbData,
2722 "Expected public key of %d bytes, got %d\n",
2723 expected->PublicKey.cbData, got->PublicKey.cbData);
2724 if (expected->PublicKey.cbData)
2725 ok(!memcmp(expected->PublicKey.pbData, got->PublicKey.pbData,
2726 got->PublicKey.cbData), "Unexpected public key value\n");
2729 static void test_decodePublicKeyInfo(DWORD dwEncoding)
2731 static const BYTE bogusPubKeyInfo[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
2732 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
2733 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
2734 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2735 DWORD i;
2736 BOOL ret;
2737 BYTE *buf = NULL;
2738 DWORD bufSize = 0;
2740 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2742 /* The NULL form decodes to the decoded member */
2743 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2744 pubKeys[i].encoded, pubKeys[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2745 NULL, (BYTE *)&buf, &bufSize);
2746 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2747 if (buf)
2749 comparePublicKeyInfo(&pubKeys[i].decoded,
2750 (CERT_PUBLIC_KEY_INFO *)buf);
2751 LocalFree(buf);
2753 /* The non-NULL form decodes to the original */
2754 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2755 pubKeys[i].encodedNoNull, pubKeys[i].encodedNoNull[1] + 2,
2756 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2757 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2758 if (buf)
2760 comparePublicKeyInfo(&pubKeys[i].info, (CERT_PUBLIC_KEY_INFO *)buf);
2761 LocalFree(buf);
2764 /* Test with bogus (not valid DER) parameters */
2765 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2766 bogusPubKeyInfo, bogusPubKeyInfo[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2767 NULL, (BYTE *)&buf, &bufSize);
2768 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2769 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2770 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2771 GetLastError());
2774 static const BYTE v1Cert[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
2775 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2776 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
2777 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
2778 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2779 static const BYTE v2Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02,
2780 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2781 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2782 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2783 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2784 static const BYTE v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2785 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2786 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2787 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2788 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2789 static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
2790 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2791 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2792 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2793 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2794 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2795 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2796 static const BYTE v1CertWithSerial[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
2797 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2798 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2799 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2800 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2801 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2802 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2803 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2804 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
2805 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
2806 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
2807 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
2808 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
2809 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
2810 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
2811 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
2812 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2813 static const BYTE v1CertWithPubKey[] = {
2814 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2815 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2816 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2817 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2818 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2819 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2820 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2821 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2822 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
2823 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
2824 0x01,0x01 };
2825 static const BYTE v1CertWithPubKeyNoNull[] = {
2826 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2827 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2828 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2829 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2830 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2831 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2832 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2833 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2834 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
2835 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2836 static const BYTE v1CertWithSubjectKeyId[] = {
2837 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2838 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2839 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2840 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2841 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2842 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2843 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
2844 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2845 0x4c,0x61,0x6e,0x67,0x00 };
2847 static const BYTE serialNum[] = { 0x01 };
2849 static void test_encodeCertToBeSigned(DWORD dwEncoding)
2851 BOOL ret;
2852 BYTE *buf = NULL;
2853 DWORD size = 0;
2854 CERT_INFO info = { 0 };
2855 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2856 static char oid_subject_key_identifier[] = szOID_SUBJECT_KEY_IDENTIFIER;
2857 CERT_EXTENSION ext;
2859 if (0)
2861 /* Test with NULL pvStructInfo (crashes on win9x) */
2862 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL,
2863 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2864 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2865 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2867 /* Test with a V1 cert */
2868 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2869 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2870 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2871 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2872 if (buf)
2874 ok(size == v1Cert[1] + 2, "Expected size %d, got %d\n",
2875 v1Cert[1] + 2, size);
2876 ok(!memcmp(buf, v1Cert, size), "Got unexpected value\n");
2877 LocalFree(buf);
2879 /* Test v2 cert */
2880 info.dwVersion = CERT_V2;
2881 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2882 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2883 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2884 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2885 if (buf)
2887 ok(size == sizeof(v2Cert), "Wrong size %d\n", size);
2888 ok(!memcmp(buf, v2Cert, size), "Got unexpected value\n");
2889 LocalFree(buf);
2891 /* Test v3 cert */
2892 info.dwVersion = CERT_V3;
2893 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2894 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2895 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2896 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2897 if (buf)
2899 ok(size == sizeof(v3Cert), "Wrong size %d\n", size);
2900 ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n");
2901 LocalFree(buf);
2903 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
2904 * API doesn't prevent it)
2906 info.dwVersion = CERT_V1;
2907 info.cExtension = 1;
2908 info.rgExtension = &criticalExt;
2909 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2910 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2911 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2912 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2913 if (buf)
2915 ok(size == sizeof(v1CertWithConstraints), "Wrong size %d\n", size);
2916 ok(!memcmp(buf, v1CertWithConstraints, size), "Got unexpected value\n");
2917 LocalFree(buf);
2919 /* test v1 cert with a serial number */
2920 info.SerialNumber.cbData = sizeof(serialNum);
2921 info.SerialNumber.pbData = (BYTE *)serialNum;
2922 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2923 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2924 if (buf)
2926 ok(size == sizeof(v1CertWithSerial), "Wrong size %d\n", size);
2927 ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n");
2928 LocalFree(buf);
2930 /* Test v1 cert with an issuer name, a subject name, and a serial number */
2931 info.Issuer.cbData = sizeof(encodedCommonName);
2932 info.Issuer.pbData = (BYTE *)encodedCommonName;
2933 info.Subject.cbData = sizeof(encodedCommonName);
2934 info.Subject.pbData = (BYTE *)encodedCommonName;
2935 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2936 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2937 if (buf)
2939 ok(size == sizeof(bigCert), "Wrong size %d\n", size);
2940 ok(!memcmp(buf, bigCert, size), "Got unexpected value\n");
2941 LocalFree(buf);
2943 /* Add a public key */
2944 info.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2945 info.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2946 info.SubjectPublicKeyInfo.PublicKey.pbData = (LPBYTE)aKey;
2947 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2948 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2949 if (buf)
2951 ok(size == sizeof(v1CertWithPubKey) ||
2952 size == sizeof(v1CertWithPubKeyNoNull), "Wrong size %d\n", size);
2953 if (size == sizeof(v1CertWithPubKey))
2954 ok(!memcmp(buf, v1CertWithPubKey, size), "Got unexpected value\n");
2955 else if (size == sizeof(v1CertWithPubKeyNoNull))
2956 ok(!memcmp(buf, v1CertWithPubKeyNoNull, size),
2957 "Got unexpected value\n");
2958 LocalFree(buf);
2960 /* Remove the public key, and add a subject key identifier extension */
2961 info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2962 info.SubjectPublicKeyInfo.PublicKey.cbData = 0;
2963 info.SubjectPublicKeyInfo.PublicKey.pbData = NULL;
2964 ext.pszObjId = oid_subject_key_identifier;
2965 ext.fCritical = FALSE;
2966 ext.Value.cbData = sizeof(octetCommonNameValue);
2967 ext.Value.pbData = (BYTE *)octetCommonNameValue;
2968 info.cExtension = 1;
2969 info.rgExtension = &ext;
2970 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2971 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2972 if (buf)
2974 ok(size == sizeof(v1CertWithSubjectKeyId), "Wrong size %d\n", size);
2975 ok(!memcmp(buf, v1CertWithSubjectKeyId, size), "Unexpected value\n");
2976 LocalFree(buf);
2980 static void test_decodeCertToBeSigned(DWORD dwEncoding)
2982 static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert,
2983 v1CertWithConstraints, v1CertWithSerial };
2984 BOOL ret;
2985 BYTE *buf = NULL;
2986 DWORD size = 0, i;
2988 /* Test with NULL pbEncoded */
2989 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 0,
2990 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2991 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
2992 GetLastError() == OSS_BAD_ARG /* Win9x */),
2993 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
2994 if (0)
2996 /* Crashes on win9x */
2997 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 1,
2998 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2999 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3000 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3002 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT, because at a
3003 * minimum a cert must have a non-zero serial number, an issuer, and a
3004 * subject.
3006 for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++)
3008 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3009 corruptCerts[i], corruptCerts[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3010 (BYTE *)&buf, &size);
3011 ok(!ret, "Expected failure\n");
3013 /* Now check with serial number, subject and issuer specified */
3014 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert,
3015 sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3016 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3017 if (buf)
3019 CERT_INFO *info = (CERT_INFO *)buf;
3021 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3022 ok(info->SerialNumber.cbData == 1,
3023 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3024 ok(*info->SerialNumber.pbData == *serialNum,
3025 "Expected serial number %d, got %d\n", *serialNum,
3026 *info->SerialNumber.pbData);
3027 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3028 "Wrong size %d\n", info->Issuer.cbData);
3029 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3030 "Unexpected issuer\n");
3031 ok(info->Subject.cbData == sizeof(encodedCommonName),
3032 "Wrong size %d\n", info->Subject.cbData);
3033 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3034 info->Subject.cbData), "Unexpected subject\n");
3035 LocalFree(buf);
3037 /* Check again with pub key specified */
3038 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3039 v1CertWithPubKey, sizeof(v1CertWithPubKey), CRYPT_DECODE_ALLOC_FLAG, NULL,
3040 (BYTE *)&buf, &size);
3041 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3042 if (buf)
3044 CERT_INFO *info = (CERT_INFO *)buf;
3046 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3047 ok(info->SerialNumber.cbData == 1,
3048 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3049 ok(*info->SerialNumber.pbData == *serialNum,
3050 "Expected serial number %d, got %d\n", *serialNum,
3051 *info->SerialNumber.pbData);
3052 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3053 "Wrong size %d\n", info->Issuer.cbData);
3054 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3055 "Unexpected issuer\n");
3056 ok(info->Subject.cbData == sizeof(encodedCommonName),
3057 "Wrong size %d\n", info->Subject.cbData);
3058 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3059 info->Subject.cbData), "Unexpected subject\n");
3060 ok(!strcmp(info->SubjectPublicKeyInfo.Algorithm.pszObjId,
3061 szOID_RSA_RSA), "Expected szOID_RSA_RSA, got %s\n",
3062 info->SubjectPublicKeyInfo.Algorithm.pszObjId);
3063 ok(info->SubjectPublicKeyInfo.PublicKey.cbData == sizeof(aKey),
3064 "Wrong size %d\n", info->SubjectPublicKeyInfo.PublicKey.cbData);
3065 ok(!memcmp(info->SubjectPublicKeyInfo.PublicKey.pbData, aKey,
3066 sizeof(aKey)), "Unexpected public key\n");
3067 LocalFree(buf);
3071 static const BYTE hash[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
3072 0xe, 0xf };
3074 static const BYTE signedBigCert[] = {
3075 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
3076 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
3077 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
3078 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3079 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
3080 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
3081 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
3082 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
3083 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
3084 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3085 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
3086 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
3088 static void test_encodeCert(DWORD dwEncoding)
3090 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
3091 * also that bigCert is a NULL-terminated string, so don't count its
3092 * last byte (otherwise the signed cert won't decode.)
3094 CERT_SIGNED_CONTENT_INFO info = { { sizeof(bigCert), (BYTE *)bigCert },
3095 { NULL, { 0, NULL } }, { sizeof(hash), (BYTE *)hash, 0 } };
3096 BOOL ret;
3097 BYTE *buf = NULL;
3098 DWORD bufSize = 0;
3100 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT, &info,
3101 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
3102 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3103 if (buf)
3105 ok(bufSize == sizeof(signedBigCert), "Wrong size %d\n", bufSize);
3106 ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n");
3107 LocalFree(buf);
3111 static void test_decodeCert(DWORD dwEncoding)
3113 BOOL ret;
3114 BYTE *buf = NULL;
3115 DWORD size = 0;
3117 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert,
3118 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3119 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3120 if (buf)
3122 CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf;
3124 ok(info->ToBeSigned.cbData == sizeof(bigCert),
3125 "Wrong cert size %d\n", info->ToBeSigned.cbData);
3126 ok(!memcmp(info->ToBeSigned.pbData, bigCert, info->ToBeSigned.cbData),
3127 "Unexpected cert\n");
3128 ok(info->Signature.cbData == sizeof(hash),
3129 "Wrong signature size %d\n", info->Signature.cbData);
3130 ok(!memcmp(info->Signature.pbData, hash, info->Signature.cbData),
3131 "Unexpected signature\n");
3132 LocalFree(buf);
3134 /* A signed cert decodes as a CERT_INFO too */
3135 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCert,
3136 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3137 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3138 if (buf)
3140 CERT_INFO *info = (CERT_INFO *)buf;
3142 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3143 ok(info->SerialNumber.cbData == 1,
3144 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3145 ok(*info->SerialNumber.pbData == *serialNum,
3146 "Expected serial number %d, got %d\n", *serialNum,
3147 *info->SerialNumber.pbData);
3148 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3149 "Wrong size %d\n", info->Issuer.cbData);
3150 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3151 "Unexpected issuer\n");
3152 ok(info->Subject.cbData == sizeof(encodedCommonName),
3153 "Wrong size %d\n", info->Subject.cbData);
3154 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3155 info->Subject.cbData), "Unexpected subject\n");
3156 LocalFree(buf);
3160 static const BYTE emptyDistPoint[] = { 0x30, 0x02, 0x30, 0x00 };
3161 static const BYTE distPointWithUrl[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3162 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3163 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3164 static const BYTE distPointWithReason[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3165 0x00, 0x03 };
3166 static const BYTE distPointWithIssuer[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3167 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3168 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3169 static const BYTE distPointWithUrlAndIssuer[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3170 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3171 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3172 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3173 0x2e, 0x6f, 0x72, 0x67 };
3174 static const BYTE crlReason = CRL_REASON_KEY_COMPROMISE |
3175 CRL_REASON_AFFILIATION_CHANGED;
3177 static void test_encodeCRLDistPoints(DWORD dwEncoding)
3179 CRL_DIST_POINTS_INFO info = { 0 };
3180 CRL_DIST_POINT point = { { 0 } };
3181 CERT_ALT_NAME_ENTRY entry = { 0 };
3182 BOOL ret;
3183 BYTE *buf = NULL;
3184 DWORD size = 0;
3186 /* Test with an empty info */
3187 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3188 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3189 ok(!ret && GetLastError() == E_INVALIDARG,
3190 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3191 /* Test with one empty dist point */
3192 info.cDistPoint = 1;
3193 info.rgDistPoint = &point;
3194 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3195 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3196 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3197 if (buf)
3199 ok(size == sizeof(emptyDistPoint), "Wrong size %d\n", size);
3200 ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n");
3201 LocalFree(buf);
3203 /* A dist point with an invalid name */
3204 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3205 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3206 U(entry).pwszURL = (LPWSTR)nihongoURL;
3207 U(point.DistPointName).FullName.cAltEntry = 1;
3208 U(point.DistPointName).FullName.rgAltEntry = &entry;
3209 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3210 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3211 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
3212 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
3213 /* The first invalid character is at index 7 */
3214 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
3215 "Expected invalid char at index 7, got %d\n",
3216 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
3217 /* A dist point with (just) a valid name */
3218 U(entry).pwszURL = (LPWSTR)url;
3219 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3220 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3221 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3222 if (buf)
3224 ok(size == sizeof(distPointWithUrl), "Wrong size %d\n", size);
3225 ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n");
3226 LocalFree(buf);
3228 /* A dist point with (just) reason flags */
3229 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3230 point.ReasonFlags.cbData = sizeof(crlReason);
3231 point.ReasonFlags.pbData = (LPBYTE)&crlReason;
3232 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3233 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3234 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3235 if (buf)
3237 ok(size == sizeof(distPointWithReason), "Wrong size %d\n", size);
3238 ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n");
3239 LocalFree(buf);
3241 /* A dist point with just an issuer */
3242 point.ReasonFlags.cbData = 0;
3243 point.CRLIssuer.cAltEntry = 1;
3244 point.CRLIssuer.rgAltEntry = &entry;
3245 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3246 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3247 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3248 if (buf)
3250 ok(size == sizeof(distPointWithIssuer), "Wrong size %d\n", size);
3251 ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n");
3252 LocalFree(buf);
3254 /* A dist point with both a name and an issuer */
3255 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3256 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3257 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3258 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3259 if (buf)
3261 ok(size == sizeof(distPointWithUrlAndIssuer),
3262 "Wrong size %d\n", size);
3263 ok(!memcmp(buf, distPointWithUrlAndIssuer, size), "Unexpected value\n");
3264 LocalFree(buf);
3268 static void test_decodeCRLDistPoints(DWORD dwEncoding)
3270 BOOL ret;
3271 BYTE *buf = NULL;
3272 DWORD size = 0;
3273 PCRL_DIST_POINTS_INFO info;
3274 PCRL_DIST_POINT point;
3275 PCERT_ALT_NAME_ENTRY entry;
3277 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3278 emptyDistPoint, emptyDistPoint[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3279 (BYTE *)&buf, &size);
3280 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3281 if (ret)
3283 info = (PCRL_DIST_POINTS_INFO)buf;
3284 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3285 "Wrong size %d\n", size);
3286 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3287 info->cDistPoint);
3288 point = info->rgDistPoint;
3289 ok(point->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_NO_NAME,
3290 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3291 point->DistPointName.dwDistPointNameChoice);
3292 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3293 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3294 LocalFree(buf);
3296 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3297 distPointWithUrl, distPointWithUrl[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3298 (BYTE *)&buf, &size);
3299 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3300 if (ret)
3302 info = (PCRL_DIST_POINTS_INFO)buf;
3303 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3304 "Wrong size %d\n", size);
3305 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3306 info->cDistPoint);
3307 point = info->rgDistPoint;
3308 ok(point->DistPointName.dwDistPointNameChoice ==
3309 CRL_DIST_POINT_FULL_NAME,
3310 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3311 point->DistPointName.dwDistPointNameChoice);
3312 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3313 "Expected 1 name entry, got %d\n",
3314 U(point->DistPointName).FullName.cAltEntry);
3315 entry = U(point->DistPointName).FullName.rgAltEntry;
3316 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3317 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3318 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3319 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3320 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3321 LocalFree(buf);
3323 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3324 distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
3325 NULL, (BYTE *)&buf, &size);
3326 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3327 if (ret)
3329 info = (PCRL_DIST_POINTS_INFO)buf;
3330 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3331 "Wrong size %d\n", size);
3332 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3333 info->cDistPoint);
3334 point = info->rgDistPoint;
3335 ok(point->DistPointName.dwDistPointNameChoice ==
3336 CRL_DIST_POINT_NO_NAME,
3337 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3338 point->DistPointName.dwDistPointNameChoice);
3339 ok(point->ReasonFlags.cbData == sizeof(crlReason),
3340 "Expected reason length\n");
3341 ok(!memcmp(point->ReasonFlags.pbData, &crlReason, sizeof(crlReason)),
3342 "Unexpected reason\n");
3343 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3344 LocalFree(buf);
3346 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3347 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2,
3348 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3349 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3350 if (ret)
3352 info = (PCRL_DIST_POINTS_INFO)buf;
3353 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3354 "Wrong size %d\n", size);
3355 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3356 info->cDistPoint);
3357 point = info->rgDistPoint;
3358 ok(point->DistPointName.dwDistPointNameChoice ==
3359 CRL_DIST_POINT_FULL_NAME,
3360 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3361 point->DistPointName.dwDistPointNameChoice);
3362 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3363 "Expected 1 name entry, got %d\n",
3364 U(point->DistPointName).FullName.cAltEntry);
3365 entry = U(point->DistPointName).FullName.rgAltEntry;
3366 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3367 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3368 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3369 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3370 ok(point->CRLIssuer.cAltEntry == 1,
3371 "Expected 1 issuer entry, got %d\n", point->CRLIssuer.cAltEntry);
3372 entry = point->CRLIssuer.rgAltEntry;
3373 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3374 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3375 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3376 LocalFree(buf);
3380 static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3381 static const BYTE emptyNameIDP[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3382 static const BYTE urlIDP[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3383 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3384 0x67 };
3386 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding)
3388 BOOL ret;
3389 BYTE *buf = NULL;
3390 DWORD size = 0;
3391 CRL_ISSUING_DIST_POINT point = { { 0 } };
3392 CERT_ALT_NAME_ENTRY entry;
3394 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, NULL,
3395 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3396 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3398 skip("no X509_ISSUING_DIST_POINT encode support\n");
3399 return;
3401 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3402 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
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(emptySequence), "Unexpected size %d\n", size);
3409 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
3410 LocalFree(buf);
3412 /* nonsensical flags */
3413 point.fOnlyContainsUserCerts = TRUE;
3414 point.fOnlyContainsCACerts = TRUE;
3415 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3416 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3417 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3418 if (buf)
3420 ok(size == sizeof(badFlagsIDP), "Unexpected size %d\n", size);
3421 ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n");
3422 LocalFree(buf);
3424 /* unimplemented name type */
3425 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3426 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_ISSUER_RDN_NAME;
3427 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3428 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3429 ok(!ret && GetLastError() == E_INVALIDARG,
3430 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3431 /* empty name */
3432 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3433 U(point.DistPointName).FullName.cAltEntry = 0;
3434 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3435 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3436 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3437 if (buf)
3439 ok(size == sizeof(emptyNameIDP), "Unexpected size %d\n", size);
3440 ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n");
3441 LocalFree(buf);
3443 /* name with URL entry */
3444 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3445 U(entry).pwszURL = (LPWSTR)url;
3446 U(point.DistPointName).FullName.cAltEntry = 1;
3447 U(point.DistPointName).FullName.rgAltEntry = &entry;
3448 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3449 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3450 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3451 if (buf)
3453 ok(size == sizeof(urlIDP), "Unexpected size %d\n", size);
3454 ok(!memcmp(buf, urlIDP, size), "Unexpected value\n");
3455 LocalFree(buf);
3459 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY *expected,
3460 const CERT_ALT_NAME_ENTRY *got)
3462 ok(expected->dwAltNameChoice == got->dwAltNameChoice,
3463 "Expected name choice %d, got %d\n", expected->dwAltNameChoice,
3464 got->dwAltNameChoice);
3465 if (expected->dwAltNameChoice == got->dwAltNameChoice)
3467 switch (got->dwAltNameChoice)
3469 case CERT_ALT_NAME_RFC822_NAME:
3470 case CERT_ALT_NAME_DNS_NAME:
3471 case CERT_ALT_NAME_EDI_PARTY_NAME:
3472 case CERT_ALT_NAME_URL:
3473 case CERT_ALT_NAME_REGISTERED_ID:
3474 ok((!U(*expected).pwszURL && !U(*got).pwszURL) ||
3475 (!U(*expected).pwszURL && !lstrlenW(U(*got).pwszURL)) ||
3476 (!U(*got).pwszURL && !lstrlenW(U(*expected).pwszURL)) ||
3477 !lstrcmpW(U(*expected).pwszURL, U(*got).pwszURL),
3478 "Unexpected name\n");
3479 break;
3480 case CERT_ALT_NAME_X400_ADDRESS:
3481 case CERT_ALT_NAME_DIRECTORY_NAME:
3482 case CERT_ALT_NAME_IP_ADDRESS:
3483 ok(U(*got).IPAddress.cbData == U(*expected).IPAddress.cbData,
3484 "Unexpected IP address length %d\n", U(*got).IPAddress.cbData);
3485 ok(!memcmp(U(*got).IPAddress.pbData, U(*got).IPAddress.pbData,
3486 U(*got).IPAddress.cbData), "Unexpected value\n");
3487 break;
3492 static void compareAltNameInfo(const CERT_ALT_NAME_INFO *expected,
3493 const CERT_ALT_NAME_INFO *got)
3495 DWORD i;
3497 ok(expected->cAltEntry == got->cAltEntry, "Expected %d entries, got %d\n",
3498 expected->cAltEntry, got->cAltEntry);
3499 for (i = 0; i < min(expected->cAltEntry, got->cAltEntry); i++)
3500 compareAltNameEntry(&expected->rgAltEntry[i], &got->rgAltEntry[i]);
3503 static void compareDistPointName(const CRL_DIST_POINT_NAME *expected,
3504 const CRL_DIST_POINT_NAME *got)
3506 ok(got->dwDistPointNameChoice == expected->dwDistPointNameChoice,
3507 "Unexpected name choice %d\n", got->dwDistPointNameChoice);
3508 if (got->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME)
3509 compareAltNameInfo(&(U(*expected).FullName), &(U(*got).FullName));
3512 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT *expected,
3513 const CRL_ISSUING_DIST_POINT *got)
3515 compareDistPointName(&expected->DistPointName, &got->DistPointName);
3516 ok(got->fOnlyContainsUserCerts == expected->fOnlyContainsUserCerts,
3517 "Unexpected fOnlyContainsUserCerts\n");
3518 ok(got->fOnlyContainsCACerts == expected->fOnlyContainsCACerts,
3519 "Unexpected fOnlyContainsCACerts\n");
3520 ok(got->OnlySomeReasonFlags.cbData == expected->OnlySomeReasonFlags.cbData,
3521 "Unexpected reason flags\n");
3522 ok(got->fIndirectCRL == expected->fIndirectCRL,
3523 "Unexpected fIndirectCRL\n");
3526 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding)
3528 BOOL ret;
3529 BYTE *buf = NULL;
3530 DWORD size = 0;
3531 CRL_ISSUING_DIST_POINT point = { { 0 } };
3533 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3534 emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3535 (BYTE *)&buf, &size);
3536 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3538 skip("no X509_ISSUING_DIST_POINT decode support\n");
3539 return;
3541 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3542 if (ret)
3544 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3545 LocalFree(buf);
3547 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3548 badFlagsIDP, badFlagsIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3549 (BYTE *)&buf, &size);
3550 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3551 if (ret)
3553 point.fOnlyContainsUserCerts = point.fOnlyContainsCACerts = TRUE;
3554 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3555 LocalFree(buf);
3557 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3558 emptyNameIDP, emptyNameIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3559 (BYTE *)&buf, &size);
3560 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3561 if (ret)
3563 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3564 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3565 U(point.DistPointName).FullName.cAltEntry = 0;
3566 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3567 LocalFree(buf);
3569 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3570 urlIDP, urlIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3571 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3572 if (ret)
3574 CERT_ALT_NAME_ENTRY entry;
3576 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3577 U(entry).pwszURL = (LPWSTR)url;
3578 U(point.DistPointName).FullName.cAltEntry = 1;
3579 U(point.DistPointName).FullName.rgAltEntry = &entry;
3580 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3581 LocalFree(buf);
3585 static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3586 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3587 0x30, 0x5a };
3588 static const BYTE v2CRL[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3589 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3590 0x30, 0x30, 0x30, 0x30, 0x5a };
3591 static const BYTE v1CRLWithIssuer[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3592 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3593 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3594 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3595 0x5a };
3596 static const BYTE v1CRLWithIssuerAndEmptyEntry[] = { 0x30, 0x43, 0x30, 0x02,
3597 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3598 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3599 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3600 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3601 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3602 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3603 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3604 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3605 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3606 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3607 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3608 static const BYTE v1CRLWithEntryExt[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3609 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3610 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3611 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3612 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3613 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3614 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3615 static const BYTE v1CRLWithExt[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3616 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3617 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3618 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
3619 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3620 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
3621 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3622 static const BYTE v2CRLWithExt[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
3623 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
3624 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
3625 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
3626 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
3627 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
3628 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3629 static const BYTE v2CRLWithIssuingDistPoint[] = { 0x30,0x5c,0x02,0x01,0x01,
3630 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
3631 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
3632 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
3633 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3634 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
3635 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3637 static void test_encodeCRLToBeSigned(DWORD dwEncoding)
3639 BOOL ret;
3640 BYTE *buf = NULL;
3641 static CHAR oid_issuing_dist_point[] = szOID_ISSUING_DIST_POINT;
3642 DWORD size = 0;
3643 CRL_INFO info = { 0 };
3644 CRL_ENTRY entry = { { 0 }, { 0 }, 0, 0 };
3645 CERT_EXTENSION ext;
3647 /* Test with a V1 CRL */
3648 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3649 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3650 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3651 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3652 if (buf)
3654 ok(size == sizeof(v1CRL), "Wrong size %d\n", size);
3655 ok(!memcmp(buf, v1CRL, size), "Got unexpected value\n");
3656 LocalFree(buf);
3658 /* Test v2 CRL */
3659 info.dwVersion = CRL_V2;
3660 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3661 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3662 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3663 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3664 if (buf)
3666 ok(size == v2CRL[1] + 2, "Expected size %d, got %d\n",
3667 v2CRL[1] + 2, size);
3668 ok(!memcmp(buf, v2CRL, size), "Got unexpected value\n");
3669 LocalFree(buf);
3671 /* v1 CRL with a name */
3672 info.dwVersion = CRL_V1;
3673 info.Issuer.cbData = sizeof(encodedCommonName);
3674 info.Issuer.pbData = (BYTE *)encodedCommonName;
3675 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3676 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3677 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3678 if (buf)
3680 ok(size == sizeof(v1CRLWithIssuer), "Wrong size %d\n", size);
3681 ok(!memcmp(buf, v1CRLWithIssuer, size), "Got unexpected value\n");
3682 LocalFree(buf);
3684 if (0)
3686 /* v1 CRL with a name and a NULL entry pointer (crashes on win9x) */
3687 info.cCRLEntry = 1;
3688 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3689 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3690 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3691 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3693 /* now set an empty entry */
3694 info.cCRLEntry = 1;
3695 info.rgCRLEntry = &entry;
3696 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3697 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3698 if (buf)
3700 ok(size == sizeof(v1CRLWithIssuerAndEmptyEntry),
3701 "Wrong size %d\n", size);
3702 ok(!memcmp(buf, v1CRLWithIssuerAndEmptyEntry, size),
3703 "Got unexpected value\n");
3704 LocalFree(buf);
3706 /* an entry with a serial number */
3707 entry.SerialNumber.cbData = sizeof(serialNum);
3708 entry.SerialNumber.pbData = (BYTE *)serialNum;
3709 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3710 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3711 if (buf)
3713 ok(size == sizeof(v1CRLWithIssuerAndEntry),
3714 "Wrong size %d\n", size);
3715 ok(!memcmp(buf, v1CRLWithIssuerAndEntry, size),
3716 "Got unexpected value\n");
3717 LocalFree(buf);
3719 /* an entry with an extension */
3720 entry.cExtension = 1;
3721 entry.rgExtension = &criticalExt;
3722 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3723 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3724 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3725 if (buf)
3727 ok(size == sizeof(v1CRLWithEntryExt), "Wrong size %d\n", size);
3728 ok(!memcmp(buf, v1CRLWithEntryExt, size), "Got unexpected value\n");
3729 LocalFree(buf);
3731 /* a CRL with an extension */
3732 entry.cExtension = 0;
3733 info.cExtension = 1;
3734 info.rgExtension = &criticalExt;
3735 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3736 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3737 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3738 if (buf)
3740 ok(size == sizeof(v1CRLWithExt), "Wrong size %d\n", size);
3741 ok(!memcmp(buf, v1CRLWithExt, size), "Got unexpected value\n");
3742 LocalFree(buf);
3744 /* a v2 CRL with an extension, this time non-critical */
3745 info.dwVersion = CRL_V2;
3746 info.rgExtension = &nonCriticalExt;
3747 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3748 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3749 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3750 if (buf)
3752 ok(size == sizeof(v2CRLWithExt), "Wrong size %d\n", size);
3753 ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n");
3754 LocalFree(buf);
3756 /* a v2 CRL with an issuing dist point extension */
3757 ext.pszObjId = oid_issuing_dist_point;
3758 ext.fCritical = TRUE;
3759 ext.Value.cbData = sizeof(urlIDP);
3760 ext.Value.pbData = (LPBYTE)urlIDP;
3761 entry.rgExtension = &ext;
3762 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3763 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3764 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3765 if (buf)
3767 ok(size == sizeof(v2CRLWithIssuingDistPoint), "Wrong size %d\n", size);
3768 ok(!memcmp(buf, v2CRLWithIssuingDistPoint, size), "Unexpected value\n");
3769 LocalFree(buf);
3773 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
3774 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
3775 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
3776 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
3777 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
3778 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
3779 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
3780 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
3781 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
3782 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
3783 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
3784 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
3785 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
3786 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
3787 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
3788 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
3789 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
3790 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
3791 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
3792 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
3793 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
3794 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
3795 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
3796 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
3797 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
3798 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
3799 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
3800 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
3801 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
3802 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
3803 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
3804 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
3805 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
3806 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
3807 0xcd };
3808 static const BYTE verisignCRLWithLotsOfEntries[] = {
3809 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
3810 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
3811 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
3812 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
3813 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
3814 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
3815 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
3816 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
3817 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
3818 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
3819 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
3820 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
3821 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
3822 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
3823 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
3824 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
3825 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3826 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
3827 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
3828 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3829 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
3830 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
3831 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
3832 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
3833 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
3834 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
3835 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
3836 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
3837 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
3838 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
3839 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3840 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
3841 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
3842 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3843 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
3844 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
3845 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
3846 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
3847 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
3848 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
3849 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
3850 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
3851 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
3852 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
3853 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
3854 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
3855 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
3856 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
3857 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
3858 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
3859 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
3860 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
3861 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
3862 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
3863 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3864 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
3865 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
3866 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
3867 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
3868 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
3869 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
3870 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
3871 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
3872 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
3873 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
3874 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
3875 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
3876 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
3877 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
3878 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
3879 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
3880 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
3881 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
3882 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
3883 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
3884 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
3885 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
3886 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
3887 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
3888 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
3889 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
3890 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
3891 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3892 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
3893 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
3894 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
3895 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
3896 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
3897 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
3898 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
3899 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
3900 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
3901 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
3902 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
3903 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
3904 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
3905 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
3906 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
3907 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
3908 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
3909 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
3910 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
3911 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
3912 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
3913 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
3914 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
3915 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
3916 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
3917 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
3918 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
3919 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3920 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
3921 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
3922 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
3923 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
3924 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
3925 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
3926 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
3927 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
3928 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
3929 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
3930 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
3931 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
3932 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
3933 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3934 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
3935 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
3936 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
3937 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
3938 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
3939 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
3940 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
3941 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
3942 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
3943 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
3944 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
3945 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
3946 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
3947 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
3948 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
3949 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
3950 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
3951 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
3952 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
3953 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
3954 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
3955 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
3956 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
3957 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
3958 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
3959 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
3960 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
3961 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
3962 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
3963 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
3964 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
3965 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
3966 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
3967 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
3968 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
3969 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
3970 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
3971 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
3972 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
3973 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
3974 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
3975 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
3976 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
3977 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
3978 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
3979 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
3980 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
3981 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
3982 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
3983 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
3984 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
3985 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
3986 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
3987 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
3988 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
3989 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
3990 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
3991 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
3992 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
3993 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
3994 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
3995 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
3996 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
3997 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
3998 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
3999 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
4000 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
4001 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
4002 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
4003 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
4004 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
4005 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
4006 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
4007 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
4008 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
4009 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
4010 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
4011 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
4012 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
4013 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
4014 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
4015 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
4016 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
4017 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
4018 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
4019 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
4020 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
4021 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
4022 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
4023 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
4024 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
4025 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
4026 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
4027 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
4028 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
4029 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
4030 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
4031 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
4032 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
4033 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
4034 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
4035 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
4036 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
4037 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
4038 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
4039 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
4040 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
4041 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
4042 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
4043 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
4044 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
4045 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
4046 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
4047 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
4048 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
4049 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
4050 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
4051 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
4052 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
4053 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
4054 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
4055 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
4056 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
4057 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
4058 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
4059 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
4060 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
4061 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
4062 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
4063 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
4064 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
4065 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
4066 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
4067 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
4068 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
4069 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
4070 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
4071 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
4072 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
4073 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
4074 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
4075 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
4076 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
4077 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
4078 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
4079 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
4080 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
4081 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
4082 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
4083 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
4084 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
4085 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
4086 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
4087 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
4088 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
4089 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
4090 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
4091 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
4092 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
4093 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
4094 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
4095 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
4096 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
4097 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
4098 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
4099 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
4100 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
4101 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
4102 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
4103 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
4104 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
4105 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
4106 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
4107 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
4108 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
4109 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
4110 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
4111 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
4112 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4113 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4114 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4115 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4116 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4117 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4118 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4119 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4120 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4121 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4122 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4123 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4124 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4125 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4126 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4127 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4128 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4129 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4130 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4131 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4132 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4133 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4134 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4135 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4136 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4137 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4138 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4139 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4140 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4141 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4142 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4143 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4144 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4145 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4146 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4147 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4148 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4149 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4150 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4151 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4152 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4153 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4154 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4155 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4156 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4157 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4158 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4159 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4160 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4161 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4162 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4163 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4164 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4165 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4166 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4167 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4168 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4169 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4170 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4171 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4172 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4173 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4174 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4175 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4176 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4177 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4178 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4179 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4180 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4181 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4182 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4183 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4184 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4185 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4186 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4187 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4188 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4189 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4190 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4191 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4192 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4193 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4194 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4195 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4196 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4197 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4198 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4199 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4200 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4201 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4202 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4203 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4204 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4205 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4206 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4207 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4208 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4209 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4210 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4211 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4212 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4213 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4214 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4215 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4216 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4217 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4218 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4219 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4220 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4221 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4222 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4223 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4224 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4225 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4226 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4227 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4228 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4229 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4230 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4231 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4232 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4233 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4234 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4235 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4236 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4237 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4238 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4239 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4240 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4241 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4242 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4243 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4244 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4245 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4246 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4247 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4248 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4249 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4250 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4251 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4252 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4253 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4254 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4255 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4256 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4257 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4258 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4259 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4260 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4261 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4262 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4263 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4264 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4265 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4266 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4267 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4268 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4269 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4270 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4271 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4272 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4273 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4274 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4275 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4276 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4277 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4278 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4279 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4280 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4281 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4282 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4283 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4284 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4285 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4286 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4287 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4288 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4289 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4290 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4291 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4292 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4293 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4294 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4295 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4296 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4297 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4298 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4299 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4300 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4301 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4302 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4303 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4304 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4305 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4306 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4307 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4308 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4309 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4310 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4311 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4312 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4313 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4314 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4315 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4316 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4318 static void test_decodeCRLToBeSigned(DWORD dwEncoding)
4320 static const BYTE *corruptCRLs[] = { v1CRL, v2CRL };
4321 BOOL ret;
4322 BYTE *buf = NULL;
4323 DWORD size = 0, i;
4325 for (i = 0; i < sizeof(corruptCRLs) / sizeof(corruptCRLs[0]); i++)
4327 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4328 corruptCRLs[i], corruptCRLs[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4329 (BYTE *)&buf, &size);
4330 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4331 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4332 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4333 GetLastError());
4335 /* at a minimum, a CRL must contain an issuer: */
4336 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4337 v1CRLWithIssuer, v1CRLWithIssuer[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4338 (BYTE *)&buf, &size);
4339 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4340 if (buf)
4342 CRL_INFO *info = (CRL_INFO *)buf;
4344 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4345 ok(info->cCRLEntry == 0, "Expected 0 CRL entries, got %d\n",
4346 info->cCRLEntry);
4347 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4348 "Wrong issuer size %d\n", info->Issuer.cbData);
4349 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4350 "Unexpected issuer\n");
4351 LocalFree(buf);
4353 /* check decoding with an empty CRL entry */
4354 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4355 v1CRLWithIssuerAndEmptyEntry, v1CRLWithIssuerAndEmptyEntry[1] + 2,
4356 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4357 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4358 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4359 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4360 GetLastError());
4361 /* with a real CRL entry */
4362 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4363 v1CRLWithIssuerAndEntry, v1CRLWithIssuerAndEntry[1] + 2,
4364 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4365 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4366 if (buf)
4368 CRL_INFO *info = (CRL_INFO *)buf;
4369 CRL_ENTRY *entry;
4371 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4372 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4373 info->cCRLEntry);
4374 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4375 entry = info->rgCRLEntry;
4376 ok(entry->SerialNumber.cbData == 1,
4377 "Expected serial number size 1, got %d\n",
4378 entry->SerialNumber.cbData);
4379 ok(*entry->SerialNumber.pbData == *serialNum,
4380 "Expected serial number %d, got %d\n", *serialNum,
4381 *entry->SerialNumber.pbData);
4382 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4383 "Wrong issuer size %d\n", info->Issuer.cbData);
4384 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4385 "Unexpected issuer\n");
4386 LocalFree(buf);
4388 /* a real CRL from verisign that has extensions */
4389 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4390 verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG,
4391 NULL, (BYTE *)&buf, &size);
4392 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4393 if (buf)
4395 CRL_INFO *info = (CRL_INFO *)buf;
4396 CRL_ENTRY *entry;
4398 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4399 ok(info->cCRLEntry == 3, "Expected 3 CRL entries, got %d\n",
4400 info->cCRLEntry);
4401 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4402 entry = info->rgCRLEntry;
4403 ok(info->cExtension == 2, "Expected 2 extensions, got %d\n",
4404 info->cExtension);
4405 LocalFree(buf);
4407 /* another real CRL from verisign that has lots of entries */
4408 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4409 verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries),
4410 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4411 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4412 if (buf)
4414 CRL_INFO *info = (CRL_INFO *)buf;
4416 ok(size >= sizeof(CRL_INFO), "Got size %d\n", size);
4417 ok(info->cCRLEntry == 209, "Expected 209 CRL entries, got %d\n",
4418 info->cCRLEntry);
4419 ok(info->cExtension == 0, "Expected 0 extensions, got %d\n",
4420 info->cExtension);
4421 LocalFree(buf);
4423 /* and finally, with an extension */
4424 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4425 v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4426 NULL, (BYTE *)&buf, &size);
4427 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4428 if (buf)
4430 CRL_INFO *info = (CRL_INFO *)buf;
4431 CRL_ENTRY *entry;
4433 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4434 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4435 info->cCRLEntry);
4436 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4437 entry = info->rgCRLEntry;
4438 ok(entry->SerialNumber.cbData == 1,
4439 "Expected serial number size 1, got %d\n",
4440 entry->SerialNumber.cbData);
4441 ok(*entry->SerialNumber.pbData == *serialNum,
4442 "Expected serial number %d, got %d\n", *serialNum,
4443 *entry->SerialNumber.pbData);
4444 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4445 "Wrong issuer size %d\n", info->Issuer.cbData);
4446 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4447 "Unexpected issuer\n");
4448 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4449 info->cExtension);
4450 LocalFree(buf);
4452 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4453 v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4454 NULL, (BYTE *)&buf, &size);
4455 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4456 if (buf)
4458 CRL_INFO *info = (CRL_INFO *)buf;
4460 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4461 info->cExtension);
4462 LocalFree(buf);
4464 /* And again, with an issuing dist point */
4465 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4466 v2CRLWithIssuingDistPoint, sizeof(v2CRLWithIssuingDistPoint),
4467 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4468 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4469 if (buf)
4471 CRL_INFO *info = (CRL_INFO *)buf;
4473 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4474 info->cExtension);
4475 LocalFree(buf);
4479 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
4480 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
4481 static const BYTE encodedUsage[] = {
4482 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4483 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4484 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4486 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding)
4488 BOOL ret;
4489 BYTE *buf = NULL;
4490 DWORD size = 0;
4491 CERT_ENHKEY_USAGE usage;
4493 /* Test with empty usage */
4494 usage.cUsageIdentifier = 0;
4495 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4496 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4497 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4498 if (buf)
4500 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
4501 ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n");
4502 LocalFree(buf);
4504 /* Test with a few usages */
4505 usage.cUsageIdentifier = sizeof(keyUsages) / sizeof(keyUsages[0]);
4506 usage.rgpszUsageIdentifier = (LPSTR *)keyUsages;
4507 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4508 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4509 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4510 if (buf)
4512 ok(size == sizeof(encodedUsage), "Wrong size %d\n", size);
4513 ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n");
4514 LocalFree(buf);
4518 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding)
4520 BOOL ret;
4521 LPBYTE buf = NULL;
4522 DWORD size = 0;
4524 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4525 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4526 (BYTE *)&buf, &size);
4527 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4528 if (buf)
4530 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4532 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4533 "Wrong size %d\n", size);
4534 ok(usage->cUsageIdentifier == 0, "Expected 0 CRL entries, got %d\n",
4535 usage->cUsageIdentifier);
4536 LocalFree(buf);
4538 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4539 encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL,
4540 (BYTE *)&buf, &size);
4541 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4542 if (buf)
4544 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4545 DWORD i;
4547 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4548 "Wrong size %d\n", size);
4549 ok(usage->cUsageIdentifier == sizeof(keyUsages) / sizeof(keyUsages[0]),
4550 "Wrong CRL entries count %d\n", usage->cUsageIdentifier);
4551 for (i = 0; i < usage->cUsageIdentifier; i++)
4552 ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]),
4553 "Expected OID %s, got %s\n", keyUsages[i],
4554 usage->rgpszUsageIdentifier[i]);
4555 LocalFree(buf);
4559 static BYTE keyId[] = { 1,2,3,4 };
4560 static const BYTE authorityKeyIdWithId[] = {
4561 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4562 static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4563 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4564 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4565 static const BYTE authorityKeyIdWithSerial[] = { 0x30,0x03,0x82,0x01,0x01 };
4567 static void test_encodeAuthorityKeyId(DWORD dwEncoding)
4569 CERT_AUTHORITY_KEY_ID_INFO info = { { 0 } };
4570 BOOL ret;
4571 BYTE *buf = NULL;
4572 DWORD size = 0;
4574 /* Test with empty id */
4575 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4576 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4577 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4578 if (buf)
4580 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4581 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4582 LocalFree(buf);
4584 /* With just a key id */
4585 info.KeyId.cbData = sizeof(keyId);
4586 info.KeyId.pbData = keyId;
4587 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4588 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4589 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4590 if (buf)
4592 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", size);
4593 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4594 LocalFree(buf);
4596 /* With just an issuer */
4597 info.KeyId.cbData = 0;
4598 info.CertIssuer.cbData = sizeof(encodedCommonName);
4599 info.CertIssuer.pbData = (BYTE *)encodedCommonName;
4600 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4601 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4602 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4603 if (buf)
4605 ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %d\n",
4606 size);
4607 ok(!memcmp(buf, authorityKeyIdWithIssuer, size), "Unexpected value\n");
4608 LocalFree(buf);
4610 /* With just a serial number */
4611 info.CertIssuer.cbData = 0;
4612 info.CertSerialNumber.cbData = sizeof(serialNum);
4613 info.CertSerialNumber.pbData = (BYTE *)serialNum;
4614 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4615 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4616 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4617 if (buf)
4619 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4620 size);
4621 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4622 LocalFree(buf);
4626 static void test_decodeAuthorityKeyId(DWORD dwEncoding)
4628 BOOL ret;
4629 LPBYTE buf = NULL;
4630 DWORD size = 0;
4632 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4633 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4634 (BYTE *)&buf, &size);
4635 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4636 if (buf)
4638 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4640 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4641 size);
4642 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4643 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4644 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4645 LocalFree(buf);
4647 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4648 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4649 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4650 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4651 if (buf)
4653 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4655 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4656 size);
4657 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4658 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4659 "Unexpected key id\n");
4660 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4661 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4662 LocalFree(buf);
4664 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4665 authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer),
4666 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4667 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4668 if (buf)
4670 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4672 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4673 size);
4674 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4675 ok(info->CertIssuer.cbData == sizeof(encodedCommonName),
4676 "Unexpected issuer len\n");
4677 ok(!memcmp(info->CertIssuer.pbData, encodedCommonName,
4678 sizeof(encodedCommonName)), "Unexpected issuer\n");
4679 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4680 LocalFree(buf);
4682 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4683 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4684 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4685 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4686 if (buf)
4688 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4690 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4691 size);
4692 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4693 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4694 ok(info->CertSerialNumber.cbData == sizeof(serialNum),
4695 "Unexpected serial number len\n");
4696 ok(!memcmp(info->CertSerialNumber.pbData, serialNum, sizeof(serialNum)),
4697 "Unexpected serial number\n");
4698 LocalFree(buf);
4702 static const BYTE authorityKeyIdWithIssuerUrl[] = { 0x30,0x15,0xa1,0x13,0x86,
4703 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
4704 0x6f,0x72,0x67 };
4706 static void test_encodeAuthorityKeyId2(DWORD dwEncoding)
4708 CERT_AUTHORITY_KEY_ID2_INFO info = { { 0 } };
4709 CERT_ALT_NAME_ENTRY entry = { 0 };
4710 BOOL ret;
4711 BYTE *buf = NULL;
4712 DWORD size = 0;
4714 /* Test with empty id */
4715 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4716 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4717 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4718 if (buf)
4720 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4721 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4722 LocalFree(buf);
4724 /* With just a key id */
4725 info.KeyId.cbData = sizeof(keyId);
4726 info.KeyId.pbData = keyId;
4727 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4728 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4729 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4730 if (buf)
4732 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n",
4733 size);
4734 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4735 LocalFree(buf);
4737 /* With a bogus issuer name */
4738 info.KeyId.cbData = 0;
4739 info.AuthorityCertIssuer.cAltEntry = 1;
4740 info.AuthorityCertIssuer.rgAltEntry = &entry;
4741 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4742 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4743 ok(!ret && GetLastError() == E_INVALIDARG,
4744 "Expected E_INVALIDARG, got %08x\n", GetLastError());
4745 /* With an issuer name */
4746 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
4747 U(entry).pwszURL = (LPWSTR)url;
4748 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4749 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4750 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4751 if (buf)
4753 ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %d\n",
4754 size);
4755 ok(!memcmp(buf, authorityKeyIdWithIssuerUrl, size),
4756 "Unexpected value\n");
4757 LocalFree(buf);
4759 /* With just a serial number */
4760 info.AuthorityCertIssuer.cAltEntry = 0;
4761 info.AuthorityCertSerialNumber.cbData = sizeof(serialNum);
4762 info.AuthorityCertSerialNumber.pbData = (BYTE *)serialNum;
4763 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4764 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4765 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4766 if (buf)
4768 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4769 size);
4770 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4771 LocalFree(buf);
4775 static void test_decodeAuthorityKeyId2(DWORD dwEncoding)
4777 BOOL ret;
4778 LPBYTE buf = NULL;
4779 DWORD size = 0;
4781 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4782 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4783 (BYTE *)&buf, &size);
4784 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4785 if (buf)
4787 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4789 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4790 size);
4791 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4792 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4793 "Expected no issuer name entries\n");
4794 ok(info->AuthorityCertSerialNumber.cbData == 0,
4795 "Expected no serial number\n");
4796 LocalFree(buf);
4798 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4799 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4800 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4801 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4802 if (buf)
4804 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4806 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4807 size);
4808 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4809 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4810 "Unexpected key id\n");
4811 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4812 "Expected no issuer name entries\n");
4813 ok(info->AuthorityCertSerialNumber.cbData == 0,
4814 "Expected no serial number\n");
4815 LocalFree(buf);
4817 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4818 authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl),
4819 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4820 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4821 if (buf)
4823 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4825 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4826 size);
4827 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4828 ok(info->AuthorityCertIssuer.cAltEntry == 1,
4829 "Expected 1 issuer entry, got %d\n",
4830 info->AuthorityCertIssuer.cAltEntry);
4831 ok(info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice ==
4832 CERT_ALT_NAME_URL, "Expected CERT_ALT_NAME_URL, got %d\n",
4833 info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice);
4834 ok(!lstrcmpW(U(info->AuthorityCertIssuer.rgAltEntry[0]).pwszURL,
4835 url), "Unexpected URL\n");
4836 ok(info->AuthorityCertSerialNumber.cbData == 0,
4837 "Expected no serial number\n");
4838 LocalFree(buf);
4840 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4841 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4842 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4843 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4844 if (buf)
4846 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4848 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4849 size);
4850 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4851 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4852 "Expected no issuer name entries\n");
4853 ok(info->AuthorityCertSerialNumber.cbData == sizeof(serialNum),
4854 "Unexpected serial number len\n");
4855 ok(!memcmp(info->AuthorityCertSerialNumber.pbData, serialNum,
4856 sizeof(serialNum)), "Unexpected serial number\n");
4857 LocalFree(buf);
4861 static const BYTE authorityInfoAccessWithUrl[] = {
4862 0x30,0x19,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
4863 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
4864 static const BYTE authorityInfoAccessWithUrlAndIPAddr[] = {
4865 0x30,0x29,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
4866 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x0e,0x06,
4867 0x02,0x2d,0x06,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
4869 static void test_encodeAuthorityInfoAccess(DWORD dwEncoding)
4871 static char oid1[] = "1.2.3";
4872 static char oid2[] = "1.5.6";
4873 BOOL ret;
4874 BYTE *buf = NULL;
4875 DWORD size = 0;
4876 CERT_ACCESS_DESCRIPTION accessDescription[2];
4877 CERT_AUTHORITY_INFO_ACCESS aia;
4879 memset(accessDescription, 0, sizeof(accessDescription));
4880 aia.cAccDescr = 0;
4881 aia.rgAccDescr = NULL;
4882 /* Having no access descriptions is allowed */
4883 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4884 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4885 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4886 if (buf)
4888 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
4889 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
4890 LocalFree(buf);
4891 buf = NULL;
4893 /* It can't have an empty access method */
4894 aia.cAccDescr = 1;
4895 aia.rgAccDescr = accessDescription;
4896 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4897 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4898 ok(!ret && (GetLastError() == E_INVALIDARG ||
4899 GetLastError() == OSS_LIMITED /* Win9x */),
4900 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
4901 /* It can't have an empty location */
4902 accessDescription[0].pszAccessMethod = oid1;
4903 SetLastError(0xdeadbeef);
4904 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4905 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4906 ok(!ret && GetLastError() == E_INVALIDARG,
4907 "expected E_INVALIDARG, got %08x\n", GetLastError());
4908 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
4909 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
4910 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4911 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4912 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4913 if (buf)
4915 ok(size == sizeof(authorityInfoAccessWithUrl), "unexpected size %d\n",
4916 size);
4917 ok(!memcmp(buf, authorityInfoAccessWithUrl, size),
4918 "unexpected value\n");
4919 LocalFree(buf);
4920 buf = NULL;
4922 accessDescription[1].pszAccessMethod = oid2;
4923 accessDescription[1].AccessLocation.dwAltNameChoice =
4924 CERT_ALT_NAME_IP_ADDRESS;
4925 U(accessDescription[1].AccessLocation).IPAddress.cbData =
4926 sizeof(encodedIPAddr);
4927 U(accessDescription[1].AccessLocation).IPAddress.pbData =
4928 (LPBYTE)encodedIPAddr;
4929 aia.cAccDescr = 2;
4930 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4931 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4932 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4933 if (buf)
4935 ok(size == sizeof(authorityInfoAccessWithUrlAndIPAddr),
4936 "unexpected size %d\n", size);
4937 ok(!memcmp(buf, authorityInfoAccessWithUrlAndIPAddr, size),
4938 "unexpected value\n");
4939 LocalFree(buf);
4940 buf = NULL;
4944 static void compareAuthorityInfoAccess(LPCSTR header,
4945 const CERT_AUTHORITY_INFO_ACCESS *expected,
4946 const CERT_AUTHORITY_INFO_ACCESS *got)
4948 DWORD i;
4950 ok(expected->cAccDescr == got->cAccDescr,
4951 "%s: expected %d access descriptions, got %d\n", header,
4952 expected->cAccDescr, got->cAccDescr);
4953 for (i = 0; i < expected->cAccDescr; i++)
4955 ok(!strcmp(expected->rgAccDescr[i].pszAccessMethod,
4956 got->rgAccDescr[i].pszAccessMethod), "%s[%d]: expected %s, got %s\n",
4957 header, i, expected->rgAccDescr[i].pszAccessMethod,
4958 got->rgAccDescr[i].pszAccessMethod);
4959 compareAltNameEntry(&expected->rgAccDescr[i].AccessLocation,
4960 &got->rgAccDescr[i].AccessLocation);
4964 static void test_decodeAuthorityInfoAccess(DWORD dwEncoding)
4966 static char oid1[] = "1.2.3";
4967 static char oid2[] = "1.5.6";
4968 BOOL ret;
4969 LPBYTE buf = NULL;
4970 DWORD size = 0;
4972 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
4973 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4974 (BYTE *)&buf, &size);
4975 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4976 if (buf)
4978 CERT_AUTHORITY_INFO_ACCESS aia = { 0, NULL };
4980 compareAuthorityInfoAccess("empty AIA", &aia,
4981 (CERT_AUTHORITY_INFO_ACCESS *)buf);
4982 LocalFree(buf);
4983 buf = NULL;
4985 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
4986 authorityInfoAccessWithUrl, sizeof(authorityInfoAccessWithUrl),
4987 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4988 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4989 if (buf)
4991 CERT_ACCESS_DESCRIPTION accessDescription;
4992 CERT_AUTHORITY_INFO_ACCESS aia;
4994 accessDescription.pszAccessMethod = oid1;
4995 accessDescription.AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
4996 U(accessDescription.AccessLocation).pwszURL = (LPWSTR)url;
4997 aia.cAccDescr = 1;
4998 aia.rgAccDescr = &accessDescription;
4999 compareAuthorityInfoAccess("AIA with URL", &aia,
5000 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5001 LocalFree(buf);
5002 buf = NULL;
5004 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5005 authorityInfoAccessWithUrlAndIPAddr,
5006 sizeof(authorityInfoAccessWithUrlAndIPAddr), CRYPT_DECODE_ALLOC_FLAG,
5007 NULL, (BYTE *)&buf, &size);
5008 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5009 if (buf)
5011 CERT_ACCESS_DESCRIPTION accessDescription[2];
5012 CERT_AUTHORITY_INFO_ACCESS aia;
5014 accessDescription[0].pszAccessMethod = oid1;
5015 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5016 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
5017 accessDescription[1].pszAccessMethod = oid2;
5018 accessDescription[1].AccessLocation.dwAltNameChoice =
5019 CERT_ALT_NAME_IP_ADDRESS;
5020 U(accessDescription[1].AccessLocation).IPAddress.cbData =
5021 sizeof(encodedIPAddr);
5022 U(accessDescription[1].AccessLocation).IPAddress.pbData =
5023 (LPBYTE)encodedIPAddr;
5024 aia.cAccDescr = 2;
5025 aia.rgAccDescr = accessDescription;
5026 compareAuthorityInfoAccess("AIA with URL and IP addr", &aia,
5027 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5028 LocalFree(buf);
5029 buf = NULL;
5033 static const BYTE emptyCTL[] = {
5034 0x30,0x17,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5035 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5036 static const BYTE emptyCTLWithVersion1[] = {
5037 0x30,0x1a,0x02,0x01,0x01,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5038 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5039 static const BYTE ctlWithUsageIdentifier[] = {
5040 0x30,0x1b,0x30,0x04,0x06,0x02,0x2a,0x03,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
5041 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5042 static const BYTE ctlWithListIdentifier[] = {
5043 0x30,0x1a,0x30,0x00,0x04,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5044 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5045 static const BYTE ctlWithSequenceNumber[] = {
5046 0x30,0x1a,0x30,0x00,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5047 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5048 static const BYTE ctlWithThisUpdate[] = {
5049 0x30,0x15,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5050 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5051 static const BYTE ctlWithThisAndNextUpdate[] = {
5052 0x30,0x24,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5053 0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5054 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5055 static const BYTE ctlWithAlgId[] = {
5056 0x30,0x1b,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5057 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5058 static const BYTE ctlWithBogusEntry[] = {
5059 0x30,0x29,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5060 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x10,0x30,0x0e,0x04,
5061 0x01,0x01,0x31,0x09,0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,0x01 };
5062 static const BYTE ctlWithOneEntry[] = {
5063 0x30,0x2a,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5064 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x11,0x30,0x0f,0x04,
5065 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00 };
5066 static const BYTE ctlWithTwoEntries[] = {
5067 0x30,0x41,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5068 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x28,0x30,0x0f,0x04,
5069 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00,0x30,
5070 0x15,0x04,0x01,0x01,0x31,0x10,0x30,0x0e,0x06,0x02,0x2d,0x06,0x31,0x08,0x30,
5071 0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5073 static void test_encodeCTL(DWORD dwEncoding)
5075 static char oid1[] = "1.2.3";
5076 static char oid2[] = "1.5.6";
5077 char *pOid1 = oid1;
5078 BOOL ret;
5079 BYTE *buf = NULL;
5080 DWORD size = 0;
5081 CTL_INFO info;
5082 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5083 CTL_ENTRY ctlEntry[2];
5084 CRYPT_ATTRIBUTE attr1, attr2;
5085 CRYPT_ATTR_BLOB value1, value2;
5087 memset(&info, 0, sizeof(info));
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(emptyCTL), "unexpected size %d\n", size);
5094 ok(!memcmp(buf, emptyCTL, size), "unexpected value\n");
5095 LocalFree(buf);
5096 buf = NULL;
5098 info.dwVersion = 1;
5099 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5100 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5101 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5102 if (buf)
5104 ok(size == sizeof(emptyCTLWithVersion1), "unexpected size %d\n", size);
5105 ok(!memcmp(buf, emptyCTLWithVersion1, size), "unexpected value\n");
5106 LocalFree(buf);
5107 buf = NULL;
5109 info.dwVersion = 0;
5110 info.SubjectUsage.cUsageIdentifier = 1;
5111 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5112 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5113 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5114 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5115 if (buf)
5117 ok(size == sizeof(ctlWithUsageIdentifier), "unexpected size %d\n",
5118 size);
5119 ok(!memcmp(buf, ctlWithUsageIdentifier, size), "unexpected value\n");
5120 LocalFree(buf);
5121 buf = NULL;
5123 info.SubjectUsage.cUsageIdentifier = 0;
5124 info.ListIdentifier.cbData = sizeof(serialNum);
5125 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5126 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5127 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5128 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5129 if (buf)
5131 ok(size == sizeof(ctlWithListIdentifier), "unexpected size %d\n", size);
5132 ok(!memcmp(buf, ctlWithListIdentifier, size), "unexpected value\n");
5133 LocalFree(buf);
5134 buf = NULL;
5136 info.ListIdentifier.cbData = 0;
5137 info.SequenceNumber.cbData = sizeof(serialNum);
5138 info.SequenceNumber.pbData = (LPBYTE)serialNum;
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(ctlWithSequenceNumber), "unexpected size %d\n",
5145 size);
5146 ok(!memcmp(buf, ctlWithSequenceNumber, size), "unexpected value\n");
5147 LocalFree(buf);
5148 buf = NULL;
5150 info.SequenceNumber.cbData = 0;
5151 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5152 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5153 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5154 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5155 if (buf)
5157 ok(size == sizeof(ctlWithThisUpdate), "unexpected size %d\n", size);
5158 ok(!memcmp(buf, ctlWithThisUpdate, size), "unexpected value\n");
5159 LocalFree(buf);
5160 buf = NULL;
5162 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5163 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5164 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5165 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5166 if (buf)
5168 ok(size == sizeof(ctlWithThisAndNextUpdate), "unexpected size %d\n",
5169 size);
5170 ok(!memcmp(buf, ctlWithThisAndNextUpdate, size), "unexpected value\n");
5171 LocalFree(buf);
5172 buf = NULL;
5174 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5175 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5176 info.SubjectAlgorithm.pszObjId = oid2;
5177 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5178 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5179 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5180 if (buf)
5182 ok(size == sizeof(ctlWithAlgId), "unexpected size %d\n", size);
5183 ok(!memcmp(buf, ctlWithAlgId, size), "unexpected value\n");
5184 LocalFree(buf);
5185 buf = NULL;
5187 /* The value is supposed to be asn.1 encoded, so this'll fail to decode
5188 * (see tests below) but it'll encode fine.
5190 info.SubjectAlgorithm.pszObjId = NULL;
5191 value1.cbData = sizeof(serialNum);
5192 value1.pbData = (LPBYTE)serialNum;
5193 attr1.pszObjId = oid1;
5194 attr1.cValue = 1;
5195 attr1.rgValue = &value1;
5196 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5197 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5198 ctlEntry[0].cAttribute = 1;
5199 ctlEntry[0].rgAttribute = &attr1;
5200 info.cCTLEntry = 1;
5201 info.rgCTLEntry = ctlEntry;
5202 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5203 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5204 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5205 if (buf)
5207 ok(size == sizeof(ctlWithBogusEntry), "unexpected size %d\n", size);
5208 ok(!memcmp(buf, ctlWithBogusEntry, size), "unexpected value\n");
5209 LocalFree(buf);
5210 buf = NULL;
5212 value1.cbData = sizeof(emptySequence);
5213 value1.pbData = (LPBYTE)emptySequence;
5214 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5215 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5216 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5217 if (buf)
5219 ok(size == sizeof(ctlWithOneEntry), "unexpected size %d\n", size);
5220 ok(!memcmp(buf, ctlWithOneEntry, size), "unexpected value\n");
5221 LocalFree(buf);
5222 buf = NULL;
5224 value2.cbData = sizeof(encodedIPAddr);
5225 value2.pbData = (LPBYTE)encodedIPAddr;
5226 attr2.pszObjId = oid2;
5227 attr2.cValue = 1;
5228 attr2.rgValue = &value2;
5229 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5230 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5231 ctlEntry[1].cAttribute = 1;
5232 ctlEntry[1].rgAttribute = &attr2;
5233 info.cCTLEntry = 2;
5234 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5235 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5236 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5237 if (buf)
5239 ok(size == sizeof(ctlWithTwoEntries), "unexpected size %d\n", size);
5240 ok(!memcmp(buf, ctlWithTwoEntries, size), "unexpected value\n");
5241 LocalFree(buf);
5242 buf = NULL;
5246 static void compareCTLInfo(LPCSTR header, const CTL_INFO *expected,
5247 const CTL_INFO *got)
5249 DWORD i, j, k;
5251 ok(expected->dwVersion == got->dwVersion,
5252 "%s: expected version %d, got %d\n", header, expected->dwVersion,
5253 got->dwVersion);
5254 ok(expected->SubjectUsage.cUsageIdentifier ==
5255 got->SubjectUsage.cUsageIdentifier,
5256 "%s: expected %d usage identifiers, got %d\n", header,
5257 expected->SubjectUsage.cUsageIdentifier,
5258 got->SubjectUsage.cUsageIdentifier);
5259 for (i = 0; i < expected->SubjectUsage.cUsageIdentifier; i++)
5260 ok(!strcmp(expected->SubjectUsage.rgpszUsageIdentifier[i],
5261 got->SubjectUsage.rgpszUsageIdentifier[i]),
5262 "%s[%d]: expected %s, got %s\n", header, i,
5263 expected->SubjectUsage.rgpszUsageIdentifier[i],
5264 got->SubjectUsage.rgpszUsageIdentifier[i]);
5265 ok(expected->ListIdentifier.cbData == got->ListIdentifier.cbData,
5266 "%s: expected list identifier of %d bytes, got %d\n", header,
5267 expected->ListIdentifier.cbData, got->ListIdentifier.cbData);
5268 if (expected->ListIdentifier.cbData)
5269 ok(!memcmp(expected->ListIdentifier.pbData, got->ListIdentifier.pbData,
5270 expected->ListIdentifier.cbData),
5271 "%s: unexpected list identifier value\n", header);
5272 ok(expected->SequenceNumber.cbData == got->SequenceNumber.cbData,
5273 "%s: expected sequence number of %d bytes, got %d\n", header,
5274 expected->SequenceNumber.cbData, got->SequenceNumber.cbData);
5275 if (expected->SequenceNumber.cbData)
5276 ok(!memcmp(expected->SequenceNumber.pbData, got->SequenceNumber.pbData,
5277 expected->SequenceNumber.cbData),
5278 "%s: unexpected sequence number value\n", header);
5279 ok(!memcmp(&expected->ThisUpdate, &got->ThisUpdate, sizeof(FILETIME)),
5280 "%s: expected this update = (%d, %d), got (%d, %d)\n", header,
5281 expected->ThisUpdate.dwLowDateTime, expected->ThisUpdate.dwHighDateTime,
5282 got->ThisUpdate.dwLowDateTime, got->ThisUpdate.dwHighDateTime);
5283 ok(!memcmp(&expected->NextUpdate, &got->NextUpdate, sizeof(FILETIME)),
5284 "%s: expected next update = (%d, %d), got (%d, %d)\n", header,
5285 expected->NextUpdate.dwLowDateTime, expected->NextUpdate.dwHighDateTime,
5286 got->NextUpdate.dwLowDateTime, got->NextUpdate.dwHighDateTime);
5287 if (expected->SubjectAlgorithm.pszObjId &&
5288 *expected->SubjectAlgorithm.pszObjId && !got->SubjectAlgorithm.pszObjId)
5289 ok(0, "%s: expected subject algorithm %s, got NULL\n", header,
5290 expected->SubjectAlgorithm.pszObjId);
5291 if (expected->SubjectAlgorithm.pszObjId && got->SubjectAlgorithm.pszObjId)
5292 ok(!strcmp(expected->SubjectAlgorithm.pszObjId,
5293 got->SubjectAlgorithm.pszObjId),
5294 "%s: expected subject algorithm %s, got %s\n", header,
5295 expected->SubjectAlgorithm.pszObjId, got->SubjectAlgorithm.pszObjId);
5296 ok(expected->SubjectAlgorithm.Parameters.cbData ==
5297 got->SubjectAlgorithm.Parameters.cbData,
5298 "%s: expected subject algorithm parameters of %d bytes, got %d\n", header,
5299 expected->SubjectAlgorithm.Parameters.cbData,
5300 got->SubjectAlgorithm.Parameters.cbData);
5301 if (expected->SubjectAlgorithm.Parameters.cbData)
5302 ok(!memcmp(expected->SubjectAlgorithm.Parameters.pbData,
5303 got->SubjectAlgorithm.Parameters.pbData,
5304 expected->SubjectAlgorithm.Parameters.cbData),
5305 "%s: unexpected subject algorithm parameter value\n", header);
5306 ok(expected->cCTLEntry == got->cCTLEntry,
5307 "%s: expected %d CTL entries, got %d\n", header, expected->cCTLEntry,
5308 got->cCTLEntry);
5309 for (i = 0; i < expected->cCTLEntry; i++)
5311 ok(expected->rgCTLEntry[i].SubjectIdentifier.cbData ==
5312 got->rgCTLEntry[i].SubjectIdentifier.cbData,
5313 "%s[%d]: expected subject identifier of %d bytes, got %d\n",
5314 header, i, expected->rgCTLEntry[i].SubjectIdentifier.cbData,
5315 got->rgCTLEntry[i].SubjectIdentifier.cbData);
5316 if (expected->rgCTLEntry[i].SubjectIdentifier.cbData)
5317 ok(!memcmp(expected->rgCTLEntry[i].SubjectIdentifier.pbData,
5318 got->rgCTLEntry[i].SubjectIdentifier.pbData,
5319 expected->rgCTLEntry[i].SubjectIdentifier.cbData),
5320 "%s[%d]: unexpected subject identifier value\n",
5321 header, i);
5322 for (j = 0; j < expected->rgCTLEntry[i].cAttribute; j++)
5324 ok(!strcmp(expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5325 got->rgCTLEntry[i].rgAttribute[j].pszObjId),
5326 "%s[%d][%d]: expected attribute OID %s, got %s\n", header, i, j,
5327 expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5328 got->rgCTLEntry[i].rgAttribute[j].pszObjId);
5329 for (k = 0; k < expected->rgCTLEntry[i].rgAttribute[j].cValue; k++)
5331 ok(expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData ==
5332 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5333 "%s[%d][%d][%d]: expected value of %d bytes, got %d\n",
5334 header, i, j, k,
5335 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5336 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData);
5337 if (expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData)
5338 ok(!memcmp(
5339 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5340 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5341 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData),
5342 "%s[%d][%d][%d]: unexpected value\n",
5343 header, i, j, k);
5347 ok(expected->cExtension == got->cExtension,
5348 "%s: expected %d extensions, got %d\n", header, expected->cExtension,
5349 got->cExtension);
5350 for (i = 0; i < expected->cExtension; i++)
5352 ok(!strcmp(expected->rgExtension[i].pszObjId,
5353 got->rgExtension[i].pszObjId), "%s[%d]: expected %s, got %s\n",
5354 header, i, expected->rgExtension[i].pszObjId,
5355 got->rgExtension[i].pszObjId);
5356 ok(expected->rgExtension[i].fCritical == got->rgExtension[i].fCritical,
5357 "%s[%d]: expected fCritical = %d, got %d\n", header, i,
5358 expected->rgExtension[i].fCritical, got->rgExtension[i].fCritical);
5359 ok(expected->rgExtension[i].Value.cbData ==
5360 got->rgExtension[i].Value.cbData,
5361 "%s[%d]: expected extension value to have %d bytes, got %d\n",
5362 header, i, expected->rgExtension[i].Value.cbData,
5363 got->rgExtension[i].Value.cbData);
5364 if (expected->rgExtension[i].Value.cbData)
5365 ok(!memcmp(expected->rgExtension[i].Value.pbData,
5366 got->rgExtension[i].Value.pbData,
5367 expected->rgExtension[i].Value.cbData),
5368 "%s[%d]: unexpected extension value\n", header, i);
5372 static const BYTE signedCTL[] = {
5373 0x30,0x81,0xc7,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
5374 0x81,0xb9,0x30,0x81,0xb6,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
5375 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x28,0x06,0x09,0x2a,0x86,
5376 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x1b,0x04,0x19,0x30,0x17,0x30,0x00,
5377 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5378 0x30,0x5a,0x30,0x02,0x06,0x00,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
5379 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
5380 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
5381 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5382 0x00,0x04,0x40,0xca,0xd8,0x32,0xd1,0xbd,0x97,0x61,0x54,0xd6,0x80,0xcf,0x0d,
5383 0xbd,0xa2,0x42,0xc7,0xca,0x37,0x91,0x7d,0x9d,0xac,0x8c,0xdf,0x05,0x8a,0x39,
5384 0xc6,0x07,0xc1,0x37,0xe6,0xb9,0xd1,0x0d,0x26,0xec,0xa5,0xb0,0x8a,0x51,0x26,
5385 0x2b,0x4f,0x73,0x44,0x86,0x83,0x5e,0x2b,0x6e,0xcc,0xf8,0x1b,0x85,0x53,0xe9,
5386 0x7a,0x80,0x8f,0x6b,0x42,0x19,0x93 };
5387 static const BYTE signedCTLWithCTLInnerContent[] = {
5388 0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
5389 0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
5390 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
5391 0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
5392 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5393 0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
5394 0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
5395 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
5396 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
5397 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
5398 0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
5399 0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
5400 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
5401 0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5402 0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
5403 0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
5404 0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
5405 0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
5406 0x57,0x6c,0x0b,0x47,0xb8 };
5408 static void test_decodeCTL(DWORD dwEncoding)
5410 static char oid1[] = "1.2.3";
5411 static char oid2[] = "1.5.6";
5412 static BYTE nullData[] = { 5,0 };
5413 char *pOid1 = oid1;
5414 BOOL ret;
5415 BYTE *buf = NULL;
5416 DWORD size = 0;
5417 CTL_INFO info;
5418 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5419 CTL_ENTRY ctlEntry[2];
5420 CRYPT_ATTRIBUTE attr1, attr2;
5421 CRYPT_ATTR_BLOB value1, value2;
5423 memset(&info, 0, sizeof(info));
5424 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTL, sizeof(emptyCTL),
5425 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5426 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5427 if (buf)
5429 compareCTLInfo("empty CTL", &info, (CTL_INFO *)buf);
5430 LocalFree(buf);
5431 buf = NULL;
5433 info.dwVersion = 1;
5434 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTLWithVersion1,
5435 sizeof(emptyCTLWithVersion1), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
5436 &size);
5437 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5438 if (buf)
5440 compareCTLInfo("v1 CTL", &info, (CTL_INFO *)buf);
5441 LocalFree(buf);
5442 buf = NULL;
5444 info.dwVersion = 0;
5445 info.SubjectUsage.cUsageIdentifier = 1;
5446 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5447 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithUsageIdentifier,
5448 sizeof(ctlWithUsageIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5449 (BYTE *)&buf, &size);
5450 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5451 if (buf)
5453 compareCTLInfo("CTL with usage identifier", &info, (CTL_INFO *)buf);
5454 LocalFree(buf);
5455 buf = NULL;
5457 info.SubjectUsage.cUsageIdentifier = 0;
5458 info.ListIdentifier.cbData = sizeof(serialNum);
5459 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5460 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithListIdentifier,
5461 sizeof(ctlWithListIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5462 (BYTE *)&buf, &size);
5463 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5464 if (buf)
5466 compareCTLInfo("CTL with list identifier", &info, (CTL_INFO *)buf);
5467 LocalFree(buf);
5468 buf = NULL;
5470 info.ListIdentifier.cbData = 0;
5471 info.SequenceNumber.cbData = sizeof(serialNum);
5472 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5473 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithSequenceNumber,
5474 sizeof(ctlWithSequenceNumber), CRYPT_DECODE_ALLOC_FLAG, NULL,
5475 (BYTE *)&buf, &size);
5476 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5477 if (buf)
5479 compareCTLInfo("CTL with sequence number", &info, (CTL_INFO *)buf);
5480 LocalFree(buf);
5481 buf = NULL;
5483 info.SequenceNumber.cbData = 0;
5484 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5485 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisUpdate,
5486 sizeof(ctlWithThisUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5487 (BYTE *)&buf, &size);
5488 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5489 if (buf)
5491 compareCTLInfo("CTL with this update", &info, (CTL_INFO *)buf);
5492 LocalFree(buf);
5493 buf = NULL;
5495 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5496 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisAndNextUpdate,
5497 sizeof(ctlWithThisAndNextUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5498 (BYTE *)&buf, &size);
5499 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5500 if (buf)
5502 compareCTLInfo("CTL with this and next update", &info, (CTL_INFO *)buf);
5503 LocalFree(buf);
5504 buf = NULL;
5506 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5507 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5508 info.SubjectAlgorithm.pszObjId = oid2;
5509 info.SubjectAlgorithm.Parameters.cbData = sizeof(nullData);
5510 info.SubjectAlgorithm.Parameters.pbData = nullData;
5511 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithAlgId,
5512 sizeof(ctlWithAlgId), CRYPT_DECODE_ALLOC_FLAG, NULL,
5513 (BYTE *)&buf, &size);
5514 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5515 if (buf)
5517 compareCTLInfo("CTL with algorithm identifier", &info, (CTL_INFO *)buf);
5518 LocalFree(buf);
5519 buf = NULL;
5521 SetLastError(0xdeadbeef);
5522 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithBogusEntry,
5523 sizeof(ctlWithBogusEntry), CRYPT_DECODE_ALLOC_FLAG, NULL,
5524 (BYTE *)&buf, &size);
5525 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD || CRYPT_E_ASN1_CORRUPT),
5526 "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n",
5527 GetLastError());
5528 info.SubjectAlgorithm.Parameters.cbData = 0;
5529 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5530 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5531 info.SubjectAlgorithm.pszObjId = oid2;
5532 info.SubjectAlgorithm.pszObjId = NULL;
5533 value1.cbData = sizeof(emptySequence);
5534 value1.pbData = (LPBYTE)emptySequence;
5535 attr1.pszObjId = oid1;
5536 attr1.cValue = 1;
5537 attr1.rgValue = &value1;
5538 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5539 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5540 ctlEntry[0].cAttribute = 1;
5541 ctlEntry[0].rgAttribute = &attr1;
5542 info.cCTLEntry = 1;
5543 info.rgCTLEntry = ctlEntry;
5544 SetLastError(0xdeadbeef);
5545 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithOneEntry,
5546 sizeof(ctlWithOneEntry), CRYPT_DECODE_ALLOC_FLAG, NULL,
5547 (BYTE *)&buf, &size);
5548 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5549 if (buf)
5551 compareCTLInfo("CTL with one entry", &info, (CTL_INFO *)buf);
5552 LocalFree(buf);
5553 buf = NULL;
5555 value2.cbData = sizeof(encodedIPAddr);
5556 value2.pbData = (LPBYTE)encodedIPAddr;
5557 attr2.pszObjId = oid2;
5558 attr2.cValue = 1;
5559 attr2.rgValue = &value2;
5560 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5561 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5562 ctlEntry[1].cAttribute = 1;
5563 ctlEntry[1].rgAttribute = &attr2;
5564 info.cCTLEntry = 2;
5565 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithTwoEntries,
5566 sizeof(ctlWithTwoEntries), CRYPT_DECODE_ALLOC_FLAG, NULL,
5567 (BYTE *)&buf, &size);
5568 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5569 if (buf)
5571 compareCTLInfo("CTL with two entries", &info, (CTL_INFO *)buf);
5572 LocalFree(buf);
5573 buf = NULL;
5575 /* A signed CTL isn't decodable, even if the inner content is a CTL */
5576 SetLastError(0xdeadbeef);
5577 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, signedCTL,
5578 sizeof(signedCTL), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5579 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5580 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5581 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5582 GetLastError());
5583 SetLastError(0xdeadbeef);
5584 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL,
5585 signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent),
5586 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5587 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5588 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5589 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5590 GetLastError());
5593 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
5594 static const BYTE emptyPKCSContentInfoExtraBytes[] = { 0x30,0x04,0x06,0x02,0x2a,
5595 0x03,0,0,0,0,0,0 };
5596 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
5597 0xa0,0x01,0x01 };
5598 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
5599 0x03,0x02,0x01,0x01 };
5600 static BYTE bogusDER[] = { 1 };
5602 static void test_encodePKCSContentInfo(DWORD dwEncoding)
5604 BOOL ret;
5605 BYTE *buf = NULL;
5606 DWORD size = 0;
5607 CRYPT_CONTENT_INFO info = { 0 };
5608 char oid1[] = "1.2.3";
5610 if (0)
5612 /* Crashes on win9x */
5613 SetLastError(0xdeadbeef);
5614 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL,
5615 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5616 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5617 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5619 SetLastError(0xdeadbeef);
5620 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5621 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5622 ok(!ret && (GetLastError() == E_INVALIDARG ||
5623 GetLastError() == OSS_LIMITED /* Win9x */),
5624 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5625 info.pszObjId = oid1;
5626 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5627 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5628 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5629 if (buf)
5631 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size);
5632 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n");
5633 LocalFree(buf);
5635 info.Content.pbData = bogusDER;
5636 info.Content.cbData = sizeof(bogusDER);
5637 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5638 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5639 ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError());
5640 if (buf)
5642 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size);
5643 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n");
5644 LocalFree(buf);
5646 info.Content.pbData = (BYTE *)ints[0].encoded;
5647 info.Content.cbData = ints[0].encoded[1] + 2;
5648 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5649 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5650 if (buf)
5652 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size);
5653 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n");
5654 LocalFree(buf);
5658 static const BYTE indefiniteSignedPKCSContent[] = {
5659 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
5660 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
5661 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
5662 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
5663 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
5664 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
5665 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5666 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5667 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
5668 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5669 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5670 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
5671 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
5672 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
5673 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
5674 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
5675 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
5676 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
5677 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
5678 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5679 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5680 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
5681 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
5682 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
5683 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
5684 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
5685 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
5686 0x00,0x00,0x00,0x00,0x00,0x00 };
5688 static void test_decodePKCSContentInfo(DWORD dwEncoding)
5690 BOOL ret;
5691 LPBYTE buf = NULL;
5692 DWORD size = 0;
5693 CRYPT_CONTENT_INFO *info;
5695 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5696 emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo),
5697 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5698 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5699 if (buf)
5701 info = (CRYPT_CONTENT_INFO *)buf;
5703 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5704 info->pszObjId);
5705 ok(info->Content.cbData == 0, "Expected no data, got %d\n",
5706 info->Content.cbData);
5707 LocalFree(buf);
5709 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5710 emptyPKCSContentInfoExtraBytes, sizeof(emptyPKCSContentInfoExtraBytes),
5711 0, NULL, NULL, &size);
5712 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5713 SetLastError(0xdeadbeef);
5714 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5715 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo),
5716 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5717 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5718 * I doubt an app depends on that.
5720 ok((!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5721 GetLastError() == CRYPT_E_ASN1_CORRUPT)) || broken(ret),
5722 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5723 GetLastError());
5724 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5725 intPKCSContentInfo, sizeof(intPKCSContentInfo),
5726 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5727 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5728 if (buf)
5730 info = (CRYPT_CONTENT_INFO *)buf;
5732 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5733 info->pszObjId);
5734 ok(info->Content.cbData == ints[0].encoded[1] + 2,
5735 "Unexpected size %d\n", info->Content.cbData);
5736 ok(!memcmp(info->Content.pbData, ints[0].encoded,
5737 info->Content.cbData), "Unexpected value\n");
5738 LocalFree(buf);
5740 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5741 indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent),
5742 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5743 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5744 if (buf)
5746 info = (CRYPT_CONTENT_INFO *)buf;
5748 ok(!strcmp(info->pszObjId, szOID_RSA_signedData),
5749 "Expected %s, got %s\n", szOID_RSA_signedData, info->pszObjId);
5750 ok(info->Content.cbData == 392, "Expected 392, got %d\n",
5751 info->Content.cbData);
5752 LocalFree(buf);
5756 static const BYTE emptyPKCSAttr[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
5757 0x00 };
5758 static const BYTE bogusPKCSAttr[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
5759 0x01 };
5760 static const BYTE intPKCSAttr[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
5761 0x02,0x01,0x01 };
5763 static void test_encodePKCSAttribute(DWORD dwEncoding)
5765 CRYPT_ATTRIBUTE attr = { 0 };
5766 BOOL ret;
5767 LPBYTE buf = NULL;
5768 DWORD size = 0;
5769 CRYPT_ATTR_BLOB blob;
5770 char oid[] = "1.2.3";
5772 if (0)
5774 /* Crashes on win9x */
5775 SetLastError(0xdeadbeef);
5776 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, NULL,
5777 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5778 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5779 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5781 SetLastError(0xdeadbeef);
5782 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5783 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5784 ok(!ret && (GetLastError() == E_INVALIDARG ||
5785 GetLastError() == OSS_LIMITED /* Win9x */),
5786 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5787 attr.pszObjId = oid;
5788 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5789 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5790 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5791 if (buf)
5793 ok(size == sizeof(emptyPKCSAttr), "Unexpected size %d\n", size);
5794 ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n");
5795 LocalFree(buf);
5797 blob.cbData = sizeof(bogusDER);
5798 blob.pbData = bogusDER;
5799 attr.cValue = 1;
5800 attr.rgValue = &blob;
5801 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5802 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5803 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5804 if (buf)
5806 ok(size == sizeof(bogusPKCSAttr), "Unexpected size %d\n", size);
5807 ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n");
5808 LocalFree(buf);
5810 blob.pbData = (BYTE *)ints[0].encoded;
5811 blob.cbData = ints[0].encoded[1] + 2;
5812 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5813 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5814 if (buf)
5816 ok(size == sizeof(intPKCSAttr), "Unexpected size %d\n", size);
5817 ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n");
5818 LocalFree(buf);
5822 static void test_decodePKCSAttribute(DWORD dwEncoding)
5824 BOOL ret;
5825 LPBYTE buf = NULL;
5826 DWORD size = 0;
5827 CRYPT_ATTRIBUTE *attr;
5829 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5830 emptyPKCSAttr, sizeof(emptyPKCSAttr),
5831 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5832 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5833 if (buf)
5835 attr = (CRYPT_ATTRIBUTE *)buf;
5837 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5838 attr->pszObjId);
5839 ok(attr->cValue == 0, "Expected no value, got %d\n", attr->cValue);
5840 LocalFree(buf);
5842 SetLastError(0xdeadbeef);
5843 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5844 bogusPKCSAttr, sizeof(bogusPKCSAttr),
5845 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5846 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5847 * I doubt an app depends on that.
5849 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5850 GetLastError() == CRYPT_E_ASN1_CORRUPT || OSS_MORE_INPUT /* Win9x */),
5851 "Expected CRYPT_E_ASN1_EOD, CRYPT_E_ASN1_CORRUPT, or OSS_MORE_INPUT, got %x\n",
5852 GetLastError());
5853 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5854 intPKCSAttr, sizeof(intPKCSAttr),
5855 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5856 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5857 if (buf)
5859 attr = (CRYPT_ATTRIBUTE *)buf;
5861 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5862 attr->pszObjId);
5863 ok(attr->cValue == 1, "Expected 1 value, got %d\n", attr->cValue);
5864 ok(attr->rgValue[0].cbData == ints[0].encoded[1] + 2,
5865 "Unexpected size %d\n", attr->rgValue[0].cbData);
5866 ok(!memcmp(attr->rgValue[0].pbData, ints[0].encoded,
5867 attr->rgValue[0].cbData), "Unexpected value\n");
5868 LocalFree(buf);
5872 static const BYTE emptyPKCSAttributes[] = { 0x31,0x00 };
5873 static const BYTE singlePKCSAttributes[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
5874 0x2a,0x03,0x31,0x00 };
5875 static const BYTE doublePKCSAttributes[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
5876 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
5878 static void test_encodePKCSAttributes(DWORD dwEncoding)
5880 CRYPT_ATTRIBUTES attributes = { 0 };
5881 CRYPT_ATTRIBUTE attr[2] = { { 0 } };
5882 CRYPT_ATTR_BLOB blob;
5883 BOOL ret;
5884 LPBYTE buf = NULL;
5885 DWORD size = 0;
5886 char oid1[] = "1.2.3", oid2[] = "1.5.6";
5888 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5889 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5890 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5891 if (buf)
5893 ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %d\n", size);
5894 ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n");
5895 LocalFree(buf);
5897 attributes.cAttr = 1;
5898 attributes.rgAttr = attr;
5899 SetLastError(0xdeadbeef);
5900 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5901 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5902 ok(!ret && (GetLastError() == E_INVALIDARG ||
5903 GetLastError() == OSS_LIMITED /* Win9x */),
5904 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
5905 attr[0].pszObjId = oid1;
5906 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5907 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5908 if (buf)
5910 ok(size == sizeof(singlePKCSAttributes), "Unexpected size %d\n", size);
5911 ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n");
5912 LocalFree(buf);
5914 attr[1].pszObjId = oid2;
5915 attr[1].cValue = 1;
5916 attr[1].rgValue = &blob;
5917 blob.pbData = (BYTE *)ints[0].encoded;
5918 blob.cbData = ints[0].encoded[1] + 2;
5919 attributes.cAttr = 2;
5920 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5921 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5922 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5923 if (buf)
5925 ok(size == sizeof(doublePKCSAttributes), "Unexpected size %d\n", size);
5926 ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n");
5927 LocalFree(buf);
5931 static void test_decodePKCSAttributes(DWORD dwEncoding)
5933 BOOL ret;
5934 LPBYTE buf = NULL;
5935 DWORD size = 0;
5936 CRYPT_ATTRIBUTES *attributes;
5938 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5939 emptyPKCSAttributes, sizeof(emptyPKCSAttributes),
5940 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5941 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5942 if (buf)
5944 attributes = (CRYPT_ATTRIBUTES *)buf;
5945 ok(attributes->cAttr == 0, "Expected no attributes, got %d\n",
5946 attributes->cAttr);
5947 LocalFree(buf);
5949 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5950 singlePKCSAttributes, sizeof(singlePKCSAttributes),
5951 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5952 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5953 if (buf)
5955 attributes = (CRYPT_ATTRIBUTES *)buf;
5956 ok(attributes->cAttr == 1, "Expected 1 attribute, got %d\n",
5957 attributes->cAttr);
5958 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5959 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5960 ok(attributes->rgAttr[0].cValue == 0,
5961 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5962 LocalFree(buf);
5964 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5965 doublePKCSAttributes, sizeof(doublePKCSAttributes),
5966 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5967 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5968 if (buf)
5970 attributes = (CRYPT_ATTRIBUTES *)buf;
5971 ok(attributes->cAttr == 2, "Expected 2 attributes, got %d\n",
5972 attributes->cAttr);
5973 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5974 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5975 ok(attributes->rgAttr[0].cValue == 0,
5976 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5977 ok(!strcmp(attributes->rgAttr[1].pszObjId, "1.5.6"),
5978 "Expected 1.5.6, got %s\n", attributes->rgAttr[1].pszObjId);
5979 ok(attributes->rgAttr[1].cValue == 1,
5980 "Expected 1 attribute, got %d\n", attributes->rgAttr[1].cValue);
5981 ok(attributes->rgAttr[1].rgValue[0].cbData == ints[0].encoded[1] + 2,
5982 "Unexpected size %d\n", attributes->rgAttr[1].rgValue[0].cbData);
5983 ok(!memcmp(attributes->rgAttr[1].rgValue[0].pbData, ints[0].encoded,
5984 attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n");
5985 LocalFree(buf);
5989 static const BYTE singleCapability[] = {
5990 0x30,0x06,0x30,0x04,0x06,0x02,0x2d,0x06 };
5991 static const BYTE twoCapabilities[] = {
5992 0x30,0x0c,0x30,0x04,0x06,0x02,0x2d,0x06,0x30,0x04,0x06,0x02,0x2a,0x03 };
5993 static const BYTE singleCapabilitywithNULL[] = {
5994 0x30,0x08,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5996 static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding)
5998 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
5999 BOOL ret;
6000 LPBYTE buf = NULL;
6001 DWORD size = 0;
6002 CRYPT_SMIME_CAPABILITY capability[2];
6003 CRYPT_SMIME_CAPABILITIES capabilities;
6005 /* An empty capabilities is allowed */
6006 capabilities.cCapability = 0;
6007 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6008 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6009 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6010 if (buf)
6012 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
6013 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
6014 LocalFree(buf);
6016 /* A non-empty capabilities with an empty capability (lacking an OID) is
6017 * not allowed
6019 capability[0].pszObjId = NULL;
6020 capability[0].Parameters.cbData = 0;
6021 capabilities.cCapability = 1;
6022 capabilities.rgCapability = capability;
6023 SetLastError(0xdeadbeef);
6024 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6025 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6026 ok(!ret && (GetLastError() == E_INVALIDARG ||
6027 GetLastError() == OSS_LIMITED /* Win9x */),
6028 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6029 capability[0].pszObjId = oid1;
6030 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6031 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6032 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6033 if (buf)
6035 ok(size == sizeof(singleCapability), "unexpected size %d\n", size);
6036 ok(!memcmp(buf, singleCapability, size), "unexpected value\n");
6037 LocalFree(buf);
6039 capability[1].pszObjId = oid2;
6040 capability[1].Parameters.cbData = 0;
6041 capabilities.cCapability = 2;
6042 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6043 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6044 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6045 if (buf)
6047 ok(size == sizeof(twoCapabilities), "unexpected size %d\n", size);
6048 ok(!memcmp(buf, twoCapabilities, size), "unexpected value\n");
6049 LocalFree(buf);
6053 static void compareSMimeCapabilities(LPCSTR header,
6054 const CRYPT_SMIME_CAPABILITIES *expected, const CRYPT_SMIME_CAPABILITIES *got)
6056 DWORD i;
6058 ok(got->cCapability == expected->cCapability,
6059 "%s: expected %d capabilities, got %d\n", header, expected->cCapability,
6060 got->cCapability);
6061 for (i = 0; i < expected->cCapability; i++)
6063 ok(!strcmp(expected->rgCapability[i].pszObjId,
6064 got->rgCapability[i].pszObjId), "%s[%d]: expected %s, got %s\n",
6065 header, i, expected->rgCapability[i].pszObjId,
6066 got->rgCapability[i].pszObjId);
6067 ok(expected->rgCapability[i].Parameters.cbData ==
6068 got->rgCapability[i].Parameters.cbData,
6069 "%s[%d]: expected %d bytes, got %d\n", header, i,
6070 expected->rgCapability[i].Parameters.cbData,
6071 got->rgCapability[i].Parameters.cbData);
6072 if (expected->rgCapability[i].Parameters.cbData)
6073 ok(!memcmp(expected->rgCapability[i].Parameters.pbData,
6074 got->rgCapability[i].Parameters.pbData,
6075 expected->rgCapability[i].Parameters.cbData),
6076 "%s[%d]: unexpected value\n", header, i);
6080 static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding)
6082 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6083 BOOL ret;
6084 DWORD size = 0;
6085 CRYPT_SMIME_CAPABILITY capability[2];
6086 CRYPT_SMIME_CAPABILITIES capabilities, *ptr;
6088 SetLastError(0xdeadbeef);
6089 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6090 emptySequence, sizeof(emptySequence),
6091 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&ptr, &size);
6092 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6093 if (ret)
6095 capabilities.cCapability = 0;
6096 compareSMimeCapabilities("empty capabilities", &capabilities, ptr);
6097 LocalFree(ptr);
6099 SetLastError(0xdeadbeef);
6100 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6101 singleCapability, sizeof(singleCapability), CRYPT_DECODE_ALLOC_FLAG, NULL,
6102 (BYTE *)&ptr, &size);
6103 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6104 if (ret)
6106 capability[0].pszObjId = oid1;
6107 capability[0].Parameters.cbData = 0;
6108 capabilities.cCapability = 1;
6109 capabilities.rgCapability = capability;
6110 compareSMimeCapabilities("single capability", &capabilities, ptr);
6111 LocalFree(ptr);
6113 SetLastError(0xdeadbeef);
6114 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6115 singleCapabilitywithNULL, sizeof(singleCapabilitywithNULL),
6116 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&ptr, &size);
6117 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6118 if (ret)
6120 BYTE NULLparam[] = {0x05, 0x00};
6121 capability[0].pszObjId = oid1;
6122 capability[0].Parameters.cbData = 2;
6123 capability[0].Parameters.pbData = NULLparam;
6124 capabilities.cCapability = 1;
6125 capabilities.rgCapability = capability;
6126 compareSMimeCapabilities("single capability with NULL", &capabilities,
6127 ptr);
6128 LocalFree(ptr);
6130 SetLastError(0xdeadbeef);
6131 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6132 twoCapabilities, sizeof(twoCapabilities), CRYPT_DECODE_ALLOC_FLAG, NULL,
6133 (BYTE *)&ptr, &size);
6134 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6135 if (ret)
6137 capability[0].Parameters.cbData = 0;
6138 capability[1].pszObjId = oid2;
6139 capability[1].Parameters.cbData = 0;
6140 capabilities.cCapability = 2;
6141 compareSMimeCapabilities("two capabilities", &capabilities, ptr);
6142 LocalFree(ptr);
6146 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
6147 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
6148 0x67 };
6149 static const BYTE minimalPKCSSigner[] = {
6150 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6151 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6152 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6153 static const BYTE PKCSSignerWithSerial[] = {
6154 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6155 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6156 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
6157 0x00 };
6158 static const BYTE PKCSSignerWithHashAlgo[] = {
6159 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6160 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6161 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
6162 0x00,0x04,0x00 };
6163 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = {
6164 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6165 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6166 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6167 0x06,0x05,0x00,0x04,0x00 };
6168 static const BYTE PKCSSignerWithHash[] = {
6169 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6170 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6171 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6172 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
6173 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6174 static const BYTE PKCSSignerWithAuthAttr[] = {
6175 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6176 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6177 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
6178 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
6179 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
6180 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
6181 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6183 static void test_encodePKCSSignerInfo(DWORD dwEncoding)
6185 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6186 BOOL ret;
6187 LPBYTE buf = NULL;
6188 DWORD size = 0;
6189 CMSG_SIGNER_INFO info = { 0 };
6190 char oid_common_name[] = szOID_COMMON_NAME;
6191 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
6192 (LPBYTE)encodedCommonName };
6193 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
6195 SetLastError(0xdeadbeef);
6196 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6197 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6198 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6200 skip("no PKCS7_SIGNER_INFO encode support\n");
6201 return;
6203 ok(!ret && (GetLastError() == E_INVALIDARG ||
6204 GetLastError() == OSS_LIMITED /* Win9x */),
6205 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6206 /* To be encoded, a signer must have an issuer at least, and the encoding
6207 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
6208 * see decoding tests.)
6210 info.Issuer.cbData = sizeof(encodedCommonNameNoNull);
6211 info.Issuer.pbData = encodedCommonNameNoNull;
6212 SetLastError(0xdeadbeef);
6213 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6214 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6215 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6216 ok(!ret && GetLastError() == E_INVALIDARG,
6217 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6218 else
6220 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6221 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6222 if (buf)
6224 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6225 if (size == sizeof(minimalPKCSSigner))
6226 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6227 else
6228 ok(0, "Unexpected value\n");
6229 LocalFree(buf);
6232 info.SerialNumber.cbData = sizeof(serialNum);
6233 info.SerialNumber.pbData = (BYTE *)serialNum;
6234 SetLastError(0xdeadbeef);
6235 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6236 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6237 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6238 ok(!ret && GetLastError() == E_INVALIDARG,
6239 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6240 else
6242 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6243 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6244 if (buf)
6246 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6247 size);
6248 if (size == sizeof(PKCSSignerWithSerial))
6249 ok(!memcmp(buf, PKCSSignerWithSerial, size),
6250 "Unexpected value\n");
6251 else
6252 ok(0, "Unexpected value\n");
6253 LocalFree(buf);
6256 info.HashAlgorithm.pszObjId = oid1;
6257 SetLastError(0xdeadbeef);
6258 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6259 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6260 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6261 ok(!ret && GetLastError() == E_INVALIDARG,
6262 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6263 else
6265 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6266 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6267 if (buf)
6269 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6270 size);
6271 if (size == sizeof(PKCSSignerWithHashAlgo))
6272 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6273 "Unexpected value\n");
6274 else
6275 ok(0, "Unexpected value\n");
6276 LocalFree(buf);
6279 info.HashEncryptionAlgorithm.pszObjId = oid2;
6280 SetLastError(0xdeadbeef);
6281 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6282 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6283 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6284 ok(!ret && GetLastError() == E_INVALIDARG,
6285 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6286 else
6288 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6289 if (buf)
6291 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6292 "Unexpected size %d\n", size);
6293 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo))
6294 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6295 "Unexpected value\n");
6296 else
6297 ok(0, "Unexpected value\n");
6298 LocalFree(buf);
6301 info.EncryptedHash.cbData = sizeof(hash);
6302 info.EncryptedHash.pbData = (BYTE *)hash;
6303 SetLastError(0xdeadbeef);
6304 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6305 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6306 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6307 ok(!ret && GetLastError() == E_INVALIDARG,
6308 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6309 else
6311 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6312 if (buf)
6314 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6315 size);
6316 if (size == sizeof(PKCSSignerWithHash))
6317 ok(!memcmp(buf, PKCSSignerWithHash, size),
6318 "Unexpected value\n");
6319 else
6320 ok(0, "Unexpected value\n");
6321 LocalFree(buf);
6324 info.AuthAttrs.cAttr = 1;
6325 info.AuthAttrs.rgAttr = &attr;
6326 SetLastError(0xdeadbeef);
6327 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6328 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6329 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6330 ok(!ret && GetLastError() == E_INVALIDARG,
6331 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6332 else
6334 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6335 if (buf)
6337 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
6338 size);
6339 if (size == sizeof(PKCSSignerWithAuthAttr))
6340 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
6341 "Unexpected value\n");
6342 else
6343 ok(0, "Unexpected value\n");
6344 LocalFree(buf);
6349 static void test_decodePKCSSignerInfo(DWORD dwEncoding)
6351 BOOL ret;
6352 LPBYTE buf = NULL;
6353 DWORD size = 0;
6354 CMSG_SIGNER_INFO *info;
6356 /* A PKCS signer can't be decoded without a serial number. */
6357 SetLastError(0xdeadbeef);
6358 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6359 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6360 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6361 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
6362 GetLastError() == OSS_DATA_ERROR /* Win9x */),
6363 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %x\n",
6364 GetLastError());
6365 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6366 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6367 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6368 ok(ret || broken(GetLastError() == OSS_DATA_ERROR),
6369 "CryptDecodeObjectEx failed: %x\n", GetLastError());
6370 if (buf)
6372 info = (CMSG_SIGNER_INFO *)buf;
6373 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6374 info->dwVersion);
6375 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6376 "Unexpected size %d\n", info->Issuer.cbData);
6377 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6378 info->Issuer.cbData), "Unexpected value\n");
6379 ok(info->SerialNumber.cbData == sizeof(serialNum),
6380 "Unexpected size %d\n", info->SerialNumber.cbData);
6381 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6382 "Unexpected value\n");
6383 LocalFree(buf);
6385 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6386 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6387 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6388 if (buf)
6390 info = (CMSG_SIGNER_INFO *)buf;
6391 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6392 info->dwVersion);
6393 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6394 "Unexpected size %d\n", info->Issuer.cbData);
6395 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6396 info->Issuer.cbData), "Unexpected value\n");
6397 ok(info->SerialNumber.cbData == sizeof(serialNum),
6398 "Unexpected size %d\n", info->SerialNumber.cbData);
6399 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6400 "Unexpected value\n");
6401 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6402 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6403 LocalFree(buf);
6405 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6406 PKCSSignerWithHashAndEncryptionAlgo,
6407 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6408 NULL, (BYTE *)&buf, &size);
6409 if (buf)
6411 info = (CMSG_SIGNER_INFO *)buf;
6412 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6413 info->dwVersion);
6414 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6415 "Unexpected size %d\n", info->Issuer.cbData);
6416 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6417 info->Issuer.cbData), "Unexpected value\n");
6418 ok(info->SerialNumber.cbData == sizeof(serialNum),
6419 "Unexpected size %d\n", info->SerialNumber.cbData);
6420 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6421 "Unexpected value\n");
6422 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6423 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6424 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6425 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6426 LocalFree(buf);
6428 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6429 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6430 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6431 if (buf)
6433 info = (CMSG_SIGNER_INFO *)buf;
6434 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6435 info->dwVersion);
6436 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6437 "Unexpected size %d\n", info->Issuer.cbData);
6438 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6439 info->Issuer.cbData), "Unexpected value\n");
6440 ok(info->SerialNumber.cbData == sizeof(serialNum),
6441 "Unexpected size %d\n", info->SerialNumber.cbData);
6442 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6443 "Unexpected value\n");
6444 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6445 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6446 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6447 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6448 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6449 info->EncryptedHash.cbData);
6450 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6451 "Unexpected value\n");
6452 LocalFree(buf);
6454 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6455 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
6456 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6457 if (buf)
6459 info = (CMSG_SIGNER_INFO *)buf;
6460 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n",
6461 info->AuthAttrs.cAttr);
6462 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
6463 "Expected %s, got %s\n", szOID_COMMON_NAME,
6464 info->AuthAttrs.rgAttr[0].pszObjId);
6465 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
6466 info->AuthAttrs.rgAttr[0].cValue);
6467 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
6468 sizeof(encodedCommonName), "Unexpected size %d\n",
6469 info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
6470 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
6471 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
6472 LocalFree(buf);
6476 static const BYTE CMSSignerWithKeyId[] = {
6477 0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,
6478 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6480 static void test_encodeCMSSignerInfo(DWORD dwEncoding)
6482 BOOL ret;
6483 LPBYTE buf = NULL;
6484 DWORD size = 0;
6485 CMSG_CMS_SIGNER_INFO info = { 0 };
6486 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6488 SetLastError(0xdeadbeef);
6489 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6490 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6491 ok(!ret, "Expected failure, got %d\n", ret);
6492 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6494 skip("no CMS_SIGNER_INFO encode support\n");
6495 return;
6497 ok(GetLastError() == E_INVALIDARG,
6498 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6499 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6500 SetLastError(0xdeadbeef);
6501 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6502 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6503 ok(!ret, "Expected failure, got %d\n", ret);
6504 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6506 skip("no CMS_SIGNER_INFO encode support\n");
6507 return;
6509 ok(GetLastError() == E_INVALIDARG,
6510 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6511 /* To be encoded, a signer must have a valid cert ID, where a valid ID may
6512 * be a key id or a issuer serial number with at least the issuer set, and
6513 * the encoding must include PKCS_7_ASN_ENCODING.
6514 * (That isn't enough to be decoded, see decoding tests.)
6516 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6517 sizeof(encodedCommonNameNoNull);
6518 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6519 SetLastError(0xdeadbeef);
6520 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6521 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6522 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6523 ok(!ret && GetLastError() == E_INVALIDARG,
6524 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6525 else
6527 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6528 if (buf)
6530 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6531 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6532 LocalFree(buf);
6535 U(info.SignerId).IssuerSerialNumber.SerialNumber.cbData = sizeof(serialNum);
6536 U(info.SignerId).IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
6537 SetLastError(0xdeadbeef);
6538 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6539 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6540 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6541 ok(!ret && GetLastError() == E_INVALIDARG,
6542 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6543 else
6545 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6546 if (buf)
6548 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6549 size);
6550 ok(!memcmp(buf, PKCSSignerWithSerial, size), "Unexpected value\n");
6551 LocalFree(buf);
6554 info.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
6555 U(info.SignerId).KeyId.cbData = sizeof(serialNum);
6556 U(info.SignerId).KeyId.pbData = (BYTE *)serialNum;
6557 SetLastError(0xdeadbeef);
6558 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6559 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6560 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6561 ok(!ret && GetLastError() == E_INVALIDARG,
6562 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6563 else
6565 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6566 if (buf)
6568 ok(size == sizeof(CMSSignerWithKeyId), "Unexpected size %d\n",
6569 size);
6570 ok(!memcmp(buf, CMSSignerWithKeyId, size), "Unexpected value\n");
6571 LocalFree(buf);
6574 /* While a CERT_ID can have a hash type, that's not allowed in CMS, where
6575 * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed
6576 * (see RFC 3852, section 5.3.)
6578 info.SignerId.dwIdChoice = CERT_ID_SHA1_HASH;
6579 U(info.SignerId).HashId.cbData = sizeof(hash);
6580 U(info.SignerId).HashId.pbData = (BYTE *)hash;
6581 SetLastError(0xdeadbeef);
6582 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6583 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6584 ok(!ret && GetLastError() == E_INVALIDARG,
6585 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6586 /* Now with a hash algo */
6587 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6588 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6589 sizeof(encodedCommonNameNoNull);
6590 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6591 info.HashAlgorithm.pszObjId = oid1;
6592 SetLastError(0xdeadbeef);
6593 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6594 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6595 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6596 ok(!ret && GetLastError() == E_INVALIDARG,
6597 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6598 else
6600 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6601 if (buf)
6603 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6604 size);
6605 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6606 "Unexpected value\n");
6607 LocalFree(buf);
6610 info.HashEncryptionAlgorithm.pszObjId = oid2;
6611 SetLastError(0xdeadbeef);
6612 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6613 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6614 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6615 ok(!ret && GetLastError() == E_INVALIDARG,
6616 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6617 else
6619 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6620 if (buf)
6622 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6623 "Unexpected size %d\n", size);
6624 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6625 "Unexpected value\n");
6626 LocalFree(buf);
6629 info.EncryptedHash.cbData = sizeof(hash);
6630 info.EncryptedHash.pbData = (BYTE *)hash;
6631 SetLastError(0xdeadbeef);
6632 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6633 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6634 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6635 ok(!ret && GetLastError() == E_INVALIDARG,
6636 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6637 else
6639 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6640 if (buf)
6642 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6643 size);
6644 ok(!memcmp(buf, PKCSSignerWithHash, size), "Unexpected value\n");
6645 LocalFree(buf);
6650 static void test_decodeCMSSignerInfo(DWORD dwEncoding)
6652 BOOL ret;
6653 LPBYTE buf = NULL;
6654 DWORD size = 0;
6655 CMSG_CMS_SIGNER_INFO *info;
6656 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6658 /* A CMS signer can't be decoded without a serial number. */
6659 SetLastError(0xdeadbeef);
6660 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6661 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6662 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6663 ok(!ret, "expected failure\n");
6664 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6666 skip("no CMS_SIGNER_INFO decode support\n");
6667 return;
6669 ok(GetLastError() == CRYPT_E_ASN1_CORRUPT,
6670 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
6671 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6672 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6673 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6674 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6675 if (buf)
6677 info = (CMSG_CMS_SIGNER_INFO *)buf;
6678 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6679 info->dwVersion);
6680 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6681 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6682 info->SignerId.dwIdChoice);
6683 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6684 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6685 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6686 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6687 encodedCommonNameNoNull,
6688 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6689 "Unexpected value\n");
6690 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6691 sizeof(serialNum), "Unexpected size %d\n",
6692 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6693 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6694 serialNum, sizeof(serialNum)), "Unexpected value\n");
6695 LocalFree(buf);
6697 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6698 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6699 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6700 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6701 if (buf)
6703 info = (CMSG_CMS_SIGNER_INFO *)buf;
6704 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6705 info->dwVersion);
6706 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6707 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6708 info->SignerId.dwIdChoice);
6709 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6710 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6711 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6712 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6713 encodedCommonNameNoNull,
6714 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6715 "Unexpected value\n");
6716 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6717 sizeof(serialNum), "Unexpected size %d\n",
6718 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6719 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6720 serialNum, sizeof(serialNum)), "Unexpected value\n");
6721 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6722 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6723 LocalFree(buf);
6725 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6726 PKCSSignerWithHashAndEncryptionAlgo,
6727 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6728 NULL, (BYTE *)&buf, &size);
6729 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6730 if (buf)
6732 info = (CMSG_CMS_SIGNER_INFO *)buf;
6733 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6734 info->dwVersion);
6735 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6736 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6737 info->SignerId.dwIdChoice);
6738 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6739 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6740 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6741 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6742 encodedCommonNameNoNull,
6743 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6744 "Unexpected value\n");
6745 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6746 sizeof(serialNum), "Unexpected size %d\n",
6747 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6748 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6749 serialNum, sizeof(serialNum)), "Unexpected value\n");
6750 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6751 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6752 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6753 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6754 LocalFree(buf);
6756 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6757 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6758 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6759 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6760 if (buf)
6762 info = (CMSG_CMS_SIGNER_INFO *)buf;
6763 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6764 info->dwVersion);
6765 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6766 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6767 info->SignerId.dwIdChoice);
6768 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6769 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6770 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6771 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6772 encodedCommonNameNoNull,
6773 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6774 "Unexpected value\n");
6775 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6776 sizeof(serialNum), "Unexpected size %d\n",
6777 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6778 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6779 serialNum, sizeof(serialNum)), "Unexpected value\n");
6780 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6781 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6782 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6783 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6784 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6785 info->EncryptedHash.cbData);
6786 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6787 "Unexpected value\n");
6788 LocalFree(buf);
6790 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6791 CMSSignerWithKeyId, sizeof(CMSSignerWithKeyId),
6792 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6793 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6794 if (buf)
6796 info = (CMSG_CMS_SIGNER_INFO *)buf;
6797 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6798 info->dwVersion);
6799 ok(info->SignerId.dwIdChoice == CERT_ID_KEY_IDENTIFIER,
6800 "Expected CERT_ID_KEY_IDENTIFIER, got %d\n",
6801 info->SignerId.dwIdChoice);
6802 ok(U(info->SignerId).KeyId.cbData == sizeof(serialNum),
6803 "Unexpected size %d\n", U(info->SignerId).KeyId.cbData);
6804 ok(!memcmp(U(info->SignerId).KeyId.pbData, serialNum, sizeof(serialNum)),
6805 "Unexpected value\n");
6806 LocalFree(buf);
6810 static BYTE emptyDNSPermittedConstraints[] = {
6811 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
6812 static BYTE emptyDNSExcludedConstraints[] = {
6813 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
6814 static BYTE DNSExcludedConstraints[] = {
6815 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
6816 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6817 static BYTE permittedAndExcludedConstraints[] = {
6818 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6819 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
6820 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6821 static BYTE permittedAndExcludedWithMinConstraints[] = {
6822 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6823 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
6824 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6825 static BYTE permittedAndExcludedWithMinMaxConstraints[] = {
6826 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6827 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
6828 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6830 static void test_encodeNameConstraints(DWORD dwEncoding)
6832 BOOL ret;
6833 CERT_NAME_CONSTRAINTS_INFO constraints = { 0 };
6834 CERT_GENERAL_SUBTREE permitted = { { 0 } };
6835 CERT_GENERAL_SUBTREE excluded = { { 0 } };
6836 LPBYTE buf;
6837 DWORD size;
6839 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6840 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6841 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6843 skip("no X509_NAME_CONSTRAINTS encode support\n");
6844 return;
6846 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6847 if (ret)
6849 ok(size == sizeof(emptySequence), "Unexpected size\n");
6850 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
6851 LocalFree(buf);
6853 constraints.cPermittedSubtree = 1;
6854 constraints.rgPermittedSubtree = &permitted;
6855 SetLastError(0xdeadbeef);
6856 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6857 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6858 ok(!ret && GetLastError() == E_INVALIDARG,
6859 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6860 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
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(emptyDNSPermittedConstraints), "Unexpected size\n");
6867 ok(!memcmp(buf, emptyDNSPermittedConstraints, size),
6868 "Unexpected value\n");
6869 LocalFree(buf);
6871 constraints.cPermittedSubtree = 0;
6872 constraints.cExcludedSubtree = 1;
6873 constraints.rgExcludedSubtree = &excluded;
6874 excluded.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
6875 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6876 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6877 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6878 if (ret)
6880 ok(size == sizeof(emptyDNSExcludedConstraints), "Unexpected size\n");
6881 ok(!memcmp(buf, emptyDNSExcludedConstraints, size),
6882 "Unexpected value\n");
6883 LocalFree(buf);
6885 U(excluded.Base).pwszURL = (LPWSTR)url;
6886 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6887 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6888 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6889 if (ret)
6891 ok(size == sizeof(DNSExcludedConstraints), "Unexpected size\n");
6892 ok(!memcmp(buf, DNSExcludedConstraints, size),
6893 "Unexpected value\n");
6894 LocalFree(buf);
6896 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
6897 U(permitted.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6898 U(permitted.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6899 constraints.cPermittedSubtree = 1;
6900 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6901 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6902 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6903 if (ret)
6905 ok(size == sizeof(permittedAndExcludedConstraints),
6906 "Unexpected size\n");
6907 ok(!memcmp(buf, permittedAndExcludedConstraints, size),
6908 "Unexpected value\n");
6909 LocalFree(buf);
6911 permitted.dwMinimum = 5;
6912 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6913 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6914 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6915 if (ret)
6917 ok(size == sizeof(permittedAndExcludedWithMinConstraints),
6918 "Unexpected size\n");
6919 ok(!memcmp(buf, permittedAndExcludedWithMinConstraints, size),
6920 "Unexpected value\n");
6921 LocalFree(buf);
6923 permitted.fMaximum = TRUE;
6924 permitted.dwMaximum = 3;
6925 SetLastError(0xdeadbeef);
6926 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6927 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6928 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6929 if (ret)
6931 ok(size == sizeof(permittedAndExcludedWithMinMaxConstraints),
6932 "Unexpected size\n");
6933 ok(!memcmp(buf, permittedAndExcludedWithMinMaxConstraints, size),
6934 "Unexpected value\n");
6935 LocalFree(buf);
6939 struct EncodedNameConstraints
6941 CRYPT_DATA_BLOB encoded;
6942 CERT_NAME_CONSTRAINTS_INFO constraints;
6945 static CERT_GENERAL_SUBTREE emptyDNSSubtree = {
6946 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
6947 static CERT_GENERAL_SUBTREE DNSSubtree = {
6948 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
6949 static CERT_GENERAL_SUBTREE IPAddressSubtree = {
6950 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 0 };
6951 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree = {
6952 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, 0 };
6953 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree = {
6954 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, TRUE, 3 };
6956 struct EncodedNameConstraints encodedNameConstraints[] = {
6957 { { sizeof(emptySequence), (LPBYTE)emptySequence }, { 0 } },
6958 { { sizeof(emptyDNSPermittedConstraints), emptyDNSPermittedConstraints },
6959 { 1, &emptyDNSSubtree, 0, NULL } },
6960 { { sizeof(emptyDNSExcludedConstraints), emptyDNSExcludedConstraints },
6961 { 0, NULL, 1, &emptyDNSSubtree } },
6962 { { sizeof(DNSExcludedConstraints), DNSExcludedConstraints },
6963 { 0, NULL, 1, &DNSSubtree } },
6964 { { sizeof(permittedAndExcludedConstraints), permittedAndExcludedConstraints },
6965 { 1, &IPAddressSubtree, 1, &DNSSubtree } },
6966 { { sizeof(permittedAndExcludedWithMinConstraints),
6967 permittedAndExcludedWithMinConstraints },
6968 { 1, &IPAddressWithMinSubtree, 1, &DNSSubtree } },
6969 { { sizeof(permittedAndExcludedWithMinMaxConstraints),
6970 permittedAndExcludedWithMinMaxConstraints },
6971 { 1, &IPAddressWithMinMaxSubtree, 1, &DNSSubtree } },
6974 static void test_decodeNameConstraints(DWORD dwEncoding)
6976 BOOL ret;
6977 DWORD i;
6978 CERT_NAME_CONSTRAINTS_INFO *constraints;
6980 U(DNSSubtree.Base).pwszURL = (LPWSTR)url;
6981 U(IPAddressSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6982 U(IPAddressSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6983 U(IPAddressWithMinSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6984 U(IPAddressWithMinSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6985 U(IPAddressWithMinMaxSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6986 U(IPAddressWithMinMaxSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6987 for (i = 0;
6988 i < sizeof(encodedNameConstraints) / sizeof(encodedNameConstraints[0]);
6989 i++)
6991 DWORD size;
6993 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS,
6994 encodedNameConstraints[i].encoded.pbData,
6995 encodedNameConstraints[i].encoded.cbData,
6996 CRYPT_DECODE_ALLOC_FLAG, NULL, &constraints, &size);
6997 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6999 skip("no X509_NAME_CONSTRAINTS decode support\n");
7000 return;
7002 ok(ret, "%d: CryptDecodeObjectEx failed: %08x\n", i, GetLastError());
7003 if (ret)
7005 DWORD j;
7007 if (constraints->cPermittedSubtree !=
7008 encodedNameConstraints[i].constraints.cPermittedSubtree)
7009 fprintf(stderr, "%d: expected %d permitted, got %d\n", i,
7010 encodedNameConstraints[i].constraints.cPermittedSubtree,
7011 constraints->cPermittedSubtree);
7012 if (constraints->cPermittedSubtree ==
7013 encodedNameConstraints[i].constraints.cPermittedSubtree)
7015 for (j = 0; j < constraints->cPermittedSubtree; j++)
7017 compareAltNameEntry(&constraints->rgPermittedSubtree[j].Base,
7018 &encodedNameConstraints[i].constraints.rgPermittedSubtree[j].Base);
7021 if (constraints->cExcludedSubtree !=
7022 encodedNameConstraints[i].constraints.cExcludedSubtree)
7023 fprintf(stderr, "%d: expected %d excluded, got %d\n", i,
7024 encodedNameConstraints[i].constraints.cExcludedSubtree,
7025 constraints->cExcludedSubtree);
7026 if (constraints->cExcludedSubtree ==
7027 encodedNameConstraints[i].constraints.cExcludedSubtree)
7029 for (j = 0; j < constraints->cExcludedSubtree; j++)
7031 compareAltNameEntry(&constraints->rgExcludedSubtree[j].Base,
7032 &encodedNameConstraints[i].constraints.rgExcludedSubtree[j].Base);
7035 LocalFree(constraints);
7040 static WCHAR noticeText[] = { 'T','h','i','s',' ','i','s',' ','a',' ',
7041 'n','o','t','i','c','e',0 };
7042 static const BYTE noticeWithDisplayText[] = {
7043 0x30,0x22,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,0x00,
7044 0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,0x74,
7045 0x00,0x69,0x00,0x63,0x00,0x65
7047 static char org[] = "Wine";
7048 static int noticeNumbers[] = { 2,3 };
7049 static BYTE noticeWithReference[] = {
7050 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7051 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7052 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7053 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7056 static void test_encodePolicyQualifierUserNotice(DWORD dwEncoding)
7058 BOOL ret;
7059 LPBYTE buf;
7060 DWORD size;
7061 CERT_POLICY_QUALIFIER_USER_NOTICE notice;
7062 CERT_POLICY_QUALIFIER_NOTICE_REFERENCE reference;
7064 memset(&notice, 0, sizeof(notice));
7065 ret = pCryptEncodeObjectEx(dwEncoding,
7066 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, &notice, CRYPT_ENCODE_ALLOC_FLAG,
7067 NULL, &buf, &size);
7068 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7069 if (ret)
7071 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size);
7072 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
7073 LocalFree(buf);
7075 notice.pszDisplayText = noticeText;
7076 ret = pCryptEncodeObjectEx(dwEncoding,
7077 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, &notice, CRYPT_ENCODE_ALLOC_FLAG,
7078 NULL, &buf, &size);
7079 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7080 if (ret)
7082 ok(sizeof(noticeWithDisplayText) == size, "unexpected size %d\n", size);
7083 ok(!memcmp(buf, noticeWithDisplayText, size), "unexpected value\n");
7084 LocalFree(buf);
7086 reference.pszOrganization = org;
7087 reference.cNoticeNumbers = 2;
7088 reference.rgNoticeNumbers = noticeNumbers;
7089 notice.pNoticeReference = &reference;
7090 ret = pCryptEncodeObjectEx(dwEncoding,
7091 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, &notice, CRYPT_ENCODE_ALLOC_FLAG,
7092 NULL, &buf, &size);
7093 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7094 if (ret)
7096 ok(sizeof(noticeWithReference) == size, "unexpected size %d\n", size);
7097 ok(!memcmp(buf, noticeWithReference, size), "unexpected value\n");
7098 LocalFree(buf);
7102 static void test_decodePolicyQualifierUserNotice(DWORD dwEncoding)
7104 BOOL ret;
7105 CERT_POLICY_QUALIFIER_USER_NOTICE *notice;
7106 DWORD size;
7108 ret = pCryptDecodeObjectEx(dwEncoding,
7109 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7110 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7111 &notice, &size);
7112 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7113 if (ret)
7115 ok(notice->pszDisplayText == NULL, "unexpected display text\n");
7116 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7117 LocalFree(notice);
7119 ret = pCryptDecodeObjectEx(dwEncoding,
7120 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7121 noticeWithDisplayText, sizeof(noticeWithDisplayText),
7122 CRYPT_DECODE_ALLOC_FLAG, NULL, &notice, &size);
7123 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7124 if (ret)
7126 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7127 "unexpected display text\n");
7128 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7129 LocalFree(notice);
7131 ret = pCryptDecodeObjectEx(dwEncoding,
7132 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7133 noticeWithReference, sizeof(noticeWithReference),
7134 CRYPT_DECODE_ALLOC_FLAG, NULL, &notice, &size);
7135 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7136 if (ret)
7138 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7139 "unexpected display text\n");
7140 ok(notice->pNoticeReference != NULL, "expected a notice reference\n");
7141 if (notice->pNoticeReference)
7143 ok(!strcmp(notice->pNoticeReference->pszOrganization, org),
7144 "unexpected organization %s\n",
7145 notice->pNoticeReference->pszOrganization);
7146 ok(notice->pNoticeReference->cNoticeNumbers == 2,
7147 "expected 2 notice numbers, got %d\n",
7148 notice->pNoticeReference->cNoticeNumbers);
7149 ok(notice->pNoticeReference->rgNoticeNumbers[0] == noticeNumbers[0],
7150 "unexpected notice number %d\n",
7151 notice->pNoticeReference->rgNoticeNumbers[0]);
7152 ok(notice->pNoticeReference->rgNoticeNumbers[1] == noticeNumbers[1],
7153 "unexpected notice number %d\n",
7154 notice->pNoticeReference->rgNoticeNumbers[1]);
7156 LocalFree(notice);
7160 /* Free *pInfo with HeapFree */
7161 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
7163 BOOL ret;
7164 DWORD size = 0;
7165 HCRYPTKEY key;
7167 /* This crashes
7168 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
7170 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size);
7171 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7172 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7173 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL,
7174 &size);
7175 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7176 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7177 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL,
7178 NULL, &size);
7179 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7180 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7181 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7182 0, NULL, NULL, &size);
7183 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7184 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7185 /* Test with no key */
7186 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7187 0, NULL, NULL, &size);
7188 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n",
7189 GetLastError());
7190 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
7191 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
7192 if (ret)
7194 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
7195 NULL, 0, NULL, NULL, &size);
7196 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
7197 *pInfo = HeapAlloc(GetProcessHeap(), 0, size);
7198 if (*pInfo)
7200 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
7201 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size);
7202 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n",
7203 GetLastError());
7204 if (ret)
7206 /* By default (we passed NULL as the OID) the OID is
7207 * szOID_RSA_RSA.
7209 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA),
7210 "Expected %s, got %s\n", szOID_RSA_RSA,
7211 (*pInfo)->Algorithm.pszObjId);
7215 CryptDestroyKey(key);
7218 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
7219 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
7220 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
7221 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7222 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7223 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7224 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
7225 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
7226 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7227 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7228 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7229 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
7230 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
7231 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
7232 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
7233 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
7234 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
7235 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
7236 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
7237 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
7238 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
7239 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
7240 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
7241 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
7242 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
7244 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info)
7246 BOOL ret;
7247 HCRYPTKEY key;
7248 PCCERT_CONTEXT context;
7249 DWORD dwSize;
7250 ALG_ID ai;
7252 /* These crash
7253 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
7254 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
7255 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
7256 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7257 NULL);
7259 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key);
7260 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7261 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7262 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key);
7263 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7264 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7265 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL,
7266 &key);
7267 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7268 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7270 /* Export key with standard algorithm (CALG_RSA_KEYX) */
7271 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7272 &key);
7273 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7275 dwSize = sizeof(ai);
7276 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7277 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7278 if(ret)
7280 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7281 ok(ai == CALG_RSA_KEYX, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai);
7284 CryptDestroyKey(key);
7286 /* Repeat with forced algorithm */
7287 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, CALG_RSA_SIGN, 0, NULL,
7288 &key);
7289 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7291 dwSize = sizeof(ai);
7292 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7293 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7294 if(ret)
7296 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7297 ok(ai == CALG_RSA_SIGN, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai);
7300 CryptDestroyKey(key);
7302 /* Test importing a public key from a certificate context */
7303 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert,
7304 sizeof(expiredCert));
7305 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
7306 GetLastError());
7307 if (context)
7309 ok(!strcmp(szOID_RSA_RSA,
7310 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId),
7311 "Expected %s, got %s\n", szOID_RSA_RSA,
7312 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
7313 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING,
7314 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
7315 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7316 CryptDestroyKey(key);
7317 CertFreeCertificateContext(context);
7321 static const char cspName[] = "WineCryptTemp";
7323 static void testPortPublicKeyInfo(void)
7325 HCRYPTPROV csp;
7326 BOOL ret;
7327 PCERT_PUBLIC_KEY_INFO info = NULL;
7329 /* Just in case a previous run failed, delete this thing */
7330 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7331 CRYPT_DELETEKEYSET);
7332 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7333 CRYPT_NEWKEYSET);
7335 testExportPublicKey(csp, &info);
7336 testImportPublicKey(csp, info);
7338 HeapFree(GetProcessHeap(), 0, info);
7339 CryptReleaseContext(csp, 0);
7340 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7341 CRYPT_DELETEKEYSET);
7344 START_TEST(encode)
7346 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
7347 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING };
7348 HMODULE hCrypt32;
7349 DWORD i;
7351 hCrypt32 = GetModuleHandleA("crypt32.dll");
7352 pCryptDecodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptDecodeObjectEx");
7353 pCryptEncodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptEncodeObjectEx");
7354 if (!pCryptDecodeObjectEx || !pCryptEncodeObjectEx)
7356 skip("CryptDecodeObjectEx() is not available\n");
7357 return;
7360 for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++)
7362 test_encodeInt(encodings[i]);
7363 test_decodeInt(encodings[i]);
7364 test_encodeEnumerated(encodings[i]);
7365 test_decodeEnumerated(encodings[i]);
7366 test_encodeFiletime(encodings[i]);
7367 test_decodeFiletime(encodings[i]);
7368 test_encodeName(encodings[i]);
7369 test_decodeName(encodings[i]);
7370 test_encodeUnicodeName(encodings[i]);
7371 test_decodeUnicodeName(encodings[i]);
7372 test_encodeNameValue(encodings[i]);
7373 test_decodeNameValue(encodings[i]);
7374 test_encodeUnicodeNameValue(encodings[i]);
7375 test_decodeUnicodeNameValue(encodings[i]);
7376 test_encodeAltName(encodings[i]);
7377 test_decodeAltName(encodings[i]);
7378 test_encodeOctets(encodings[i]);
7379 test_decodeOctets(encodings[i]);
7380 test_encodeBits(encodings[i]);
7381 test_decodeBits(encodings[i]);
7382 test_encodeBasicConstraints(encodings[i]);
7383 test_decodeBasicConstraints(encodings[i]);
7384 test_encodeRsaPublicKey(encodings[i]);
7385 test_decodeRsaPublicKey(encodings[i]);
7386 test_encodeSequenceOfAny(encodings[i]);
7387 test_decodeSequenceOfAny(encodings[i]);
7388 test_encodeExtensions(encodings[i]);
7389 test_decodeExtensions(encodings[i]);
7390 test_encodePublicKeyInfo(encodings[i]);
7391 test_decodePublicKeyInfo(encodings[i]);
7392 test_encodeCertToBeSigned(encodings[i]);
7393 test_decodeCertToBeSigned(encodings[i]);
7394 test_encodeCert(encodings[i]);
7395 test_decodeCert(encodings[i]);
7396 test_encodeCRLDistPoints(encodings[i]);
7397 test_decodeCRLDistPoints(encodings[i]);
7398 test_encodeCRLIssuingDistPoint(encodings[i]);
7399 test_decodeCRLIssuingDistPoint(encodings[i]);
7400 test_encodeCRLToBeSigned(encodings[i]);
7401 test_decodeCRLToBeSigned(encodings[i]);
7402 test_encodeEnhancedKeyUsage(encodings[i]);
7403 test_decodeEnhancedKeyUsage(encodings[i]);
7404 test_encodeAuthorityKeyId(encodings[i]);
7405 test_decodeAuthorityKeyId(encodings[i]);
7406 test_encodeAuthorityKeyId2(encodings[i]);
7407 test_decodeAuthorityKeyId2(encodings[i]);
7408 test_encodeAuthorityInfoAccess(encodings[i]);
7409 test_decodeAuthorityInfoAccess(encodings[i]);
7410 test_encodeCTL(encodings[i]);
7411 test_decodeCTL(encodings[i]);
7412 test_encodePKCSContentInfo(encodings[i]);
7413 test_decodePKCSContentInfo(encodings[i]);
7414 test_encodePKCSAttribute(encodings[i]);
7415 test_decodePKCSAttribute(encodings[i]);
7416 test_encodePKCSAttributes(encodings[i]);
7417 test_decodePKCSAttributes(encodings[i]);
7418 test_encodePKCSSMimeCapabilities(encodings[i]);
7419 test_decodePKCSSMimeCapabilities(encodings[i]);
7420 test_encodePKCSSignerInfo(encodings[i]);
7421 test_decodePKCSSignerInfo(encodings[i]);
7422 test_encodeCMSSignerInfo(encodings[i]);
7423 test_decodeCMSSignerInfo(encodings[i]);
7424 test_encodeNameConstraints(encodings[i]);
7425 test_decodeNameConstraints(encodings[i]);
7426 test_encodePolicyQualifierUserNotice(encodings[i]);
7427 test_decodePolicyQualifierUserNotice(encodings[i]);
7429 testPortPublicKeyInfo();