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
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
*);
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
[] = {
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
)
93 CRYPT_INTEGER_BLOB blob
;
96 /* CryptEncodeObjectEx with NULL bufSize crashes..
97 ret = pCryptEncodeObjectEx(3, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
100 /* check bogus encoding */
101 ret
= pCryptEncodeObjectEx(0, X509_INTEGER
, &ints
[0].val
, 0, NULL
, NULL
,
103 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
104 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
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
,
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());
126 ok(buf
[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
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
);
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());
145 ok(buf
[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
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
);
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());
169 ok(buf
[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
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");
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());
192 ok(buf
[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
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");
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 };
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
,
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
, &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
, &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",
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
,
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
, &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");
261 ok(!memcmp(buf
, &ints
[i
].val
, bufSize
), "Expected %d, got %d\n",
262 ints
[i
].val
, *(int *)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
,
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
, &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");
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
),
286 ok(!memcmp(blob
->pbData
, bigInts
[i
].decoded
, blob
->cbData
),
287 "Unexpected value\n");
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
,
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
, &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");
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
),
311 ok(!memcmp(blob
->pbData
, bigUInts
[i
].val
, blob
->cbData
),
312 "Unexpected value\n");
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
, &buf
, &bufSize
);
319 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
322 ok(*(int *)buf
== 1, "Expected 1, got %d\n", *(int *)buf
);
325 /* check with extra bytes at the end */
326 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_INTEGER
, extraBytes
,
327 sizeof(extraBytes
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
328 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
331 ok(*(int *)buf
== 1, "Expected 1, got %d\n", *(int *)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, &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
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
, &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
364 static const struct encodedInt enums
[] = {
369 /* X509_CRL_REASON_CODE is also an enumerated type, but it's #defined to
372 static const LPCSTR enumeratedTypes
[] = { X509_ENUMERATED
,
373 szOID_CRL_REASON_CODE
};
375 static void test_encodeEnumerated(DWORD dwEncoding
)
379 for (i
= 0; i
< sizeof(enumeratedTypes
) / sizeof(enumeratedTypes
[0]); i
++)
381 for (j
= 0; j
< sizeof(enums
) / sizeof(enums
[0]); j
++)
387 ret
= pCryptEncodeObjectEx(dwEncoding
, enumeratedTypes
[i
],
388 &enums
[j
].val
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
,
390 ok(ret
, "CryptEncodeObjectEx failed: %d\n", GetLastError());
394 "Got unexpected type %d for enumerated (expected 0xa)\n",
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",
408 static void test_decodeEnumerated(DWORD dwEncoding
)
412 for (i
= 0; i
< sizeof(enumeratedTypes
) / sizeof(enumeratedTypes
[0]); i
++)
414 for (j
= 0; j
< sizeof(enums
) / sizeof(enums
[0]); j
++)
417 DWORD bufSize
= sizeof(int);
420 ret
= pCryptDecodeObjectEx(dwEncoding
, enumeratedTypes
[i
],
421 enums
[j
].encoded
, enums
[j
].encoded
[1] + 2, 0, NULL
,
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",
432 struct encodedFiletime
435 const BYTE
*encodedTime
;
438 static void testTimeEncoding(DWORD dwEncoding
, LPCSTR structType
,
439 const struct encodedFiletime
*time
)
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
, &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(),
458 ok(buf
!= NULL
, "Expected an allocated buffer\n");
461 ok(buf
[0] == time
->encodedTime
[0],
462 "Expected type 0x%02x, got 0x%02x\n", time
->encodedTime
[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");
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
)
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
);
486 static const char *printFileTime(const FILETIME
*ft
)
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
);
497 static void compareTime(const SYSTEMTIME
*expected
, const FILETIME
*got
)
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
)
524 DWORD size
= sizeof(ft
);
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(),
539 compareTime(&time
->sysTime
, &ft
);
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",
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
)
565 for (i
= 0; i
< sizeof(times
) / sizeof(times
[0]); i
++)
567 testTimeEncoding(dwEncoding
, X509_CHOICE_OF_TIME
, ×
[i
]);
568 testTimeEncoding(dwEncoding
, PKCS_UTC_TIME
, ×
[i
]);
569 testTimeEncoding(dwEncoding
, szOID_RSA_signingTime
, ×
[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",
635 FILETIME ft1
= { 0 }, ft2
= { 0 };
638 /* Check bogus length with non-NULL buffer */
639 ret
= SystemTimeToFileTime(×
[0].sysTime
, &ft1
);
640 ok(ret
, "SystemTimeToFileTime failed: %d\n", GetLastError());
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());
647 for (i
= 0; i
< sizeof(times
) / sizeof(times
[0]); i
++)
649 testTimeDecoding(dwEncoding
, X509_CHOICE_OF_TIME
, ×
[i
]);
650 testTimeDecoding(dwEncoding
, PKCS_UTC_TIME
, ×
[i
]);
651 testTimeDecoding(dwEncoding
, szOID_RSA_signingTime
, ×
[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
++)
662 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CHOICE_OF_TIME
,
663 bogusTimes
[i
], bogusTimes
[i
][1] + 2, 0, NULL
, &ft1
, &size
);
664 ok((!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
665 GetLastError() == OSS_DATA_ERROR
/* Win9x */)) ||
666 broken(ret
), /* Win9x and NT4 for bin38 */
667 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
672 static const char commonName
[] = "Juan Lang";
673 static const char surName
[] = "Lang";
675 static const BYTE emptySequence
[] = { 0x30, 0 };
676 static const BYTE emptyRDNs
[] = { 0x30, 0x02, 0x31, 0 };
677 static const BYTE twoRDNs
[] = {
678 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
679 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
680 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0};
681 static const BYTE encodedTwoRDNs
[] = {
682 0x30,0x2e,0x31,0x2c,0x30,0x2a,0x06,0x03,0x55,0x04,0x03,0x30,0x23,0x31,0x21,
683 0x30,0x0c,0x06,0x03,0x55,0x04,0x04,0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,
684 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
688 static const BYTE us
[] = { 0x55, 0x53 };
689 static const BYTE minnesota
[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x73, 0x6f,
691 static const BYTE minneapolis
[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x61, 0x70,
692 0x6f, 0x6c, 0x69, 0x73 };
693 static const BYTE codeweavers
[] = { 0x43, 0x6f, 0x64, 0x65, 0x57, 0x65, 0x61,
694 0x76, 0x65, 0x72, 0x73 };
695 static const BYTE wine
[] = { 0x57, 0x69, 0x6e, 0x65, 0x20, 0x44, 0x65, 0x76,
696 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74 };
697 static const BYTE localhostAttr
[] = { 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
699 static const BYTE aric
[] = { 0x61, 0x72, 0x69, 0x63, 0x40, 0x63, 0x6f, 0x64,
700 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d };
702 #define RDNA(arr) oid_ ## arr, CERT_RDN_PRINTABLE_STRING, { sizeof(arr), (LPBYTE)arr }
703 #define RDNIA5(arr) oid_ ## arr, CERT_RDN_IA5_STRING, { sizeof(arr), (LPBYTE)arr }
705 static CHAR oid_us
[] = "2.5.4.6",
706 oid_minnesota
[] = "2.5.4.8",
707 oid_minneapolis
[] = "2.5.4.7",
708 oid_codeweavers
[] = "2.5.4.10",
709 oid_wine
[] = "2.5.4.11",
710 oid_localhostAttr
[] = "2.5.4.3",
711 oid_aric
[] = "1.2.840.113549.1.9.1";
712 static CERT_RDN_ATTR rdnAttrs
[] = { { RDNA(us
) },
714 { RDNA(minneapolis
) },
715 { RDNA(codeweavers
) },
717 { RDNA(localhostAttr
) },
719 static CERT_RDN_ATTR decodedRdnAttrs
[] = { { RDNA(us
) },
720 { RDNA(localhostAttr
) },
722 { RDNA(minneapolis
) },
723 { RDNA(codeweavers
) },
730 static const BYTE encodedRDNAttrs
[] = {
731 0x30,0x81,0x96,0x31,0x81,0x93,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
732 0x53,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x68,
733 0x6f,0x73,0x74,0x30,0x10,0x06,0x03,0x55,0x04,0x08,0x13,0x09,0x4d,0x69,0x6e,0x6e,
734 0x65,0x73,0x6f,0x74,0x61,0x30,0x12,0x06,0x03,0x55,0x04,0x07,0x13,0x0b,0x4d,0x69,
735 0x6e,0x6e,0x65,0x61,0x70,0x6f,0x6c,0x69,0x73,0x30,0x12,0x06,0x03,0x55,0x04,0x0a,
736 0x13,0x0b,0x43,0x6f,0x64,0x65,0x57,0x65,0x61,0x76,0x65,0x72,0x73,0x30,0x17,0x06,
737 0x03,0x55,0x04,0x0b,0x13,0x10,0x57,0x69,0x6e,0x65,0x20,0x44,0x65,0x76,0x65,0x6c,
738 0x6f,0x70,0x6d,0x65,0x6e,0x74,0x30,0x21,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
739 0x01,0x09,0x01,0x16,0x14,0x61,0x72,0x69,0x63,0x40,0x63,0x6f,0x64,0x65,0x77,0x65,
740 0x61,0x76,0x65,0x72,0x73,0x2e,0x63,0x6f,0x6d
743 static void test_encodeName(DWORD dwEncoding
)
745 CERT_RDN_ATTR attrs
[2];
748 static CHAR oid_common_name
[] = szOID_COMMON_NAME
,
749 oid_sur_name
[] = szOID_SUR_NAME
;
756 /* Test with NULL pvStructInfo (crashes on win9x) */
757 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, NULL
,
758 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
759 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
760 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
762 /* Test with empty CERT_NAME_INFO */
765 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
766 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
767 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
770 ok(!memcmp(buf
, emptySequence
, sizeof(emptySequence
)),
771 "Got unexpected encoding for empty name\n");
776 /* Test with bogus CERT_RDN (crashes on win9x) */
778 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
779 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
780 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
781 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
783 /* Test with empty CERT_RDN */
785 rdn
.rgRDNAttr
= NULL
;
788 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
789 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
790 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
793 ok(!memcmp(buf
, emptyRDNs
, sizeof(emptyRDNs
)),
794 "Got unexpected encoding for empty RDN array\n");
799 /* Test with bogus attr array (crashes on win9x) */
801 rdn
.rgRDNAttr
= NULL
;
802 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
803 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
804 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
805 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
807 /* oddly, a bogus OID is accepted by Windows XP; not testing.
808 attrs[0].pszObjId = "bogus";
809 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
810 attrs[0].Value.cbData = sizeof(commonName);
811 attrs[0].Value.pbData = commonName;
813 rdn.rgRDNAttr = attrs;
814 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
815 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
816 ok(!ret, "Expected failure, got success\n");
818 /* Check with two CERT_RDN_ATTRs. Note DER encoding forces the order of
819 * the encoded attributes to be swapped.
821 attrs
[0].pszObjId
= oid_common_name
;
822 attrs
[0].dwValueType
= CERT_RDN_PRINTABLE_STRING
;
823 attrs
[0].Value
.cbData
= sizeof(commonName
);
824 attrs
[0].Value
.pbData
= (BYTE
*)commonName
;
825 attrs
[1].pszObjId
= oid_sur_name
;
826 attrs
[1].dwValueType
= CERT_RDN_PRINTABLE_STRING
;
827 attrs
[1].Value
.cbData
= sizeof(surName
);
828 attrs
[1].Value
.pbData
= (BYTE
*)surName
;
830 rdn
.rgRDNAttr
= attrs
;
831 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
832 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
833 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
836 ok(!memcmp(buf
, twoRDNs
, sizeof(twoRDNs
)),
837 "Got unexpected encoding for two RDN array\n");
840 /* A name can be "encoded" with previously encoded RDN attrs. */
841 attrs
[0].dwValueType
= CERT_RDN_ENCODED_BLOB
;
842 attrs
[0].Value
.pbData
= (LPBYTE
)twoRDNs
;
843 attrs
[0].Value
.cbData
= sizeof(twoRDNs
);
845 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
846 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
847 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
850 ok(size
== sizeof(encodedTwoRDNs
), "Unexpected size %d\n", size
);
851 ok(!memcmp(buf
, encodedTwoRDNs
, size
),
852 "Unexpected value for re-encoded two RDN array\n");
855 /* CERT_RDN_ANY_TYPE is too vague for X509_NAMEs, check the return */
857 attrs
[0].dwValueType
= CERT_RDN_ANY_TYPE
;
858 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
859 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
860 ok(!ret
&& GetLastError() == E_INVALIDARG
,
861 "Expected E_INVALIDARG, got %08x\n", GetLastError());
862 /* Test a more complex name */
863 rdn
.cRDNAttr
= sizeof(rdnAttrs
) / sizeof(rdnAttrs
[0]);
864 rdn
.rgRDNAttr
= rdnAttrs
;
869 ret
= pCryptEncodeObjectEx(X509_ASN_ENCODING
, X509_NAME
, &info
,
870 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
871 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
874 ok(size
== sizeof(encodedRDNAttrs
), "Wrong size %d\n", size
);
875 ok(!memcmp(buf
, encodedRDNAttrs
, size
), "Unexpected value\n");
880 static WCHAR commonNameW
[] = { 'J','u','a','n',' ','L','a','n','g',0 };
881 static WCHAR surNameW
[] = { 'L','a','n','g',0 };
883 static const BYTE twoRDNsNoNull
[] = {
884 0x30,0x21,0x31,0x1f,0x30,0x0b,0x06,0x03,0x55,0x04,0x04,0x13,0x04,0x4c,0x61,
885 0x6e,0x67,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,
886 0x20,0x4c,0x61,0x6e,0x67 };
887 static const BYTE anyType
[] = {
888 0x30,0x2f,0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x1e,0x24,0x23,0x30,
889 0x21,0x31,0x0c,0x30,0x03,0x06,0x04,0x55,0x13,0x04,0x4c,0x05,0x6e,0x61,0x00,
890 0x67,0x11,0x30,0x03,0x06,0x04,0x55,0x13,0x03,0x4a,0x0a,0x61,0x75,0x20,0x6e,
891 0x61,0x4c,0x67,0x6e };
893 static void test_encodeUnicodeName(DWORD dwEncoding
)
895 CERT_RDN_ATTR attrs
[2];
898 static CHAR oid_common_name
[] = szOID_COMMON_NAME
,
899 oid_sur_name
[] = szOID_SUR_NAME
;
906 /* Test with NULL pvStructInfo (crashes on win9x) */
907 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, NULL
,
908 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
909 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
910 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
912 /* Test with empty CERT_NAME_INFO */
915 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, &info
,
916 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
917 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
920 ok(!memcmp(buf
, emptySequence
, sizeof(emptySequence
)),
921 "Got unexpected encoding for empty name\n");
924 /* Check with one CERT_RDN_ATTR, that has an invalid character for the
925 * encoding (the NULL).
927 attrs
[0].pszObjId
= oid_common_name
;
928 attrs
[0].dwValueType
= CERT_RDN_PRINTABLE_STRING
;
929 attrs
[0].Value
.cbData
= sizeof(commonNameW
);
930 attrs
[0].Value
.pbData
= (BYTE
*)commonNameW
;
932 rdn
.rgRDNAttr
= attrs
;
935 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, &info
,
936 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
937 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING
,
938 "Expected CRYPT_E_INVALID_PRINTABLE_STRING, got %08x\n", GetLastError());
939 ok(size
== 9, "Unexpected error index %08x\n", size
);
940 /* Check with two NULL-terminated CERT_RDN_ATTRs. Note DER encoding
941 * forces the order of the encoded attributes to be swapped.
943 attrs
[0].pszObjId
= oid_common_name
;
944 attrs
[0].dwValueType
= CERT_RDN_PRINTABLE_STRING
;
945 attrs
[0].Value
.cbData
= 0;
946 attrs
[0].Value
.pbData
= (BYTE
*)commonNameW
;
947 attrs
[1].pszObjId
= oid_sur_name
;
948 attrs
[1].dwValueType
= CERT_RDN_PRINTABLE_STRING
;
949 attrs
[1].Value
.cbData
= 0;
950 attrs
[1].Value
.pbData
= (BYTE
*)surNameW
;
952 rdn
.rgRDNAttr
= attrs
;
955 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, &info
,
956 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
957 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
960 ok(!memcmp(buf
, twoRDNsNoNull
, sizeof(twoRDNsNoNull
)),
961 "Got unexpected encoding for two RDN array\n");
964 /* A name can be "encoded" with previously encoded RDN attrs. */
965 attrs
[0].dwValueType
= CERT_RDN_ENCODED_BLOB
;
966 attrs
[0].Value
.pbData
= (LPBYTE
)twoRDNs
;
967 attrs
[0].Value
.cbData
= sizeof(twoRDNs
);
969 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, &info
,
970 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
971 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
974 ok(size
== sizeof(encodedTwoRDNs
), "Unexpected size %d\n", size
);
975 ok(!memcmp(buf
, encodedTwoRDNs
, size
),
976 "Unexpected value for re-encoded two RDN array\n");
979 /* Unicode names infer the type for CERT_RDN_ANY_TYPE */
981 attrs
[0].dwValueType
= CERT_RDN_ANY_TYPE
;
982 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, &info
,
983 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
984 todo_wine
ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
987 ok(size
== sizeof(anyType
), "Unexpected size %d\n", size
);
988 ok(!memcmp(buf
, anyType
, size
), "Unexpected value\n");
993 static void compareNameValues(const CERT_NAME_VALUE
*expected
,
994 const CERT_NAME_VALUE
*got
)
996 if (expected
->dwValueType
== CERT_RDN_UTF8_STRING
&&
997 got
->dwValueType
== CERT_RDN_ENCODED_BLOB
)
999 win_skip("Can't handle CERT_RDN_UTF8_STRING\n");
1003 ok(got
->dwValueType
== expected
->dwValueType
,
1004 "Expected string type %d, got %d\n", expected
->dwValueType
,
1006 ok(got
->Value
.cbData
== expected
->Value
.cbData
||
1007 got
->Value
.cbData
== expected
->Value
.cbData
- sizeof(WCHAR
) /* Win8 */,
1008 "String type %d: unexpected data size, got %d, expected %d\n",
1009 expected
->dwValueType
, got
->Value
.cbData
, expected
->Value
.cbData
);
1010 if (got
->Value
.cbData
&& got
->Value
.pbData
)
1011 ok(!memcmp(got
->Value
.pbData
, expected
->Value
.pbData
,
1012 min(got
->Value
.cbData
, expected
->Value
.cbData
)),
1013 "String type %d: unexpected value\n", expected
->dwValueType
);
1016 static void compareRDNAttrs(const CERT_RDN_ATTR
*expected
,
1017 const CERT_RDN_ATTR
*got
)
1019 if (expected
->pszObjId
&& strlen(expected
->pszObjId
))
1021 ok(got
->pszObjId
!= NULL
, "Expected OID %s, got NULL\n",
1022 expected
->pszObjId
);
1025 ok(!strcmp(got
->pszObjId
, expected
->pszObjId
),
1026 "Got unexpected OID %s, expected %s\n", got
->pszObjId
,
1027 expected
->pszObjId
);
1030 compareNameValues((const CERT_NAME_VALUE
*)&expected
->dwValueType
,
1031 (const CERT_NAME_VALUE
*)&got
->dwValueType
);
1034 static void compareRDNs(const CERT_RDN
*expected
, const CERT_RDN
*got
)
1036 ok(got
->cRDNAttr
== expected
->cRDNAttr
,
1037 "Expected %d RDN attrs, got %d\n", expected
->cRDNAttr
, got
->cRDNAttr
);
1042 for (i
= 0; i
< got
->cRDNAttr
; i
++)
1043 compareRDNAttrs(&expected
->rgRDNAttr
[i
], &got
->rgRDNAttr
[i
]);
1047 static void compareNames(const CERT_NAME_INFO
*expected
,
1048 const CERT_NAME_INFO
*got
)
1050 ok(got
->cRDN
== expected
->cRDN
, "Expected %d RDNs, got %d\n",
1051 expected
->cRDN
, got
->cRDN
);
1056 for (i
= 0; i
< got
->cRDN
; i
++)
1057 compareRDNs(&expected
->rgRDN
[i
], &got
->rgRDN
[i
]);
1061 static const BYTE emptyIndefiniteSequence
[] = { 0x30,0x80,0x00,0x00 };
1062 static const BYTE twoRDNsExtraBytes
[] = {
1063 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
1064 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1065 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0,0,0,0,0,0};
1067 static void test_decodeName(DWORD dwEncoding
)
1073 CERT_NAME_INFO info
= { 1, &rdn
};
1075 /* test empty name */
1077 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME
, emptySequence
,
1078 emptySequence
[1] + 2,
1079 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1081 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1082 /* Interestingly, in Windows, if cRDN is 0, rgRGN may not be NULL. My
1083 * decoder works the same way, so only test the count.
1087 ok(bufSize
== sizeof(CERT_NAME_INFO
), "Wrong bufSize %d\n", bufSize
);
1088 ok(((CERT_NAME_INFO
*)buf
)->cRDN
== 0,
1089 "Expected 0 RDNs in empty info, got %d\n",
1090 ((CERT_NAME_INFO
*)buf
)->cRDN
);
1093 /* test empty name with indefinite-length encoding */
1094 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME
, emptyIndefiniteSequence
,
1095 sizeof(emptyIndefiniteSequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1097 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1100 ok(bufSize
== sizeof(CERT_NAME_INFO
), "Wrong bufSize %d\n", bufSize
);
1101 ok(((CERT_NAME_INFO
*)buf
)->cRDN
== 0,
1102 "Expected 0 RDNs in empty info, got %d\n",
1103 ((CERT_NAME_INFO
*)buf
)->cRDN
);
1106 /* test empty RDN */
1108 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME
, emptyRDNs
,
1110 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1112 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1115 CERT_NAME_INFO
*info
= (CERT_NAME_INFO
*)buf
;
1117 ok(bufSize
== sizeof(CERT_NAME_INFO
) + sizeof(CERT_RDN
) &&
1118 info
->cRDN
== 1 && info
->rgRDN
&& info
->rgRDN
[0].cRDNAttr
== 0,
1119 "Got unexpected value for empty RDN\n");
1122 /* test two RDN attrs */
1124 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME
, twoRDNs
,
1126 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1128 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1131 static CHAR oid_sur_name
[] = szOID_SUR_NAME
,
1132 oid_common_name
[] = szOID_COMMON_NAME
;
1134 CERT_RDN_ATTR attrs
[] = {
1135 { oid_sur_name
, CERT_RDN_PRINTABLE_STRING
, { sizeof(surName
),
1136 (BYTE
*)surName
} },
1137 { oid_common_name
, CERT_RDN_PRINTABLE_STRING
, { sizeof(commonName
),
1138 (BYTE
*)commonName
} },
1141 rdn
.cRDNAttr
= sizeof(attrs
) / sizeof(attrs
[0]);
1142 rdn
.rgRDNAttr
= attrs
;
1143 compareNames(&info
, (CERT_NAME_INFO
*)buf
);
1146 /* test that two RDN attrs with extra bytes succeeds */
1148 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME
, twoRDNsExtraBytes
,
1149 sizeof(twoRDNsExtraBytes
), 0, NULL
, NULL
, &bufSize
);
1150 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1151 /* And, a slightly more complicated name */
1154 ret
= pCryptDecodeObjectEx(X509_ASN_ENCODING
, X509_NAME
, encodedRDNAttrs
,
1155 sizeof(encodedRDNAttrs
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1156 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1159 rdn
.cRDNAttr
= sizeof(decodedRdnAttrs
) / sizeof(decodedRdnAttrs
[0]);
1160 rdn
.rgRDNAttr
= decodedRdnAttrs
;
1161 compareNames(&info
, (CERT_NAME_INFO
*)buf
);
1166 static void test_decodeUnicodeName(DWORD dwEncoding
)
1172 CERT_NAME_INFO info
= { 1, &rdn
};
1174 /* test empty name */
1176 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, emptySequence
,
1177 emptySequence
[1] + 2,
1178 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1180 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1183 ok(bufSize
== sizeof(CERT_NAME_INFO
),
1184 "Got wrong bufSize %d\n", bufSize
);
1185 ok(((CERT_NAME_INFO
*)buf
)->cRDN
== 0,
1186 "Expected 0 RDNs in empty info, got %d\n",
1187 ((CERT_NAME_INFO
*)buf
)->cRDN
);
1190 /* test empty RDN */
1192 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, emptyRDNs
,
1194 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1196 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1199 CERT_NAME_INFO
*info
= (CERT_NAME_INFO
*)buf
;
1201 ok(bufSize
== sizeof(CERT_NAME_INFO
) + sizeof(CERT_RDN
) &&
1202 info
->cRDN
== 1 && info
->rgRDN
&& info
->rgRDN
[0].cRDNAttr
== 0,
1203 "Got unexpected value for empty RDN\n");
1206 /* test two RDN attrs */
1208 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, twoRDNsNoNull
,
1209 sizeof(twoRDNsNoNull
),
1210 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1212 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1215 static CHAR oid_sur_name
[] = szOID_SUR_NAME
,
1216 oid_common_name
[] = szOID_COMMON_NAME
;
1218 CERT_RDN_ATTR attrs
[] = {
1219 { oid_sur_name
, CERT_RDN_PRINTABLE_STRING
,
1220 { lstrlenW(surNameW
) * sizeof(WCHAR
), (BYTE
*)surNameW
} },
1221 { oid_common_name
, CERT_RDN_PRINTABLE_STRING
,
1222 { lstrlenW(commonNameW
) * sizeof(WCHAR
), (BYTE
*)commonNameW
} },
1225 rdn
.cRDNAttr
= sizeof(attrs
) / sizeof(attrs
[0]);
1226 rdn
.rgRDNAttr
= attrs
;
1227 compareNames(&info
, (CERT_NAME_INFO
*)buf
);
1232 struct EncodedNameValue
1234 CERT_NAME_VALUE value
;
1235 const BYTE
*encoded
;
1239 static const char bogusIA5
[] = "\x80";
1240 static const char bogusPrintable
[] = "~";
1241 static const char bogusNumeric
[] = "A";
1242 static const BYTE bin42
[] = { 0x16,0x02,0x80,0x00 };
1243 static const BYTE bin43
[] = { 0x13,0x02,0x7e,0x00 };
1244 static const BYTE bin44
[] = { 0x12,0x02,0x41,0x00 };
1245 static BYTE octetCommonNameValue
[] = {
1246 0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1247 static BYTE numericCommonNameValue
[] = {
1248 0x12,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1249 static BYTE printableCommonNameValue
[] = {
1250 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1251 static BYTE t61CommonNameValue
[] = {
1252 0x14,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1253 static BYTE videotexCommonNameValue
[] = {
1254 0x15,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1255 static BYTE ia5CommonNameValue
[] = {
1256 0x16,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1257 static BYTE graphicCommonNameValue
[] = {
1258 0x19,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1259 static BYTE visibleCommonNameValue
[] = {
1260 0x1a,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1261 static BYTE generalCommonNameValue
[] = {
1262 0x1b,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1263 static BYTE bmpCommonNameValue
[] = {
1264 0x1e,0x14,0x00,0x4a,0x00,0x75,0x00,0x61,0x00,0x6e,0x00,0x20,0x00,0x4c,0x00,
1265 0x61,0x00,0x6e,0x00,0x67,0x00,0x00 };
1266 static BYTE utf8CommonNameValue
[] = {
1267 0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1268 static char embedded_null
[] = "foo\0com";
1269 static BYTE ia5EmbeddedNull
[] = {
1270 0x16,0x07,0x66,0x6f,0x6f,0x00,0x63,0x6f,0x6d };
1272 static struct EncodedNameValue nameValues
[] = {
1273 { { CERT_RDN_OCTET_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1274 octetCommonNameValue
, sizeof(octetCommonNameValue
) },
1275 { { CERT_RDN_NUMERIC_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1276 numericCommonNameValue
, sizeof(numericCommonNameValue
) },
1277 { { CERT_RDN_PRINTABLE_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1278 printableCommonNameValue
, sizeof(printableCommonNameValue
) },
1279 { { CERT_RDN_T61_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1280 t61CommonNameValue
, sizeof(t61CommonNameValue
) },
1281 { { CERT_RDN_VIDEOTEX_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1282 videotexCommonNameValue
, sizeof(videotexCommonNameValue
) },
1283 { { CERT_RDN_IA5_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1284 ia5CommonNameValue
, sizeof(ia5CommonNameValue
) },
1285 { { CERT_RDN_GRAPHIC_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1286 graphicCommonNameValue
, sizeof(graphicCommonNameValue
) },
1287 { { CERT_RDN_VISIBLE_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1288 visibleCommonNameValue
, sizeof(visibleCommonNameValue
) },
1289 { { CERT_RDN_GENERAL_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1290 generalCommonNameValue
, sizeof(generalCommonNameValue
) },
1291 { { CERT_RDN_BMP_STRING
, { sizeof(commonNameW
), (BYTE
*)commonNameW
} },
1292 bmpCommonNameValue
, sizeof(bmpCommonNameValue
) },
1293 { { CERT_RDN_UTF8_STRING
, { sizeof(commonNameW
), (BYTE
*)commonNameW
} },
1294 utf8CommonNameValue
, sizeof(utf8CommonNameValue
) },
1295 /* The following tests succeed under Windows, but really should fail,
1296 * they contain characters that are illegal for the encoding. I'm
1297 * including them to justify my lazy encoding.
1299 { { CERT_RDN_IA5_STRING
, { sizeof(bogusIA5
), (BYTE
*)bogusIA5
} }, bin42
,
1301 { { CERT_RDN_PRINTABLE_STRING
, { sizeof(bogusPrintable
),
1302 (BYTE
*)bogusPrintable
} }, bin43
, sizeof(bin43
) },
1303 { { CERT_RDN_NUMERIC_STRING
, { sizeof(bogusNumeric
), (BYTE
*)bogusNumeric
} },
1304 bin44
, sizeof(bin44
) },
1306 /* This is kept separate, because the decoding doesn't return to the original
1309 static struct EncodedNameValue embeddedNullNameValue
= {
1310 { CERT_RDN_IA5_STRING
, { sizeof(embedded_null
) - 1, (BYTE
*)embedded_null
} },
1311 ia5EmbeddedNull
, sizeof(ia5EmbeddedNull
) };
1313 static void test_encodeNameValue(DWORD dwEncoding
)
1318 CERT_NAME_VALUE value
= { 0, { 0, NULL
} };
1320 value
.dwValueType
= CERT_RDN_ENCODED_BLOB
;
1321 value
.Value
.pbData
= printableCommonNameValue
;
1322 value
.Value
.cbData
= sizeof(printableCommonNameValue
);
1323 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_VALUE
, &value
,
1324 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1325 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1328 ok(size
== sizeof(printableCommonNameValue
), "Unexpected size %d\n",
1330 ok(!memcmp(buf
, printableCommonNameValue
, size
),
1331 "Unexpected encoding\n");
1334 for (i
= 0; i
< sizeof(nameValues
) / sizeof(nameValues
[0]); i
++)
1336 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_VALUE
,
1337 &nameValues
[i
].value
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1338 ok(ret
|| broken(GetLastError() == OSS_PDU_MISMATCH
) /* NT4/Win9x */,
1339 "Type %d: CryptEncodeObjectEx failed: %08x\n",
1340 nameValues
[i
].value
.dwValueType
, GetLastError());
1343 ok(size
== nameValues
[i
].encodedSize
,
1344 "Expected size %d, got %d\n", nameValues
[i
].encodedSize
, size
);
1345 ok(!memcmp(buf
, nameValues
[i
].encoded
, size
),
1346 "Got unexpected encoding\n");
1350 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_VALUE
,
1351 &embeddedNullNameValue
.value
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1352 ok(ret
|| broken(GetLastError() == OSS_PDU_MISMATCH
) /* NT4/Win9x */,
1353 "Type %d: CryptEncodeObjectEx failed: %08x\n",
1354 embeddedNullNameValue
.value
.dwValueType
, GetLastError());
1357 ok(size
== embeddedNullNameValue
.encodedSize
,
1358 "Expected size %d, got %d\n", embeddedNullNameValue
.encodedSize
, size
);
1359 ok(!memcmp(buf
, embeddedNullNameValue
.encoded
, size
),
1360 "Got unexpected encoding\n");
1365 static void test_decodeNameValue(DWORD dwEncoding
)
1372 for (i
= 0; i
< sizeof(nameValues
) / sizeof(nameValues
[0]); i
++)
1374 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME_VALUE
,
1375 nameValues
[i
].encoded
, nameValues
[i
].encoded
[1] + 2,
1376 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1378 ok(ret
, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
1379 nameValues
[i
].value
.dwValueType
, GetLastError());
1382 compareNameValues(&nameValues
[i
].value
,
1383 (const CERT_NAME_VALUE
*)buf
);
1387 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME_VALUE
,
1388 embeddedNullNameValue
.encoded
, embeddedNullNameValue
.encodedSize
,
1389 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1391 /* Some Windows versions disallow name values with embedded NULLs, so
1392 * either success or failure is acceptable.
1396 CERT_NAME_VALUE rdnEncodedValue
= { CERT_RDN_ENCODED_BLOB
,
1397 { sizeof(ia5EmbeddedNull
), ia5EmbeddedNull
} };
1398 CERT_NAME_VALUE embeddedNullValue
= { CERT_RDN_IA5_STRING
,
1399 { sizeof(embedded_null
) - 1, (BYTE
*)embedded_null
} };
1400 const CERT_NAME_VALUE
*got
= (const CERT_NAME_VALUE
*)buf
,
1403 /* Some Windows versions decode name values with embedded NULLs,
1404 * others leave them encoded, even with the same version of crypt32.
1407 ok(got
->dwValueType
== CERT_RDN_ENCODED_BLOB
||
1408 got
->dwValueType
== CERT_RDN_IA5_STRING
,
1409 "Expected CERT_RDN_ENCODED_BLOB or CERT_RDN_IA5_STRING, got %d\n",
1411 if (got
->dwValueType
== CERT_RDN_ENCODED_BLOB
)
1412 expected
= &rdnEncodedValue
;
1413 else if (got
->dwValueType
== CERT_RDN_IA5_STRING
)
1414 expected
= &embeddedNullValue
;
1417 ok(got
->Value
.cbData
== expected
->Value
.cbData
,
1418 "String type %d: unexpected data size, got %d, expected %d\n",
1419 got
->dwValueType
, got
->Value
.cbData
, expected
->Value
.cbData
);
1420 if (got
->Value
.cbData
&& got
->Value
.pbData
)
1421 ok(!memcmp(got
->Value
.pbData
, expected
->Value
.pbData
,
1422 min(got
->Value
.cbData
, expected
->Value
.cbData
)),
1423 "String type %d: unexpected value\n", expected
->dwValueType
);
1429 static const BYTE emptyURL
[] = { 0x30, 0x02, 0x86, 0x00 };
1430 static const BYTE emptyURLExtraBytes
[] = { 0x30, 0x02, 0x86, 0x00, 0, 0, 0 };
1431 static const WCHAR url
[] = { 'h','t','t','p',':','/','/','w','i','n','e',
1432 'h','q','.','o','r','g',0 };
1433 static const BYTE encodedURL
[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74,
1434 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e,
1436 static const WCHAR nihongoURL
[] = { 'h','t','t','p',':','/','/',0x226f,
1438 static const WCHAR dnsName
[] = { 'w','i','n','e','h','q','.','o','r','g',0 };
1439 static const BYTE encodedDnsName
[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69,
1440 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
1441 static const BYTE localhost
[] = { 127, 0, 0, 1 };
1442 static const BYTE encodedIPAddr
[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00,
1444 static const unsigned char encodedCommonName
[] = {
1445 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0};
1446 static const BYTE encodedOidName
[] = { 0x30,0x04,0x88,0x02,0x2a,0x03 };
1447 static const BYTE encodedDirectoryName
[] = {
1448 0x30,0x19,0xa4,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1449 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1451 static void test_encodeAltName(DWORD dwEncoding
)
1453 CERT_ALT_NAME_INFO info
= { 0 };
1454 CERT_ALT_NAME_ENTRY entry
= { 0 };
1458 char oid
[] = "1.2.3";
1460 /* Test with empty info */
1461 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1462 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1465 ok(size
== sizeof(emptySequence
), "Wrong size %d\n", size
);
1466 ok(!memcmp(buf
, emptySequence
, size
), "Unexpected value\n");
1469 /* Test with an empty entry */
1471 info
.rgAltEntry
= &entry
;
1472 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1473 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1474 ok(!ret
&& GetLastError() == E_INVALIDARG
,
1475 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1476 /* Test with an empty pointer */
1477 entry
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
1478 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1479 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1482 ok(size
== sizeof(emptyURL
), "Wrong size %d\n", size
);
1483 ok(!memcmp(buf
, emptyURL
, size
), "Unexpected value\n");
1486 /* Test with a real URL */
1487 U(entry
).pwszURL
= (LPWSTR
)url
;
1488 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1489 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1492 ok(size
== sizeof(encodedURL
), "Wrong size %d\n", size
);
1493 ok(!memcmp(buf
, encodedURL
, size
), "Unexpected value\n");
1496 /* Now with the URL containing an invalid IA5 char */
1497 U(entry
).pwszURL
= (LPWSTR
)nihongoURL
;
1498 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1499 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1500 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_IA5_STRING
,
1501 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
1502 /* The first invalid character is at index 7 */
1503 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size
) == 7,
1504 "Expected invalid char at index 7, got %d\n",
1505 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size
));
1506 /* Now with the URL missing a scheme */
1507 U(entry
).pwszURL
= (LPWSTR
)dnsName
;
1508 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1509 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1510 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1513 /* This succeeds, but it shouldn't, so don't worry about conforming */
1516 /* Now with a DNS name */
1517 entry
.dwAltNameChoice
= CERT_ALT_NAME_DNS_NAME
;
1518 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1519 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1520 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1523 ok(size
== sizeof(encodedDnsName
), "Wrong size %d\n", size
);
1524 ok(!memcmp(buf
, encodedDnsName
, size
), "Unexpected value\n");
1527 /* Test with an IP address */
1528 entry
.dwAltNameChoice
= CERT_ALT_NAME_IP_ADDRESS
;
1529 U(entry
).IPAddress
.cbData
= sizeof(localhost
);
1530 U(entry
).IPAddress
.pbData
= (LPBYTE
)localhost
;
1531 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1532 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1535 ok(size
== sizeof(encodedIPAddr
), "Wrong size %d\n", size
);
1536 ok(!memcmp(buf
, encodedIPAddr
, size
), "Unexpected value\n");
1540 entry
.dwAltNameChoice
= CERT_ALT_NAME_REGISTERED_ID
;
1541 U(entry
).pszRegisteredID
= oid
;
1542 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1543 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1546 ok(size
== sizeof(encodedOidName
), "Wrong size %d\n", size
);
1547 ok(!memcmp(buf
, encodedOidName
, size
), "Unexpected value\n");
1550 /* Test with directory name */
1551 entry
.dwAltNameChoice
= CERT_ALT_NAME_DIRECTORY_NAME
;
1552 U(entry
).DirectoryName
.cbData
= sizeof(encodedCommonName
);
1553 U(entry
).DirectoryName
.pbData
= (LPBYTE
)encodedCommonName
;
1554 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1555 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1558 ok(size
== sizeof(encodedDirectoryName
), "Wrong size %d\n", size
);
1559 ok(!memcmp(buf
, encodedDirectoryName
, size
), "Unexpected value\n");
1564 static void test_decodeAltName(DWORD dwEncoding
)
1566 static const BYTE unimplementedType
[] = { 0x30, 0x06, 0x85, 0x04, 0x7f,
1568 static const BYTE bogusType
[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00,
1570 static const BYTE dns_embedded_null
[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f,
1571 0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 };
1572 static const BYTE dns_embedded_bell
[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f,
1573 0x6f,0x2e,0x63,0x6f,0x6d,0x07,0x62,0x61,0x64,0x64,0x69,0x65 };
1574 static const BYTE url_embedded_null
[] = { 0x30,0x10,0x86,0x0e,0x66,0x6f,
1575 0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 };
1579 CERT_ALT_NAME_INFO
*info
;
1581 /* Test some bogus ones first */
1582 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1583 unimplementedType
, sizeof(unimplementedType
), CRYPT_DECODE_ALLOC_FLAG
,
1584 NULL
, &buf
, &bufSize
);
1585 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_BADTAG
||
1586 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
1587 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
1589 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1590 bogusType
, sizeof(bogusType
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
,
1592 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
1593 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
1594 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
1596 /* Now expected cases */
1597 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, emptySequence
,
1598 emptySequence
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1599 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1602 info
= (CERT_ALT_NAME_INFO
*)buf
;
1604 ok(info
->cAltEntry
== 0, "Expected 0 entries, got %d\n",
1608 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, emptyURL
,
1609 emptyURL
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1610 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1613 info
= (CERT_ALT_NAME_INFO
*)buf
;
1615 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1617 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_URL
,
1618 "Expected CERT_ALT_NAME_URL, got %d\n",
1619 info
->rgAltEntry
[0].dwAltNameChoice
);
1620 ok(U(info
->rgAltEntry
[0]).pwszURL
== NULL
|| !*U(info
->rgAltEntry
[0]).pwszURL
,
1621 "Expected empty URL\n");
1624 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1625 emptyURLExtraBytes
, sizeof(emptyURLExtraBytes
), 0, NULL
, NULL
, &bufSize
);
1626 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1627 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, encodedURL
,
1628 encodedURL
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1629 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1632 info
= (CERT_ALT_NAME_INFO
*)buf
;
1634 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1636 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_URL
,
1637 "Expected CERT_ALT_NAME_URL, got %d\n",
1638 info
->rgAltEntry
[0].dwAltNameChoice
);
1639 ok(!lstrcmpW(U(info
->rgAltEntry
[0]).pwszURL
, url
), "Unexpected URL\n");
1642 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, encodedDnsName
,
1643 encodedDnsName
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1644 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1647 info
= (CERT_ALT_NAME_INFO
*)buf
;
1649 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1651 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_DNS_NAME
,
1652 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1653 info
->rgAltEntry
[0].dwAltNameChoice
);
1654 ok(!lstrcmpW(U(info
->rgAltEntry
[0]).pwszDNSName
, dnsName
),
1655 "Unexpected DNS name\n");
1658 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, encodedIPAddr
,
1659 encodedIPAddr
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1660 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1663 info
= (CERT_ALT_NAME_INFO
*)buf
;
1665 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1667 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_IP_ADDRESS
,
1668 "Expected CERT_ALT_NAME_IP_ADDRESS, got %d\n",
1669 info
->rgAltEntry
[0].dwAltNameChoice
);
1670 ok(U(info
->rgAltEntry
[0]).IPAddress
.cbData
== sizeof(localhost
),
1671 "Unexpected IP address length %d\n",
1672 U(info
->rgAltEntry
[0]).IPAddress
.cbData
);
1673 ok(!memcmp(U(info
->rgAltEntry
[0]).IPAddress
.pbData
, localhost
,
1674 sizeof(localhost
)), "Unexpected IP address value\n");
1677 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, encodedOidName
,
1678 sizeof(encodedOidName
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1679 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1682 info
= (CERT_ALT_NAME_INFO
*)buf
;
1684 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1686 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_REGISTERED_ID
,
1687 "Expected CERT_ALT_NAME_REGISTERED_ID, got %d\n",
1688 info
->rgAltEntry
[0].dwAltNameChoice
);
1689 ok(!strcmp(U(info
->rgAltEntry
[0]).pszRegisteredID
, "1.2.3"),
1690 "Expected OID 1.2.3, got %s\n", U(info
->rgAltEntry
[0]).pszRegisteredID
);
1693 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1694 encodedDirectoryName
, sizeof(encodedDirectoryName
),
1695 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1696 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1699 info
= (CERT_ALT_NAME_INFO
*)buf
;
1701 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1703 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_DIRECTORY_NAME
,
1704 "Expected CERT_ALT_NAME_DIRECTORY_NAME, got %d\n",
1705 info
->rgAltEntry
[0].dwAltNameChoice
);
1706 ok(U(info
->rgAltEntry
[0]).DirectoryName
.cbData
==
1707 sizeof(encodedCommonName
), "Unexpected directory name length %d\n",
1708 U(info
->rgAltEntry
[0]).DirectoryName
.cbData
);
1709 ok(!memcmp(U(info
->rgAltEntry
[0]).DirectoryName
.pbData
,
1710 encodedCommonName
, sizeof(encodedCommonName
)),
1711 "Unexpected directory name value\n");
1714 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1715 dns_embedded_null
, sizeof(dns_embedded_null
), CRYPT_DECODE_ALLOC_FLAG
,
1716 NULL
, &buf
, &bufSize
);
1717 /* Fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned about the
1718 * particular failure, just that it doesn't decode.
1719 * It succeeds on (broken) Windows versions that haven't addressed
1720 * embedded NULLs in alternate names.
1722 ok(!ret
|| broken(ret
), "expected failure\n");
1723 /* An embedded bell character is allowed, however. */
1724 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1725 dns_embedded_bell
, sizeof(dns_embedded_bell
), CRYPT_DECODE_ALLOC_FLAG
,
1726 NULL
, &buf
, &bufSize
);
1727 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1730 info
= (CERT_ALT_NAME_INFO
*)buf
;
1732 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1734 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_DNS_NAME
,
1735 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1736 info
->rgAltEntry
[0].dwAltNameChoice
);
1739 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1740 url_embedded_null
, sizeof(dns_embedded_null
), CRYPT_DECODE_ALLOC_FLAG
,
1741 NULL
, &buf
, &bufSize
);
1742 /* Again, fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned
1743 * about the particular failure, just that it doesn't decode.
1744 * It succeeds on (broken) Windows versions that haven't addressed
1745 * embedded NULLs in alternate names.
1747 ok(!ret
|| broken(ret
), "expected failure\n");
1750 struct UnicodeExpectedError
1758 static const WCHAR oneW
[] = { '1',0 };
1759 static const WCHAR aW
[] = { 'a',0 };
1760 static const WCHAR quoteW
[] = { '"', 0 };
1762 static struct UnicodeExpectedError unicodeErrors
[] = {
1763 { CERT_RDN_ANY_TYPE
, oneW
, 0, CRYPT_E_NOT_CHAR_STRING
},
1764 { CERT_RDN_ENCODED_BLOB
, oneW
, 0, CRYPT_E_NOT_CHAR_STRING
},
1765 { CERT_RDN_OCTET_STRING
, oneW
, 0, CRYPT_E_NOT_CHAR_STRING
},
1766 { CERT_RDN_NUMERIC_STRING
, aW
, 0, CRYPT_E_INVALID_NUMERIC_STRING
},
1767 { CERT_RDN_PRINTABLE_STRING
, quoteW
, 0, CRYPT_E_INVALID_PRINTABLE_STRING
},
1768 { CERT_RDN_IA5_STRING
, nihongoURL
, 7, CRYPT_E_INVALID_IA5_STRING
},
1771 struct UnicodeExpectedResult
1775 CRYPT_DATA_BLOB encoded
;
1778 static BYTE oneNumeric
[] = { 0x12, 0x01, 0x31 };
1779 static BYTE onePrintable
[] = { 0x13, 0x01, 0x31 };
1780 static BYTE oneTeletex
[] = { 0x14, 0x01, 0x31 };
1781 static BYTE oneVideotex
[] = { 0x15, 0x01, 0x31 };
1782 static BYTE oneIA5
[] = { 0x16, 0x01, 0x31 };
1783 static BYTE oneGraphic
[] = { 0x19, 0x01, 0x31 };
1784 static BYTE oneVisible
[] = { 0x1a, 0x01, 0x31 };
1785 static BYTE oneUniversal
[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 };
1786 static BYTE oneGeneral
[] = { 0x1b, 0x01, 0x31 };
1787 static BYTE oneBMP
[] = { 0x1e, 0x02, 0x00, 0x31 };
1788 static BYTE oneUTF8
[] = { 0x0c, 0x01, 0x31 };
1789 static BYTE nihongoT61
[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,
1791 static BYTE nihongoGeneral
[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1793 static BYTE nihongoBMP
[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,
1794 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
1795 static BYTE nihongoUTF8
[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1796 0xe2,0x89,0xaf,0xe5,0x9d,0x9b };
1798 static struct UnicodeExpectedResult unicodeResults
[] = {
1799 { CERT_RDN_NUMERIC_STRING
, oneW
, { sizeof(oneNumeric
), oneNumeric
} },
1800 { CERT_RDN_PRINTABLE_STRING
, oneW
, { sizeof(onePrintable
), onePrintable
} },
1801 { CERT_RDN_TELETEX_STRING
, oneW
, { sizeof(oneTeletex
), oneTeletex
} },
1802 { CERT_RDN_VIDEOTEX_STRING
, oneW
, { sizeof(oneVideotex
), oneVideotex
} },
1803 { CERT_RDN_IA5_STRING
, oneW
, { sizeof(oneIA5
), oneIA5
} },
1804 { CERT_RDN_GRAPHIC_STRING
, oneW
, { sizeof(oneGraphic
), oneGraphic
} },
1805 { CERT_RDN_VISIBLE_STRING
, oneW
, { sizeof(oneVisible
), oneVisible
} },
1806 { CERT_RDN_UNIVERSAL_STRING
, oneW
, { sizeof(oneUniversal
), oneUniversal
} },
1807 { CERT_RDN_GENERAL_STRING
, oneW
, { sizeof(oneGeneral
), oneGeneral
} },
1808 { CERT_RDN_BMP_STRING
, oneW
, { sizeof(oneBMP
), oneBMP
} },
1809 { CERT_RDN_UTF8_STRING
, oneW
, { sizeof(oneUTF8
), oneUTF8
} },
1810 { CERT_RDN_BMP_STRING
, nihongoURL
, { sizeof(nihongoBMP
), nihongoBMP
} },
1811 { CERT_RDN_UTF8_STRING
, nihongoURL
, { sizeof(nihongoUTF8
), nihongoUTF8
} },
1814 static struct UnicodeExpectedResult unicodeWeirdness
[] = {
1815 { CERT_RDN_TELETEX_STRING
, nihongoURL
, { sizeof(nihongoT61
), nihongoT61
} },
1816 { CERT_RDN_GENERAL_STRING
, nihongoURL
, { sizeof(nihongoGeneral
), nihongoGeneral
} },
1819 static void test_encodeUnicodeNameValue(DWORD dwEncoding
)
1824 CERT_NAME_VALUE value
;
1828 /* Crashes on win9x */
1829 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, NULL
,
1830 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1831 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
1832 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1834 /* Have to have a string of some sort */
1835 value
.dwValueType
= 0; /* aka CERT_RDN_ANY_TYPE */
1836 value
.Value
.pbData
= NULL
;
1837 value
.Value
.cbData
= 0;
1838 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1839 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1840 ok(!ret
&& GetLastError() == CRYPT_E_NOT_CHAR_STRING
,
1841 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1842 value
.dwValueType
= CERT_RDN_ENCODED_BLOB
;
1843 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1844 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1845 ok(!ret
&& GetLastError() == CRYPT_E_NOT_CHAR_STRING
,
1846 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1847 value
.dwValueType
= CERT_RDN_ANY_TYPE
;
1848 value
.Value
.pbData
= (LPBYTE
)oneW
;
1849 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1850 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1851 ok(!ret
&& GetLastError() == CRYPT_E_NOT_CHAR_STRING
,
1852 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1853 value
.Value
.cbData
= sizeof(oneW
);
1854 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1855 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1856 ok(!ret
&& GetLastError() == CRYPT_E_NOT_CHAR_STRING
,
1857 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1858 /* An encoded string with specified length isn't good enough either */
1859 value
.dwValueType
= CERT_RDN_ENCODED_BLOB
;
1860 value
.Value
.pbData
= oneUniversal
;
1861 value
.Value
.cbData
= sizeof(oneUniversal
);
1862 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1863 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1864 ok(!ret
&& GetLastError() == CRYPT_E_NOT_CHAR_STRING
,
1865 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1866 /* More failure checking */
1867 value
.Value
.cbData
= 0;
1868 for (i
= 0; i
< sizeof(unicodeErrors
) / sizeof(unicodeErrors
[0]); i
++)
1870 value
.Value
.pbData
= (LPBYTE
)unicodeErrors
[i
].str
;
1871 value
.dwValueType
= unicodeErrors
[i
].valueType
;
1872 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1873 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1874 ok(!ret
&& GetLastError() == unicodeErrors
[i
].error
,
1875 "Value type %d: expected %08x, got %08x\n", value
.dwValueType
,
1876 unicodeErrors
[i
].error
, GetLastError());
1877 ok(size
== unicodeErrors
[i
].errorIndex
,
1878 "Expected error index %d, got %d\n", unicodeErrors
[i
].errorIndex
,
1881 /* cbData can be zero if the string is NULL-terminated */
1882 value
.Value
.cbData
= 0;
1883 for (i
= 0; i
< sizeof(unicodeResults
) / sizeof(unicodeResults
[0]); i
++)
1885 value
.Value
.pbData
= (LPBYTE
)unicodeResults
[i
].str
;
1886 value
.dwValueType
= unicodeResults
[i
].valueType
;
1887 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1888 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1889 ok(ret
|| broken(GetLastError() == OSS_PDU_MISMATCH
/* Win9x */),
1890 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1893 ok(size
== unicodeResults
[i
].encoded
.cbData
,
1894 "Value type %d: expected size %d, got %d\n",
1895 value
.dwValueType
, unicodeResults
[i
].encoded
.cbData
, size
);
1896 ok(!memcmp(unicodeResults
[i
].encoded
.pbData
, buf
, size
),
1897 "Value type %d: unexpected value\n", value
.dwValueType
);
1901 /* These "encode," but they do so by truncating each unicode character
1902 * rather than properly encoding it. Kept separate from the proper results,
1903 * because the encoded forms won't decode to their original strings.
1905 for (i
= 0; i
< sizeof(unicodeWeirdness
) / sizeof(unicodeWeirdness
[0]); i
++)
1907 value
.Value
.pbData
= (LPBYTE
)unicodeWeirdness
[i
].str
;
1908 value
.dwValueType
= unicodeWeirdness
[i
].valueType
;
1909 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1910 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1911 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1914 ok(size
== unicodeWeirdness
[i
].encoded
.cbData
,
1915 "Value type %d: expected size %d, got %d\n",
1916 value
.dwValueType
, unicodeWeirdness
[i
].encoded
.cbData
, size
);
1917 ok(!memcmp(unicodeWeirdness
[i
].encoded
.pbData
, buf
, size
),
1918 "Value type %d: unexpected value\n", value
.dwValueType
);
1924 static inline int strncmpW( const WCHAR
*str1
, const WCHAR
*str2
, int n
)
1926 if (n
<= 0) return 0;
1927 while ((--n
> 0) && *str1
&& (*str1
== *str2
)) { str1
++; str2
++; }
1928 return *str1
- *str2
;
1931 static void test_decodeUnicodeNameValue(DWORD dwEncoding
)
1935 for (i
= 0; i
< sizeof(unicodeResults
) / sizeof(unicodeResults
[0]); i
++)
1941 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
,
1942 unicodeResults
[i
].encoded
.pbData
, unicodeResults
[i
].encoded
.cbData
,
1943 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1944 ok(ret
|| broken(GetLastError() == CRYPT_E_NOT_CHAR_STRING
/* Win9x */),
1945 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1948 PCERT_NAME_VALUE value
= (PCERT_NAME_VALUE
)buf
;
1950 ok(value
->dwValueType
== unicodeResults
[i
].valueType
,
1951 "Expected value type %d, got %d\n", unicodeResults
[i
].valueType
,
1952 value
->dwValueType
);
1953 ok(!strncmpW((LPWSTR
)value
->Value
.pbData
, unicodeResults
[i
].str
,
1954 value
->Value
.cbData
/ sizeof(WCHAR
)),
1955 "Unexpected decoded value for index %d (value type %d)\n", i
,
1956 unicodeResults
[i
].valueType
);
1962 struct encodedOctets
1965 const BYTE
*encoded
;
1968 static const unsigned char bin46
[] = { 'h','i',0 };
1969 static const unsigned char bin47
[] = { 0x04,0x02,'h','i',0 };
1970 static const unsigned char bin48
[] = {
1971 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1972 static const unsigned char bin49
[] = {
1973 0x04,0x0f,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1974 static const unsigned char bin50
[] = { 0 };
1975 static const unsigned char bin51
[] = { 0x04,0x00,0 };
1977 static const struct encodedOctets octets
[] = {
1983 static void test_encodeOctets(DWORD dwEncoding
)
1985 CRYPT_DATA_BLOB blob
;
1988 for (i
= 0; i
< sizeof(octets
) / sizeof(octets
[0]); i
++)
1994 blob
.cbData
= strlen((const char*)octets
[i
].val
);
1995 blob
.pbData
= (BYTE
*)octets
[i
].val
;
1996 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_OCTET_STRING
, &blob
,
1997 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1998 ok(ret
, "CryptEncodeObjectEx failed: %d\n", GetLastError());
2002 "Got unexpected type %d for octet string (expected 4)\n", buf
[0]);
2003 ok(buf
[1] == octets
[i
].encoded
[1], "Got length %d, expected %d\n",
2004 buf
[1], octets
[i
].encoded
[1]);
2005 ok(!memcmp(buf
+ 1, octets
[i
].encoded
+ 1,
2006 octets
[i
].encoded
[1] + 1), "Got unexpected value\n");
2012 static void test_decodeOctets(DWORD dwEncoding
)
2016 for (i
= 0; i
< sizeof(octets
) / sizeof(octets
[0]); i
++)
2022 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_OCTET_STRING
,
2023 octets
[i
].encoded
, octets
[i
].encoded
[1] + 2,
2024 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2025 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2026 ok(bufSize
>= sizeof(CRYPT_DATA_BLOB
) + octets
[i
].encoded
[1],
2027 "Expected size >= %d, got %d\n",
2028 (int)sizeof(CRYPT_DATA_BLOB
) + octets
[i
].encoded
[1], bufSize
);
2029 ok(buf
!= NULL
, "Expected allocated buffer\n");
2032 CRYPT_DATA_BLOB
*blob
= (CRYPT_DATA_BLOB
*)buf
;
2035 ok(!memcmp(blob
->pbData
, octets
[i
].val
, blob
->cbData
),
2036 "Unexpected value\n");
2042 static const BYTE bytesToEncode
[] = { 0xff, 0xff };
2047 const BYTE
*encoded
;
2049 const BYTE
*decoded
;
2052 static const unsigned char bin52
[] = { 0x03,0x03,0x00,0xff,0xff };
2053 static const unsigned char bin53
[] = { 0xff,0xff };
2054 static const unsigned char bin54
[] = { 0x03,0x03,0x01,0xff,0xfe };
2055 static const unsigned char bin55
[] = { 0xff,0xfe };
2056 static const unsigned char bin56
[] = { 0x03,0x02,0x01,0xfe };
2057 static const unsigned char bin57
[] = { 0xfe };
2058 static const unsigned char bin58
[] = { 0x03,0x01,0x00 };
2060 static const struct encodedBits bits
[] = {
2061 /* normal test cases */
2062 { 0, bin52
, 2, bin53
},
2063 { 1, bin54
, 2, bin55
},
2064 /* strange test case, showing cUnusedBits >= 8 is allowed */
2065 { 9, bin56
, 1, bin57
},
2068 static void test_encodeBits(DWORD dwEncoding
)
2072 for (i
= 0; i
< sizeof(bits
) / sizeof(bits
[0]); i
++)
2074 CRYPT_BIT_BLOB blob
;
2079 blob
.cbData
= sizeof(bytesToEncode
);
2080 blob
.pbData
= (BYTE
*)bytesToEncode
;
2081 blob
.cUnusedBits
= bits
[i
].cUnusedBits
;
2082 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_BITS
, &blob
,
2083 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2084 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2087 ok(bufSize
== bits
[i
].encoded
[1] + 2,
2088 "%d: Got unexpected size %d, expected %d\n", i
, bufSize
,
2089 bits
[i
].encoded
[1] + 2);
2090 ok(!memcmp(buf
, bits
[i
].encoded
, bits
[i
].encoded
[1] + 2),
2091 "%d: Unexpected value\n", i
);
2097 static void test_decodeBits(DWORD dwEncoding
)
2099 static const BYTE ber
[] = "\x03\x02\x01\xff";
2100 static const BYTE berDecoded
= 0xfe;
2107 for (i
= 0; i
< sizeof(bits
) / sizeof(bits
[0]); i
++)
2109 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BITS
, bits
[i
].encoded
,
2110 bits
[i
].encoded
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
,
2112 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2115 CRYPT_BIT_BLOB
*blob
;
2117 ok(bufSize
>= sizeof(CRYPT_BIT_BLOB
) + bits
[i
].cbDecoded
,
2118 "Got unexpected size %d\n", bufSize
);
2119 blob
= (CRYPT_BIT_BLOB
*)buf
;
2120 ok(blob
->cbData
== bits
[i
].cbDecoded
,
2121 "Got unexpected length %d, expected %d\n", blob
->cbData
,
2123 if (blob
->cbData
&& bits
[i
].cbDecoded
)
2124 ok(!memcmp(blob
->pbData
, bits
[i
].decoded
, bits
[i
].cbDecoded
),
2125 "Unexpected value\n");
2129 /* special case: check that something that's valid in BER but not in DER
2130 * decodes successfully
2132 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BITS
, ber
, ber
[1] + 2,
2133 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2134 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2137 CRYPT_BIT_BLOB
*blob
;
2139 ok(bufSize
>= sizeof(CRYPT_BIT_BLOB
) + sizeof(berDecoded
),
2140 "Got unexpected size %d\n", bufSize
);
2141 blob
= (CRYPT_BIT_BLOB
*)buf
;
2142 ok(blob
->cbData
== sizeof(berDecoded
),
2143 "Got unexpected length %d\n", blob
->cbData
);
2145 ok(*blob
->pbData
== berDecoded
, "Unexpected value\n");
2152 CERT_BASIC_CONSTRAINTS2_INFO info
;
2153 const BYTE
*encoded
;
2156 static const unsigned char bin59
[] = { 0x30,0x00 };
2157 static const unsigned char bin60
[] = { 0x30,0x03,0x01,0x01,0xff };
2158 static const unsigned char bin61
[] = { 0x30,0x03,0x02,0x01,0x00 };
2159 static const unsigned char bin62
[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2160 static const struct Constraints2 constraints2
[] = {
2161 /* empty constraints */
2162 { { FALSE
, FALSE
, 0}, bin59
},
2164 { { TRUE
, FALSE
, 0}, bin60
},
2165 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well,
2166 * but that's not the case
2168 { { FALSE
, TRUE
, 0}, bin61
},
2169 /* can be a CA and has path length constraints set */
2170 { { TRUE
, TRUE
, 1}, bin62
},
2173 static const BYTE emptyConstraint
[] = { 0x30, 0x03, 0x03, 0x01, 0x00 };
2174 static const BYTE encodedDomainName
[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11,
2175 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
2176 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
2177 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2178 static const BYTE constraintWithDomainName
[] = { 0x30, 0x32, 0x03, 0x01, 0x00,
2179 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
2180 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30,
2181 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
2182 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2184 static void test_encodeBasicConstraints(DWORD dwEncoding
)
2186 DWORD i
, bufSize
= 0;
2187 CERT_BASIC_CONSTRAINTS_INFO info
= { { 0 } };
2188 CERT_NAME_BLOB nameBlob
= { sizeof(encodedDomainName
),
2189 (LPBYTE
)encodedDomainName
};
2193 /* First test with the simpler info2 */
2194 for (i
= 0; i
< sizeof(constraints2
) / sizeof(constraints2
[0]); i
++)
2196 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS2
,
2197 &constraints2
[i
].info
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
,
2199 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2202 ok(bufSize
== constraints2
[i
].encoded
[1] + 2,
2203 "Expected %d bytes, got %d\n", constraints2
[i
].encoded
[1] + 2,
2205 ok(!memcmp(buf
, constraints2
[i
].encoded
,
2206 constraints2
[i
].encoded
[1] + 2), "Unexpected value\n");
2210 /* Now test with more complex basic constraints */
2211 info
.SubjectType
.cbData
= 0;
2212 info
.fPathLenConstraint
= FALSE
;
2213 info
.cSubtreesConstraint
= 0;
2214 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS
, &info
,
2215 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2216 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
2217 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2220 ok(bufSize
== sizeof(emptyConstraint
), "Wrong size %d\n", bufSize
);
2221 ok(!memcmp(buf
, emptyConstraint
, sizeof(emptyConstraint
)),
2222 "Unexpected value\n");
2225 /* None of the certs I examined had any subtree constraint, but I test one
2226 * anyway just in case.
2228 info
.cSubtreesConstraint
= 1;
2229 info
.rgSubtreesConstraint
= &nameBlob
;
2230 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS
, &info
,
2231 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2232 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
2233 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2236 ok(bufSize
== sizeof(constraintWithDomainName
), "Wrong size %d\n", bufSize
);
2237 ok(!memcmp(buf
, constraintWithDomainName
,
2238 sizeof(constraintWithDomainName
)), "Unexpected value\n");
2241 /* FIXME: test encoding with subject type. */
2244 static const unsigned char bin63
[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 };
2246 static void test_decodeBasicConstraints(DWORD dwEncoding
)
2248 static const BYTE inverted
[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01,
2250 static const struct Constraints2 badBool
= { { TRUE
, TRUE
, 1 }, bin63
};
2256 /* First test with simpler info2 */
2257 for (i
= 0; i
< sizeof(constraints2
) / sizeof(constraints2
[0]); i
++)
2259 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS2
,
2260 constraints2
[i
].encoded
, constraints2
[i
].encoded
[1] + 2,
2261 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2262 ok(ret
, "CryptDecodeObjectEx failed for item %d: %08x\n", i
,
2266 CERT_BASIC_CONSTRAINTS2_INFO
*info
=
2267 (CERT_BASIC_CONSTRAINTS2_INFO
*)buf
;
2269 ok(!memcmp(info
, &constraints2
[i
].info
, sizeof(*info
)),
2270 "Unexpected value for item %d\n", i
);
2274 /* Check with the order of encoded elements inverted */
2276 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS2
,
2277 inverted
, inverted
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
,
2279 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
2280 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
2281 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2283 ok(!buf
, "Expected buf to be set to NULL\n");
2284 /* Check with a non-DER bool */
2285 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS2
,
2286 badBool
.encoded
, badBool
.encoded
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
2288 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2291 CERT_BASIC_CONSTRAINTS2_INFO
*info
=
2292 (CERT_BASIC_CONSTRAINTS2_INFO
*)buf
;
2294 ok(!memcmp(info
, &badBool
.info
, sizeof(*info
)), "Unexpected value\n");
2297 /* Check with a non-basic constraints value */
2298 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS2
,
2299 encodedCommonName
, encodedCommonName
[1] + 2,
2300 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2301 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
2302 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
2303 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2305 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */
2306 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS
,
2307 emptyConstraint
, sizeof(emptyConstraint
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
2309 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2312 CERT_BASIC_CONSTRAINTS_INFO
*info
= (CERT_BASIC_CONSTRAINTS_INFO
*)buf
;
2314 ok(info
->SubjectType
.cbData
== 0, "Expected no subject type\n");
2315 ok(!info
->fPathLenConstraint
, "Expected no path length constraint\n");
2316 ok(info
->cSubtreesConstraint
== 0, "Expected no subtree constraints\n");
2319 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS
,
2320 constraintWithDomainName
, sizeof(constraintWithDomainName
),
2321 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2322 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2325 CERT_BASIC_CONSTRAINTS_INFO
*info
= (CERT_BASIC_CONSTRAINTS_INFO
*)buf
;
2327 ok(info
->SubjectType
.cbData
== 0, "Expected no subject type\n");
2328 ok(!info
->fPathLenConstraint
, "Expected no path length constraint\n");
2329 ok(info
->cSubtreesConstraint
== 1, "Expected a subtree constraint\n");
2330 if (info
->cSubtreesConstraint
&& info
->rgSubtreesConstraint
)
2332 ok(info
->rgSubtreesConstraint
[0].cbData
==
2333 sizeof(encodedDomainName
), "Wrong size %d\n",
2334 info
->rgSubtreesConstraint
[0].cbData
);
2335 ok(!memcmp(info
->rgSubtreesConstraint
[0].pbData
, encodedDomainName
,
2336 sizeof(encodedDomainName
)), "Unexpected value\n");
2342 /* These are terrible public keys of course, I'm just testing encoding */
2343 static const BYTE modulus1
[] = { 0,0,0,1,1,1,1,1 };
2344 static const BYTE modulus2
[] = { 1,1,1,1,1,0,0,0 };
2345 static const BYTE modulus3
[] = { 0x80,1,1,1,1,0,0,0 };
2346 static const BYTE modulus4
[] = { 1,1,1,1,1,0,0,0x80 };
2347 static const BYTE mod1_encoded
[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 };
2348 static const BYTE mod2_encoded
[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2349 static const BYTE mod3_encoded
[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 };
2350 static const BYTE mod4_encoded
[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2352 struct EncodedRSAPubKey
2354 const BYTE
*modulus
;
2356 const BYTE
*encoded
;
2357 size_t decodedModulusLen
;
2360 static const struct EncodedRSAPubKey rsaPubKeys
[] = {
2361 { modulus1
, sizeof(modulus1
), mod1_encoded
, sizeof(modulus1
) },
2362 { modulus2
, sizeof(modulus2
), mod2_encoded
, 5 },
2363 { modulus3
, sizeof(modulus3
), mod3_encoded
, 5 },
2364 { modulus4
, sizeof(modulus4
), mod4_encoded
, 8 },
2367 static void test_encodeRsaPublicKey(DWORD dwEncoding
)
2369 BYTE toEncode
[sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) + sizeof(modulus1
)];
2370 BLOBHEADER
*hdr
= (BLOBHEADER
*)toEncode
;
2371 RSAPUBKEY
*rsaPubKey
= (RSAPUBKEY
*)(toEncode
+ sizeof(BLOBHEADER
));
2374 DWORD bufSize
= 0, i
;
2376 /* Try with a bogus blob type */
2378 hdr
->bVersion
= CUR_BLOB_VERSION
;
2380 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
2381 rsaPubKey
->magic
= 0x31415352;
2382 rsaPubKey
->bitlen
= sizeof(modulus1
) * 8;
2383 rsaPubKey
->pubexp
= 65537;
2384 memcpy(toEncode
+ sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
), modulus1
,
2387 ret
= pCryptEncodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2388 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2389 ok(!ret
&& GetLastError() == E_INVALIDARG
,
2390 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2391 /* Now with a bogus reserved field */
2392 hdr
->bType
= PUBLICKEYBLOB
;
2394 ret
= pCryptEncodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2395 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2398 ok(bufSize
== rsaPubKeys
[0].encoded
[1] + 2,
2399 "Expected size %d, got %d\n", rsaPubKeys
[0].encoded
[1] + 2, bufSize
);
2400 ok(!memcmp(buf
, rsaPubKeys
[0].encoded
, bufSize
), "Unexpected value\n");
2403 /* Now with a bogus blob version */
2406 ret
= pCryptEncodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2407 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2410 ok(bufSize
== rsaPubKeys
[0].encoded
[1] + 2,
2411 "Expected size %d, got %d\n", rsaPubKeys
[0].encoded
[1] + 2, bufSize
);
2412 ok(!memcmp(buf
, rsaPubKeys
[0].encoded
, bufSize
), "Unexpected value\n");
2415 /* And with a bogus alg ID */
2416 hdr
->bVersion
= CUR_BLOB_VERSION
;
2417 hdr
->aiKeyAlg
= CALG_DES
;
2418 ret
= pCryptEncodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2419 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2422 ok(bufSize
== rsaPubKeys
[0].encoded
[1] + 2,
2423 "Expected size %d, got %d\n", rsaPubKeys
[0].encoded
[1] + 2, bufSize
);
2424 ok(!memcmp(buf
, rsaPubKeys
[0].encoded
, bufSize
), "Unexpected value\n");
2427 /* Check a couple of RSA-related OIDs */
2428 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
2429 ret
= pCryptEncodeObjectEx(dwEncoding
, szOID_RSA_RSA
,
2430 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2431 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
2432 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2433 ret
= pCryptEncodeObjectEx(dwEncoding
, szOID_RSA_SHA1RSA
,
2434 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2435 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
2436 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2437 /* Finally, all valid */
2438 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
2439 for (i
= 0; i
< sizeof(rsaPubKeys
) / sizeof(rsaPubKeys
[0]); i
++)
2441 memcpy(toEncode
+ sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
),
2442 rsaPubKeys
[i
].modulus
, rsaPubKeys
[i
].modulusLen
);
2443 ret
= pCryptEncodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2444 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2445 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2448 ok(bufSize
== rsaPubKeys
[i
].encoded
[1] + 2,
2449 "Expected size %d, got %d\n", rsaPubKeys
[i
].encoded
[1] + 2,
2451 ok(!memcmp(buf
, rsaPubKeys
[i
].encoded
, bufSize
),
2452 "Unexpected value\n");
2458 static void test_decodeRsaPublicKey(DWORD dwEncoding
)
2465 /* Try with a bad length */
2466 ret
= pCryptDecodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2467 rsaPubKeys
[0].encoded
, rsaPubKeys
[0].encoded
[1],
2468 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2469 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_EOD
||
2470 GetLastError() == OSS_MORE_INPUT
/* Win9x/NT4 */),
2471 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n",
2473 /* Try with a couple of RSA-related OIDs */
2474 ret
= pCryptDecodeObjectEx(dwEncoding
, szOID_RSA_RSA
,
2475 rsaPubKeys
[0].encoded
, rsaPubKeys
[0].encoded
[1] + 2,
2476 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2477 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
2478 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2479 ret
= pCryptDecodeObjectEx(dwEncoding
, szOID_RSA_SHA1RSA
,
2480 rsaPubKeys
[0].encoded
, rsaPubKeys
[0].encoded
[1] + 2,
2481 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2482 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
2483 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2484 /* Now try success cases */
2485 for (i
= 0; i
< sizeof(rsaPubKeys
) / sizeof(rsaPubKeys
[0]); i
++)
2488 ret
= pCryptDecodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2489 rsaPubKeys
[i
].encoded
, rsaPubKeys
[i
].encoded
[1] + 2,
2490 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2491 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2494 BLOBHEADER
*hdr
= (BLOBHEADER
*)buf
;
2495 RSAPUBKEY
*rsaPubKey
= (RSAPUBKEY
*)(buf
+ sizeof(BLOBHEADER
));
2497 ok(bufSize
>= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
2498 rsaPubKeys
[i
].decodedModulusLen
,
2499 "Wrong size %d\n", bufSize
);
2500 ok(hdr
->bType
== PUBLICKEYBLOB
,
2501 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB
,
2503 ok(hdr
->bVersion
== CUR_BLOB_VERSION
,
2504 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
2505 CUR_BLOB_VERSION
, hdr
->bVersion
);
2506 ok(hdr
->reserved
== 0, "Expected reserved 0, got %d\n",
2508 ok(hdr
->aiKeyAlg
== CALG_RSA_KEYX
,
2509 "Expected CALG_RSA_KEYX, got %08x\n", hdr
->aiKeyAlg
);
2510 ok(rsaPubKey
->magic
== 0x31415352,
2511 "Expected magic RSA1, got %08x\n", rsaPubKey
->magic
);
2512 ok(rsaPubKey
->bitlen
== rsaPubKeys
[i
].decodedModulusLen
* 8,
2513 "Wrong bit len %d\n", rsaPubKey
->bitlen
);
2514 ok(rsaPubKey
->pubexp
== 65537, "Expected pubexp 65537, got %d\n",
2516 ok(!memcmp(buf
+ sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
),
2517 rsaPubKeys
[i
].modulus
, rsaPubKeys
[i
].decodedModulusLen
),
2518 "Unexpected modulus\n");
2524 static const BYTE intSequence
[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01,
2525 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02,
2526 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2528 static const BYTE mixedSequence
[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
2529 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f,
2530 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02,
2531 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2533 static void test_encodeSequenceOfAny(DWORD dwEncoding
)
2535 CRYPT_DER_BLOB blobs
[sizeof(ints
) / sizeof(ints
[0])];
2536 CRYPT_SEQUENCE_OF_ANY seq
;
2542 /* Encode a homogeneous sequence */
2543 for (i
= 0; i
< sizeof(ints
) / sizeof(ints
[0]); i
++)
2545 blobs
[i
].cbData
= ints
[i
].encoded
[1] + 2;
2546 blobs
[i
].pbData
= (BYTE
*)ints
[i
].encoded
;
2548 seq
.cValue
= sizeof(ints
) / sizeof(ints
[0]);
2549 seq
.rgValue
= blobs
;
2551 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_SEQUENCE_OF_ANY
, &seq
,
2552 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2553 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2556 ok(bufSize
== sizeof(intSequence
), "Wrong size %d\n", bufSize
);
2557 ok(!memcmp(buf
, intSequence
, intSequence
[1] + 2), "Unexpected value\n");
2560 /* Change the type of the first element in the sequence, and give it
2563 blobs
[0].cbData
= times
[0].encodedTime
[1] + 2;
2564 blobs
[0].pbData
= (BYTE
*)times
[0].encodedTime
;
2565 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_SEQUENCE_OF_ANY
, &seq
,
2566 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2567 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2570 ok(bufSize
== sizeof(mixedSequence
), "Wrong size %d\n", bufSize
);
2571 ok(!memcmp(buf
, mixedSequence
, mixedSequence
[1] + 2),
2572 "Unexpected value\n");
2577 static void test_decodeSequenceOfAny(DWORD dwEncoding
)
2583 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_SEQUENCE_OF_ANY
, intSequence
,
2584 intSequence
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2585 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2588 CRYPT_SEQUENCE_OF_ANY
*seq
= (CRYPT_SEQUENCE_OF_ANY
*)buf
;
2591 ok(seq
->cValue
== sizeof(ints
) / sizeof(ints
[0]),
2592 "Wrong elements %d\n", seq
->cValue
);
2593 for (i
= 0; i
< min(seq
->cValue
, sizeof(ints
) / sizeof(ints
[0])); i
++)
2595 ok(seq
->rgValue
[i
].cbData
== ints
[i
].encoded
[1] + 2,
2596 "Expected %d bytes, got %d\n", ints
[i
].encoded
[1] + 2,
2597 seq
->rgValue
[i
].cbData
);
2598 ok(!memcmp(seq
->rgValue
[i
].pbData
, ints
[i
].encoded
,
2599 ints
[i
].encoded
[1] + 2), "Unexpected value\n");
2603 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_SEQUENCE_OF_ANY
, mixedSequence
,
2604 mixedSequence
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
,
2606 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2609 CRYPT_SEQUENCE_OF_ANY
*seq
= (CRYPT_SEQUENCE_OF_ANY
*)buf
;
2611 ok(seq
->cValue
== sizeof(ints
) / sizeof(ints
[0]),
2612 "Wrong elements %d\n", seq
->cValue
);
2613 /* Just check the first element since it's all that changed */
2614 ok(seq
->rgValue
[0].cbData
== times
[0].encodedTime
[1] + 2,
2615 "Expected %d bytes, got %d\n", times
[0].encodedTime
[1] + 2,
2616 seq
->rgValue
[0].cbData
);
2617 ok(!memcmp(seq
->rgValue
[0].pbData
, times
[0].encodedTime
,
2618 times
[0].encodedTime
[1] + 2), "Unexpected value\n");
2623 struct encodedExtensions
2625 CERT_EXTENSIONS exts
;
2626 const BYTE
*encoded
;
2629 static BYTE crit_ext_data
[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2630 static BYTE noncrit_ext_data
[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2631 static CHAR oid_basic_constraints2
[] = szOID_BASIC_CONSTRAINTS2
;
2632 static CERT_EXTENSION criticalExt
=
2633 { oid_basic_constraints2
, TRUE
, { 8, crit_ext_data
} };
2634 static CERT_EXTENSION nonCriticalExt
=
2635 { oid_basic_constraints2
, FALSE
, { 8, noncrit_ext_data
} };
2636 static CHAR oid_short
[] = "1.1";
2637 static CERT_EXTENSION extWithShortOid
=
2638 { oid_short
, FALSE
, { 0, NULL
} };
2640 static const BYTE ext0
[] = { 0x30,0x00 };
2641 static const BYTE ext1
[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2642 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2643 static const BYTE ext2
[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2644 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2645 static const BYTE ext3
[] = { 0x30,0x07,0x30,0x05,0x06,0x01,0x29,0x04,0x00 };
2647 static const struct encodedExtensions exts
[] = {
2648 { { 0, NULL
}, ext0
},
2649 { { 1, &criticalExt
}, ext1
},
2650 { { 1, &nonCriticalExt
}, ext2
},
2651 { { 1, &extWithShortOid
}, ext3
}
2654 static void test_encodeExtensions(DWORD dwEncoding
)
2658 for (i
= 0; i
< sizeof(exts
) / sizeof(exts
[i
]); i
++)
2664 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_EXTENSIONS
, &exts
[i
].exts
,
2665 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2666 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2669 ok(bufSize
== exts
[i
].encoded
[1] + 2,
2670 "Expected %d bytes, got %d\n", exts
[i
].encoded
[1] + 2, bufSize
);
2671 ok(!memcmp(buf
, exts
[i
].encoded
, exts
[i
].encoded
[1] + 2),
2672 "Unexpected value\n");
2678 static void test_decodeExtensions(DWORD dwEncoding
)
2682 for (i
= 0; i
< sizeof(exts
) / sizeof(exts
[i
]); i
++)
2688 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_EXTENSIONS
,
2689 exts
[i
].encoded
, exts
[i
].encoded
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
,
2690 NULL
, &buf
, &bufSize
);
2691 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2694 CERT_EXTENSIONS
*ext
= (CERT_EXTENSIONS
*)buf
;
2697 ok(ext
->cExtension
== exts
[i
].exts
.cExtension
,
2698 "Expected %d extensions, see %d\n", exts
[i
].exts
.cExtension
,
2700 for (j
= 0; j
< min(ext
->cExtension
, exts
[i
].exts
.cExtension
); j
++)
2702 ok(!strcmp(ext
->rgExtension
[j
].pszObjId
,
2703 exts
[i
].exts
.rgExtension
[j
].pszObjId
),
2704 "Expected OID %s, got %s\n",
2705 exts
[i
].exts
.rgExtension
[j
].pszObjId
,
2706 ext
->rgExtension
[j
].pszObjId
);
2707 ok(!memcmp(ext
->rgExtension
[j
].Value
.pbData
,
2708 exts
[i
].exts
.rgExtension
[j
].Value
.pbData
,
2709 exts
[i
].exts
.rgExtension
[j
].Value
.cbData
),
2710 "Unexpected value\n");
2714 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_EXTENSIONS
,
2715 exts
[i
].encoded
, exts
[i
].encoded
[1] + 2, 0, NULL
, NULL
, &bufSize
);
2716 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2717 buf
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, bufSize
);
2720 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_EXTENSIONS
,
2721 exts
[i
].encoded
, exts
[i
].encoded
[1] + 2, 0, NULL
, buf
, &bufSize
);
2722 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2723 HeapFree(GetProcessHeap(), 0, buf
);
2728 /* MS encodes public key info with a NULL if the algorithm identifier's
2729 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2730 * it encodes them by omitting the algorithm parameters. It accepts either
2731 * form for decoding.
2733 struct encodedPublicKey
2735 CERT_PUBLIC_KEY_INFO info
;
2736 const BYTE
*encoded
;
2737 const BYTE
*encodedNoNull
;
2738 CERT_PUBLIC_KEY_INFO decoded
;
2741 static const BYTE aKey
[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2743 static const BYTE params
[] = { 0x02, 0x01, 0x01 };
2745 static const unsigned char bin64
[] = {
2746 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2747 static const unsigned char bin65
[] = {
2748 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2749 static const unsigned char bin66
[] = {
2750 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2751 static const unsigned char bin67
[] = {
2752 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2753 static const unsigned char bin68
[] = {
2754 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01,
2755 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2756 static const unsigned char bin69
[] = {
2757 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2758 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2759 static const unsigned char bin70
[] = {
2760 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2761 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2763 static const unsigned char bin71
[] = {
2764 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2765 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2767 static unsigned char bin72
[] = { 0x05,0x00};
2769 static CHAR oid_bogus
[] = "1.2.3",
2770 oid_rsa
[] = szOID_RSA
;
2772 static const struct encodedPublicKey pubKeys
[] = {
2773 /* with a bogus OID */
2774 { { { oid_bogus
, { 0, NULL
} }, { 0, NULL
, 0 } },
2776 { { oid_bogus
, { 2, bin72
} }, { 0, NULL
, 0 } } },
2777 /* some normal keys */
2778 { { { oid_rsa
, { 0, NULL
} }, { 0, NULL
, 0} },
2780 { { oid_rsa
, { 2, bin72
} }, { 0, NULL
, 0 } } },
2781 { { { oid_rsa
, { 0, NULL
} }, { sizeof(aKey
), (BYTE
*)aKey
, 0} },
2783 { { oid_rsa
, { 2, bin72
} }, { sizeof(aKey
), (BYTE
*)aKey
, 0} } },
2784 /* with add'l parameters--note they must be DER-encoded */
2785 { { { oid_rsa
, { sizeof(params
), (BYTE
*)params
} }, { sizeof(aKey
),
2786 (BYTE
*)aKey
, 0 } },
2788 { { oid_rsa
, { sizeof(params
), (BYTE
*)params
} }, { sizeof(aKey
),
2789 (BYTE
*)aKey
, 0 } } },
2792 static void test_encodePublicKeyInfo(DWORD dwEncoding
)
2796 for (i
= 0; i
< sizeof(pubKeys
) / sizeof(pubKeys
[0]); i
++)
2802 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_PUBLIC_KEY_INFO
,
2803 &pubKeys
[i
].info
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
,
2805 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
2806 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2809 ok(bufSize
== pubKeys
[i
].encoded
[1] + 2,
2810 "Expected %d bytes, got %d\n", pubKeys
[i
].encoded
[1] + 2, bufSize
);
2811 if (bufSize
== pubKeys
[i
].encoded
[1] + 2)
2812 ok(!memcmp(buf
, pubKeys
[i
].encoded
, pubKeys
[i
].encoded
[1] + 2),
2813 "Unexpected value\n");
2819 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO
*expected
,
2820 const CERT_PUBLIC_KEY_INFO
*got
)
2822 ok(!strcmp(expected
->Algorithm
.pszObjId
, got
->Algorithm
.pszObjId
),
2823 "Expected OID %s, got %s\n", expected
->Algorithm
.pszObjId
,
2824 got
->Algorithm
.pszObjId
);
2825 ok(expected
->Algorithm
.Parameters
.cbData
==
2826 got
->Algorithm
.Parameters
.cbData
,
2827 "Expected parameters of %d bytes, got %d\n",
2828 expected
->Algorithm
.Parameters
.cbData
, got
->Algorithm
.Parameters
.cbData
);
2829 if (expected
->Algorithm
.Parameters
.cbData
)
2830 ok(!memcmp(expected
->Algorithm
.Parameters
.pbData
,
2831 got
->Algorithm
.Parameters
.pbData
, got
->Algorithm
.Parameters
.cbData
),
2832 "Unexpected algorithm parameters\n");
2833 ok(expected
->PublicKey
.cbData
== got
->PublicKey
.cbData
,
2834 "Expected public key of %d bytes, got %d\n",
2835 expected
->PublicKey
.cbData
, got
->PublicKey
.cbData
);
2836 if (expected
->PublicKey
.cbData
)
2837 ok(!memcmp(expected
->PublicKey
.pbData
, got
->PublicKey
.pbData
,
2838 got
->PublicKey
.cbData
), "Unexpected public key value\n");
2841 static void test_decodePublicKeyInfo(DWORD dwEncoding
)
2843 static const BYTE bogusPubKeyInfo
[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
2844 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
2845 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
2846 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2852 for (i
= 0; i
< sizeof(pubKeys
) / sizeof(pubKeys
[0]); i
++)
2854 /* The NULL form decodes to the decoded member */
2855 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_PUBLIC_KEY_INFO
,
2856 pubKeys
[i
].encoded
, pubKeys
[i
].encoded
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
,
2857 NULL
, &buf
, &bufSize
);
2858 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2861 comparePublicKeyInfo(&pubKeys
[i
].decoded
,
2862 (CERT_PUBLIC_KEY_INFO
*)buf
);
2865 /* The non-NULL form decodes to the original */
2866 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_PUBLIC_KEY_INFO
,
2867 pubKeys
[i
].encodedNoNull
, pubKeys
[i
].encodedNoNull
[1] + 2,
2868 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2869 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2872 comparePublicKeyInfo(&pubKeys
[i
].info
, (CERT_PUBLIC_KEY_INFO
*)buf
);
2876 /* Test with bogus (not valid DER) parameters */
2877 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_PUBLIC_KEY_INFO
,
2878 bogusPubKeyInfo
, bogusPubKeyInfo
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
,
2879 NULL
, &buf
, &bufSize
);
2880 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
2881 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
2882 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2886 static const BYTE v1Cert
[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
2887 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2888 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
2889 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
2890 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2891 static const BYTE v2Cert
[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02,
2892 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2893 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2894 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2895 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2896 static const BYTE v3Cert
[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2897 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2898 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2899 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2900 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2901 static const BYTE v4Cert
[] = {
2902 0x30,0x38,0xa0,0x03,0x02,0x01,0x03,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,
2903 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
2904 0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
2905 0x30,0x30,0x30,0x5a,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00 };
2906 static const BYTE v1CertWithConstraints
[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
2907 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2908 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2909 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2910 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2911 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2912 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2913 static const BYTE v1CertWithSerial
[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
2914 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2915 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2916 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2917 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2918 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2919 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2920 static const BYTE bigCert
[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2921 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
2922 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
2923 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
2924 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
2925 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
2926 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
2927 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
2928 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
2929 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2930 static const BYTE v1CertWithPubKey
[] = {
2931 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2932 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2933 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2934 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2935 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2936 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2937 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2938 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2939 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
2940 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
2942 static const BYTE v1CertWithPubKeyNoNull
[] = {
2943 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2944 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2945 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2946 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2947 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2948 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2949 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2950 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2951 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
2952 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2953 static const BYTE v1CertWithSubjectKeyId
[] = {
2954 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2955 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2956 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2957 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2958 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2959 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2960 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
2961 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2962 0x4c,0x61,0x6e,0x67,0x00 };
2963 static const BYTE v1CertWithIssuerUniqueId
[] = {
2964 0x30,0x38,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
2965 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
2966 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
2967 0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x81,0x02,0x00,0x01 };
2968 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueId
[] = {
2969 0x30,0x81,0x99,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2970 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2971 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2972 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2973 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2974 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2975 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2976 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2977 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,
2978 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
2979 0x01,0x01,0xff,0x02,0x01,0x01 };
2980 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull
[] = {
2981 0x30,0x81,0x97,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2982 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2983 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2984 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2985 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2986 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2987 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2988 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2989 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
2990 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
2991 0xff,0x02,0x01,0x01 };
2993 static const BYTE serialNum
[] = { 0x01 };
2995 static void test_encodeCertToBeSigned(DWORD dwEncoding
)
3000 CERT_INFO info
= { 0 };
3001 static char oid_rsa_rsa
[] = szOID_RSA_RSA
;
3002 static char oid_subject_key_identifier
[] = szOID_SUBJECT_KEY_IDENTIFIER
;
3007 /* Test with NULL pvStructInfo (crashes on win9x) */
3008 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, NULL
,
3009 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3010 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
3011 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3013 /* Test with a V1 cert */
3014 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3015 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3016 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
3017 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3020 ok(size
== v1Cert
[1] + 2, "Expected size %d, got %d\n",
3021 v1Cert
[1] + 2, size
);
3022 ok(!memcmp(buf
, v1Cert
, size
), "Got unexpected value\n");
3026 info
.dwVersion
= CERT_V2
;
3027 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3028 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3029 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
3030 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3033 ok(size
== sizeof(v2Cert
), "Wrong size %d\n", size
);
3034 ok(!memcmp(buf
, v2Cert
, size
), "Got unexpected value\n");
3038 info
.dwVersion
= CERT_V3
;
3039 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3040 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3041 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
3042 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3045 ok(size
== sizeof(v3Cert
), "Wrong size %d\n", size
);
3046 ok(!memcmp(buf
, v3Cert
, size
), "Got unexpected value\n");
3050 info
.dwVersion
= 3; /* Not a typo, CERT_V3 is 2 */
3051 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3052 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3055 ok(size
== sizeof(v4Cert
), "Wrong size %d\n", size
);
3056 ok(!memcmp(buf
, v4Cert
, size
), "Unexpected value\n");
3059 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
3060 * API doesn't prevent it)
3062 info
.dwVersion
= CERT_V1
;
3063 info
.cExtension
= 1;
3064 info
.rgExtension
= &criticalExt
;
3065 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3066 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3067 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
3068 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3071 ok(size
== sizeof(v1CertWithConstraints
), "Wrong size %d\n", size
);
3072 ok(!memcmp(buf
, v1CertWithConstraints
, size
), "Got unexpected value\n");
3075 /* test v1 cert with a serial number */
3076 info
.SerialNumber
.cbData
= sizeof(serialNum
);
3077 info
.SerialNumber
.pbData
= (BYTE
*)serialNum
;
3078 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3079 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3082 ok(size
== sizeof(v1CertWithSerial
), "Wrong size %d\n", size
);
3083 ok(!memcmp(buf
, v1CertWithSerial
, size
), "Got unexpected value\n");
3086 /* Test v1 cert with an issuer name, serial number, and issuer unique id */
3087 info
.dwVersion
= CERT_V1
;
3088 info
.cExtension
= 0;
3089 info
.IssuerUniqueId
.cbData
= sizeof(serialNum
);
3090 info
.IssuerUniqueId
.pbData
= (BYTE
*)serialNum
;
3091 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3092 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3093 ok(ret
|| broken(GetLastError() == OSS_BAD_PTR
/* Win98 */),
3094 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3097 ok(size
== sizeof(v1CertWithIssuerUniqueId
), "Wrong size %d\n", size
);
3098 ok(!memcmp(buf
, v1CertWithIssuerUniqueId
, size
),
3099 "Got unexpected value\n");
3102 /* Test v1 cert with an issuer name, a subject name, and a serial number */
3103 info
.IssuerUniqueId
.cbData
= 0;
3104 info
.IssuerUniqueId
.pbData
= NULL
;
3105 info
.cExtension
= 1;
3106 info
.rgExtension
= &criticalExt
;
3107 info
.Issuer
.cbData
= sizeof(encodedCommonName
);
3108 info
.Issuer
.pbData
= (BYTE
*)encodedCommonName
;
3109 info
.Subject
.cbData
= sizeof(encodedCommonName
);
3110 info
.Subject
.pbData
= (BYTE
*)encodedCommonName
;
3111 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3112 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3115 ok(size
== sizeof(bigCert
), "Wrong size %d\n", size
);
3116 ok(!memcmp(buf
, bigCert
, size
), "Got unexpected value\n");
3119 /* Add a public key */
3120 info
.SubjectPublicKeyInfo
.Algorithm
.pszObjId
= oid_rsa_rsa
;
3121 info
.SubjectPublicKeyInfo
.PublicKey
.cbData
= sizeof(aKey
);
3122 info
.SubjectPublicKeyInfo
.PublicKey
.pbData
= (LPBYTE
)aKey
;
3123 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3124 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3127 ok(size
== sizeof(v1CertWithPubKey
) ||
3128 size
== sizeof(v1CertWithPubKeyNoNull
), "Wrong size %d\n", size
);
3129 if (size
== sizeof(v1CertWithPubKey
))
3130 ok(!memcmp(buf
, v1CertWithPubKey
, size
), "Got unexpected value\n");
3131 else if (size
== sizeof(v1CertWithPubKeyNoNull
))
3132 ok(!memcmp(buf
, v1CertWithPubKeyNoNull
, size
),
3133 "Got unexpected value\n");
3136 /* Again add an issuer unique id */
3137 info
.IssuerUniqueId
.cbData
= sizeof(serialNum
);
3138 info
.IssuerUniqueId
.pbData
= (BYTE
*)serialNum
;
3139 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3140 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3141 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3144 ok(size
== sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId
) ||
3145 size
== sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull
),
3146 "Wrong size %d\n", size
);
3147 if (size
== sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId
))
3148 ok(!memcmp(buf
, v1CertWithSubjectIssuerSerialAndIssuerUniqueId
,
3149 size
), "unexpected value\n");
3151 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull
))
3153 v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull
, size
),
3154 "unexpected value\n");
3157 /* Remove the public key, and add a subject key identifier extension */
3158 info
.IssuerUniqueId
.cbData
= 0;
3159 info
.IssuerUniqueId
.pbData
= NULL
;
3160 info
.SubjectPublicKeyInfo
.Algorithm
.pszObjId
= NULL
;
3161 info
.SubjectPublicKeyInfo
.PublicKey
.cbData
= 0;
3162 info
.SubjectPublicKeyInfo
.PublicKey
.pbData
= NULL
;
3163 ext
.pszObjId
= oid_subject_key_identifier
;
3164 ext
.fCritical
= FALSE
;
3165 ext
.Value
.cbData
= sizeof(octetCommonNameValue
);
3166 ext
.Value
.pbData
= octetCommonNameValue
;
3167 info
.cExtension
= 1;
3168 info
.rgExtension
= &ext
;
3169 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3170 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3173 ok(size
== sizeof(v1CertWithSubjectKeyId
), "Wrong size %d\n", size
);
3174 ok(!memcmp(buf
, v1CertWithSubjectKeyId
, size
), "Unexpected value\n");
3179 static void test_decodeCertToBeSigned(DWORD dwEncoding
)
3181 static const BYTE
*corruptCerts
[] = { v1Cert
, v2Cert
, v3Cert
, v4Cert
,
3182 v1CertWithConstraints
, v1CertWithSerial
, v1CertWithIssuerUniqueId
};
3187 /* Test with NULL pbEncoded */
3188 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, NULL
, 0,
3189 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3190 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_EOD
||
3191 GetLastError() == OSS_BAD_ARG
/* Win9x */),
3192 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
3195 /* Crashes on win9x */
3196 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, NULL
, 1,
3197 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3198 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
3199 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3201 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT or
3202 * CRYPT_E_ASN1_BADTAG, because at a minimum a cert must have a non-zero
3203 * serial number, an issuer, a subject, and a public key.
3205 for (i
= 0; i
< sizeof(corruptCerts
) / sizeof(corruptCerts
[0]); i
++)
3207 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
,
3208 corruptCerts
[i
], corruptCerts
[i
][1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3210 ok(!ret
, "Expected failure\n");
3212 /* The following succeeds, even though v1 certs are not allowed to have
3215 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
,
3216 v1CertWithSubjectKeyId
, sizeof(v1CertWithSubjectKeyId
),
3217 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3218 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3221 CERT_INFO
*info
= (CERT_INFO
*)buf
;
3223 ok(size
>= sizeof(CERT_INFO
), "Wrong size %d\n", size
);
3224 ok(info
->dwVersion
== CERT_V1
, "expected CERT_V1, got %d\n",
3226 ok(info
->cExtension
== 1, "expected 1 extension, got %d\n",
3230 /* The following also succeeds, even though V1 certs are not allowed to
3231 * have issuer unique ids.
3233 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
,
3234 v1CertWithSubjectIssuerSerialAndIssuerUniqueId
,
3235 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId
),
3236 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3237 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3240 CERT_INFO
*info
= (CERT_INFO
*)buf
;
3242 ok(size
>= sizeof(CERT_INFO
), "Wrong size %d\n", size
);
3243 ok(info
->dwVersion
== CERT_V1
, "expected CERT_V1, got %d\n",
3245 ok(info
->IssuerUniqueId
.cbData
== sizeof(serialNum
),
3246 "unexpected issuer unique id size %d\n", info
->IssuerUniqueId
.cbData
);
3247 ok(!memcmp(info
->IssuerUniqueId
.pbData
, serialNum
, sizeof(serialNum
)),
3248 "unexpected issuer unique id value\n");
3251 /* Now check with serial number, subject and issuer specified */
3252 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, bigCert
,
3253 sizeof(bigCert
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3254 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3257 CERT_INFO
*info
= (CERT_INFO
*)buf
;
3259 ok(size
>= sizeof(CERT_INFO
), "Wrong size %d\n", size
);
3260 ok(info
->SerialNumber
.cbData
== 1,
3261 "Expected serial number size 1, got %d\n", info
->SerialNumber
.cbData
);
3262 ok(*info
->SerialNumber
.pbData
== *serialNum
,
3263 "Expected serial number %d, got %d\n", *serialNum
,
3264 *info
->SerialNumber
.pbData
);
3265 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
3266 "Wrong size %d\n", info
->Issuer
.cbData
);
3267 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
3268 "Unexpected issuer\n");
3269 ok(info
->Subject
.cbData
== sizeof(encodedCommonName
),
3270 "Wrong size %d\n", info
->Subject
.cbData
);
3271 ok(!memcmp(info
->Subject
.pbData
, encodedCommonName
,
3272 info
->Subject
.cbData
), "Unexpected subject\n");
3275 /* Check again with pub key specified */
3276 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
,
3277 v1CertWithPubKey
, sizeof(v1CertWithPubKey
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3279 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3282 CERT_INFO
*info
= (CERT_INFO
*)buf
;
3284 ok(size
>= sizeof(CERT_INFO
), "Wrong size %d\n", size
);
3285 ok(info
->SerialNumber
.cbData
== 1,
3286 "Expected serial number size 1, got %d\n", info
->SerialNumber
.cbData
);
3287 ok(*info
->SerialNumber
.pbData
== *serialNum
,
3288 "Expected serial number %d, got %d\n", *serialNum
,
3289 *info
->SerialNumber
.pbData
);
3290 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
3291 "Wrong size %d\n", info
->Issuer
.cbData
);
3292 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
3293 "Unexpected issuer\n");
3294 ok(info
->Subject
.cbData
== sizeof(encodedCommonName
),
3295 "Wrong size %d\n", info
->Subject
.cbData
);
3296 ok(!memcmp(info
->Subject
.pbData
, encodedCommonName
,
3297 info
->Subject
.cbData
), "Unexpected subject\n");
3298 ok(!strcmp(info
->SubjectPublicKeyInfo
.Algorithm
.pszObjId
,
3299 szOID_RSA_RSA
), "Expected szOID_RSA_RSA, got %s\n",
3300 info
->SubjectPublicKeyInfo
.Algorithm
.pszObjId
);
3301 ok(info
->SubjectPublicKeyInfo
.PublicKey
.cbData
== sizeof(aKey
),
3302 "Wrong size %d\n", info
->SubjectPublicKeyInfo
.PublicKey
.cbData
);
3303 ok(!memcmp(info
->SubjectPublicKeyInfo
.PublicKey
.pbData
, aKey
,
3304 sizeof(aKey
)), "Unexpected public key\n");
3309 static const BYTE hash
[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
3312 static const BYTE signedBigCert
[] = {
3313 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
3314 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
3315 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
3316 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3317 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
3318 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
3319 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
3320 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
3321 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
3322 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3323 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
3324 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
3326 static void test_encodeCert(DWORD dwEncoding
)
3328 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
3329 * also that bigCert is a NULL-terminated string, so don't count its
3330 * last byte (otherwise the signed cert won't decode.)
3332 CERT_SIGNED_CONTENT_INFO info
= { { sizeof(bigCert
), (BYTE
*)bigCert
},
3333 { NULL
, { 0, NULL
} }, { sizeof(hash
), (BYTE
*)hash
, 0 } };
3338 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT
, &info
,
3339 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
3340 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3343 ok(bufSize
== sizeof(signedBigCert
), "Wrong size %d\n", bufSize
);
3344 ok(!memcmp(buf
, signedBigCert
, bufSize
), "Unexpected cert\n");
3349 static void test_decodeCert(DWORD dwEncoding
)
3355 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT
, signedBigCert
,
3356 sizeof(signedBigCert
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3357 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3360 CERT_SIGNED_CONTENT_INFO
*info
= (CERT_SIGNED_CONTENT_INFO
*)buf
;
3362 ok(info
->ToBeSigned
.cbData
== sizeof(bigCert
),
3363 "Wrong cert size %d\n", info
->ToBeSigned
.cbData
);
3364 ok(!memcmp(info
->ToBeSigned
.pbData
, bigCert
, info
->ToBeSigned
.cbData
),
3365 "Unexpected cert\n");
3366 ok(info
->Signature
.cbData
== sizeof(hash
),
3367 "Wrong signature size %d\n", info
->Signature
.cbData
);
3368 ok(!memcmp(info
->Signature
.pbData
, hash
, info
->Signature
.cbData
),
3369 "Unexpected signature\n");
3372 /* A signed cert decodes as a CERT_INFO too */
3373 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, signedBigCert
,
3374 sizeof(signedBigCert
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3375 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3378 CERT_INFO
*info
= (CERT_INFO
*)buf
;
3380 ok(size
>= sizeof(CERT_INFO
), "Wrong size %d\n", size
);
3381 ok(info
->SerialNumber
.cbData
== 1,
3382 "Expected serial number size 1, got %d\n", info
->SerialNumber
.cbData
);
3383 ok(*info
->SerialNumber
.pbData
== *serialNum
,
3384 "Expected serial number %d, got %d\n", *serialNum
,
3385 *info
->SerialNumber
.pbData
);
3386 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
3387 "Wrong size %d\n", info
->Issuer
.cbData
);
3388 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
3389 "Unexpected issuer\n");
3390 ok(info
->Subject
.cbData
== sizeof(encodedCommonName
),
3391 "Wrong size %d\n", info
->Subject
.cbData
);
3392 ok(!memcmp(info
->Subject
.pbData
, encodedCommonName
,
3393 info
->Subject
.cbData
), "Unexpected subject\n");
3398 static const BYTE emptyDistPoint
[] = { 0x30, 0x02, 0x30, 0x00 };
3399 static const BYTE distPointWithUrl
[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3400 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3401 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3402 static const BYTE distPointWithReason
[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3404 static const BYTE distPointWithIssuer
[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3405 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3406 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3407 static const BYTE distPointWithUrlAndIssuer
[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3408 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3409 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3410 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3411 0x2e, 0x6f, 0x72, 0x67 };
3412 static const BYTE crlReason
= CRL_REASON_KEY_COMPROMISE
|
3413 CRL_REASON_AFFILIATION_CHANGED
;
3415 static void test_encodeCRLDistPoints(DWORD dwEncoding
)
3417 CRL_DIST_POINTS_INFO info
= { 0 };
3418 CRL_DIST_POINT point
= { { 0 } };
3419 CERT_ALT_NAME_ENTRY entry
= { 0 };
3424 /* Test with an empty info */
3425 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3426 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3427 ok(!ret
&& GetLastError() == E_INVALIDARG
,
3428 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3429 /* Test with one empty dist point */
3430 info
.cDistPoint
= 1;
3431 info
.rgDistPoint
= &point
;
3432 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3433 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3434 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3437 ok(size
== sizeof(emptyDistPoint
), "Wrong size %d\n", size
);
3438 ok(!memcmp(buf
, emptyDistPoint
, size
), "Unexpected value\n");
3441 /* A dist point with an invalid name */
3442 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3443 entry
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
3444 U(entry
).pwszURL
= (LPWSTR
)nihongoURL
;
3445 U(point
.DistPointName
).FullName
.cAltEntry
= 1;
3446 U(point
.DistPointName
).FullName
.rgAltEntry
= &entry
;
3447 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3448 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3449 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_IA5_STRING
,
3450 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
3451 /* The first invalid character is at index 7 */
3452 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size
) == 7,
3453 "Expected invalid char at index 7, got %d\n",
3454 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size
));
3455 /* A dist point with (just) a valid name */
3456 U(entry
).pwszURL
= (LPWSTR
)url
;
3457 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3458 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3459 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3462 ok(size
== sizeof(distPointWithUrl
), "Wrong size %d\n", size
);
3463 ok(!memcmp(buf
, distPointWithUrl
, size
), "Unexpected value\n");
3466 /* A dist point with (just) reason flags */
3467 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
3468 point
.ReasonFlags
.cbData
= sizeof(crlReason
);
3469 point
.ReasonFlags
.pbData
= (LPBYTE
)&crlReason
;
3470 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3471 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3472 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3475 ok(size
== sizeof(distPointWithReason
), "Wrong size %d\n", size
);
3476 ok(!memcmp(buf
, distPointWithReason
, size
), "Unexpected value\n");
3479 /* A dist point with just an issuer */
3480 point
.ReasonFlags
.cbData
= 0;
3481 point
.CRLIssuer
.cAltEntry
= 1;
3482 point
.CRLIssuer
.rgAltEntry
= &entry
;
3483 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3484 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3485 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3488 ok(size
== sizeof(distPointWithIssuer
), "Wrong size %d\n", size
);
3489 ok(!memcmp(buf
, distPointWithIssuer
, size
), "Unexpected value\n");
3492 /* A dist point with both a name and an issuer */
3493 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3494 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3495 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3496 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3499 ok(size
== sizeof(distPointWithUrlAndIssuer
),
3500 "Wrong size %d\n", size
);
3501 ok(!memcmp(buf
, distPointWithUrlAndIssuer
, size
), "Unexpected value\n");
3506 static void test_decodeCRLDistPoints(DWORD dwEncoding
)
3511 PCRL_DIST_POINTS_INFO info
;
3512 PCRL_DIST_POINT point
;
3513 PCERT_ALT_NAME_ENTRY entry
;
3515 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
,
3516 emptyDistPoint
, emptyDistPoint
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3518 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3521 info
= (PCRL_DIST_POINTS_INFO
)buf
;
3522 ok(size
>= sizeof(CRL_DIST_POINTS_INFO
) + sizeof(CRL_DIST_POINT
),
3523 "Wrong size %d\n", size
);
3524 ok(info
->cDistPoint
== 1, "Expected 1 dist points, got %d\n",
3526 point
= info
->rgDistPoint
;
3527 ok(point
->DistPointName
.dwDistPointNameChoice
== CRL_DIST_POINT_NO_NAME
,
3528 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3529 point
->DistPointName
.dwDistPointNameChoice
);
3530 ok(point
->ReasonFlags
.cbData
== 0, "Expected no reason\n");
3531 ok(point
->CRLIssuer
.cAltEntry
== 0, "Expected no issuer\n");
3534 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
,
3535 distPointWithUrl
, distPointWithUrl
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3537 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3540 info
= (PCRL_DIST_POINTS_INFO
)buf
;
3541 ok(size
>= sizeof(CRL_DIST_POINTS_INFO
) + sizeof(CRL_DIST_POINT
),
3542 "Wrong size %d\n", size
);
3543 ok(info
->cDistPoint
== 1, "Expected 1 dist points, got %d\n",
3545 point
= info
->rgDistPoint
;
3546 ok(point
->DistPointName
.dwDistPointNameChoice
==
3547 CRL_DIST_POINT_FULL_NAME
,
3548 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3549 point
->DistPointName
.dwDistPointNameChoice
);
3550 ok(U(point
->DistPointName
).FullName
.cAltEntry
== 1,
3551 "Expected 1 name entry, got %d\n",
3552 U(point
->DistPointName
).FullName
.cAltEntry
);
3553 entry
= U(point
->DistPointName
).FullName
.rgAltEntry
;
3554 ok(entry
->dwAltNameChoice
== CERT_ALT_NAME_URL
,
3555 "Expected CERT_ALT_NAME_URL, got %d\n", entry
->dwAltNameChoice
);
3556 ok(!lstrcmpW(U(*entry
).pwszURL
, url
), "Unexpected name\n");
3557 ok(point
->ReasonFlags
.cbData
== 0, "Expected no reason\n");
3558 ok(point
->CRLIssuer
.cAltEntry
== 0, "Expected no issuer\n");
3561 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
,
3562 distPointWithReason
, distPointWithReason
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
,
3564 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3567 info
= (PCRL_DIST_POINTS_INFO
)buf
;
3568 ok(size
>= sizeof(CRL_DIST_POINTS_INFO
) + sizeof(CRL_DIST_POINT
),
3569 "Wrong size %d\n", size
);
3570 ok(info
->cDistPoint
== 1, "Expected 1 dist points, got %d\n",
3572 point
= info
->rgDistPoint
;
3573 ok(point
->DistPointName
.dwDistPointNameChoice
==
3574 CRL_DIST_POINT_NO_NAME
,
3575 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3576 point
->DistPointName
.dwDistPointNameChoice
);
3577 ok(point
->ReasonFlags
.cbData
== sizeof(crlReason
),
3578 "Expected reason length\n");
3579 ok(!memcmp(point
->ReasonFlags
.pbData
, &crlReason
, sizeof(crlReason
)),
3580 "Unexpected reason\n");
3581 ok(point
->CRLIssuer
.cAltEntry
== 0, "Expected no issuer\n");
3584 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
,
3585 distPointWithUrlAndIssuer
, distPointWithUrlAndIssuer
[1] + 2,
3586 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3587 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3590 info
= (PCRL_DIST_POINTS_INFO
)buf
;
3591 ok(size
>= sizeof(CRL_DIST_POINTS_INFO
) + sizeof(CRL_DIST_POINT
),
3592 "Wrong size %d\n", size
);
3593 ok(info
->cDistPoint
== 1, "Expected 1 dist points, got %d\n",
3595 point
= info
->rgDistPoint
;
3596 ok(point
->DistPointName
.dwDistPointNameChoice
==
3597 CRL_DIST_POINT_FULL_NAME
,
3598 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3599 point
->DistPointName
.dwDistPointNameChoice
);
3600 ok(U(point
->DistPointName
).FullName
.cAltEntry
== 1,
3601 "Expected 1 name entry, got %d\n",
3602 U(point
->DistPointName
).FullName
.cAltEntry
);
3603 entry
= U(point
->DistPointName
).FullName
.rgAltEntry
;
3604 ok(entry
->dwAltNameChoice
== CERT_ALT_NAME_URL
,
3605 "Expected CERT_ALT_NAME_URL, got %d\n", entry
->dwAltNameChoice
);
3606 ok(!lstrcmpW(U(*entry
).pwszURL
, url
), "Unexpected name\n");
3607 ok(point
->ReasonFlags
.cbData
== 0, "Expected no reason\n");
3608 ok(point
->CRLIssuer
.cAltEntry
== 1,
3609 "Expected 1 issuer entry, got %d\n", point
->CRLIssuer
.cAltEntry
);
3610 entry
= point
->CRLIssuer
.rgAltEntry
;
3611 ok(entry
->dwAltNameChoice
== CERT_ALT_NAME_URL
,
3612 "Expected CERT_ALT_NAME_URL, got %d\n", entry
->dwAltNameChoice
);
3613 ok(!lstrcmpW(U(*entry
).pwszURL
, url
), "Unexpected name\n");
3616 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
,
3617 distPointWithUrlAndIssuer
, distPointWithUrlAndIssuer
[1] + 2, 0,
3619 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3620 buf
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
3623 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
,
3624 distPointWithUrlAndIssuer
, distPointWithUrlAndIssuer
[1] + 2, 0,
3626 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3627 HeapFree(GetProcessHeap(), 0, buf
);
3631 static const BYTE badFlagsIDP
[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3632 static const BYTE emptyNameIDP
[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3633 static const BYTE urlIDP
[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3634 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3637 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding
)
3642 CRL_ISSUING_DIST_POINT point
= { { 0 } };
3643 CERT_ALT_NAME_ENTRY entry
;
3645 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, NULL
,
3646 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3647 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
3649 skip("no X509_ISSUING_DIST_POINT encode support\n");
3652 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
3653 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3654 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, &point
,
3655 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3656 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3659 ok(size
== sizeof(emptySequence
), "Unexpected size %d\n", size
);
3660 ok(!memcmp(buf
, emptySequence
, size
), "Unexpected value\n");
3663 /* nonsensical flags */
3664 point
.fOnlyContainsUserCerts
= TRUE
;
3665 point
.fOnlyContainsCACerts
= TRUE
;
3666 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, &point
,
3667 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3668 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3671 ok(size
== sizeof(badFlagsIDP
), "Unexpected size %d\n", size
);
3672 ok(!memcmp(buf
, badFlagsIDP
, size
), "Unexpected value\n");
3675 /* unimplemented name type */
3676 point
.fOnlyContainsCACerts
= point
.fOnlyContainsUserCerts
= FALSE
;
3677 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_ISSUER_RDN_NAME
;
3678 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, &point
,
3679 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3680 ok(!ret
&& GetLastError() == E_INVALIDARG
,
3681 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3683 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3684 U(point
.DistPointName
).FullName
.cAltEntry
= 0;
3685 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, &point
,
3686 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3687 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3690 ok(size
== sizeof(emptyNameIDP
), "Unexpected size %d\n", size
);
3691 ok(!memcmp(buf
, emptyNameIDP
, size
), "Unexpected value\n");
3694 /* name with URL entry */
3695 entry
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
3696 U(entry
).pwszURL
= (LPWSTR
)url
;
3697 U(point
.DistPointName
).FullName
.cAltEntry
= 1;
3698 U(point
.DistPointName
).FullName
.rgAltEntry
= &entry
;
3699 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, &point
,
3700 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3701 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3704 ok(size
== sizeof(urlIDP
), "Unexpected size %d\n", size
);
3705 ok(!memcmp(buf
, urlIDP
, size
), "Unexpected value\n");
3710 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY
*expected
,
3711 const CERT_ALT_NAME_ENTRY
*got
)
3713 ok(expected
->dwAltNameChoice
== got
->dwAltNameChoice
,
3714 "Expected name choice %d, got %d\n", expected
->dwAltNameChoice
,
3715 got
->dwAltNameChoice
);
3716 if (expected
->dwAltNameChoice
== got
->dwAltNameChoice
)
3718 switch (got
->dwAltNameChoice
)
3720 case CERT_ALT_NAME_RFC822_NAME
:
3721 case CERT_ALT_NAME_DNS_NAME
:
3722 case CERT_ALT_NAME_EDI_PARTY_NAME
:
3723 case CERT_ALT_NAME_URL
:
3724 case CERT_ALT_NAME_REGISTERED_ID
:
3725 ok((!U(*expected
).pwszURL
&& !U(*got
).pwszURL
) ||
3726 (!U(*expected
).pwszURL
&& !lstrlenW(U(*got
).pwszURL
)) ||
3727 (!U(*got
).pwszURL
&& !lstrlenW(U(*expected
).pwszURL
)) ||
3728 !lstrcmpW(U(*expected
).pwszURL
, U(*got
).pwszURL
),
3729 "Unexpected name\n");
3731 case CERT_ALT_NAME_X400_ADDRESS
:
3732 case CERT_ALT_NAME_DIRECTORY_NAME
:
3733 case CERT_ALT_NAME_IP_ADDRESS
:
3734 ok(U(*got
).IPAddress
.cbData
== U(*expected
).IPAddress
.cbData
,
3735 "Unexpected IP address length %d\n", U(*got
).IPAddress
.cbData
);
3736 ok(!memcmp(U(*got
).IPAddress
.pbData
, U(*got
).IPAddress
.pbData
,
3737 U(*got
).IPAddress
.cbData
), "Unexpected value\n");
3743 static void compareAltNameInfo(const CERT_ALT_NAME_INFO
*expected
,
3744 const CERT_ALT_NAME_INFO
*got
)
3748 ok(expected
->cAltEntry
== got
->cAltEntry
, "Expected %d entries, got %d\n",
3749 expected
->cAltEntry
, got
->cAltEntry
);
3750 for (i
= 0; i
< min(expected
->cAltEntry
, got
->cAltEntry
); i
++)
3751 compareAltNameEntry(&expected
->rgAltEntry
[i
], &got
->rgAltEntry
[i
]);
3754 static void compareDistPointName(const CRL_DIST_POINT_NAME
*expected
,
3755 const CRL_DIST_POINT_NAME
*got
)
3757 ok(got
->dwDistPointNameChoice
== expected
->dwDistPointNameChoice
,
3758 "Unexpected name choice %d\n", got
->dwDistPointNameChoice
);
3759 if (got
->dwDistPointNameChoice
== CRL_DIST_POINT_FULL_NAME
)
3760 compareAltNameInfo(&(U(*expected
).FullName
), &(U(*got
).FullName
));
3763 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT
*expected
,
3764 const CRL_ISSUING_DIST_POINT
*got
)
3766 compareDistPointName(&expected
->DistPointName
, &got
->DistPointName
);
3767 ok(got
->fOnlyContainsUserCerts
== expected
->fOnlyContainsUserCerts
,
3768 "Unexpected fOnlyContainsUserCerts\n");
3769 ok(got
->fOnlyContainsCACerts
== expected
->fOnlyContainsCACerts
,
3770 "Unexpected fOnlyContainsCACerts\n");
3771 ok(got
->OnlySomeReasonFlags
.cbData
== expected
->OnlySomeReasonFlags
.cbData
,
3772 "Unexpected reason flags\n");
3773 ok(got
->fIndirectCRL
== expected
->fIndirectCRL
,
3774 "Unexpected fIndirectCRL\n");
3777 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding
)
3782 CRL_ISSUING_DIST_POINT point
= { { 0 } };
3784 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
,
3785 emptySequence
, emptySequence
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3787 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
3789 skip("no X509_ISSUING_DIST_POINT decode support\n");
3792 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3795 compareCRLIssuingDistPoints(&point
, (PCRL_ISSUING_DIST_POINT
)buf
);
3798 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
,
3799 badFlagsIDP
, badFlagsIDP
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3801 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3804 point
.fOnlyContainsUserCerts
= point
.fOnlyContainsCACerts
= TRUE
;
3805 compareCRLIssuingDistPoints(&point
, (PCRL_ISSUING_DIST_POINT
)buf
);
3808 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
,
3809 emptyNameIDP
, emptyNameIDP
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3811 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3814 point
.fOnlyContainsCACerts
= point
.fOnlyContainsUserCerts
= FALSE
;
3815 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3816 U(point
.DistPointName
).FullName
.cAltEntry
= 0;
3817 compareCRLIssuingDistPoints(&point
, (PCRL_ISSUING_DIST_POINT
)buf
);
3820 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
,
3821 urlIDP
, urlIDP
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3822 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3825 CERT_ALT_NAME_ENTRY entry
;
3827 entry
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
3828 U(entry
).pwszURL
= (LPWSTR
)url
;
3829 U(point
.DistPointName
).FullName
.cAltEntry
= 1;
3830 U(point
.DistPointName
).FullName
.rgAltEntry
= &entry
;
3831 compareCRLIssuingDistPoints(&point
, (PCRL_ISSUING_DIST_POINT
)buf
);
3836 static const BYTE v1CRL
[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3837 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3839 static const BYTE v2CRL
[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3840 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3841 0x30, 0x30, 0x30, 0x30, 0x5a };
3842 static const BYTE v1CRLWithIssuer
[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3843 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3844 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3845 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3847 static const BYTE v1CRLWithIssuerAndEmptyEntry
[] = { 0x30, 0x43, 0x30, 0x02,
3848 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3849 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3850 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3851 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3852 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3853 static const BYTE v1CRLWithIssuerAndEntry
[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3854 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3855 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3856 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3857 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3858 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3859 static const BYTE v1CRLWithEntryExt
[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3860 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3861 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3862 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3863 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3864 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3865 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3866 static const BYTE v1CRLWithExt
[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3867 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3868 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3869 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
3870 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3871 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
3872 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3873 static const BYTE v2CRLWithExt
[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
3874 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
3875 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
3876 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
3877 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
3878 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
3879 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3881 static void test_encodeCRLToBeSigned(DWORD dwEncoding
)
3886 CRL_INFO info
= { 0 };
3887 CRL_ENTRY entry
= { { 0 }, { 0 }, 0, 0 };
3889 /* Test with a V1 CRL */
3890 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3891 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3892 ok(ret
|| broken(GetLastError() == OSS_DATA_ERROR
/* Win9x */),
3893 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3896 ok(size
== sizeof(v1CRL
), "Wrong size %d\n", size
);
3897 ok(!memcmp(buf
, v1CRL
, size
), "Got unexpected value\n");
3901 info
.dwVersion
= CRL_V2
;
3902 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3903 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3904 ok(ret
|| broken(GetLastError() == OSS_DATA_ERROR
/* Win9x */),
3905 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3908 ok(size
== v2CRL
[1] + 2, "Expected size %d, got %d\n",
3909 v2CRL
[1] + 2, size
);
3910 ok(!memcmp(buf
, v2CRL
, size
), "Got unexpected value\n");
3913 /* v1 CRL with a name */
3914 info
.dwVersion
= CRL_V1
;
3915 info
.Issuer
.cbData
= sizeof(encodedCommonName
);
3916 info
.Issuer
.pbData
= (BYTE
*)encodedCommonName
;
3917 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3918 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3919 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3922 ok(size
== sizeof(v1CRLWithIssuer
), "Wrong size %d\n", size
);
3923 ok(!memcmp(buf
, v1CRLWithIssuer
, size
), "Got unexpected value\n");
3928 /* v1 CRL with a name and a NULL entry pointer (crashes on win9x) */
3930 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3931 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3932 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
3933 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3935 /* now set an empty entry */
3937 info
.rgCRLEntry
= &entry
;
3938 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3939 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3942 ok(size
== sizeof(v1CRLWithIssuerAndEmptyEntry
),
3943 "Wrong size %d\n", size
);
3944 ok(!memcmp(buf
, v1CRLWithIssuerAndEmptyEntry
, size
),
3945 "Got unexpected value\n");
3948 /* an entry with a serial number */
3949 entry
.SerialNumber
.cbData
= sizeof(serialNum
);
3950 entry
.SerialNumber
.pbData
= (BYTE
*)serialNum
;
3951 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3952 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3955 ok(size
== sizeof(v1CRLWithIssuerAndEntry
),
3956 "Wrong size %d\n", size
);
3957 ok(!memcmp(buf
, v1CRLWithIssuerAndEntry
, size
),
3958 "Got unexpected value\n");
3961 /* an entry with an extension */
3962 entry
.cExtension
= 1;
3963 entry
.rgExtension
= &criticalExt
;
3964 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3965 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3966 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3969 ok(size
== sizeof(v1CRLWithEntryExt
), "Wrong size %d\n", size
);
3970 ok(!memcmp(buf
, v1CRLWithEntryExt
, size
), "Got unexpected value\n");
3973 /* a CRL with an extension */
3974 entry
.cExtension
= 0;
3975 info
.cExtension
= 1;
3976 info
.rgExtension
= &criticalExt
;
3977 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3978 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3979 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3982 ok(size
== sizeof(v1CRLWithExt
), "Wrong size %d\n", size
);
3983 ok(!memcmp(buf
, v1CRLWithExt
, size
), "Got unexpected value\n");
3986 /* a v2 CRL with an extension, this time non-critical */
3987 info
.dwVersion
= CRL_V2
;
3988 info
.rgExtension
= &nonCriticalExt
;
3989 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3990 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3991 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3994 ok(size
== sizeof(v2CRLWithExt
), "Wrong size %d\n", size
);
3995 ok(!memcmp(buf
, v2CRLWithExt
, size
), "Got unexpected value\n");
4000 static const BYTE verisignCRL
[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
4001 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
4002 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
4003 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
4004 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
4005 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
4006 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
4007 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
4008 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
4009 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
4010 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
4011 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
4012 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
4013 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
4014 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
4015 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
4016 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
4017 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
4018 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
4019 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
4020 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
4021 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
4022 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
4023 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
4024 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
4025 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
4026 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
4027 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
4028 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
4029 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
4030 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
4031 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
4032 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
4033 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
4035 static const BYTE verisignCRLWithLotsOfEntries
[] = {
4036 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
4037 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
4038 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
4039 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
4040 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
4041 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
4042 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
4043 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
4044 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
4045 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
4046 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
4047 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
4048 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
4049 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
4050 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
4051 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
4052 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
4053 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
4054 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
4055 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
4056 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
4057 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
4058 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
4059 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
4060 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
4061 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
4062 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
4063 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
4064 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
4065 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
4066 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
4067 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
4068 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
4069 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
4070 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
4071 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
4072 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
4073 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
4074 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
4075 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
4076 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
4077 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
4078 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
4079 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
4080 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
4081 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
4082 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
4083 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
4084 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
4085 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
4086 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
4087 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
4088 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
4089 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
4090 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
4091 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
4092 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
4093 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
4094 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
4095 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
4096 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
4097 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
4098 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
4099 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
4100 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
4101 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
4102 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
4103 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
4104 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
4105 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
4106 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
4107 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
4108 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
4109 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
4110 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
4111 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
4112 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
4113 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
4114 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
4115 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
4116 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
4117 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
4118 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
4119 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
4120 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
4121 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
4122 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
4123 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
4124 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
4125 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
4126 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
4127 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
4128 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
4129 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
4130 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
4131 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
4132 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
4133 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
4134 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
4135 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
4136 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
4137 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
4138 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
4139 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
4140 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
4141 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
4142 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
4143 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
4144 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
4145 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
4146 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
4147 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
4148 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
4149 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
4150 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
4151 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
4152 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
4153 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
4154 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
4155 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
4156 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
4157 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
4158 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
4159 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
4160 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
4161 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
4162 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
4163 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
4164 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
4165 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
4166 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
4167 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
4168 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
4169 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
4170 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
4171 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
4172 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
4173 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
4174 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
4175 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
4176 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
4177 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
4178 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
4179 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
4180 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
4181 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
4182 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
4183 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
4184 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
4185 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
4186 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
4187 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
4188 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
4189 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
4190 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
4191 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
4192 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
4193 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
4194 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
4195 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
4196 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
4197 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
4198 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
4199 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
4200 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
4201 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
4202 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
4203 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
4204 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
4205 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
4206 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
4207 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
4208 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
4209 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
4210 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
4211 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
4212 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
4213 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
4214 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
4215 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
4216 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
4217 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
4218 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
4219 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
4220 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
4221 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
4222 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
4223 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
4224 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
4225 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
4226 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
4227 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
4228 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
4229 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
4230 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
4231 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
4232 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
4233 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
4234 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
4235 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
4236 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
4237 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
4238 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
4239 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
4240 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
4241 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
4242 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
4243 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
4244 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
4245 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
4246 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
4247 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
4248 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
4249 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
4250 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
4251 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
4252 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
4253 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
4254 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
4255 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
4256 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
4257 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
4258 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
4259 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
4260 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
4261 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
4262 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
4263 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
4264 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
4265 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
4266 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
4267 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
4268 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
4269 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
4270 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
4271 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
4272 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
4273 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
4274 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
4275 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
4276 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
4277 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
4278 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
4279 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
4280 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
4281 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
4282 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
4283 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
4284 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
4285 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
4286 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
4287 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
4288 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
4289 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
4290 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
4291 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
4292 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
4293 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
4294 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
4295 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
4296 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
4297 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
4298 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
4299 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
4300 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
4301 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
4302 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
4303 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
4304 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
4305 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
4306 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
4307 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
4308 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
4309 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
4310 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
4311 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
4312 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
4313 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
4314 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
4315 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
4316 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
4317 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
4318 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
4319 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
4320 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
4321 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
4322 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
4323 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
4324 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
4325 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
4326 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
4327 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
4328 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
4329 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
4330 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
4331 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
4332 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
4333 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
4334 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
4335 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
4336 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
4337 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
4338 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
4339 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4340 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4341 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4342 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4343 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4344 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4345 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4346 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4347 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4348 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4349 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4350 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4351 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4352 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4353 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4354 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4355 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4356 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4357 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4358 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4359 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4360 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4361 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4362 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4363 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4364 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4365 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4366 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4367 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4368 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4369 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4370 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4371 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4372 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4373 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4374 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4375 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4376 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4377 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4378 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4379 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4380 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4381 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4382 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4383 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4384 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4385 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4386 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4387 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4388 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4389 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4390 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4391 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4392 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4393 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4394 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4395 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4396 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4397 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4398 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4399 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4400 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4401 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4402 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4403 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4404 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4405 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4406 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4407 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4408 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4409 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4410 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4411 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4412 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4413 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4414 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4415 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4416 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4417 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4418 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4419 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4420 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4421 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4422 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4423 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4424 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4425 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4426 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4427 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4428 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4429 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4430 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4431 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4432 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4433 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4434 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4435 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4436 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4437 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4438 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4439 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4440 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4441 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4442 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4443 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4444 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4445 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4446 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4447 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4448 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4449 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4450 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4451 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4452 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4453 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4454 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4455 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4456 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4457 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4458 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4459 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4460 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4461 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4462 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4463 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4464 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4465 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4466 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4467 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4468 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4469 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4470 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4471 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4472 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4473 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4474 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4475 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4476 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4477 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4478 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4479 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4480 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4481 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4482 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4483 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4484 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4485 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4486 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4487 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4488 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4489 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4490 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4491 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4492 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4493 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4494 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4495 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4496 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4497 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4498 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4499 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4500 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4501 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4502 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4503 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4504 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4505 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4506 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4507 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4508 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4509 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4510 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4511 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4512 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4513 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4514 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4515 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4516 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4517 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4518 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4519 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4520 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4521 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4522 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4523 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4524 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4525 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4526 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4527 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4528 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4529 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4530 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4531 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4532 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4533 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4534 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4535 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4536 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4537 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4538 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4539 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4540 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4541 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4542 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4543 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4545 static void test_decodeCRLToBeSigned(DWORD dwEncoding
)
4547 static const BYTE
*corruptCRLs
[] = { v1CRL
, v2CRL
};
4552 for (i
= 0; i
< sizeof(corruptCRLs
) / sizeof(corruptCRLs
[0]); i
++)
4554 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4555 corruptCRLs
[i
], corruptCRLs
[i
][1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4557 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
4558 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
4559 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4562 /* at a minimum, a CRL must contain an issuer: */
4563 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4564 v1CRLWithIssuer
, v1CRLWithIssuer
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4566 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4569 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4571 ok(size
>= sizeof(CRL_INFO
), "Wrong size %d\n", size
);
4572 ok(info
->cCRLEntry
== 0, "Expected 0 CRL entries, got %d\n",
4574 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
4575 "Wrong issuer size %d\n", info
->Issuer
.cbData
);
4576 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
4577 "Unexpected issuer\n");
4580 /* check decoding with an empty CRL entry */
4581 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4582 v1CRLWithIssuerAndEmptyEntry
, v1CRLWithIssuerAndEmptyEntry
[1] + 2,
4583 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4584 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
4585 GetLastError() == OSS_DATA_ERROR
/* Win9x */ ||
4586 GetLastError() == CRYPT_E_BAD_ENCODE
/* Win8 */),
4587 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4589 /* with a real CRL entry */
4590 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4591 v1CRLWithIssuerAndEntry
, v1CRLWithIssuerAndEntry
[1] + 2,
4592 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4593 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4596 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4599 ok(size
>= sizeof(CRL_INFO
), "Wrong size %d\n", size
);
4600 ok(info
->cCRLEntry
== 1, "Expected 1 CRL entries, got %d\n",
4602 ok(info
->rgCRLEntry
!= NULL
, "Expected a valid CRL entry array\n");
4603 entry
= info
->rgCRLEntry
;
4604 ok(entry
->SerialNumber
.cbData
== 1,
4605 "Expected serial number size 1, got %d\n",
4606 entry
->SerialNumber
.cbData
);
4607 ok(*entry
->SerialNumber
.pbData
== *serialNum
,
4608 "Expected serial number %d, got %d\n", *serialNum
,
4609 *entry
->SerialNumber
.pbData
);
4610 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
4611 "Wrong issuer size %d\n", info
->Issuer
.cbData
);
4612 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
4613 "Unexpected issuer\n");
4616 /* a real CRL from verisign that has extensions */
4617 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4618 verisignCRL
, sizeof(verisignCRL
), CRYPT_DECODE_ALLOC_FLAG
,
4620 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4623 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4625 ok(size
>= sizeof(CRL_INFO
), "Wrong size %d\n", size
);
4626 ok(info
->cCRLEntry
== 3, "Expected 3 CRL entries, got %d\n",
4628 ok(info
->rgCRLEntry
!= NULL
, "Expected a valid CRL entry array\n");
4629 ok(info
->cExtension
== 2, "Expected 2 extensions, got %d\n",
4633 /* another real CRL from verisign that has lots of entries */
4634 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4635 verisignCRLWithLotsOfEntries
, sizeof(verisignCRLWithLotsOfEntries
),
4636 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4637 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4640 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4642 ok(size
>= sizeof(CRL_INFO
), "Got size %d\n", size
);
4643 ok(info
->cCRLEntry
== 209, "Expected 209 CRL entries, got %d\n",
4645 ok(info
->cExtension
== 0, "Expected 0 extensions, got %d\n",
4649 /* and finally, with an extension */
4650 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4651 v1CRLWithExt
, sizeof(v1CRLWithExt
), CRYPT_DECODE_ALLOC_FLAG
,
4653 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4656 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4659 ok(size
>= sizeof(CRL_INFO
), "Wrong size %d\n", size
);
4660 ok(info
->cCRLEntry
== 1, "Expected 1 CRL entries, got %d\n",
4662 ok(info
->rgCRLEntry
!= NULL
, "Expected a valid CRL entry array\n");
4663 entry
= info
->rgCRLEntry
;
4664 ok(entry
->SerialNumber
.cbData
== 1,
4665 "Expected serial number size 1, got %d\n",
4666 entry
->SerialNumber
.cbData
);
4667 ok(*entry
->SerialNumber
.pbData
== *serialNum
,
4668 "Expected serial number %d, got %d\n", *serialNum
,
4669 *entry
->SerialNumber
.pbData
);
4670 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
4671 "Wrong issuer size %d\n", info
->Issuer
.cbData
);
4672 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
4673 "Unexpected issuer\n");
4674 ok(info
->cExtension
== 1, "Expected 1 extensions, got %d\n",
4678 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4679 v2CRLWithExt
, sizeof(v2CRLWithExt
), CRYPT_DECODE_ALLOC_FLAG
,
4681 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4684 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4686 ok(info
->cExtension
== 1, "Expected 1 extensions, got %d\n",
4692 static const LPCSTR keyUsages
[] = { szOID_PKIX_KP_CODE_SIGNING
,
4693 szOID_PKIX_KP_CLIENT_AUTH
, szOID_RSA_RSA
};
4694 static const BYTE encodedUsage
[] = {
4695 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4696 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4697 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4699 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding
)
4704 CERT_ENHKEY_USAGE usage
;
4706 /* Test with empty usage */
4707 usage
.cUsageIdentifier
= 0;
4708 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ENHANCED_KEY_USAGE
, &usage
,
4709 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4710 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4713 ok(size
== sizeof(emptySequence
), "Wrong size %d\n", size
);
4714 ok(!memcmp(buf
, emptySequence
, size
), "Got unexpected value\n");
4717 /* Test with a few usages */
4718 usage
.cUsageIdentifier
= sizeof(keyUsages
) / sizeof(keyUsages
[0]);
4719 usage
.rgpszUsageIdentifier
= (LPSTR
*)keyUsages
;
4720 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ENHANCED_KEY_USAGE
, &usage
,
4721 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4722 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4725 ok(size
== sizeof(encodedUsage
), "Wrong size %d\n", size
);
4726 ok(!memcmp(buf
, encodedUsage
, size
), "Got unexpected value\n");
4731 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding
)
4737 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ENHANCED_KEY_USAGE
,
4738 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4740 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4743 CERT_ENHKEY_USAGE
*usage
= (CERT_ENHKEY_USAGE
*)buf
;
4745 ok(size
>= sizeof(CERT_ENHKEY_USAGE
),
4746 "Wrong size %d\n", size
);
4747 ok(usage
->cUsageIdentifier
== 0, "Expected 0 CRL entries, got %d\n",
4748 usage
->cUsageIdentifier
);
4751 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ENHANCED_KEY_USAGE
,
4752 encodedUsage
, sizeof(encodedUsage
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4754 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4757 CERT_ENHKEY_USAGE
*usage
= (CERT_ENHKEY_USAGE
*)buf
;
4760 ok(size
>= sizeof(CERT_ENHKEY_USAGE
),
4761 "Wrong size %d\n", size
);
4762 ok(usage
->cUsageIdentifier
== sizeof(keyUsages
) / sizeof(keyUsages
[0]),
4763 "Wrong CRL entries count %d\n", usage
->cUsageIdentifier
);
4764 for (i
= 0; i
< usage
->cUsageIdentifier
; i
++)
4765 ok(!strcmp(usage
->rgpszUsageIdentifier
[i
], keyUsages
[i
]),
4766 "Expected OID %s, got %s\n", keyUsages
[i
],
4767 usage
->rgpszUsageIdentifier
[i
]);
4770 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ENHANCED_KEY_USAGE
,
4771 encodedUsage
, sizeof(encodedUsage
), 0, NULL
, NULL
, &size
);
4772 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4773 buf
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
4776 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ENHANCED_KEY_USAGE
,
4777 encodedUsage
, sizeof(encodedUsage
), 0, NULL
, buf
, &size
);
4778 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4779 HeapFree(GetProcessHeap(), 0, buf
);
4783 static BYTE keyId
[] = { 1,2,3,4 };
4784 static const BYTE authorityKeyIdWithId
[] = {
4785 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4786 static const BYTE authorityKeyIdWithIssuer
[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4787 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4788 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4789 static const BYTE authorityKeyIdWithSerial
[] = { 0x30,0x03,0x82,0x01,0x01 };
4791 static void test_encodeAuthorityKeyId(DWORD dwEncoding
)
4793 CERT_AUTHORITY_KEY_ID_INFO info
= { { 0 } };
4798 /* Test with empty id */
4799 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
, &info
,
4800 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4801 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4804 ok(size
== sizeof(emptySequence
), "Unexpected size %d\n", size
);
4805 ok(!memcmp(buf
, emptySequence
, size
), "Unexpected value\n");
4808 /* With just a key id */
4809 info
.KeyId
.cbData
= sizeof(keyId
);
4810 info
.KeyId
.pbData
= keyId
;
4811 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
, &info
,
4812 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4813 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4816 ok(size
== sizeof(authorityKeyIdWithId
), "Unexpected size %d\n", size
);
4817 ok(!memcmp(buf
, authorityKeyIdWithId
, size
), "Unexpected value\n");
4820 /* With just an issuer */
4821 info
.KeyId
.cbData
= 0;
4822 info
.CertIssuer
.cbData
= sizeof(encodedCommonName
);
4823 info
.CertIssuer
.pbData
= (BYTE
*)encodedCommonName
;
4824 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
, &info
,
4825 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4826 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4829 ok(size
== sizeof(authorityKeyIdWithIssuer
), "Unexpected size %d\n",
4831 ok(!memcmp(buf
, authorityKeyIdWithIssuer
, size
), "Unexpected value\n");
4834 /* With just a serial number */
4835 info
.CertIssuer
.cbData
= 0;
4836 info
.CertSerialNumber
.cbData
= sizeof(serialNum
);
4837 info
.CertSerialNumber
.pbData
= (BYTE
*)serialNum
;
4838 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
, &info
,
4839 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4840 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4843 ok(size
== sizeof(authorityKeyIdWithSerial
), "Unexpected size %d\n",
4845 ok(!memcmp(buf
, authorityKeyIdWithSerial
, size
), "Unexpected value\n");
4850 static void test_decodeAuthorityKeyId(DWORD dwEncoding
)
4856 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
,
4857 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4859 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4862 CERT_AUTHORITY_KEY_ID_INFO
*info
= (CERT_AUTHORITY_KEY_ID_INFO
*)buf
;
4864 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID_INFO
), "Unexpected size %d\n",
4866 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
4867 ok(info
->CertIssuer
.cbData
== 0, "Expected no issuer name\n");
4868 ok(info
->CertSerialNumber
.cbData
== 0, "Expected no serial number\n");
4871 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
,
4872 authorityKeyIdWithId
, sizeof(authorityKeyIdWithId
),
4873 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4874 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4877 CERT_AUTHORITY_KEY_ID_INFO
*info
= (CERT_AUTHORITY_KEY_ID_INFO
*)buf
;
4879 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID_INFO
), "Unexpected size %d\n",
4881 ok(info
->KeyId
.cbData
== sizeof(keyId
), "Unexpected key id len\n");
4882 ok(!memcmp(info
->KeyId
.pbData
, keyId
, sizeof(keyId
)),
4883 "Unexpected key id\n");
4884 ok(info
->CertIssuer
.cbData
== 0, "Expected no issuer name\n");
4885 ok(info
->CertSerialNumber
.cbData
== 0, "Expected no serial number\n");
4888 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
,
4889 authorityKeyIdWithIssuer
, sizeof(authorityKeyIdWithIssuer
),
4890 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4891 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4894 CERT_AUTHORITY_KEY_ID_INFO
*info
= (CERT_AUTHORITY_KEY_ID_INFO
*)buf
;
4896 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID_INFO
), "Unexpected size %d\n",
4898 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
4899 ok(info
->CertIssuer
.cbData
== sizeof(encodedCommonName
),
4900 "Unexpected issuer len\n");
4901 ok(!memcmp(info
->CertIssuer
.pbData
, encodedCommonName
,
4902 sizeof(encodedCommonName
)), "Unexpected issuer\n");
4903 ok(info
->CertSerialNumber
.cbData
== 0, "Expected no serial number\n");
4906 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
,
4907 authorityKeyIdWithSerial
, sizeof(authorityKeyIdWithSerial
),
4908 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4909 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4912 CERT_AUTHORITY_KEY_ID_INFO
*info
= (CERT_AUTHORITY_KEY_ID_INFO
*)buf
;
4914 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID_INFO
), "Unexpected size %d\n",
4916 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
4917 ok(info
->CertIssuer
.cbData
== 0, "Expected no issuer name\n");
4918 ok(info
->CertSerialNumber
.cbData
== sizeof(serialNum
),
4919 "Unexpected serial number len\n");
4920 ok(!memcmp(info
->CertSerialNumber
.pbData
, serialNum
, sizeof(serialNum
)),
4921 "Unexpected serial number\n");
4926 static const BYTE authorityKeyIdWithIssuerUrl
[] = { 0x30,0x15,0xa1,0x13,0x86,
4927 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
4930 static void test_encodeAuthorityKeyId2(DWORD dwEncoding
)
4932 CERT_AUTHORITY_KEY_ID2_INFO info
= { { 0 } };
4933 CERT_ALT_NAME_ENTRY entry
= { 0 };
4938 /* Test with empty id */
4939 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
, &info
,
4940 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4941 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4944 ok(size
== sizeof(emptySequence
), "Unexpected size %d\n", size
);
4945 ok(!memcmp(buf
, emptySequence
, size
), "Unexpected value\n");
4948 /* With just a key id */
4949 info
.KeyId
.cbData
= sizeof(keyId
);
4950 info
.KeyId
.pbData
= keyId
;
4951 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
, &info
,
4952 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4953 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4956 ok(size
== sizeof(authorityKeyIdWithId
), "Unexpected size %d\n",
4958 ok(!memcmp(buf
, authorityKeyIdWithId
, size
), "Unexpected value\n");
4961 /* With a bogus issuer name */
4962 info
.KeyId
.cbData
= 0;
4963 info
.AuthorityCertIssuer
.cAltEntry
= 1;
4964 info
.AuthorityCertIssuer
.rgAltEntry
= &entry
;
4965 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
, &info
,
4966 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4967 ok(!ret
&& GetLastError() == E_INVALIDARG
,
4968 "Expected E_INVALIDARG, got %08x\n", GetLastError());
4969 /* With an issuer name */
4970 entry
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
4971 U(entry
).pwszURL
= (LPWSTR
)url
;
4972 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
, &info
,
4973 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4974 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4977 ok(size
== sizeof(authorityKeyIdWithIssuerUrl
), "Unexpected size %d\n",
4979 ok(!memcmp(buf
, authorityKeyIdWithIssuerUrl
, size
),
4980 "Unexpected value\n");
4983 /* With just a serial number */
4984 info
.AuthorityCertIssuer
.cAltEntry
= 0;
4985 info
.AuthorityCertSerialNumber
.cbData
= sizeof(serialNum
);
4986 info
.AuthorityCertSerialNumber
.pbData
= (BYTE
*)serialNum
;
4987 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
, &info
,
4988 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4989 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4992 ok(size
== sizeof(authorityKeyIdWithSerial
), "Unexpected size %d\n",
4994 ok(!memcmp(buf
, authorityKeyIdWithSerial
, size
), "Unexpected value\n");
4999 static void test_decodeAuthorityKeyId2(DWORD dwEncoding
)
5005 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
,
5006 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5008 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5011 CERT_AUTHORITY_KEY_ID2_INFO
*info
= (CERT_AUTHORITY_KEY_ID2_INFO
*)buf
;
5013 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID2_INFO
), "Unexpected size %d\n",
5015 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
5016 ok(info
->AuthorityCertIssuer
.cAltEntry
== 0,
5017 "Expected no issuer name entries\n");
5018 ok(info
->AuthorityCertSerialNumber
.cbData
== 0,
5019 "Expected no serial number\n");
5022 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
,
5023 authorityKeyIdWithId
, sizeof(authorityKeyIdWithId
),
5024 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5025 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5028 CERT_AUTHORITY_KEY_ID2_INFO
*info
= (CERT_AUTHORITY_KEY_ID2_INFO
*)buf
;
5030 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID2_INFO
), "Unexpected size %d\n",
5032 ok(info
->KeyId
.cbData
== sizeof(keyId
), "Unexpected key id len\n");
5033 ok(!memcmp(info
->KeyId
.pbData
, keyId
, sizeof(keyId
)),
5034 "Unexpected key id\n");
5035 ok(info
->AuthorityCertIssuer
.cAltEntry
== 0,
5036 "Expected no issuer name entries\n");
5037 ok(info
->AuthorityCertSerialNumber
.cbData
== 0,
5038 "Expected no serial number\n");
5041 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
,
5042 authorityKeyIdWithIssuerUrl
, sizeof(authorityKeyIdWithIssuerUrl
),
5043 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5044 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5047 CERT_AUTHORITY_KEY_ID2_INFO
*info
= (CERT_AUTHORITY_KEY_ID2_INFO
*)buf
;
5049 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID2_INFO
), "Unexpected size %d\n",
5051 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
5052 ok(info
->AuthorityCertIssuer
.cAltEntry
== 1,
5053 "Expected 1 issuer entry, got %d\n",
5054 info
->AuthorityCertIssuer
.cAltEntry
);
5055 ok(info
->AuthorityCertIssuer
.rgAltEntry
[0].dwAltNameChoice
==
5056 CERT_ALT_NAME_URL
, "Expected CERT_ALT_NAME_URL, got %d\n",
5057 info
->AuthorityCertIssuer
.rgAltEntry
[0].dwAltNameChoice
);
5058 ok(!lstrcmpW(U(info
->AuthorityCertIssuer
.rgAltEntry
[0]).pwszURL
,
5059 url
), "Unexpected URL\n");
5060 ok(info
->AuthorityCertSerialNumber
.cbData
== 0,
5061 "Expected no serial number\n");
5064 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
,
5065 authorityKeyIdWithSerial
, sizeof(authorityKeyIdWithSerial
),
5066 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5067 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5070 CERT_AUTHORITY_KEY_ID2_INFO
*info
= (CERT_AUTHORITY_KEY_ID2_INFO
*)buf
;
5072 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID2_INFO
), "Unexpected size %d\n",
5074 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
5075 ok(info
->AuthorityCertIssuer
.cAltEntry
== 0,
5076 "Expected no issuer name entries\n");
5077 ok(info
->AuthorityCertSerialNumber
.cbData
== sizeof(serialNum
),
5078 "Unexpected serial number len\n");
5079 ok(!memcmp(info
->AuthorityCertSerialNumber
.pbData
, serialNum
,
5080 sizeof(serialNum
)), "Unexpected serial number\n");
5085 static const BYTE authorityInfoAccessWithUrl
[] = {
5086 0x30,0x19,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
5087 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5088 static const BYTE authorityInfoAccessWithUrlAndIPAddr
[] = {
5089 0x30,0x29,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
5090 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x0e,0x06,
5091 0x02,0x2d,0x06,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5093 static void test_encodeAuthorityInfoAccess(DWORD dwEncoding
)
5095 static char oid1
[] = "1.2.3";
5096 static char oid2
[] = "1.5.6";
5100 CERT_ACCESS_DESCRIPTION accessDescription
[2];
5101 CERT_AUTHORITY_INFO_ACCESS aia
;
5103 memset(accessDescription
, 0, sizeof(accessDescription
));
5105 aia
.rgAccDescr
= NULL
;
5106 /* Having no access descriptions is allowed */
5107 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
, &aia
,
5108 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5109 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5112 ok(size
== sizeof(emptySequence
), "unexpected size %d\n", size
);
5113 ok(!memcmp(buf
, emptySequence
, size
), "unexpected value\n");
5117 /* It can't have an empty access method */
5119 aia
.rgAccDescr
= accessDescription
;
5120 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
, &aia
,
5121 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5122 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
5123 GetLastError() == OSS_LIMITED
/* Win9x */),
5124 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
5125 /* It can't have an empty location */
5126 accessDescription
[0].pszAccessMethod
= oid1
;
5127 SetLastError(0xdeadbeef);
5128 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
, &aia
,
5129 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5130 ok(!ret
&& GetLastError() == E_INVALIDARG
,
5131 "expected E_INVALIDARG, got %08x\n", GetLastError());
5132 accessDescription
[0].AccessLocation
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
5133 U(accessDescription
[0].AccessLocation
).pwszURL
= (LPWSTR
)url
;
5134 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
, &aia
,
5135 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5136 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5139 ok(size
== sizeof(authorityInfoAccessWithUrl
), "unexpected size %d\n",
5141 ok(!memcmp(buf
, authorityInfoAccessWithUrl
, size
),
5142 "unexpected value\n");
5146 accessDescription
[1].pszAccessMethod
= oid2
;
5147 accessDescription
[1].AccessLocation
.dwAltNameChoice
=
5148 CERT_ALT_NAME_IP_ADDRESS
;
5149 U(accessDescription
[1].AccessLocation
).IPAddress
.cbData
=
5150 sizeof(encodedIPAddr
);
5151 U(accessDescription
[1].AccessLocation
).IPAddress
.pbData
=
5152 (LPBYTE
)encodedIPAddr
;
5154 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
, &aia
,
5155 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5156 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5159 ok(size
== sizeof(authorityInfoAccessWithUrlAndIPAddr
),
5160 "unexpected size %d\n", size
);
5161 ok(!memcmp(buf
, authorityInfoAccessWithUrlAndIPAddr
, size
),
5162 "unexpected value\n");
5168 static void compareAuthorityInfoAccess(LPCSTR header
,
5169 const CERT_AUTHORITY_INFO_ACCESS
*expected
,
5170 const CERT_AUTHORITY_INFO_ACCESS
*got
)
5174 ok(expected
->cAccDescr
== got
->cAccDescr
,
5175 "%s: expected %d access descriptions, got %d\n", header
,
5176 expected
->cAccDescr
, got
->cAccDescr
);
5177 for (i
= 0; i
< expected
->cAccDescr
; i
++)
5179 ok(!strcmp(expected
->rgAccDescr
[i
].pszAccessMethod
,
5180 got
->rgAccDescr
[i
].pszAccessMethod
), "%s[%d]: expected %s, got %s\n",
5181 header
, i
, expected
->rgAccDescr
[i
].pszAccessMethod
,
5182 got
->rgAccDescr
[i
].pszAccessMethod
);
5183 compareAltNameEntry(&expected
->rgAccDescr
[i
].AccessLocation
,
5184 &got
->rgAccDescr
[i
].AccessLocation
);
5188 static void test_decodeAuthorityInfoAccess(DWORD dwEncoding
)
5190 static char oid1
[] = "1.2.3";
5191 static char oid2
[] = "1.5.6";
5196 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
,
5197 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5199 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5202 CERT_AUTHORITY_INFO_ACCESS aia
= { 0, NULL
};
5204 compareAuthorityInfoAccess("empty AIA", &aia
,
5205 (CERT_AUTHORITY_INFO_ACCESS
*)buf
);
5209 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
,
5210 authorityInfoAccessWithUrl
, sizeof(authorityInfoAccessWithUrl
),
5211 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5212 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5215 CERT_ACCESS_DESCRIPTION accessDescription
;
5216 CERT_AUTHORITY_INFO_ACCESS aia
;
5218 accessDescription
.pszAccessMethod
= oid1
;
5219 accessDescription
.AccessLocation
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
5220 U(accessDescription
.AccessLocation
).pwszURL
= (LPWSTR
)url
;
5222 aia
.rgAccDescr
= &accessDescription
;
5223 compareAuthorityInfoAccess("AIA with URL", &aia
,
5224 (CERT_AUTHORITY_INFO_ACCESS
*)buf
);
5228 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
,
5229 authorityInfoAccessWithUrlAndIPAddr
,
5230 sizeof(authorityInfoAccessWithUrlAndIPAddr
), CRYPT_DECODE_ALLOC_FLAG
,
5232 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5235 CERT_ACCESS_DESCRIPTION accessDescription
[2];
5236 CERT_AUTHORITY_INFO_ACCESS aia
;
5238 accessDescription
[0].pszAccessMethod
= oid1
;
5239 accessDescription
[0].AccessLocation
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
5240 U(accessDescription
[0].AccessLocation
).pwszURL
= (LPWSTR
)url
;
5241 accessDescription
[1].pszAccessMethod
= oid2
;
5242 accessDescription
[1].AccessLocation
.dwAltNameChoice
=
5243 CERT_ALT_NAME_IP_ADDRESS
;
5244 U(accessDescription
[1].AccessLocation
).IPAddress
.cbData
=
5245 sizeof(encodedIPAddr
);
5246 U(accessDescription
[1].AccessLocation
).IPAddress
.pbData
=
5247 (LPBYTE
)encodedIPAddr
;
5249 aia
.rgAccDescr
= accessDescription
;
5250 compareAuthorityInfoAccess("AIA with URL and IP addr", &aia
,
5251 (CERT_AUTHORITY_INFO_ACCESS
*)buf
);
5255 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
,
5256 authorityInfoAccessWithUrlAndIPAddr
,
5257 sizeof(authorityInfoAccessWithUrlAndIPAddr
), 0, NULL
, NULL
, &size
);
5258 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5259 buf
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
5262 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
,
5263 authorityInfoAccessWithUrlAndIPAddr
,
5264 sizeof(authorityInfoAccessWithUrlAndIPAddr
), 0, NULL
, buf
, &size
);
5265 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5266 HeapFree(GetProcessHeap(), 0, buf
);
5270 static const BYTE emptyCTL
[] = {
5271 0x30,0x17,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5272 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5273 static const BYTE emptyCTLWithVersion1
[] = {
5274 0x30,0x1a,0x02,0x01,0x01,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5275 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5276 static const BYTE ctlWithUsageIdentifier
[] = {
5277 0x30,0x1b,0x30,0x04,0x06,0x02,0x2a,0x03,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
5278 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5279 static const BYTE ctlWithListIdentifier
[] = {
5280 0x30,0x1a,0x30,0x00,0x04,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5281 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5282 static const BYTE ctlWithSequenceNumber
[] = {
5283 0x30,0x1a,0x30,0x00,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5284 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5285 static const BYTE ctlWithThisUpdate
[] = {
5286 0x30,0x15,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5287 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5288 static const BYTE ctlWithThisAndNextUpdate
[] = {
5289 0x30,0x24,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5290 0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5291 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5292 static const BYTE ctlWithAlgId
[] = {
5293 0x30,0x1b,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5294 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5295 static const BYTE ctlWithBogusEntry
[] = {
5296 0x30,0x29,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5297 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x10,0x30,0x0e,0x04,
5298 0x01,0x01,0x31,0x09,0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,0x01 };
5299 static const BYTE ctlWithOneEntry
[] = {
5300 0x30,0x2a,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5301 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x11,0x30,0x0f,0x04,
5302 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00 };
5303 static const BYTE ctlWithTwoEntries
[] = {
5304 0x30,0x41,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5305 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x28,0x30,0x0f,0x04,
5306 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00,0x30,
5307 0x15,0x04,0x01,0x01,0x31,0x10,0x30,0x0e,0x06,0x02,0x2d,0x06,0x31,0x08,0x30,
5308 0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5310 static void test_encodeCTL(DWORD dwEncoding
)
5312 static char oid1
[] = "1.2.3";
5313 static char oid2
[] = "1.5.6";
5319 SYSTEMTIME thisUpdate
= { 2005, 6, 1, 6, 16, 10, 0, 0 };
5320 CTL_ENTRY ctlEntry
[2];
5321 CRYPT_ATTRIBUTE attr1
, attr2
;
5322 CRYPT_ATTR_BLOB value1
, value2
;
5324 memset(&info
, 0, sizeof(info
));
5325 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5326 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5327 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5330 ok(size
== sizeof(emptyCTL
), "unexpected size %d\n", size
);
5331 ok(!memcmp(buf
, emptyCTL
, size
), "unexpected value\n");
5336 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5337 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5338 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5341 ok(size
== sizeof(emptyCTLWithVersion1
), "unexpected size %d\n", size
);
5342 ok(!memcmp(buf
, emptyCTLWithVersion1
, size
), "unexpected value\n");
5347 info
.SubjectUsage
.cUsageIdentifier
= 1;
5348 info
.SubjectUsage
.rgpszUsageIdentifier
= &pOid1
;
5349 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5350 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5351 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5354 ok(size
== sizeof(ctlWithUsageIdentifier
), "unexpected size %d\n",
5356 ok(!memcmp(buf
, ctlWithUsageIdentifier
, size
), "unexpected value\n");
5360 info
.SubjectUsage
.cUsageIdentifier
= 0;
5361 info
.ListIdentifier
.cbData
= sizeof(serialNum
);
5362 info
.ListIdentifier
.pbData
= (LPBYTE
)serialNum
;
5363 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5364 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5365 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5368 ok(size
== sizeof(ctlWithListIdentifier
), "unexpected size %d\n", size
);
5369 ok(!memcmp(buf
, ctlWithListIdentifier
, size
), "unexpected value\n");
5373 info
.ListIdentifier
.cbData
= 0;
5374 info
.SequenceNumber
.cbData
= sizeof(serialNum
);
5375 info
.SequenceNumber
.pbData
= (LPBYTE
)serialNum
;
5376 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5377 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5378 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5381 ok(size
== sizeof(ctlWithSequenceNumber
), "unexpected size %d\n",
5383 ok(!memcmp(buf
, ctlWithSequenceNumber
, size
), "unexpected value\n");
5387 info
.SequenceNumber
.cbData
= 0;
5388 SystemTimeToFileTime(&thisUpdate
, &info
.ThisUpdate
);
5389 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5390 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5391 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5394 ok(size
== sizeof(ctlWithThisUpdate
), "unexpected size %d\n", size
);
5395 ok(!memcmp(buf
, ctlWithThisUpdate
, size
), "unexpected value\n");
5399 SystemTimeToFileTime(&thisUpdate
, &info
.NextUpdate
);
5400 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5401 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5402 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5405 ok(size
== sizeof(ctlWithThisAndNextUpdate
), "unexpected size %d\n",
5407 ok(!memcmp(buf
, ctlWithThisAndNextUpdate
, size
), "unexpected value\n");
5411 info
.ThisUpdate
.dwLowDateTime
= info
.ThisUpdate
.dwHighDateTime
= 0;
5412 info
.NextUpdate
.dwLowDateTime
= info
.NextUpdate
.dwHighDateTime
= 0;
5413 info
.SubjectAlgorithm
.pszObjId
= oid2
;
5414 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5415 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5416 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5419 ok(size
== sizeof(ctlWithAlgId
), "unexpected size %d\n", size
);
5420 ok(!memcmp(buf
, ctlWithAlgId
, size
), "unexpected value\n");
5424 /* The value is supposed to be asn.1 encoded, so this'll fail to decode
5425 * (see tests below) but it'll encode fine.
5427 info
.SubjectAlgorithm
.pszObjId
= NULL
;
5428 value1
.cbData
= sizeof(serialNum
);
5429 value1
.pbData
= (LPBYTE
)serialNum
;
5430 attr1
.pszObjId
= oid1
;
5432 attr1
.rgValue
= &value1
;
5433 ctlEntry
[0].SubjectIdentifier
.cbData
= sizeof(serialNum
);
5434 ctlEntry
[0].SubjectIdentifier
.pbData
= (LPBYTE
)serialNum
;
5435 ctlEntry
[0].cAttribute
= 1;
5436 ctlEntry
[0].rgAttribute
= &attr1
;
5438 info
.rgCTLEntry
= ctlEntry
;
5439 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5440 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5441 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5444 ok(size
== sizeof(ctlWithBogusEntry
), "unexpected size %d\n", size
);
5445 ok(!memcmp(buf
, ctlWithBogusEntry
, size
), "unexpected value\n");
5449 value1
.cbData
= sizeof(emptySequence
);
5450 value1
.pbData
= (LPBYTE
)emptySequence
;
5451 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5452 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5453 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5456 ok(size
== sizeof(ctlWithOneEntry
), "unexpected size %d\n", size
);
5457 ok(!memcmp(buf
, ctlWithOneEntry
, size
), "unexpected value\n");
5461 value2
.cbData
= sizeof(encodedIPAddr
);
5462 value2
.pbData
= (LPBYTE
)encodedIPAddr
;
5463 attr2
.pszObjId
= oid2
;
5465 attr2
.rgValue
= &value2
;
5466 ctlEntry
[1].SubjectIdentifier
.cbData
= sizeof(serialNum
);
5467 ctlEntry
[1].SubjectIdentifier
.pbData
= (LPBYTE
)serialNum
;
5468 ctlEntry
[1].cAttribute
= 1;
5469 ctlEntry
[1].rgAttribute
= &attr2
;
5471 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5472 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5473 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5476 ok(size
== sizeof(ctlWithTwoEntries
), "unexpected size %d\n", size
);
5477 ok(!memcmp(buf
, ctlWithTwoEntries
, size
), "unexpected value\n");
5483 static void compareCTLInfo(LPCSTR header
, const CTL_INFO
*expected
,
5484 const CTL_INFO
*got
)
5488 ok(expected
->dwVersion
== got
->dwVersion
,
5489 "%s: expected version %d, got %d\n", header
, expected
->dwVersion
,
5491 ok(expected
->SubjectUsage
.cUsageIdentifier
==
5492 got
->SubjectUsage
.cUsageIdentifier
,
5493 "%s: expected %d usage identifiers, got %d\n", header
,
5494 expected
->SubjectUsage
.cUsageIdentifier
,
5495 got
->SubjectUsage
.cUsageIdentifier
);
5496 for (i
= 0; i
< expected
->SubjectUsage
.cUsageIdentifier
; i
++)
5497 ok(!strcmp(expected
->SubjectUsage
.rgpszUsageIdentifier
[i
],
5498 got
->SubjectUsage
.rgpszUsageIdentifier
[i
]),
5499 "%s[%d]: expected %s, got %s\n", header
, i
,
5500 expected
->SubjectUsage
.rgpszUsageIdentifier
[i
],
5501 got
->SubjectUsage
.rgpszUsageIdentifier
[i
]);
5502 ok(expected
->ListIdentifier
.cbData
== got
->ListIdentifier
.cbData
,
5503 "%s: expected list identifier of %d bytes, got %d\n", header
,
5504 expected
->ListIdentifier
.cbData
, got
->ListIdentifier
.cbData
);
5505 if (expected
->ListIdentifier
.cbData
)
5506 ok(!memcmp(expected
->ListIdentifier
.pbData
, got
->ListIdentifier
.pbData
,
5507 expected
->ListIdentifier
.cbData
),
5508 "%s: unexpected list identifier value\n", header
);
5509 ok(expected
->SequenceNumber
.cbData
== got
->SequenceNumber
.cbData
,
5510 "%s: expected sequence number of %d bytes, got %d\n", header
,
5511 expected
->SequenceNumber
.cbData
, got
->SequenceNumber
.cbData
);
5512 if (expected
->SequenceNumber
.cbData
)
5513 ok(!memcmp(expected
->SequenceNumber
.pbData
, got
->SequenceNumber
.pbData
,
5514 expected
->SequenceNumber
.cbData
),
5515 "%s: unexpected sequence number value\n", header
);
5516 ok(!memcmp(&expected
->ThisUpdate
, &got
->ThisUpdate
, sizeof(FILETIME
)),
5517 "%s: expected this update = (%d, %d), got (%d, %d)\n", header
,
5518 expected
->ThisUpdate
.dwLowDateTime
, expected
->ThisUpdate
.dwHighDateTime
,
5519 got
->ThisUpdate
.dwLowDateTime
, got
->ThisUpdate
.dwHighDateTime
);
5520 ok(!memcmp(&expected
->NextUpdate
, &got
->NextUpdate
, sizeof(FILETIME
)),
5521 "%s: expected next update = (%d, %d), got (%d, %d)\n", header
,
5522 expected
->NextUpdate
.dwLowDateTime
, expected
->NextUpdate
.dwHighDateTime
,
5523 got
->NextUpdate
.dwLowDateTime
, got
->NextUpdate
.dwHighDateTime
);
5524 if (expected
->SubjectAlgorithm
.pszObjId
&&
5525 *expected
->SubjectAlgorithm
.pszObjId
&& !got
->SubjectAlgorithm
.pszObjId
)
5526 ok(0, "%s: expected subject algorithm %s, got NULL\n", header
,
5527 expected
->SubjectAlgorithm
.pszObjId
);
5528 if (expected
->SubjectAlgorithm
.pszObjId
&& got
->SubjectAlgorithm
.pszObjId
)
5529 ok(!strcmp(expected
->SubjectAlgorithm
.pszObjId
,
5530 got
->SubjectAlgorithm
.pszObjId
),
5531 "%s: expected subject algorithm %s, got %s\n", header
,
5532 expected
->SubjectAlgorithm
.pszObjId
, got
->SubjectAlgorithm
.pszObjId
);
5533 ok(expected
->SubjectAlgorithm
.Parameters
.cbData
==
5534 got
->SubjectAlgorithm
.Parameters
.cbData
,
5535 "%s: expected subject algorithm parameters of %d bytes, got %d\n", header
,
5536 expected
->SubjectAlgorithm
.Parameters
.cbData
,
5537 got
->SubjectAlgorithm
.Parameters
.cbData
);
5538 if (expected
->SubjectAlgorithm
.Parameters
.cbData
)
5539 ok(!memcmp(expected
->SubjectAlgorithm
.Parameters
.pbData
,
5540 got
->SubjectAlgorithm
.Parameters
.pbData
,
5541 expected
->SubjectAlgorithm
.Parameters
.cbData
),
5542 "%s: unexpected subject algorithm parameter value\n", header
);
5543 ok(expected
->cCTLEntry
== got
->cCTLEntry
,
5544 "%s: expected %d CTL entries, got %d\n", header
, expected
->cCTLEntry
,
5546 for (i
= 0; i
< expected
->cCTLEntry
; i
++)
5548 ok(expected
->rgCTLEntry
[i
].SubjectIdentifier
.cbData
==
5549 got
->rgCTLEntry
[i
].SubjectIdentifier
.cbData
,
5550 "%s[%d]: expected subject identifier of %d bytes, got %d\n",
5551 header
, i
, expected
->rgCTLEntry
[i
].SubjectIdentifier
.cbData
,
5552 got
->rgCTLEntry
[i
].SubjectIdentifier
.cbData
);
5553 if (expected
->rgCTLEntry
[i
].SubjectIdentifier
.cbData
)
5554 ok(!memcmp(expected
->rgCTLEntry
[i
].SubjectIdentifier
.pbData
,
5555 got
->rgCTLEntry
[i
].SubjectIdentifier
.pbData
,
5556 expected
->rgCTLEntry
[i
].SubjectIdentifier
.cbData
),
5557 "%s[%d]: unexpected subject identifier value\n",
5559 for (j
= 0; j
< expected
->rgCTLEntry
[i
].cAttribute
; j
++)
5561 ok(!strcmp(expected
->rgCTLEntry
[i
].rgAttribute
[j
].pszObjId
,
5562 got
->rgCTLEntry
[i
].rgAttribute
[j
].pszObjId
),
5563 "%s[%d][%d]: expected attribute OID %s, got %s\n", header
, i
, j
,
5564 expected
->rgCTLEntry
[i
].rgAttribute
[j
].pszObjId
,
5565 got
->rgCTLEntry
[i
].rgAttribute
[j
].pszObjId
);
5566 for (k
= 0; k
< expected
->rgCTLEntry
[i
].rgAttribute
[j
].cValue
; k
++)
5568 ok(expected
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].cbData
==
5569 got
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].cbData
,
5570 "%s[%d][%d][%d]: expected value of %d bytes, got %d\n",
5572 expected
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].cbData
,
5573 got
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].cbData
);
5574 if (expected
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].cbData
)
5576 expected
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].pbData
,
5577 got
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].pbData
,
5578 expected
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].cbData
),
5579 "%s[%d][%d][%d]: unexpected value\n",
5584 ok(expected
->cExtension
== got
->cExtension
,
5585 "%s: expected %d extensions, got %d\n", header
, expected
->cExtension
,
5587 for (i
= 0; i
< expected
->cExtension
; i
++)
5589 ok(!strcmp(expected
->rgExtension
[i
].pszObjId
,
5590 got
->rgExtension
[i
].pszObjId
), "%s[%d]: expected %s, got %s\n",
5591 header
, i
, expected
->rgExtension
[i
].pszObjId
,
5592 got
->rgExtension
[i
].pszObjId
);
5593 ok(expected
->rgExtension
[i
].fCritical
== got
->rgExtension
[i
].fCritical
,
5594 "%s[%d]: expected fCritical = %d, got %d\n", header
, i
,
5595 expected
->rgExtension
[i
].fCritical
, got
->rgExtension
[i
].fCritical
);
5596 ok(expected
->rgExtension
[i
].Value
.cbData
==
5597 got
->rgExtension
[i
].Value
.cbData
,
5598 "%s[%d]: expected extension value to have %d bytes, got %d\n",
5599 header
, i
, expected
->rgExtension
[i
].Value
.cbData
,
5600 got
->rgExtension
[i
].Value
.cbData
);
5601 if (expected
->rgExtension
[i
].Value
.cbData
)
5602 ok(!memcmp(expected
->rgExtension
[i
].Value
.pbData
,
5603 got
->rgExtension
[i
].Value
.pbData
,
5604 expected
->rgExtension
[i
].Value
.cbData
),
5605 "%s[%d]: unexpected extension value\n", header
, i
);
5609 static const BYTE signedCTL
[] = {
5610 0x30,0x81,0xc7,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
5611 0x81,0xb9,0x30,0x81,0xb6,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
5612 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x28,0x06,0x09,0x2a,0x86,
5613 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x1b,0x04,0x19,0x30,0x17,0x30,0x00,
5614 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5615 0x30,0x5a,0x30,0x02,0x06,0x00,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
5616 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
5617 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
5618 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5619 0x00,0x04,0x40,0xca,0xd8,0x32,0xd1,0xbd,0x97,0x61,0x54,0xd6,0x80,0xcf,0x0d,
5620 0xbd,0xa2,0x42,0xc7,0xca,0x37,0x91,0x7d,0x9d,0xac,0x8c,0xdf,0x05,0x8a,0x39,
5621 0xc6,0x07,0xc1,0x37,0xe6,0xb9,0xd1,0x0d,0x26,0xec,0xa5,0xb0,0x8a,0x51,0x26,
5622 0x2b,0x4f,0x73,0x44,0x86,0x83,0x5e,0x2b,0x6e,0xcc,0xf8,0x1b,0x85,0x53,0xe9,
5623 0x7a,0x80,0x8f,0x6b,0x42,0x19,0x93 };
5624 static const BYTE signedCTLWithCTLInnerContent
[] = {
5625 0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
5626 0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
5627 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
5628 0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
5629 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5630 0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
5631 0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
5632 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
5633 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
5634 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
5635 0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
5636 0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
5637 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
5638 0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5639 0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
5640 0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
5641 0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
5642 0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
5643 0x57,0x6c,0x0b,0x47,0xb8 };
5645 static void test_decodeCTL(DWORD dwEncoding
)
5647 static char oid1
[] = "1.2.3";
5648 static char oid2
[] = "1.5.6";
5649 static BYTE nullData
[] = { 5,0 };
5655 SYSTEMTIME thisUpdate
= { 2005, 6, 1, 6, 16, 10, 0, 0 };
5656 CTL_ENTRY ctlEntry
[2];
5657 CRYPT_ATTRIBUTE attr1
, attr2
;
5658 CRYPT_ATTR_BLOB value1
, value2
;
5660 memset(&info
, 0, sizeof(info
));
5661 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, emptyCTL
, sizeof(emptyCTL
),
5662 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5663 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5666 compareCTLInfo("empty CTL", &info
, (CTL_INFO
*)buf
);
5671 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, emptyCTLWithVersion1
,
5672 sizeof(emptyCTLWithVersion1
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
,
5674 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5677 compareCTLInfo("v1 CTL", &info
, (CTL_INFO
*)buf
);
5682 info
.SubjectUsage
.cUsageIdentifier
= 1;
5683 info
.SubjectUsage
.rgpszUsageIdentifier
= &pOid1
;
5684 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithUsageIdentifier
,
5685 sizeof(ctlWithUsageIdentifier
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5687 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5690 compareCTLInfo("CTL with usage identifier", &info
, (CTL_INFO
*)buf
);
5694 info
.SubjectUsage
.cUsageIdentifier
= 0;
5695 info
.ListIdentifier
.cbData
= sizeof(serialNum
);
5696 info
.ListIdentifier
.pbData
= (LPBYTE
)serialNum
;
5697 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithListIdentifier
,
5698 sizeof(ctlWithListIdentifier
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5699 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5702 compareCTLInfo("CTL with list identifier", &info
, (CTL_INFO
*)buf
);
5706 info
.ListIdentifier
.cbData
= 0;
5707 info
.SequenceNumber
.cbData
= sizeof(serialNum
);
5708 info
.SequenceNumber
.pbData
= (LPBYTE
)serialNum
;
5709 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithSequenceNumber
,
5710 sizeof(ctlWithSequenceNumber
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5711 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5714 compareCTLInfo("CTL with sequence number", &info
, (CTL_INFO
*)buf
);
5718 info
.SequenceNumber
.cbData
= 0;
5719 SystemTimeToFileTime(&thisUpdate
, &info
.ThisUpdate
);
5720 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithThisUpdate
,
5721 sizeof(ctlWithThisUpdate
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5722 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5725 compareCTLInfo("CTL with this update", &info
, (CTL_INFO
*)buf
);
5729 SystemTimeToFileTime(&thisUpdate
, &info
.NextUpdate
);
5730 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithThisAndNextUpdate
,
5731 sizeof(ctlWithThisAndNextUpdate
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5733 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5736 compareCTLInfo("CTL with this and next update", &info
, (CTL_INFO
*)buf
);
5740 info
.ThisUpdate
.dwLowDateTime
= info
.ThisUpdate
.dwHighDateTime
= 0;
5741 info
.NextUpdate
.dwLowDateTime
= info
.NextUpdate
.dwHighDateTime
= 0;
5742 info
.SubjectAlgorithm
.pszObjId
= oid2
;
5743 info
.SubjectAlgorithm
.Parameters
.cbData
= sizeof(nullData
);
5744 info
.SubjectAlgorithm
.Parameters
.pbData
= nullData
;
5745 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithAlgId
,
5746 sizeof(ctlWithAlgId
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5747 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5750 compareCTLInfo("CTL with algorithm identifier", &info
, (CTL_INFO
*)buf
);
5754 SetLastError(0xdeadbeef);
5755 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithBogusEntry
,
5756 sizeof(ctlWithBogusEntry
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5758 (GetLastError() == CRYPT_E_ASN1_EOD
||
5759 GetLastError() == CRYPT_E_ASN1_CORRUPT
||
5760 GetLastError() == OSS_MORE_INPUT
), /* Win9x */
5761 "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n",
5763 info
.SubjectAlgorithm
.Parameters
.cbData
= 0;
5764 info
.ThisUpdate
.dwLowDateTime
= info
.ThisUpdate
.dwHighDateTime
= 0;
5765 info
.NextUpdate
.dwLowDateTime
= info
.NextUpdate
.dwHighDateTime
= 0;
5766 info
.SubjectAlgorithm
.pszObjId
= oid2
;
5767 info
.SubjectAlgorithm
.pszObjId
= NULL
;
5768 value1
.cbData
= sizeof(emptySequence
);
5769 value1
.pbData
= (LPBYTE
)emptySequence
;
5770 attr1
.pszObjId
= oid1
;
5772 attr1
.rgValue
= &value1
;
5773 ctlEntry
[0].SubjectIdentifier
.cbData
= sizeof(serialNum
);
5774 ctlEntry
[0].SubjectIdentifier
.pbData
= (LPBYTE
)serialNum
;
5775 ctlEntry
[0].cAttribute
= 1;
5776 ctlEntry
[0].rgAttribute
= &attr1
;
5778 info
.rgCTLEntry
= ctlEntry
;
5779 SetLastError(0xdeadbeef);
5780 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithOneEntry
,
5781 sizeof(ctlWithOneEntry
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5782 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5785 compareCTLInfo("CTL with one entry", &info
, (CTL_INFO
*)buf
);
5789 value2
.cbData
= sizeof(encodedIPAddr
);
5790 value2
.pbData
= (LPBYTE
)encodedIPAddr
;
5791 attr2
.pszObjId
= oid2
;
5793 attr2
.rgValue
= &value2
;
5794 ctlEntry
[1].SubjectIdentifier
.cbData
= sizeof(serialNum
);
5795 ctlEntry
[1].SubjectIdentifier
.pbData
= (LPBYTE
)serialNum
;
5796 ctlEntry
[1].cAttribute
= 1;
5797 ctlEntry
[1].rgAttribute
= &attr2
;
5799 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithTwoEntries
,
5800 sizeof(ctlWithTwoEntries
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5801 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5804 compareCTLInfo("CTL with two entries", &info
, (CTL_INFO
*)buf
);
5808 /* A signed CTL isn't decodable, even if the inner content is a CTL */
5809 SetLastError(0xdeadbeef);
5810 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, signedCTL
,
5811 sizeof(signedCTL
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5812 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_BADTAG
||
5813 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
5814 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5816 SetLastError(0xdeadbeef);
5817 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
,
5818 signedCTLWithCTLInnerContent
, sizeof(signedCTLWithCTLInnerContent
),
5819 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5820 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_BADTAG
||
5821 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
5822 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5826 static const BYTE emptyPKCSContentInfo
[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
5827 static const BYTE emptyPKCSContentInfoExtraBytes
[] = { 0x30,0x04,0x06,0x02,0x2a,
5829 static const BYTE bogusPKCSContentInfo
[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
5831 static const BYTE intPKCSContentInfo
[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
5832 0x03,0x02,0x01,0x01 };
5833 static BYTE bogusDER
[] = { 1 };
5835 static void test_encodePKCSContentInfo(DWORD dwEncoding
)
5840 CRYPT_CONTENT_INFO info
= { 0 };
5841 char oid1
[] = "1.2.3";
5845 /* Crashes on win9x */
5846 SetLastError(0xdeadbeef);
5847 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
, NULL
,
5848 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5849 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
5850 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5852 SetLastError(0xdeadbeef);
5853 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
, &info
,
5854 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5855 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
5856 GetLastError() == OSS_LIMITED
/* Win9x */),
5857 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5858 info
.pszObjId
= oid1
;
5859 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
, &info
,
5860 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5861 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5864 ok(size
== sizeof(emptyPKCSContentInfo
), "Unexpected size %d\n", size
);
5865 ok(!memcmp(buf
, emptyPKCSContentInfo
, size
), "Unexpected value\n");
5868 info
.Content
.pbData
= bogusDER
;
5869 info
.Content
.cbData
= sizeof(bogusDER
);
5870 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
, &info
,
5871 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5872 ok(ret
, "CryptEncodeObjectEx failed; %x\n", GetLastError());
5875 ok(size
== sizeof(bogusPKCSContentInfo
), "Unexpected size %d\n", size
);
5876 ok(!memcmp(buf
, bogusPKCSContentInfo
, size
), "Unexpected value\n");
5879 info
.Content
.pbData
= (BYTE
*)ints
[0].encoded
;
5880 info
.Content
.cbData
= ints
[0].encoded
[1] + 2;
5881 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
, &info
,
5882 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5885 ok(size
== sizeof(intPKCSContentInfo
), "Unexpected size %d\n", size
);
5886 ok(!memcmp(buf
, intPKCSContentInfo
, size
), "Unexpected value\n");
5891 static const BYTE indefiniteSignedPKCSContent
[] = {
5892 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
5893 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
5894 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
5895 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
5896 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
5897 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
5898 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5899 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5900 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
5901 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5902 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5903 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
5904 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
5905 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
5906 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
5907 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
5908 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
5909 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
5910 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
5911 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5912 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5913 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
5914 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
5915 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
5916 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
5917 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
5918 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
5919 0x00,0x00,0x00,0x00,0x00,0x00 };
5921 static void test_decodePKCSContentInfo(DWORD dwEncoding
)
5926 CRYPT_CONTENT_INFO
*info
;
5928 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
,
5929 emptyPKCSContentInfo
, sizeof(emptyPKCSContentInfo
),
5930 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5931 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5934 info
= (CRYPT_CONTENT_INFO
*)buf
;
5936 ok(!strcmp(info
->pszObjId
, "1.2.3"), "Expected 1.2.3, got %s\n",
5938 ok(info
->Content
.cbData
== 0, "Expected no data, got %d\n",
5939 info
->Content
.cbData
);
5942 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
,
5943 emptyPKCSContentInfoExtraBytes
, sizeof(emptyPKCSContentInfoExtraBytes
),
5944 0, NULL
, NULL
, &size
);
5945 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5946 SetLastError(0xdeadbeef);
5947 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
,
5948 bogusPKCSContentInfo
, sizeof(bogusPKCSContentInfo
),
5949 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5950 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5951 * I doubt an app depends on that.
5953 ok((!ret
&& (GetLastError() == CRYPT_E_ASN1_EOD
||
5954 GetLastError() == CRYPT_E_ASN1_CORRUPT
)) || broken(ret
),
5955 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5957 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
,
5958 intPKCSContentInfo
, sizeof(intPKCSContentInfo
),
5959 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5960 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5963 info
= (CRYPT_CONTENT_INFO
*)buf
;
5965 ok(!strcmp(info
->pszObjId
, "1.2.3"), "Expected 1.2.3, got %s\n",
5967 ok(info
->Content
.cbData
== ints
[0].encoded
[1] + 2,
5968 "Unexpected size %d\n", info
->Content
.cbData
);
5969 ok(!memcmp(info
->Content
.pbData
, ints
[0].encoded
,
5970 info
->Content
.cbData
), "Unexpected value\n");
5973 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
,
5974 indefiniteSignedPKCSContent
, sizeof(indefiniteSignedPKCSContent
),
5975 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5976 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5979 info
= (CRYPT_CONTENT_INFO
*)buf
;
5981 ok(!strcmp(info
->pszObjId
, szOID_RSA_signedData
),
5982 "Expected %s, got %s\n", szOID_RSA_signedData
, info
->pszObjId
);
5983 ok(info
->Content
.cbData
== 392, "Expected 392, got %d\n",
5984 info
->Content
.cbData
);
5989 static const BYTE emptyPKCSAttr
[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
5991 static const BYTE bogusPKCSAttr
[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
5993 static const BYTE intPKCSAttr
[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
5996 static void test_encodePKCSAttribute(DWORD dwEncoding
)
5998 CRYPT_ATTRIBUTE attr
= { 0 };
6002 CRYPT_ATTR_BLOB blob
;
6003 char oid
[] = "1.2.3";
6007 /* Crashes on win9x */
6008 SetLastError(0xdeadbeef);
6009 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
, NULL
,
6010 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6011 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
6012 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
6014 SetLastError(0xdeadbeef);
6015 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
, &attr
,
6016 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6017 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
6018 GetLastError() == OSS_LIMITED
/* Win9x */),
6019 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
6020 attr
.pszObjId
= oid
;
6021 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
, &attr
,
6022 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6023 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6026 ok(size
== sizeof(emptyPKCSAttr
), "Unexpected size %d\n", size
);
6027 ok(!memcmp(buf
, emptyPKCSAttr
, size
), "Unexpected value\n");
6030 blob
.cbData
= sizeof(bogusDER
);
6031 blob
.pbData
= bogusDER
;
6033 attr
.rgValue
= &blob
;
6034 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
, &attr
,
6035 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6036 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6039 ok(size
== sizeof(bogusPKCSAttr
), "Unexpected size %d\n", size
);
6040 ok(!memcmp(buf
, bogusPKCSAttr
, size
), "Unexpected value\n");
6043 blob
.pbData
= (BYTE
*)ints
[0].encoded
;
6044 blob
.cbData
= ints
[0].encoded
[1] + 2;
6045 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
, &attr
,
6046 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6049 ok(size
== sizeof(intPKCSAttr
), "Unexpected size %d\n", size
);
6050 ok(!memcmp(buf
, intPKCSAttr
, size
), "Unexpected value\n");
6055 static void test_decodePKCSAttribute(DWORD dwEncoding
)
6060 CRYPT_ATTRIBUTE
*attr
;
6062 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
,
6063 emptyPKCSAttr
, sizeof(emptyPKCSAttr
),
6064 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6065 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6068 attr
= (CRYPT_ATTRIBUTE
*)buf
;
6070 ok(!strcmp(attr
->pszObjId
, "1.2.3"), "Expected 1.2.3, got %s\n",
6072 ok(attr
->cValue
== 0, "Expected no value, got %d\n", attr
->cValue
);
6075 SetLastError(0xdeadbeef);
6076 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
,
6077 bogusPKCSAttr
, sizeof(bogusPKCSAttr
),
6078 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6079 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
6080 * I doubt an app depends on that.
6082 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_EOD
||
6083 GetLastError() == CRYPT_E_ASN1_CORRUPT
||
6084 GetLastError() == OSS_MORE_INPUT
/* Win9x */),
6085 "Expected CRYPT_E_ASN1_EOD, CRYPT_E_ASN1_CORRUPT, or OSS_MORE_INPUT, got %x\n",
6087 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
,
6088 intPKCSAttr
, sizeof(intPKCSAttr
),
6089 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6090 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6093 attr
= (CRYPT_ATTRIBUTE
*)buf
;
6095 ok(!strcmp(attr
->pszObjId
, "1.2.3"), "Expected 1.2.3, got %s\n",
6097 ok(attr
->cValue
== 1, "Expected 1 value, got %d\n", attr
->cValue
);
6098 ok(attr
->rgValue
[0].cbData
== ints
[0].encoded
[1] + 2,
6099 "Unexpected size %d\n", attr
->rgValue
[0].cbData
);
6100 ok(!memcmp(attr
->rgValue
[0].pbData
, ints
[0].encoded
,
6101 attr
->rgValue
[0].cbData
), "Unexpected value\n");
6106 static const BYTE emptyPKCSAttributes
[] = { 0x31,0x00 };
6107 static const BYTE singlePKCSAttributes
[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
6108 0x2a,0x03,0x31,0x00 };
6109 static const BYTE doublePKCSAttributes
[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
6110 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
6112 static void test_encodePKCSAttributes(DWORD dwEncoding
)
6114 CRYPT_ATTRIBUTES attributes
= { 0 };
6115 CRYPT_ATTRIBUTE attr
[2] = { { 0 } };
6116 CRYPT_ATTR_BLOB blob
;
6120 char oid1
[] = "1.2.3", oid2
[] = "1.5.6";
6122 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
, &attributes
,
6123 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6124 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6127 ok(size
== sizeof(emptyPKCSAttributes
), "Unexpected size %d\n", size
);
6128 ok(!memcmp(buf
, emptyPKCSAttributes
, size
), "Unexpected value\n");
6131 attributes
.cAttr
= 1;
6132 attributes
.rgAttr
= attr
;
6133 SetLastError(0xdeadbeef);
6134 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
, &attributes
,
6135 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6136 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
6137 GetLastError() == OSS_LIMITED
/* Win9x */),
6138 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6139 attr
[0].pszObjId
= oid1
;
6140 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
, &attributes
,
6141 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6144 ok(size
== sizeof(singlePKCSAttributes
), "Unexpected size %d\n", size
);
6145 ok(!memcmp(buf
, singlePKCSAttributes
, size
), "Unexpected value\n");
6148 attr
[1].pszObjId
= oid2
;
6150 attr
[1].rgValue
= &blob
;
6151 blob
.pbData
= (BYTE
*)ints
[0].encoded
;
6152 blob
.cbData
= ints
[0].encoded
[1] + 2;
6153 attributes
.cAttr
= 2;
6154 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
, &attributes
,
6155 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6156 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6159 ok(size
== sizeof(doublePKCSAttributes
), "Unexpected size %d\n", size
);
6160 ok(!memcmp(buf
, doublePKCSAttributes
, size
), "Unexpected value\n");
6165 static void test_decodePKCSAttributes(DWORD dwEncoding
)
6170 CRYPT_ATTRIBUTES
*attributes
;
6172 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
,
6173 emptyPKCSAttributes
, sizeof(emptyPKCSAttributes
),
6174 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6175 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6178 attributes
= (CRYPT_ATTRIBUTES
*)buf
;
6179 ok(attributes
->cAttr
== 0, "Expected no attributes, got %d\n",
6183 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
,
6184 singlePKCSAttributes
, sizeof(singlePKCSAttributes
),
6185 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6186 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6189 attributes
= (CRYPT_ATTRIBUTES
*)buf
;
6190 ok(attributes
->cAttr
== 1, "Expected 1 attribute, got %d\n",
6192 ok(!strcmp(attributes
->rgAttr
[0].pszObjId
, "1.2.3"),
6193 "Expected 1.2.3, got %s\n", attributes
->rgAttr
[0].pszObjId
);
6194 ok(attributes
->rgAttr
[0].cValue
== 0,
6195 "Expected no attributes, got %d\n", attributes
->rgAttr
[0].cValue
);
6198 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
,
6199 doublePKCSAttributes
, sizeof(doublePKCSAttributes
),
6200 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6201 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6204 attributes
= (CRYPT_ATTRIBUTES
*)buf
;
6205 ok(attributes
->cAttr
== 2, "Expected 2 attributes, got %d\n",
6207 ok(!strcmp(attributes
->rgAttr
[0].pszObjId
, "1.2.3"),
6208 "Expected 1.2.3, got %s\n", attributes
->rgAttr
[0].pszObjId
);
6209 ok(attributes
->rgAttr
[0].cValue
== 0,
6210 "Expected no attributes, got %d\n", attributes
->rgAttr
[0].cValue
);
6211 ok(!strcmp(attributes
->rgAttr
[1].pszObjId
, "1.5.6"),
6212 "Expected 1.5.6, got %s\n", attributes
->rgAttr
[1].pszObjId
);
6213 ok(attributes
->rgAttr
[1].cValue
== 1,
6214 "Expected 1 attribute, got %d\n", attributes
->rgAttr
[1].cValue
);
6215 ok(attributes
->rgAttr
[1].rgValue
[0].cbData
== ints
[0].encoded
[1] + 2,
6216 "Unexpected size %d\n", attributes
->rgAttr
[1].rgValue
[0].cbData
);
6217 ok(!memcmp(attributes
->rgAttr
[1].rgValue
[0].pbData
, ints
[0].encoded
,
6218 attributes
->rgAttr
[1].rgValue
[0].cbData
), "Unexpected value\n");
6221 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
,
6222 doublePKCSAttributes
, sizeof(doublePKCSAttributes
), 0, NULL
, NULL
, &size
);
6223 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6224 buf
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
6227 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
,
6228 doublePKCSAttributes
, sizeof(doublePKCSAttributes
), 0, NULL
, buf
, &size
);
6229 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6230 HeapFree(GetProcessHeap(), 0, buf
);
6234 static const BYTE singleCapability
[] = {
6235 0x30,0x06,0x30,0x04,0x06,0x02,0x2d,0x06 };
6236 static const BYTE twoCapabilities
[] = {
6237 0x30,0x0c,0x30,0x04,0x06,0x02,0x2d,0x06,0x30,0x04,0x06,0x02,0x2a,0x03 };
6238 static const BYTE singleCapabilitywithNULL
[] = {
6239 0x30,0x08,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
6241 static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding
)
6243 static char oid1
[] = "1.5.6", oid2
[] = "1.2.3";
6247 CRYPT_SMIME_CAPABILITY capability
[2];
6248 CRYPT_SMIME_CAPABILITIES capabilities
;
6250 /* An empty capabilities is allowed */
6251 capabilities
.cCapability
= 0;
6252 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6253 &capabilities
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6254 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6257 ok(size
== sizeof(emptySequence
), "unexpected size %d\n", size
);
6258 ok(!memcmp(buf
, emptySequence
, size
), "unexpected value\n");
6261 /* A non-empty capabilities with an empty capability (lacking an OID) is
6264 capability
[0].pszObjId
= NULL
;
6265 capability
[0].Parameters
.cbData
= 0;
6266 capabilities
.cCapability
= 1;
6267 capabilities
.rgCapability
= capability
;
6268 SetLastError(0xdeadbeef);
6269 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6270 &capabilities
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6271 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
6272 GetLastError() == OSS_LIMITED
/* Win9x */),
6273 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6274 capability
[0].pszObjId
= oid1
;
6275 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6276 &capabilities
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6277 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6280 ok(size
== sizeof(singleCapability
), "unexpected size %d\n", size
);
6281 ok(!memcmp(buf
, singleCapability
, size
), "unexpected value\n");
6284 capability
[1].pszObjId
= oid2
;
6285 capability
[1].Parameters
.cbData
= 0;
6286 capabilities
.cCapability
= 2;
6287 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6288 &capabilities
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6289 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6292 ok(size
== sizeof(twoCapabilities
), "unexpected size %d\n", size
);
6293 ok(!memcmp(buf
, twoCapabilities
, size
), "unexpected value\n");
6298 static void compareSMimeCapabilities(LPCSTR header
,
6299 const CRYPT_SMIME_CAPABILITIES
*expected
, const CRYPT_SMIME_CAPABILITIES
*got
)
6303 ok(got
->cCapability
== expected
->cCapability
,
6304 "%s: expected %d capabilities, got %d\n", header
, expected
->cCapability
,
6306 for (i
= 0; i
< expected
->cCapability
; i
++)
6308 ok(!strcmp(expected
->rgCapability
[i
].pszObjId
,
6309 got
->rgCapability
[i
].pszObjId
), "%s[%d]: expected %s, got %s\n",
6310 header
, i
, expected
->rgCapability
[i
].pszObjId
,
6311 got
->rgCapability
[i
].pszObjId
);
6312 ok(expected
->rgCapability
[i
].Parameters
.cbData
==
6313 got
->rgCapability
[i
].Parameters
.cbData
,
6314 "%s[%d]: expected %d bytes, got %d\n", header
, i
,
6315 expected
->rgCapability
[i
].Parameters
.cbData
,
6316 got
->rgCapability
[i
].Parameters
.cbData
);
6317 if (expected
->rgCapability
[i
].Parameters
.cbData
)
6318 ok(!memcmp(expected
->rgCapability
[i
].Parameters
.pbData
,
6319 got
->rgCapability
[i
].Parameters
.pbData
,
6320 expected
->rgCapability
[i
].Parameters
.cbData
),
6321 "%s[%d]: unexpected value\n", header
, i
);
6325 static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding
)
6327 static char oid1
[] = "1.5.6", oid2
[] = "1.2.3";
6330 CRYPT_SMIME_CAPABILITY capability
[2];
6331 CRYPT_SMIME_CAPABILITIES capabilities
, *ptr
;
6333 SetLastError(0xdeadbeef);
6334 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6335 emptySequence
, sizeof(emptySequence
),
6336 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &ptr
, &size
);
6337 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6340 capabilities
.cCapability
= 0;
6341 compareSMimeCapabilities("empty capabilities", &capabilities
, ptr
);
6344 SetLastError(0xdeadbeef);
6345 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6346 singleCapability
, sizeof(singleCapability
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
6348 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6351 capability
[0].pszObjId
= oid1
;
6352 capability
[0].Parameters
.cbData
= 0;
6353 capabilities
.cCapability
= 1;
6354 capabilities
.rgCapability
= capability
;
6355 compareSMimeCapabilities("single capability", &capabilities
, ptr
);
6358 SetLastError(0xdeadbeef);
6359 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6360 singleCapabilitywithNULL
, sizeof(singleCapabilitywithNULL
),
6361 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &ptr
, &size
);
6362 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6365 BYTE NULLparam
[] = {0x05, 0x00};
6366 capability
[0].pszObjId
= oid1
;
6367 capability
[0].Parameters
.cbData
= 2;
6368 capability
[0].Parameters
.pbData
= NULLparam
;
6369 capabilities
.cCapability
= 1;
6370 capabilities
.rgCapability
= capability
;
6371 compareSMimeCapabilities("single capability with NULL", &capabilities
,
6375 SetLastError(0xdeadbeef);
6376 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6377 twoCapabilities
, sizeof(twoCapabilities
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
6379 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6382 capability
[0].Parameters
.cbData
= 0;
6383 capability
[1].pszObjId
= oid2
;
6384 capability
[1].Parameters
.cbData
= 0;
6385 capabilities
.cCapability
= 2;
6386 compareSMimeCapabilities("two capabilities", &capabilities
, ptr
);
6389 SetLastError(0xdeadbeef);
6390 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6391 twoCapabilities
, sizeof(twoCapabilities
), 0, NULL
, NULL
, &size
);
6392 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6393 ptr
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
6396 SetLastError(0xdeadbeef);
6397 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6398 twoCapabilities
, sizeof(twoCapabilities
), 0, NULL
, ptr
, &size
);
6399 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6400 HeapFree(GetProcessHeap(), 0, ptr
);
6404 static BYTE encodedCommonNameNoNull
[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
6405 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
6407 static const BYTE minimalPKCSSigner
[] = {
6408 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6409 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6410 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6411 static const BYTE PKCSSignerWithSerial
[] = {
6412 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6413 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6414 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
6416 static const BYTE PKCSSignerWithHashAlgo
[] = {
6417 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6418 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6419 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
6421 static const BYTE PKCSSignerWithHashAndEncryptionAlgo
[] = {
6422 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6423 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6424 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6425 0x06,0x05,0x00,0x04,0x00 };
6426 static const BYTE PKCSSignerWithHash
[] = {
6427 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6428 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6429 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6430 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
6431 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6432 static const BYTE PKCSSignerWithAuthAttr
[] = {
6433 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6434 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6435 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
6436 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
6437 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
6438 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
6439 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6441 static void test_encodePKCSSignerInfo(DWORD dwEncoding
)
6443 static char oid1
[] = "1.2.3", oid2
[] = "1.5.6";
6447 CMSG_SIGNER_INFO info
= { 0 };
6448 char oid_common_name
[] = szOID_COMMON_NAME
;
6449 CRYPT_ATTR_BLOB commonName
= { sizeof(encodedCommonName
),
6450 (LPBYTE
)encodedCommonName
};
6451 CRYPT_ATTRIBUTE attr
= { oid_common_name
, 1, &commonName
};
6453 SetLastError(0xdeadbeef);
6454 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6455 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6456 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
6458 skip("no PKCS7_SIGNER_INFO encode support\n");
6461 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
6462 GetLastError() == OSS_LIMITED
/* Win9x */),
6463 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6464 /* To be encoded, a signer must have an issuer at least, and the encoding
6465 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
6466 * see decoding tests.)
6468 info
.Issuer
.cbData
= sizeof(encodedCommonNameNoNull
);
6469 info
.Issuer
.pbData
= encodedCommonNameNoNull
;
6470 SetLastError(0xdeadbeef);
6471 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6472 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6473 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6474 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6475 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6478 ok(ret
|| broken(GetLastError() == OSS_LIMITED
/* Win9x */),
6479 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6482 ok(size
== sizeof(minimalPKCSSigner
), "Unexpected size %d\n", size
);
6483 if (size
== sizeof(minimalPKCSSigner
))
6484 ok(!memcmp(buf
, minimalPKCSSigner
, size
), "Unexpected value\n");
6486 ok(0, "Unexpected value\n");
6490 info
.SerialNumber
.cbData
= sizeof(serialNum
);
6491 info
.SerialNumber
.pbData
= (BYTE
*)serialNum
;
6492 SetLastError(0xdeadbeef);
6493 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6494 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6495 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6496 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6497 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6500 ok(ret
|| broken(GetLastError() == OSS_LIMITED
/* Win9x */),
6501 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6504 ok(size
== sizeof(PKCSSignerWithSerial
), "Unexpected size %d\n",
6506 if (size
== sizeof(PKCSSignerWithSerial
))
6507 ok(!memcmp(buf
, PKCSSignerWithSerial
, size
),
6508 "Unexpected value\n");
6510 ok(0, "Unexpected value\n");
6514 info
.HashAlgorithm
.pszObjId
= oid1
;
6515 SetLastError(0xdeadbeef);
6516 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6517 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6518 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6519 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6520 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6523 ok(ret
|| broken(GetLastError() == OSS_LIMITED
/* Win9x */),
6524 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6527 ok(size
== sizeof(PKCSSignerWithHashAlgo
), "Unexpected size %d\n",
6529 if (size
== sizeof(PKCSSignerWithHashAlgo
))
6530 ok(!memcmp(buf
, PKCSSignerWithHashAlgo
, size
),
6531 "Unexpected value\n");
6533 ok(0, "Unexpected value\n");
6537 info
.HashEncryptionAlgorithm
.pszObjId
= oid2
;
6538 SetLastError(0xdeadbeef);
6539 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6540 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6541 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6542 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6543 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6546 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6549 ok(size
== sizeof(PKCSSignerWithHashAndEncryptionAlgo
),
6550 "Unexpected size %d\n", size
);
6551 if (size
== sizeof(PKCSSignerWithHashAndEncryptionAlgo
))
6552 ok(!memcmp(buf
, PKCSSignerWithHashAndEncryptionAlgo
, size
),
6553 "Unexpected value\n");
6555 ok(0, "Unexpected value\n");
6559 info
.EncryptedHash
.cbData
= sizeof(hash
);
6560 info
.EncryptedHash
.pbData
= (BYTE
*)hash
;
6561 SetLastError(0xdeadbeef);
6562 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6563 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6564 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6565 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6566 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6569 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6572 ok(size
== sizeof(PKCSSignerWithHash
), "Unexpected size %d\n",
6574 if (size
== sizeof(PKCSSignerWithHash
))
6575 ok(!memcmp(buf
, PKCSSignerWithHash
, size
),
6576 "Unexpected value\n");
6578 ok(0, "Unexpected value\n");
6582 info
.AuthAttrs
.cAttr
= 1;
6583 info
.AuthAttrs
.rgAttr
= &attr
;
6584 SetLastError(0xdeadbeef);
6585 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6586 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6587 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6588 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6589 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6592 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6595 ok(size
== sizeof(PKCSSignerWithAuthAttr
), "Unexpected size %d\n",
6597 if (size
== sizeof(PKCSSignerWithAuthAttr
))
6598 ok(!memcmp(buf
, PKCSSignerWithAuthAttr
, size
),
6599 "Unexpected value\n");
6601 ok(0, "Unexpected value\n");
6607 static void test_decodePKCSSignerInfo(DWORD dwEncoding
)
6612 CMSG_SIGNER_INFO
*info
;
6614 /* A PKCS signer can't be decoded without a serial number. */
6615 SetLastError(0xdeadbeef);
6616 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
6617 minimalPKCSSigner
, sizeof(minimalPKCSSigner
),
6618 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6619 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
6620 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
6621 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %x\n",
6623 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
6624 PKCSSignerWithSerial
, sizeof(PKCSSignerWithSerial
),
6625 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6626 ok(ret
|| broken(GetLastError() == OSS_DATA_ERROR
),
6627 "CryptDecodeObjectEx failed: %x\n", GetLastError());
6630 info
= (CMSG_SIGNER_INFO
*)buf
;
6631 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6633 ok(info
->Issuer
.cbData
== sizeof(encodedCommonNameNoNull
),
6634 "Unexpected size %d\n", info
->Issuer
.cbData
);
6635 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonNameNoNull
,
6636 info
->Issuer
.cbData
), "Unexpected value\n");
6637 ok(info
->SerialNumber
.cbData
== sizeof(serialNum
),
6638 "Unexpected size %d\n", info
->SerialNumber
.cbData
);
6639 ok(!memcmp(info
->SerialNumber
.pbData
, serialNum
, sizeof(serialNum
)),
6640 "Unexpected value\n");
6643 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
6644 PKCSSignerWithHashAlgo
, sizeof(PKCSSignerWithHashAlgo
),
6645 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6648 info
= (CMSG_SIGNER_INFO
*)buf
;
6649 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6651 ok(info
->Issuer
.cbData
== sizeof(encodedCommonNameNoNull
),
6652 "Unexpected size %d\n", info
->Issuer
.cbData
);
6653 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonNameNoNull
,
6654 info
->Issuer
.cbData
), "Unexpected value\n");
6655 ok(info
->SerialNumber
.cbData
== sizeof(serialNum
),
6656 "Unexpected size %d\n", info
->SerialNumber
.cbData
);
6657 ok(!memcmp(info
->SerialNumber
.pbData
, serialNum
, sizeof(serialNum
)),
6658 "Unexpected value\n");
6659 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, "1.2.3"),
6660 "Expected 1.2.3, got %s\n", info
->HashAlgorithm
.pszObjId
);
6663 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
6664 PKCSSignerWithHashAndEncryptionAlgo
,
6665 sizeof(PKCSSignerWithHashAndEncryptionAlgo
), CRYPT_DECODE_ALLOC_FLAG
,
6669 info
= (CMSG_SIGNER_INFO
*)buf
;
6670 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6672 ok(info
->Issuer
.cbData
== sizeof(encodedCommonNameNoNull
),
6673 "Unexpected size %d\n", info
->Issuer
.cbData
);
6674 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonNameNoNull
,
6675 info
->Issuer
.cbData
), "Unexpected value\n");
6676 ok(info
->SerialNumber
.cbData
== sizeof(serialNum
),
6677 "Unexpected size %d\n", info
->SerialNumber
.cbData
);
6678 ok(!memcmp(info
->SerialNumber
.pbData
, serialNum
, sizeof(serialNum
)),
6679 "Unexpected value\n");
6680 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, "1.2.3"),
6681 "Expected 1.2.3, got %s\n", info
->HashAlgorithm
.pszObjId
);
6682 ok(!strcmp(info
->HashEncryptionAlgorithm
.pszObjId
, "1.5.6"),
6683 "Expected 1.5.6, got %s\n", info
->HashEncryptionAlgorithm
.pszObjId
);
6686 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
6687 PKCSSignerWithHash
, sizeof(PKCSSignerWithHash
),
6688 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6691 info
= (CMSG_SIGNER_INFO
*)buf
;
6692 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6694 ok(info
->Issuer
.cbData
== sizeof(encodedCommonNameNoNull
),
6695 "Unexpected size %d\n", info
->Issuer
.cbData
);
6696 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonNameNoNull
,
6697 info
->Issuer
.cbData
), "Unexpected value\n");
6698 ok(info
->SerialNumber
.cbData
== sizeof(serialNum
),
6699 "Unexpected size %d\n", info
->SerialNumber
.cbData
);
6700 ok(!memcmp(info
->SerialNumber
.pbData
, serialNum
, sizeof(serialNum
)),
6701 "Unexpected value\n");
6702 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, "1.2.3"),
6703 "Expected 1.2.3, got %s\n", info
->HashAlgorithm
.pszObjId
);
6704 ok(!strcmp(info
->HashEncryptionAlgorithm
.pszObjId
, "1.5.6"),
6705 "Expected 1.5.6, got %s\n", info
->HashEncryptionAlgorithm
.pszObjId
);
6706 ok(info
->EncryptedHash
.cbData
== sizeof(hash
), "Unexpected size %d\n",
6707 info
->EncryptedHash
.cbData
);
6708 ok(!memcmp(info
->EncryptedHash
.pbData
, hash
, sizeof(hash
)),
6709 "Unexpected value\n");
6712 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
6713 PKCSSignerWithAuthAttr
, sizeof(PKCSSignerWithAuthAttr
),
6714 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6717 info
= (CMSG_SIGNER_INFO
*)buf
;
6718 ok(info
->AuthAttrs
.cAttr
== 1, "Expected 1 attribute, got %d\n",
6719 info
->AuthAttrs
.cAttr
);
6720 ok(!strcmp(info
->AuthAttrs
.rgAttr
[0].pszObjId
, szOID_COMMON_NAME
),
6721 "Expected %s, got %s\n", szOID_COMMON_NAME
,
6722 info
->AuthAttrs
.rgAttr
[0].pszObjId
);
6723 ok(info
->AuthAttrs
.rgAttr
[0].cValue
== 1, "Expected 1 value, got %d\n",
6724 info
->AuthAttrs
.rgAttr
[0].cValue
);
6725 ok(info
->AuthAttrs
.rgAttr
[0].rgValue
[0].cbData
==
6726 sizeof(encodedCommonName
), "Unexpected size %d\n",
6727 info
->AuthAttrs
.rgAttr
[0].rgValue
[0].cbData
);
6728 ok(!memcmp(info
->AuthAttrs
.rgAttr
[0].rgValue
[0].pbData
,
6729 encodedCommonName
, sizeof(encodedCommonName
)), "Unexpected value\n");
6734 static const BYTE CMSSignerWithKeyId
[] = {
6735 0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,
6736 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6738 static void test_encodeCMSSignerInfo(DWORD dwEncoding
)
6743 CMSG_CMS_SIGNER_INFO info
= { 0 };
6744 static char oid1
[] = "1.2.3", oid2
[] = "1.5.6";
6746 SetLastError(0xdeadbeef);
6747 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6748 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6749 ok(!ret
, "Expected failure, got %d\n", ret
);
6750 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
6752 skip("no CMS_SIGNER_INFO encode support\n");
6755 ok(GetLastError() == E_INVALIDARG
,
6756 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6757 info
.SignerId
.dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
6758 SetLastError(0xdeadbeef);
6759 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6760 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6761 ok(!ret
, "Expected failure, got %d\n", ret
);
6762 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
6764 skip("no CMS_SIGNER_INFO encode support\n");
6767 ok(GetLastError() == E_INVALIDARG
,
6768 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6769 /* To be encoded, a signer must have a valid cert ID, where a valid ID may
6770 * be a key id or an issuer serial number with at least the issuer set, and
6771 * the encoding must include PKCS_7_ASN_ENCODING.
6772 * (That isn't enough to be decoded, see decoding tests.)
6774 U(info
.SignerId
).IssuerSerialNumber
.Issuer
.cbData
=
6775 sizeof(encodedCommonNameNoNull
);
6776 U(info
.SignerId
).IssuerSerialNumber
.Issuer
.pbData
= encodedCommonNameNoNull
;
6777 SetLastError(0xdeadbeef);
6778 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6779 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6780 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6781 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6782 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6785 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6788 ok(size
== sizeof(minimalPKCSSigner
), "Unexpected size %d\n", size
);
6789 ok(!memcmp(buf
, minimalPKCSSigner
, size
), "Unexpected value\n");
6793 U(info
.SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
= sizeof(serialNum
);
6794 U(info
.SignerId
).IssuerSerialNumber
.SerialNumber
.pbData
= (BYTE
*)serialNum
;
6795 SetLastError(0xdeadbeef);
6796 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6797 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6798 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6799 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6800 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6803 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6806 ok(size
== sizeof(PKCSSignerWithSerial
), "Unexpected size %d\n",
6808 ok(!memcmp(buf
, PKCSSignerWithSerial
, size
), "Unexpected value\n");
6812 info
.SignerId
.dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
6813 U(info
.SignerId
).KeyId
.cbData
= sizeof(serialNum
);
6814 U(info
.SignerId
).KeyId
.pbData
= (BYTE
*)serialNum
;
6815 SetLastError(0xdeadbeef);
6816 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6817 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6818 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6819 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6820 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6823 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6826 ok(size
== sizeof(CMSSignerWithKeyId
), "Unexpected size %d\n",
6828 ok(!memcmp(buf
, CMSSignerWithKeyId
, size
), "Unexpected value\n");
6832 /* While a CERT_ID can have a hash type, that's not allowed in CMS, where
6833 * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed
6834 * (see RFC 3852, section 5.3.)
6836 info
.SignerId
.dwIdChoice
= CERT_ID_SHA1_HASH
;
6837 U(info
.SignerId
).HashId
.cbData
= sizeof(hash
);
6838 U(info
.SignerId
).HashId
.pbData
= (BYTE
*)hash
;
6839 SetLastError(0xdeadbeef);
6840 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6841 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6842 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6843 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6844 /* Now with a hash algo */
6845 info
.SignerId
.dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
6846 U(info
.SignerId
).IssuerSerialNumber
.Issuer
.cbData
=
6847 sizeof(encodedCommonNameNoNull
);
6848 U(info
.SignerId
).IssuerSerialNumber
.Issuer
.pbData
= encodedCommonNameNoNull
;
6849 info
.HashAlgorithm
.pszObjId
= oid1
;
6850 SetLastError(0xdeadbeef);
6851 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6852 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6853 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6854 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6855 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6858 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6861 ok(size
== sizeof(PKCSSignerWithHashAlgo
), "Unexpected size %d\n",
6863 ok(!memcmp(buf
, PKCSSignerWithHashAlgo
, size
),
6864 "Unexpected value\n");
6868 info
.HashEncryptionAlgorithm
.pszObjId
= oid2
;
6869 SetLastError(0xdeadbeef);
6870 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6871 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6872 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6873 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6874 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6877 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6880 ok(size
== sizeof(PKCSSignerWithHashAndEncryptionAlgo
),
6881 "Unexpected size %d\n", size
);
6882 ok(!memcmp(buf
, PKCSSignerWithHashAndEncryptionAlgo
, size
),
6883 "Unexpected value\n");
6887 info
.EncryptedHash
.cbData
= sizeof(hash
);
6888 info
.EncryptedHash
.pbData
= (BYTE
*)hash
;
6889 SetLastError(0xdeadbeef);
6890 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6891 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6892 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6893 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6894 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6897 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6900 ok(size
== sizeof(PKCSSignerWithHash
), "Unexpected size %d\n",
6902 ok(!memcmp(buf
, PKCSSignerWithHash
, size
), "Unexpected value\n");
6908 static void test_decodeCMSSignerInfo(DWORD dwEncoding
)
6913 CMSG_CMS_SIGNER_INFO
*info
;
6914 static const char oid1
[] = "1.2.3", oid2
[] = "1.5.6";
6916 /* A CMS signer can't be decoded without a serial number. */
6917 SetLastError(0xdeadbeef);
6918 ret
= pCryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
6919 minimalPKCSSigner
, sizeof(minimalPKCSSigner
),
6920 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6921 ok(!ret
, "expected failure\n");
6922 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
6924 skip("no CMS_SIGNER_INFO decode support\n");
6927 ok(GetLastError() == CRYPT_E_ASN1_CORRUPT
,
6928 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
6929 ret
= pCryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
6930 PKCSSignerWithSerial
, sizeof(PKCSSignerWithSerial
),
6931 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6932 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6935 info
= (CMSG_CMS_SIGNER_INFO
*)buf
;
6936 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6938 ok(info
->SignerId
.dwIdChoice
== CERT_ID_ISSUER_SERIAL_NUMBER
,
6939 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6940 info
->SignerId
.dwIdChoice
);
6941 ok(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
==
6942 sizeof(encodedCommonNameNoNull
), "Unexpected size %d\n",
6943 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
);
6944 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.pbData
,
6945 encodedCommonNameNoNull
,
6946 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
),
6947 "Unexpected value\n");
6948 ok(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
==
6949 sizeof(serialNum
), "Unexpected size %d\n",
6950 U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
);
6951 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.pbData
,
6952 serialNum
, sizeof(serialNum
)), "Unexpected value\n");
6955 ret
= pCryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
6956 PKCSSignerWithHashAlgo
, sizeof(PKCSSignerWithHashAlgo
),
6957 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6958 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6961 info
= (CMSG_CMS_SIGNER_INFO
*)buf
;
6962 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6964 ok(info
->SignerId
.dwIdChoice
== CERT_ID_ISSUER_SERIAL_NUMBER
,
6965 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6966 info
->SignerId
.dwIdChoice
);
6967 ok(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
==
6968 sizeof(encodedCommonNameNoNull
), "Unexpected size %d\n",
6969 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
);
6970 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.pbData
,
6971 encodedCommonNameNoNull
,
6972 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
),
6973 "Unexpected value\n");
6974 ok(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
==
6975 sizeof(serialNum
), "Unexpected size %d\n",
6976 U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
);
6977 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.pbData
,
6978 serialNum
, sizeof(serialNum
)), "Unexpected value\n");
6979 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, oid1
),
6980 "Expected %s, got %s\n", oid1
, info
->HashAlgorithm
.pszObjId
);
6983 ret
= pCryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
6984 PKCSSignerWithHashAndEncryptionAlgo
,
6985 sizeof(PKCSSignerWithHashAndEncryptionAlgo
), CRYPT_DECODE_ALLOC_FLAG
,
6987 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6990 info
= (CMSG_CMS_SIGNER_INFO
*)buf
;
6991 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6993 ok(info
->SignerId
.dwIdChoice
== CERT_ID_ISSUER_SERIAL_NUMBER
,
6994 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6995 info
->SignerId
.dwIdChoice
);
6996 ok(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
==
6997 sizeof(encodedCommonNameNoNull
), "Unexpected size %d\n",
6998 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
);
6999 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.pbData
,
7000 encodedCommonNameNoNull
,
7001 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
),
7002 "Unexpected value\n");
7003 ok(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
==
7004 sizeof(serialNum
), "Unexpected size %d\n",
7005 U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
);
7006 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.pbData
,
7007 serialNum
, sizeof(serialNum
)), "Unexpected value\n");
7008 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, oid1
),
7009 "Expected %s, got %s\n", oid1
, info
->HashAlgorithm
.pszObjId
);
7010 ok(!strcmp(info
->HashEncryptionAlgorithm
.pszObjId
, oid2
),
7011 "Expected %s, got %s\n", oid2
, info
->HashEncryptionAlgorithm
.pszObjId
);
7014 ret
= pCryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
7015 PKCSSignerWithHash
, sizeof(PKCSSignerWithHash
),
7016 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7017 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
7020 info
= (CMSG_CMS_SIGNER_INFO
*)buf
;
7021 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
7023 ok(info
->SignerId
.dwIdChoice
== CERT_ID_ISSUER_SERIAL_NUMBER
,
7024 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
7025 info
->SignerId
.dwIdChoice
);
7026 ok(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
==
7027 sizeof(encodedCommonNameNoNull
), "Unexpected size %d\n",
7028 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
);
7029 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.pbData
,
7030 encodedCommonNameNoNull
,
7031 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
),
7032 "Unexpected value\n");
7033 ok(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
==
7034 sizeof(serialNum
), "Unexpected size %d\n",
7035 U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
);
7036 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.pbData
,
7037 serialNum
, sizeof(serialNum
)), "Unexpected value\n");
7038 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, oid1
),
7039 "Expected %s, got %s\n", oid1
, info
->HashAlgorithm
.pszObjId
);
7040 ok(!strcmp(info
->HashEncryptionAlgorithm
.pszObjId
, oid2
),
7041 "Expected %s, got %s\n", oid2
, info
->HashEncryptionAlgorithm
.pszObjId
);
7042 ok(info
->EncryptedHash
.cbData
== sizeof(hash
), "Unexpected size %d\n",
7043 info
->EncryptedHash
.cbData
);
7044 ok(!memcmp(info
->EncryptedHash
.pbData
, hash
, sizeof(hash
)),
7045 "Unexpected value\n");
7048 ret
= pCryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
7049 CMSSignerWithKeyId
, sizeof(CMSSignerWithKeyId
),
7050 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7051 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
7054 info
= (CMSG_CMS_SIGNER_INFO
*)buf
;
7055 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
7057 ok(info
->SignerId
.dwIdChoice
== CERT_ID_KEY_IDENTIFIER
,
7058 "Expected CERT_ID_KEY_IDENTIFIER, got %d\n",
7059 info
->SignerId
.dwIdChoice
);
7060 ok(U(info
->SignerId
).KeyId
.cbData
== sizeof(serialNum
),
7061 "Unexpected size %d\n", U(info
->SignerId
).KeyId
.cbData
);
7062 ok(!memcmp(U(info
->SignerId
).KeyId
.pbData
, serialNum
, sizeof(serialNum
)),
7063 "Unexpected value\n");
7068 static BYTE emptyDNSPermittedConstraints
[] = {
7069 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
7070 static BYTE emptyDNSExcludedConstraints
[] = {
7071 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
7072 static BYTE DNSExcludedConstraints
[] = {
7073 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
7074 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7075 static BYTE permittedAndExcludedConstraints
[] = {
7076 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7077 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
7078 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7079 static BYTE permittedAndExcludedWithMinConstraints
[] = {
7080 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7081 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
7082 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7083 static BYTE permittedAndExcludedWithMinMaxConstraints
[] = {
7084 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7085 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
7086 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7088 static void test_encodeNameConstraints(DWORD dwEncoding
)
7091 CERT_NAME_CONSTRAINTS_INFO constraints
= { 0 };
7092 CERT_GENERAL_SUBTREE permitted
= { { 0 } };
7093 CERT_GENERAL_SUBTREE excluded
= { { 0 } };
7097 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
7098 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7099 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7101 skip("no X509_NAME_CONSTRAINTS encode support\n");
7104 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7107 ok(size
== sizeof(emptySequence
), "Unexpected size\n");
7108 ok(!memcmp(buf
, emptySequence
, size
), "Unexpected value\n");
7111 constraints
.cPermittedSubtree
= 1;
7112 constraints
.rgPermittedSubtree
= &permitted
;
7113 SetLastError(0xdeadbeef);
7114 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
7115 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7116 ok(!ret
&& GetLastError() == E_INVALIDARG
,
7117 "Expected E_INVALIDARG, got %08x\n", GetLastError());
7118 permitted
.Base
.dwAltNameChoice
= CERT_ALT_NAME_DNS_NAME
;
7119 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
7120 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7121 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7124 ok(size
== sizeof(emptyDNSPermittedConstraints
), "Unexpected size\n");
7125 ok(!memcmp(buf
, emptyDNSPermittedConstraints
, size
),
7126 "Unexpected value\n");
7129 constraints
.cPermittedSubtree
= 0;
7130 constraints
.cExcludedSubtree
= 1;
7131 constraints
.rgExcludedSubtree
= &excluded
;
7132 excluded
.Base
.dwAltNameChoice
= CERT_ALT_NAME_DNS_NAME
;
7133 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
7134 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7135 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7138 ok(size
== sizeof(emptyDNSExcludedConstraints
), "Unexpected size\n");
7139 ok(!memcmp(buf
, emptyDNSExcludedConstraints
, size
),
7140 "Unexpected value\n");
7143 U(excluded
.Base
).pwszURL
= (LPWSTR
)url
;
7144 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
7145 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7146 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7149 ok(size
== sizeof(DNSExcludedConstraints
), "Unexpected size\n");
7150 ok(!memcmp(buf
, DNSExcludedConstraints
, size
),
7151 "Unexpected value\n");
7154 permitted
.Base
.dwAltNameChoice
= CERT_ALT_NAME_IP_ADDRESS
;
7155 U(permitted
.Base
).IPAddress
.cbData
= sizeof(encodedIPAddr
);
7156 U(permitted
.Base
).IPAddress
.pbData
= (LPBYTE
)encodedIPAddr
;
7157 constraints
.cPermittedSubtree
= 1;
7158 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
7159 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7160 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7163 ok(size
== sizeof(permittedAndExcludedConstraints
),
7164 "Unexpected size\n");
7165 ok(!memcmp(buf
, permittedAndExcludedConstraints
, size
),
7166 "Unexpected value\n");
7169 permitted
.dwMinimum
= 5;
7170 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
7171 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7172 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7175 ok(size
== sizeof(permittedAndExcludedWithMinConstraints
),
7176 "Unexpected size\n");
7177 ok(!memcmp(buf
, permittedAndExcludedWithMinConstraints
, size
),
7178 "Unexpected value\n");
7181 permitted
.fMaximum
= TRUE
;
7182 permitted
.dwMaximum
= 3;
7183 SetLastError(0xdeadbeef);
7184 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
7185 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7186 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7189 ok(size
== sizeof(permittedAndExcludedWithMinMaxConstraints
),
7190 "Unexpected size\n");
7191 ok(!memcmp(buf
, permittedAndExcludedWithMinMaxConstraints
, size
),
7192 "Unexpected value\n");
7197 struct EncodedNameConstraints
7199 CRYPT_DATA_BLOB encoded
;
7200 CERT_NAME_CONSTRAINTS_INFO constraints
;
7203 static CERT_GENERAL_SUBTREE emptyDNSSubtree
= {
7204 { CERT_ALT_NAME_DNS_NAME
, { 0 } }, 0 };
7205 static CERT_GENERAL_SUBTREE DNSSubtree
= {
7206 { CERT_ALT_NAME_DNS_NAME
, { 0 } }, 0 };
7207 static CERT_GENERAL_SUBTREE IPAddressSubtree
= {
7208 { CERT_ALT_NAME_IP_ADDRESS
, { 0 } }, 0 };
7209 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree
= {
7210 { CERT_ALT_NAME_IP_ADDRESS
, { 0 } }, 5, 0 };
7211 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree
= {
7212 { CERT_ALT_NAME_IP_ADDRESS
, { 0 } }, 5, TRUE
, 3 };
7214 static const struct EncodedNameConstraints encodedNameConstraints
[] = {
7215 { { sizeof(emptySequence
), (LPBYTE
)emptySequence
}, { 0 } },
7216 { { sizeof(emptyDNSPermittedConstraints
), emptyDNSPermittedConstraints
},
7217 { 1, &emptyDNSSubtree
, 0, NULL
} },
7218 { { sizeof(emptyDNSExcludedConstraints
), emptyDNSExcludedConstraints
},
7219 { 0, NULL
, 1, &emptyDNSSubtree
} },
7220 { { sizeof(DNSExcludedConstraints
), DNSExcludedConstraints
},
7221 { 0, NULL
, 1, &DNSSubtree
} },
7222 { { sizeof(permittedAndExcludedConstraints
), permittedAndExcludedConstraints
},
7223 { 1, &IPAddressSubtree
, 1, &DNSSubtree
} },
7224 { { sizeof(permittedAndExcludedWithMinConstraints
),
7225 permittedAndExcludedWithMinConstraints
},
7226 { 1, &IPAddressWithMinSubtree
, 1, &DNSSubtree
} },
7227 { { sizeof(permittedAndExcludedWithMinMaxConstraints
),
7228 permittedAndExcludedWithMinMaxConstraints
},
7229 { 1, &IPAddressWithMinMaxSubtree
, 1, &DNSSubtree
} },
7232 static void test_decodeNameConstraints(DWORD dwEncoding
)
7236 CERT_NAME_CONSTRAINTS_INFO
*constraints
;
7238 U(DNSSubtree
.Base
).pwszURL
= (LPWSTR
)url
;
7239 U(IPAddressSubtree
.Base
).IPAddress
.cbData
= sizeof(encodedIPAddr
);
7240 U(IPAddressSubtree
.Base
).IPAddress
.pbData
= (LPBYTE
)encodedIPAddr
;
7241 U(IPAddressWithMinSubtree
.Base
).IPAddress
.cbData
= sizeof(encodedIPAddr
);
7242 U(IPAddressWithMinSubtree
.Base
).IPAddress
.pbData
= (LPBYTE
)encodedIPAddr
;
7243 U(IPAddressWithMinMaxSubtree
.Base
).IPAddress
.cbData
= sizeof(encodedIPAddr
);
7244 U(IPAddressWithMinMaxSubtree
.Base
).IPAddress
.pbData
= (LPBYTE
)encodedIPAddr
;
7246 i
< sizeof(encodedNameConstraints
) / sizeof(encodedNameConstraints
[0]);
7251 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
,
7252 encodedNameConstraints
[i
].encoded
.pbData
,
7253 encodedNameConstraints
[i
].encoded
.cbData
,
7254 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &constraints
, &size
);
7255 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7257 skip("no X509_NAME_CONSTRAINTS decode support\n");
7260 ok(ret
, "%d: CryptDecodeObjectEx failed: %08x\n", i
, GetLastError());
7265 if (constraints
->cPermittedSubtree
!=
7266 encodedNameConstraints
[i
].constraints
.cPermittedSubtree
)
7267 fprintf(stderr
, "%d: expected %d permitted, got %d\n", i
,
7268 encodedNameConstraints
[i
].constraints
.cPermittedSubtree
,
7269 constraints
->cPermittedSubtree
);
7270 if (constraints
->cPermittedSubtree
==
7271 encodedNameConstraints
[i
].constraints
.cPermittedSubtree
)
7273 for (j
= 0; j
< constraints
->cPermittedSubtree
; j
++)
7275 compareAltNameEntry(&constraints
->rgPermittedSubtree
[j
].Base
,
7276 &encodedNameConstraints
[i
].constraints
.rgPermittedSubtree
[j
].Base
);
7279 if (constraints
->cExcludedSubtree
!=
7280 encodedNameConstraints
[i
].constraints
.cExcludedSubtree
)
7281 fprintf(stderr
, "%d: expected %d excluded, got %d\n", i
,
7282 encodedNameConstraints
[i
].constraints
.cExcludedSubtree
,
7283 constraints
->cExcludedSubtree
);
7284 if (constraints
->cExcludedSubtree
==
7285 encodedNameConstraints
[i
].constraints
.cExcludedSubtree
)
7287 for (j
= 0; j
< constraints
->cExcludedSubtree
; j
++)
7289 compareAltNameEntry(&constraints
->rgExcludedSubtree
[j
].Base
,
7290 &encodedNameConstraints
[i
].constraints
.rgExcludedSubtree
[j
].Base
);
7293 LocalFree(constraints
);
7298 static WCHAR noticeText
[] = { 'T','h','i','s',' ','i','s',' ','a',' ',
7299 'n','o','t','i','c','e',0 };
7300 static const BYTE noticeWithDisplayText
[] = {
7301 0x30,0x22,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,0x00,
7302 0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,0x74,
7303 0x00,0x69,0x00,0x63,0x00,0x65
7305 static char org
[] = "Wine";
7306 static int noticeNumbers
[] = { 2,3 };
7307 static BYTE noticeWithReference
[] = {
7308 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7309 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7310 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7311 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7314 static void test_encodePolicyQualifierUserNotice(DWORD dwEncoding
)
7319 CERT_POLICY_QUALIFIER_USER_NOTICE notice
;
7320 CERT_POLICY_QUALIFIER_NOTICE_REFERENCE reference
;
7322 memset(¬ice
, 0, sizeof(notice
));
7323 ret
= pCryptEncodeObjectEx(dwEncoding
,
7324 X509_PKIX_POLICY_QUALIFIER_USERNOTICE
, ¬ice
, CRYPT_ENCODE_ALLOC_FLAG
,
7326 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7328 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE encode support\n");
7331 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7334 ok(sizeof(emptySequence
) == size
, "unexpected size %d\n", size
);
7335 ok(!memcmp(buf
, emptySequence
, size
), "unexpected value\n");
7338 notice
.pszDisplayText
= noticeText
;
7339 ret
= pCryptEncodeObjectEx(dwEncoding
,
7340 X509_PKIX_POLICY_QUALIFIER_USERNOTICE
, ¬ice
, CRYPT_ENCODE_ALLOC_FLAG
,
7342 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7345 ok(sizeof(noticeWithDisplayText
) == size
, "unexpected size %d\n", size
);
7346 ok(!memcmp(buf
, noticeWithDisplayText
, size
), "unexpected value\n");
7349 reference
.pszOrganization
= org
;
7350 reference
.cNoticeNumbers
= 2;
7351 reference
.rgNoticeNumbers
= noticeNumbers
;
7352 notice
.pNoticeReference
= &reference
;
7353 ret
= pCryptEncodeObjectEx(dwEncoding
,
7354 X509_PKIX_POLICY_QUALIFIER_USERNOTICE
, ¬ice
, CRYPT_ENCODE_ALLOC_FLAG
,
7356 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7359 ok(sizeof(noticeWithReference
) == size
, "unexpected size %d\n", size
);
7360 ok(!memcmp(buf
, noticeWithReference
, size
), "unexpected value\n");
7365 static void test_decodePolicyQualifierUserNotice(DWORD dwEncoding
)
7368 CERT_POLICY_QUALIFIER_USER_NOTICE
*notice
;
7371 ret
= pCryptDecodeObjectEx(dwEncoding
,
7372 X509_PKIX_POLICY_QUALIFIER_USERNOTICE
,
7373 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
7375 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7377 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE decode support\n");
7380 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7383 ok(notice
->pszDisplayText
== NULL
, "unexpected display text\n");
7384 ok(notice
->pNoticeReference
== NULL
, "unexpected notice reference\n");
7387 ret
= pCryptDecodeObjectEx(dwEncoding
,
7388 X509_PKIX_POLICY_QUALIFIER_USERNOTICE
,
7389 noticeWithDisplayText
, sizeof(noticeWithDisplayText
),
7390 CRYPT_DECODE_ALLOC_FLAG
, NULL
, ¬ice
, &size
);
7391 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7394 ok(!lstrcmpW(notice
->pszDisplayText
, noticeText
),
7395 "unexpected display text\n");
7396 ok(notice
->pNoticeReference
== NULL
, "unexpected notice reference\n");
7399 ret
= pCryptDecodeObjectEx(dwEncoding
,
7400 X509_PKIX_POLICY_QUALIFIER_USERNOTICE
,
7401 noticeWithReference
, sizeof(noticeWithReference
),
7402 CRYPT_DECODE_ALLOC_FLAG
, NULL
, ¬ice
, &size
);
7403 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7406 ok(!lstrcmpW(notice
->pszDisplayText
, noticeText
),
7407 "unexpected display text\n");
7408 ok(notice
->pNoticeReference
!= NULL
, "expected a notice reference\n");
7409 if (notice
->pNoticeReference
)
7411 ok(!strcmp(notice
->pNoticeReference
->pszOrganization
, org
),
7412 "unexpected organization %s\n",
7413 notice
->pNoticeReference
->pszOrganization
);
7414 ok(notice
->pNoticeReference
->cNoticeNumbers
== 2,
7415 "expected 2 notice numbers, got %d\n",
7416 notice
->pNoticeReference
->cNoticeNumbers
);
7417 ok(notice
->pNoticeReference
->rgNoticeNumbers
[0] == noticeNumbers
[0],
7418 "unexpected notice number %d\n",
7419 notice
->pNoticeReference
->rgNoticeNumbers
[0]);
7420 ok(notice
->pNoticeReference
->rgNoticeNumbers
[1] == noticeNumbers
[1],
7421 "unexpected notice number %d\n",
7422 notice
->pNoticeReference
->rgNoticeNumbers
[1]);
7428 static char oid_any_policy
[] = "2.5.29.32.0";
7429 static const BYTE policiesWithAnyPolicy
[] = {
7430 0x30,0x08,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00
7432 static char oid1
[] = "1.2.3";
7433 static char oid_user_notice
[] = "1.3.6.1.5.5.7.2.2";
7434 static const BYTE twoPolicies
[] = {
7435 0x30,0x50,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00,0x30,0x46,0x06,0x02,0x2a,
7436 0x03,0x30,0x40,0x30,0x3e,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x02,
7437 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7438 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7439 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7440 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7443 static void test_encodeCertPolicies(DWORD dwEncoding
)
7446 CERT_POLICIES_INFO info
;
7447 CERT_POLICY_INFO policy
[2];
7448 CERT_POLICY_QUALIFIER_INFO qualifier
;
7452 memset(&info
, 0, sizeof(info
));
7453 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_POLICIES
, &info
,
7454 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7455 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7458 ok(sizeof(emptySequence
) == size
, "unexpected size %d\n", size
);
7459 ok(!memcmp(buf
, emptySequence
, size
), "unexpected value\n");
7462 memset(policy
, 0, sizeof(policy
));
7463 info
.cPolicyInfo
= 1;
7464 info
.rgPolicyInfo
= policy
;
7465 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_POLICIES
, &info
,
7466 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7467 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
7468 GetLastError() == OSS_LIMITED
/* Win9x/NT4 */),
7469 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
7470 policy
[0].pszPolicyIdentifier
= oid_any_policy
;
7471 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_POLICIES
, &info
,
7472 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7473 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7476 ok(sizeof(policiesWithAnyPolicy
) == size
, "unexpected size %d\n", size
);
7477 ok(!memcmp(buf
, policiesWithAnyPolicy
, size
), "unexpected value\n");
7480 policy
[1].pszPolicyIdentifier
= oid1
;
7481 memset(&qualifier
, 0, sizeof(qualifier
));
7482 qualifier
.pszPolicyQualifierId
= oid_user_notice
;
7483 qualifier
.Qualifier
.cbData
= sizeof(noticeWithReference
);
7484 qualifier
.Qualifier
.pbData
= noticeWithReference
;
7485 policy
[1].cPolicyQualifier
= 1;
7486 policy
[1].rgPolicyQualifier
= &qualifier
;
7487 info
.cPolicyInfo
= 2;
7488 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_POLICIES
, &info
,
7489 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7490 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7493 ok(sizeof(twoPolicies
) == size
, "unexpected size %d\n", size
);
7494 ok(!memcmp(buf
, twoPolicies
, size
), "unexpected value\n");
7499 static void test_decodeCertPolicies(DWORD dwEncoding
)
7502 CERT_POLICIES_INFO
*info
;
7505 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_POLICIES
,
7506 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
7508 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7511 ok(info
->cPolicyInfo
== 0, "unexpected policy info %d\n",
7515 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_POLICIES
,
7516 policiesWithAnyPolicy
, sizeof(policiesWithAnyPolicy
),
7517 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
);
7518 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7521 ok(info
->cPolicyInfo
== 1, "unexpected policy info %d\n",
7523 ok(!strcmp(info
->rgPolicyInfo
[0].pszPolicyIdentifier
, oid_any_policy
),
7524 "unexpected policy id %s\n",
7525 info
->rgPolicyInfo
[0].pszPolicyIdentifier
);
7526 ok(info
->rgPolicyInfo
[0].cPolicyQualifier
== 0,
7527 "unexpected policy qualifier count %d\n",
7528 info
->rgPolicyInfo
[0].cPolicyQualifier
);
7531 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_POLICIES
,
7532 twoPolicies
, sizeof(twoPolicies
),
7533 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
);
7534 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7537 ok(info
->cPolicyInfo
== 2, "unexpected policy info %d\n",
7539 ok(!strcmp(info
->rgPolicyInfo
[0].pszPolicyIdentifier
, oid_any_policy
),
7540 "unexpected policy id %s\n",
7541 info
->rgPolicyInfo
[0].pszPolicyIdentifier
);
7542 ok(info
->rgPolicyInfo
[0].cPolicyQualifier
== 0,
7543 "unexpected policy qualifier count %d\n",
7544 info
->rgPolicyInfo
[0].cPolicyQualifier
);
7545 ok(!strcmp(info
->rgPolicyInfo
[1].pszPolicyIdentifier
, oid1
),
7546 "unexpected policy id %s\n",
7547 info
->rgPolicyInfo
[1].pszPolicyIdentifier
);
7548 ok(info
->rgPolicyInfo
[1].cPolicyQualifier
== 1,
7549 "unexpected policy qualifier count %d\n",
7550 info
->rgPolicyInfo
[1].cPolicyQualifier
);
7552 info
->rgPolicyInfo
[1].rgPolicyQualifier
[0].pszPolicyQualifierId
,
7553 oid_user_notice
), "unexpected policy qualifier id %s\n",
7554 info
->rgPolicyInfo
[1].rgPolicyQualifier
[0].pszPolicyQualifierId
);
7555 ok(info
->rgPolicyInfo
[1].rgPolicyQualifier
[0].Qualifier
.cbData
==
7556 sizeof(noticeWithReference
), "unexpected qualifier size %d\n",
7557 info
->rgPolicyInfo
[1].rgPolicyQualifier
[0].Qualifier
.cbData
);
7559 info
->rgPolicyInfo
[1].rgPolicyQualifier
[0].Qualifier
.pbData
,
7560 noticeWithReference
, sizeof(noticeWithReference
)),
7561 "unexpected qualifier value\n");
7564 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_POLICIES
,
7565 twoPolicies
, sizeof(twoPolicies
), 0, NULL
, NULL
, &size
);
7566 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7567 info
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
7570 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_POLICIES
,
7571 twoPolicies
, sizeof(twoPolicies
), 0, NULL
, info
, &size
);
7572 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7573 HeapFree(GetProcessHeap(), 0, info
);
7577 static const BYTE policyMappingWithOneMapping
[] = {
7578 0x30,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04 };
7579 static const BYTE policyMappingWithTwoMappings
[] = {
7580 0x30,0x14,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04,0x30,0x08,0x06,
7581 0x02,0x2b,0x04,0x06,0x02,0x55,0x06 };
7582 static const LPCSTR mappingOids
[] = { X509_POLICY_MAPPINGS
,
7583 szOID_POLICY_MAPPINGS
, szOID_LEGACY_POLICY_MAPPINGS
};
7585 static void test_encodeCertPolicyMappings(DWORD dwEncoding
)
7587 static char oid2
[] = "2.3.4";
7588 static char oid3
[] = "1.3.4";
7589 static char oid4
[] = "2.5.6";
7591 CERT_POLICY_MAPPINGS_INFO info
= { 0 };
7592 CERT_POLICY_MAPPING mapping
[2];
7596 /* Each of the mapping OIDs is equivalent, so check with all of them */
7597 for (i
= 0; i
< sizeof(mappingOids
) / sizeof(mappingOids
[0]); i
++)
7599 memset(&info
, 0, sizeof(info
));
7600 ret
= pCryptEncodeObjectEx(dwEncoding
, mappingOids
[i
], &info
,
7601 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7602 ok(ret
|| broken(GetLastError() == ERROR_FILE_NOT_FOUND
),
7603 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7604 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7606 win_skip("no policy mappings support\n");
7611 ok(size
== sizeof(emptySequence
), "unexpected size %d\n", size
);
7612 ok(!memcmp(buf
, emptySequence
, sizeof(emptySequence
)),
7613 "unexpected value\n");
7616 mapping
[0].pszIssuerDomainPolicy
= NULL
;
7617 mapping
[0].pszSubjectDomainPolicy
= NULL
;
7618 info
.cPolicyMapping
= 1;
7619 info
.rgPolicyMapping
= mapping
;
7620 SetLastError(0xdeadbeef);
7621 ret
= pCryptEncodeObjectEx(dwEncoding
, mappingOids
[i
], &info
,
7622 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7623 ok(!ret
&& GetLastError() == E_INVALIDARG
,
7624 "expected E_INVALIDARG, got %08x\n", GetLastError());
7625 mapping
[0].pszIssuerDomainPolicy
= oid1
;
7626 mapping
[0].pszSubjectDomainPolicy
= oid2
;
7627 ret
= pCryptEncodeObjectEx(dwEncoding
, mappingOids
[i
], &info
,
7628 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7629 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7632 ok(size
== sizeof(policyMappingWithOneMapping
),
7633 "unexpected size %d\n", size
);
7634 ok(!memcmp(buf
, policyMappingWithOneMapping
, size
),
7635 "unexpected value\n");
7638 mapping
[1].pszIssuerDomainPolicy
= oid3
;
7639 mapping
[1].pszSubjectDomainPolicy
= oid4
;
7640 info
.cPolicyMapping
= 2;
7641 ret
= pCryptEncodeObjectEx(dwEncoding
, mappingOids
[i
], &info
,
7642 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7643 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7646 ok(size
== sizeof(policyMappingWithTwoMappings
),
7647 "unexpected size %d\n", size
);
7648 ok(!memcmp(buf
, policyMappingWithTwoMappings
, size
),
7649 "unexpected value\n");
7655 static void test_decodeCertPolicyMappings(DWORD dwEncoding
)
7658 CERT_POLICY_MAPPINGS_INFO
*info
;
7661 /* Each of the mapping OIDs is equivalent, so check with all of them */
7662 for (i
= 0; i
< sizeof(mappingOids
) / sizeof(mappingOids
[0]); i
++)
7664 ret
= pCryptDecodeObjectEx(dwEncoding
, mappingOids
[i
],
7665 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
7667 ok(ret
|| broken(GetLastError() == ERROR_FILE_NOT_FOUND
),
7668 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7669 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7671 win_skip("no policy mappings support\n");
7676 ok(info
->cPolicyMapping
== 0,
7677 "expected 0 policy mappings, got %d\n", info
->cPolicyMapping
);
7680 ret
= pCryptDecodeObjectEx(dwEncoding
, mappingOids
[i
],
7681 policyMappingWithOneMapping
, sizeof(policyMappingWithOneMapping
),
7682 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
);
7683 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7686 ok(info
->cPolicyMapping
== 1,
7687 "expected 1 policy mappings, got %d\n", info
->cPolicyMapping
);
7688 ok(!strcmp(info
->rgPolicyMapping
[0].pszIssuerDomainPolicy
, "1.2.3"),
7689 "unexpected issuer policy %s\n",
7690 info
->rgPolicyMapping
[0].pszIssuerDomainPolicy
);
7691 ok(!strcmp(info
->rgPolicyMapping
[0].pszSubjectDomainPolicy
,
7692 "2.3.4"), "unexpected subject policy %s\n",
7693 info
->rgPolicyMapping
[0].pszSubjectDomainPolicy
);
7696 ret
= pCryptDecodeObjectEx(dwEncoding
, mappingOids
[i
],
7697 policyMappingWithTwoMappings
, sizeof(policyMappingWithTwoMappings
),
7698 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
);
7699 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7702 ok(info
->cPolicyMapping
== 2,
7703 "expected 2 policy mappings, got %d\n", info
->cPolicyMapping
);
7704 ok(!strcmp(info
->rgPolicyMapping
[0].pszIssuerDomainPolicy
, "1.2.3"),
7705 "unexpected issuer policy %s\n",
7706 info
->rgPolicyMapping
[0].pszIssuerDomainPolicy
);
7707 ok(!strcmp(info
->rgPolicyMapping
[0].pszSubjectDomainPolicy
,
7708 "2.3.4"), "unexpected subject policy %s\n",
7709 info
->rgPolicyMapping
[0].pszSubjectDomainPolicy
);
7710 ok(!strcmp(info
->rgPolicyMapping
[1].pszIssuerDomainPolicy
, "1.3.4"),
7711 "unexpected issuer policy %s\n",
7712 info
->rgPolicyMapping
[1].pszIssuerDomainPolicy
);
7713 ok(!strcmp(info
->rgPolicyMapping
[1].pszSubjectDomainPolicy
,
7714 "2.5.6"), "unexpected subject policy %s\n",
7715 info
->rgPolicyMapping
[1].pszSubjectDomainPolicy
);
7718 ret
= pCryptDecodeObjectEx(dwEncoding
, mappingOids
[i
],
7719 policyMappingWithTwoMappings
, sizeof(policyMappingWithTwoMappings
), 0,
7721 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7722 info
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
7725 ret
= pCryptDecodeObjectEx(dwEncoding
, mappingOids
[i
],
7726 policyMappingWithTwoMappings
, sizeof(policyMappingWithTwoMappings
), 0,
7728 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7729 HeapFree(GetProcessHeap(), 0, info
);
7734 static const BYTE policyConstraintsWithRequireExplicit
[] = {
7735 0x30,0x03,0x80,0x01,0x00 };
7736 static const BYTE policyConstraintsWithInhibitMapping
[] = {
7737 0x30,0x03,0x81,0x01,0x01 };
7738 static const BYTE policyConstraintsWithBoth
[] = {
7739 0x30,0x06,0x80,0x01,0x01,0x81,0x01,0x01 };
7741 static void test_encodeCertPolicyConstraints(DWORD dwEncoding
)
7743 CERT_POLICY_CONSTRAINTS_INFO info
= { 0 };
7748 /* Even though RFC 5280 explicitly states CAs must not issue empty
7749 * policy constraints (section 4.2.1.11), the API doesn't prevent it.
7751 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_POLICY_CONSTRAINTS
, &info
,
7752 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7753 ok(ret
|| broken(GetLastError() == ERROR_FILE_NOT_FOUND
),
7754 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7755 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7757 win_skip("no policy constraints support\n");
7762 ok(size
== sizeof(emptySequence
), "unexpected size %d\n", size
);
7763 ok(!memcmp(buf
, emptySequence
, sizeof(emptySequence
)),
7764 "unexpected value\n");
7767 /* If fRequireExplicitPolicy is set but dwRequireExplicitPolicySkipCerts
7768 * is not, then a skip of 0 is encoded.
7770 info
.fRequireExplicitPolicy
= TRUE
;
7771 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_POLICY_CONSTRAINTS
, &info
,
7772 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7773 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7776 ok(size
== sizeof(policyConstraintsWithRequireExplicit
),
7777 "unexpected size %d\n", size
);
7778 ok(!memcmp(buf
, policyConstraintsWithRequireExplicit
,
7779 sizeof(policyConstraintsWithRequireExplicit
)), "unexpected value\n");
7782 /* With inhibit policy mapping */
7783 info
.fRequireExplicitPolicy
= FALSE
;
7784 info
.dwRequireExplicitPolicySkipCerts
= 0;
7785 info
.fInhibitPolicyMapping
= TRUE
;
7786 info
.dwInhibitPolicyMappingSkipCerts
= 1;
7787 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_POLICY_CONSTRAINTS
, &info
,
7788 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7789 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7792 ok(size
== sizeof(policyConstraintsWithInhibitMapping
),
7793 "unexpected size %d\n", size
);
7794 ok(!memcmp(buf
, policyConstraintsWithInhibitMapping
,
7795 sizeof(policyConstraintsWithInhibitMapping
)), "unexpected value\n");
7799 info
.fRequireExplicitPolicy
= TRUE
;
7800 info
.dwRequireExplicitPolicySkipCerts
= 1;
7801 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_POLICY_CONSTRAINTS
, &info
,
7802 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7803 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7806 ok(size
== sizeof(policyConstraintsWithBoth
), "unexpected size %d\n",
7808 ok(!memcmp(buf
, policyConstraintsWithBoth
,
7809 sizeof(policyConstraintsWithBoth
)), "unexpected value\n");
7814 static void test_decodeCertPolicyConstraints(DWORD dwEncoding
)
7816 CERT_POLICY_CONSTRAINTS_INFO
*info
;
7820 /* Again, even though CAs must not issue such constraints, they can be
7823 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_POLICY_CONSTRAINTS
,
7824 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
7826 ok(ret
|| broken(GetLastError() == ERROR_FILE_NOT_FOUND
),
7827 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7828 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7830 win_skip("no policy mappings support\n");
7835 ok(!info
->fRequireExplicitPolicy
,
7836 "expected require explicit = FALSE\n");
7837 ok(!info
->fInhibitPolicyMapping
,
7838 "expected implicit mapping = FALSE\n");
7841 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_POLICY_CONSTRAINTS
,
7842 policyConstraintsWithRequireExplicit
,
7843 sizeof(policyConstraintsWithRequireExplicit
), CRYPT_DECODE_ALLOC_FLAG
,
7844 NULL
, &info
, &size
);
7845 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7848 ok(info
->fRequireExplicitPolicy
,
7849 "expected require explicit = TRUE\n");
7850 ok(info
->dwRequireExplicitPolicySkipCerts
== 0, "expected 0, got %d\n",
7851 info
->dwRequireExplicitPolicySkipCerts
);
7852 ok(!info
->fInhibitPolicyMapping
,
7853 "expected implicit mapping = FALSE\n");
7856 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_POLICY_CONSTRAINTS
,
7857 policyConstraintsWithInhibitMapping
,
7858 sizeof(policyConstraintsWithInhibitMapping
), CRYPT_DECODE_ALLOC_FLAG
,
7859 NULL
, &info
, &size
);
7860 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7863 ok(!info
->fRequireExplicitPolicy
,
7864 "expected require explicit = FALSE\n");
7865 ok(info
->fInhibitPolicyMapping
,
7866 "expected implicit mapping = TRUE\n");
7867 ok(info
->dwInhibitPolicyMappingSkipCerts
== 1, "expected 1, got %d\n",
7868 info
->dwInhibitPolicyMappingSkipCerts
);
7871 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_POLICY_CONSTRAINTS
,
7872 policyConstraintsWithBoth
, sizeof(policyConstraintsWithBoth
),
7873 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
);
7874 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7877 ok(info
->fRequireExplicitPolicy
,
7878 "expected require explicit = TRUE\n");
7879 ok(info
->dwRequireExplicitPolicySkipCerts
== 1, "expected 1, got %d\n",
7880 info
->dwRequireExplicitPolicySkipCerts
);
7881 ok(info
->fInhibitPolicyMapping
,
7882 "expected implicit mapping = TRUE\n");
7883 ok(info
->dwInhibitPolicyMappingSkipCerts
== 1, "expected 1, got %d\n",
7884 info
->dwInhibitPolicyMappingSkipCerts
);
7889 /* Free *pInfo with HeapFree */
7890 static void testExportPublicKey(HCRYPTPROV csp
, PCERT_PUBLIC_KEY_INFO
*pInfo
)
7897 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
7899 ret
= CryptExportPublicKeyInfoEx(0, 0, 0, NULL
, 0, NULL
, NULL
, &size
);
7900 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
7901 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7902 ret
= CryptExportPublicKeyInfoEx(0, AT_SIGNATURE
, 0, NULL
, 0, NULL
, NULL
,
7904 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
7905 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7906 ret
= CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING
, NULL
, 0, NULL
,
7908 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
7909 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7910 ret
= CryptExportPublicKeyInfoEx(0, AT_SIGNATURE
, X509_ASN_ENCODING
, NULL
,
7911 0, NULL
, NULL
, &size
);
7912 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
7913 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7914 /* Test with no key */
7915 ret
= CryptExportPublicKeyInfoEx(csp
, AT_SIGNATURE
, X509_ASN_ENCODING
, NULL
,
7916 0, NULL
, NULL
, &size
);
7917 ok(!ret
&& GetLastError() == NTE_NO_KEY
, "Expected NTE_NO_KEY, got %08x\n",
7919 ret
= CryptGenKey(csp
, AT_SIGNATURE
, 0, &key
);
7920 ok(ret
, "CryptGenKey failed: %08x\n", GetLastError());
7923 ret
= CryptExportPublicKeyInfoEx(csp
, AT_SIGNATURE
, X509_ASN_ENCODING
,
7924 NULL
, 0, NULL
, NULL
, &size
);
7925 ok(ret
, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
7926 *pInfo
= HeapAlloc(GetProcessHeap(), 0, size
);
7929 ret
= CryptExportPublicKeyInfoEx(csp
, AT_SIGNATURE
,
7930 X509_ASN_ENCODING
, NULL
, 0, NULL
, *pInfo
, &size
);
7931 ok(ret
, "CryptExportPublicKeyInfoEx failed: %08x\n",
7935 /* By default (we passed NULL as the OID) the OID is
7938 ok(!strcmp((*pInfo
)->Algorithm
.pszObjId
, szOID_RSA_RSA
),
7939 "Expected %s, got %s\n", szOID_RSA_RSA
,
7940 (*pInfo
)->Algorithm
.pszObjId
);
7944 CryptDestroyKey(key
);
7947 static const BYTE expiredCert
[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
7948 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
7949 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
7950 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7951 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7952 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7953 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
7954 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
7955 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7956 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7957 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7958 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
7959 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
7960 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
7961 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
7962 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
7963 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
7964 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
7965 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
7966 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
7967 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
7968 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
7969 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
7970 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
7971 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
7973 static void testImportPublicKey(HCRYPTPROV csp
, PCERT_PUBLIC_KEY_INFO info
)
7977 PCCERT_CONTEXT context
;
7982 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
7983 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
7984 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
7985 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7988 ret
= CryptImportPublicKeyInfoEx(0, 0, info
, 0, 0, NULL
, &key
);
7989 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
7990 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7991 ret
= CryptImportPublicKeyInfoEx(csp
, 0, info
, 0, 0, NULL
, &key
);
7992 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
7993 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7994 ret
= CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING
, info
, 0, 0, NULL
,
7996 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
7997 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7999 /* Export key with standard algorithm (CALG_RSA_KEYX) */
8000 ret
= CryptImportPublicKeyInfoEx(csp
, X509_ASN_ENCODING
, info
, 0, 0, NULL
,
8002 ok(ret
, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
8004 dwSize
= sizeof(ai
);
8005 CryptGetKeyParam(key
, KP_ALGID
, (LPVOID
)&ai
, &dwSize
, 0);
8006 ok(ret
, "CryptGetKeyParam failed: %08x\n", GetLastError());
8009 ok(dwSize
== sizeof(ai
), "CryptGetKeyParam returned size %d\n",dwSize
);
8010 ok(ai
== CALG_RSA_KEYX
, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai
);
8013 CryptDestroyKey(key
);
8015 /* Repeat with forced algorithm */
8016 ret
= CryptImportPublicKeyInfoEx(csp
, X509_ASN_ENCODING
, info
, CALG_RSA_SIGN
, 0, NULL
,
8018 ok(ret
, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
8020 dwSize
= sizeof(ai
);
8021 CryptGetKeyParam(key
, KP_ALGID
, (LPVOID
)&ai
, &dwSize
, 0);
8022 ok(ret
, "CryptGetKeyParam failed: %08x\n", GetLastError());
8025 ok(dwSize
== sizeof(ai
), "CryptGetKeyParam returned size %d\n",dwSize
);
8026 ok(ai
== CALG_RSA_SIGN
, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai
);
8029 CryptDestroyKey(key
);
8031 /* Test importing a public key from a certificate context */
8032 context
= CertCreateCertificateContext(X509_ASN_ENCODING
, expiredCert
,
8033 sizeof(expiredCert
));
8034 ok(context
!= NULL
, "CertCreateCertificateContext failed: %08x\n",
8038 ok(!strcmp(szOID_RSA_RSA
,
8039 context
->pCertInfo
->SubjectPublicKeyInfo
.Algorithm
.pszObjId
),
8040 "Expected %s, got %s\n", szOID_RSA_RSA
,
8041 context
->pCertInfo
->SubjectPublicKeyInfo
.Algorithm
.pszObjId
);
8042 ret
= CryptImportPublicKeyInfoEx(csp
, X509_ASN_ENCODING
,
8043 &context
->pCertInfo
->SubjectPublicKeyInfo
, 0, 0, NULL
, &key
);
8044 ok(ret
, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
8045 CryptDestroyKey(key
);
8046 CertFreeCertificateContext(context
);
8050 static const char cspName
[] = "WineCryptTemp";
8052 static void testPortPublicKeyInfo(void)
8056 PCERT_PUBLIC_KEY_INFO info
= NULL
;
8058 /* Just in case a previous run failed, delete this thing */
8059 CryptAcquireContextA(&csp
, cspName
, MS_DEF_PROV_A
, PROV_RSA_FULL
,
8060 CRYPT_DELETEKEYSET
);
8061 ret
= CryptAcquireContextA(&csp
, cspName
, MS_DEF_PROV_A
, PROV_RSA_FULL
,
8063 ok(ret
,"CryptAcquireContextA failed\n");
8065 testExportPublicKey(csp
, &info
);
8066 testImportPublicKey(csp
, info
);
8068 HeapFree(GetProcessHeap(), 0, info
);
8069 CryptReleaseContext(csp
, 0);
8070 ret
= CryptAcquireContextA(&csp
, cspName
, MS_DEF_PROV_A
, PROV_RSA_FULL
,
8071 CRYPT_DELETEKEYSET
);
8072 ok(ret
,"CryptAcquireContextA failed\n");
8077 static const DWORD encodings
[] = { X509_ASN_ENCODING
, PKCS_7_ASN_ENCODING
,
8078 X509_ASN_ENCODING
| PKCS_7_ASN_ENCODING
};
8082 hCrypt32
= GetModuleHandleA("crypt32.dll");
8083 pCryptDecodeObjectEx
= (void*)GetProcAddress(hCrypt32
, "CryptDecodeObjectEx");
8084 pCryptEncodeObjectEx
= (void*)GetProcAddress(hCrypt32
, "CryptEncodeObjectEx");
8085 if (!pCryptDecodeObjectEx
|| !pCryptEncodeObjectEx
)
8087 win_skip("CryptDecodeObjectEx() is not available\n");
8091 for (i
= 0; i
< sizeof(encodings
) / sizeof(encodings
[0]); i
++)
8093 test_encodeInt(encodings
[i
]);
8094 test_decodeInt(encodings
[i
]);
8095 test_encodeEnumerated(encodings
[i
]);
8096 test_decodeEnumerated(encodings
[i
]);
8097 test_encodeFiletime(encodings
[i
]);
8098 test_decodeFiletime(encodings
[i
]);
8099 test_encodeName(encodings
[i
]);
8100 test_decodeName(encodings
[i
]);
8101 test_encodeUnicodeName(encodings
[i
]);
8102 test_decodeUnicodeName(encodings
[i
]);
8103 test_encodeNameValue(encodings
[i
]);
8104 test_decodeNameValue(encodings
[i
]);
8105 test_encodeUnicodeNameValue(encodings
[i
]);
8106 test_decodeUnicodeNameValue(encodings
[i
]);
8107 test_encodeAltName(encodings
[i
]);
8108 test_decodeAltName(encodings
[i
]);
8109 test_encodeOctets(encodings
[i
]);
8110 test_decodeOctets(encodings
[i
]);
8111 test_encodeBits(encodings
[i
]);
8112 test_decodeBits(encodings
[i
]);
8113 test_encodeBasicConstraints(encodings
[i
]);
8114 test_decodeBasicConstraints(encodings
[i
]);
8115 test_encodeRsaPublicKey(encodings
[i
]);
8116 test_decodeRsaPublicKey(encodings
[i
]);
8117 test_encodeSequenceOfAny(encodings
[i
]);
8118 test_decodeSequenceOfAny(encodings
[i
]);
8119 test_encodeExtensions(encodings
[i
]);
8120 test_decodeExtensions(encodings
[i
]);
8121 test_encodePublicKeyInfo(encodings
[i
]);
8122 test_decodePublicKeyInfo(encodings
[i
]);
8123 test_encodeCertToBeSigned(encodings
[i
]);
8124 test_decodeCertToBeSigned(encodings
[i
]);
8125 test_encodeCert(encodings
[i
]);
8126 test_decodeCert(encodings
[i
]);
8127 test_encodeCRLDistPoints(encodings
[i
]);
8128 test_decodeCRLDistPoints(encodings
[i
]);
8129 test_encodeCRLIssuingDistPoint(encodings
[i
]);
8130 test_decodeCRLIssuingDistPoint(encodings
[i
]);
8131 test_encodeCRLToBeSigned(encodings
[i
]);
8132 test_decodeCRLToBeSigned(encodings
[i
]);
8133 test_encodeEnhancedKeyUsage(encodings
[i
]);
8134 test_decodeEnhancedKeyUsage(encodings
[i
]);
8135 test_encodeAuthorityKeyId(encodings
[i
]);
8136 test_decodeAuthorityKeyId(encodings
[i
]);
8137 test_encodeAuthorityKeyId2(encodings
[i
]);
8138 test_decodeAuthorityKeyId2(encodings
[i
]);
8139 test_encodeAuthorityInfoAccess(encodings
[i
]);
8140 test_decodeAuthorityInfoAccess(encodings
[i
]);
8141 test_encodeCTL(encodings
[i
]);
8142 test_decodeCTL(encodings
[i
]);
8143 test_encodePKCSContentInfo(encodings
[i
]);
8144 test_decodePKCSContentInfo(encodings
[i
]);
8145 test_encodePKCSAttribute(encodings
[i
]);
8146 test_decodePKCSAttribute(encodings
[i
]);
8147 test_encodePKCSAttributes(encodings
[i
]);
8148 test_decodePKCSAttributes(encodings
[i
]);
8149 test_encodePKCSSMimeCapabilities(encodings
[i
]);
8150 test_decodePKCSSMimeCapabilities(encodings
[i
]);
8151 test_encodePKCSSignerInfo(encodings
[i
]);
8152 test_decodePKCSSignerInfo(encodings
[i
]);
8153 test_encodeCMSSignerInfo(encodings
[i
]);
8154 test_decodeCMSSignerInfo(encodings
[i
]);
8155 test_encodeNameConstraints(encodings
[i
]);
8156 test_decodeNameConstraints(encodings
[i
]);
8157 test_encodePolicyQualifierUserNotice(encodings
[i
]);
8158 test_decodePolicyQualifierUserNotice(encodings
[i
]);
8159 test_encodeCertPolicies(encodings
[i
]);
8160 test_decodeCertPolicies(encodings
[i
]);
8161 test_encodeCertPolicyMappings(encodings
[i
]);
8162 test_decodeCertPolicyMappings(encodings
[i
]);
8163 test_encodeCertPolicyConstraints(encodings
[i
]);
8164 test_decodeCertPolicyConstraints(encodings
[i
]);
8166 testPortPublicKeyInfo();