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());
105 /* check with NULL integer buffer. Windows XP incorrectly returns an
108 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_INTEGER
, NULL
, 0, NULL
, NULL
,
110 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
111 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
112 for (i
= 0; i
< sizeof(ints
) / sizeof(ints
[0]); i
++)
114 /* encode as normal integer */
115 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_INTEGER
, &ints
[i
].val
, 0,
116 NULL
, NULL
, &bufSize
);
117 ok(ret
, "Expected success, got %d\n", GetLastError());
118 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_INTEGER
, &ints
[i
].val
,
119 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
120 ok(ret
, "CryptEncodeObjectEx failed: %d\n", GetLastError());
123 ok(buf
[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
125 ok(buf
[1] == ints
[i
].encoded
[1], "Got length %d, expected %d\n",
126 buf
[1], ints
[i
].encoded
[1]);
127 ok(!memcmp(buf
+ 1, ints
[i
].encoded
+ 1, ints
[i
].encoded
[1] + 1),
128 "Encoded value of 0x%08x didn't match expected\n", ints
[i
].val
);
131 /* encode as multibyte integer */
132 blob
.cbData
= sizeof(ints
[i
].val
);
133 blob
.pbData
= (BYTE
*)&ints
[i
].val
;
134 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_MULTI_BYTE_INTEGER
, &blob
,
135 0, NULL
, NULL
, &bufSize
);
136 ok(ret
, "Expected success, got %d\n", GetLastError());
137 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_MULTI_BYTE_INTEGER
, &blob
,
138 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
139 ok(ret
, "CryptEncodeObjectEx failed: %d\n", GetLastError());
142 ok(buf
[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
144 ok(buf
[1] == ints
[i
].encoded
[1], "Got length %d, expected %d\n",
145 buf
[1], ints
[i
].encoded
[1]);
146 ok(!memcmp(buf
+ 1, ints
[i
].encoded
+ 1, ints
[i
].encoded
[1] + 1),
147 "Encoded value of 0x%08x didn't match expected\n", ints
[i
].val
);
151 /* encode a couple bigger ints, just to show it's little-endian and leading
152 * sign bytes are dropped
154 for (i
= 0; i
< sizeof(bigInts
) / sizeof(bigInts
[0]); i
++)
156 blob
.cbData
= strlen((const char*)bigInts
[i
].val
);
157 blob
.pbData
= (BYTE
*)bigInts
[i
].val
;
158 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_MULTI_BYTE_INTEGER
, &blob
,
159 0, NULL
, NULL
, &bufSize
);
160 ok(ret
, "Expected success, got %d\n", GetLastError());
161 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_MULTI_BYTE_INTEGER
, &blob
,
162 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
163 ok(ret
, "CryptEncodeObjectEx failed: %d\n", GetLastError());
166 ok(buf
[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
168 ok(buf
[1] == bigInts
[i
].encoded
[1], "Got length %d, expected %d\n",
169 buf
[1], bigInts
[i
].encoded
[1]);
170 ok(!memcmp(buf
+ 1, bigInts
[i
].encoded
+ 1,
171 bigInts
[i
].encoded
[1] + 1),
172 "Encoded value didn't match expected\n");
176 /* and, encode some uints */
177 for (i
= 0; i
< sizeof(bigUInts
) / sizeof(bigUInts
[0]); i
++)
179 blob
.cbData
= strlen((const char*)bigUInts
[i
].val
);
180 blob
.pbData
= (BYTE
*)bigUInts
[i
].val
;
181 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_MULTI_BYTE_UINT
, &blob
,
182 0, NULL
, NULL
, &bufSize
);
183 ok(ret
, "Expected success, got %d\n", GetLastError());
184 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_MULTI_BYTE_UINT
, &blob
,
185 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
186 ok(ret
, "CryptEncodeObjectEx failed: %d\n", GetLastError());
189 ok(buf
[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
191 ok(buf
[1] == bigUInts
[i
].encoded
[1], "Got length %d, expected %d\n",
192 buf
[1], bigUInts
[i
].encoded
[1]);
193 ok(!memcmp(buf
+ 1, bigUInts
[i
].encoded
+ 1,
194 bigUInts
[i
].encoded
[1] + 1),
195 "Encoded value didn't match expected\n");
201 static void test_decodeInt(DWORD dwEncoding
)
203 static const BYTE bigInt
[] = { 2, 5, 0xff, 0xfe, 0xff, 0xfe, 0xff };
204 static const BYTE testStr
[] = { 0x16, 4, 't', 'e', 's', 't' };
205 static const BYTE longForm
[] = { 2, 0x81, 0x01, 0x01 };
206 static const BYTE bigBogus
[] = { 0x02, 0x84, 0x01, 0xff, 0xff, 0xf9 };
207 static const BYTE extraBytes
[] = { 2, 1, 1, 0, 0, 0, 0 };
213 /* CryptDecodeObjectEx with NULL bufSize crashes..
214 ret = pCryptDecodeObjectEx(3, X509_INTEGER, &ints[0].encoded,
215 ints[0].encoded[1] + 2, 0, NULL, NULL, NULL);
217 /* check bogus encoding */
218 ret
= pCryptDecodeObjectEx(3, X509_INTEGER
, (BYTE
*)&ints
[0].encoded
,
219 ints
[0].encoded
[1] + 2, 0, NULL
, NULL
, &bufSize
);
220 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
221 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
222 /* check with NULL integer buffer */
223 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_INTEGER
, NULL
, 0, 0, NULL
, NULL
,
225 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_EOD
,
226 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
227 /* check with a valid, but too large, integer */
228 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_INTEGER
, bigInt
, bigInt
[1] + 2,
229 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
230 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_LARGE
,
231 "Expected CRYPT_E_ASN1_LARGE, got %d\n", GetLastError());
232 /* check with a DER-encoded string */
233 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_INTEGER
, testStr
, testStr
[1] + 2,
234 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
235 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_BADTAG
,
236 "Expected CRYPT_E_ASN1_BADTAG, got %d\n", GetLastError());
237 for (i
= 0; i
< sizeof(ints
) / sizeof(ints
[0]); i
++)
239 /* When the output buffer is NULL, this always succeeds */
240 SetLastError(0xdeadbeef);
241 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_INTEGER
,
242 ints
[i
].encoded
, ints
[i
].encoded
[1] + 2, 0, NULL
, NULL
,
244 ok(ret
&& GetLastError() == NOERROR
,
245 "Expected success and NOERROR, got %d\n", GetLastError());
246 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_INTEGER
,
247 ints
[i
].encoded
, ints
[i
].encoded
[1] + 2,
248 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
249 ok(ret
, "CryptDecodeObjectEx failed: %d\n", GetLastError());
250 ok(bufSize
== sizeof(int), "Wrong size %d\n", bufSize
);
251 ok(buf
!= NULL
, "Expected allocated buffer\n");
254 ok(!memcmp(buf
, &ints
[i
].val
, bufSize
), "Expected %d, got %d\n",
255 ints
[i
].val
, *(int *)buf
);
259 for (i
= 0; i
< sizeof(bigInts
) / sizeof(bigInts
[0]); i
++)
261 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_MULTI_BYTE_INTEGER
,
262 bigInts
[i
].encoded
, bigInts
[i
].encoded
[1] + 2, 0, NULL
, NULL
,
264 ok(ret
&& GetLastError() == NOERROR
,
265 "Expected success and NOERROR, got %d\n", GetLastError());
266 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_MULTI_BYTE_INTEGER
,
267 bigInts
[i
].encoded
, bigInts
[i
].encoded
[1] + 2,
268 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
269 ok(ret
, "CryptDecodeObjectEx failed: %d\n", GetLastError());
270 ok(bufSize
>= sizeof(CRYPT_INTEGER_BLOB
), "Wrong size %d\n", bufSize
);
271 ok(buf
!= NULL
, "Expected allocated buffer\n");
274 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)buf
;
276 ok(blob
->cbData
== strlen((const char*)bigInts
[i
].decoded
),
277 "Expected len %d, got %d\n", lstrlenA((const char*)bigInts
[i
].decoded
),
279 ok(!memcmp(blob
->pbData
, bigInts
[i
].decoded
, blob
->cbData
),
280 "Unexpected value\n");
284 for (i
= 0; i
< sizeof(bigUInts
) / sizeof(bigUInts
[0]); i
++)
286 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_MULTI_BYTE_UINT
,
287 bigUInts
[i
].encoded
, bigUInts
[i
].encoded
[1] + 2, 0, NULL
, NULL
,
289 ok(ret
&& GetLastError() == NOERROR
,
290 "Expected success and NOERROR, got %d\n", GetLastError());
291 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_MULTI_BYTE_UINT
,
292 bigUInts
[i
].encoded
, bigUInts
[i
].encoded
[1] + 2,
293 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
294 ok(ret
, "CryptDecodeObjectEx failed: %d\n", GetLastError());
295 ok(bufSize
>= sizeof(CRYPT_INTEGER_BLOB
), "Wrong size %d\n", bufSize
);
296 ok(buf
!= NULL
, "Expected allocated buffer\n");
299 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)buf
;
301 ok(blob
->cbData
== strlen((const char*)bigUInts
[i
].val
),
302 "Expected len %d, got %d\n", lstrlenA((const char*)bigUInts
[i
].val
),
304 ok(!memcmp(blob
->pbData
, bigUInts
[i
].val
, blob
->cbData
),
305 "Unexpected value\n");
309 /* Decode the value 1 with long-form length */
310 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_MULTI_BYTE_INTEGER
, longForm
,
311 sizeof(longForm
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
312 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
315 ok(*(int *)buf
== 1, "Expected 1, got %d\n", *(int *)buf
);
318 /* check with extra bytes at the end */
319 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_INTEGER
, extraBytes
,
320 sizeof(extraBytes
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
321 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
324 ok(*(int *)buf
== 1, "Expected 1, got %d\n", *(int *)buf
);
327 /* Try to decode some bogus large items */
328 /* The buffer size is smaller than the encoded length, so this should fail
329 * with CRYPT_E_ASN1_EOD if it's being decoded.
330 * Under XP it fails with CRYPT_E_ASN1_LARGE, which means there's a limit
331 * on the size decoded, but in ME it fails with CRYPT_E_ASN1_EOD or crashes.
332 * So this test unfortunately isn't useful.
333 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, tooBig,
334 0x7fffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
335 ok(!ret && GetLastError() == CRYPT_E_ASN1_LARGE,
336 "Expected CRYPT_E_ASN1_LARGE, got %08x\n", GetLastError());
338 /* This will try to decode the buffer and overflow it, check that it's
343 /* a large buffer isn't guaranteed to crash, it depends on memory allocation order */
344 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_MULTI_BYTE_INTEGER
, bigBogus
,
345 0x01ffffff, CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
346 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
347 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
351 static const BYTE bin18
[] = {0x0a,0x01,0x01};
352 static const BYTE bin19
[] = {0x0a,0x05,0x00,0xff,0xff,0xff,0x80};
354 /* These are always encoded unsigned, and aren't constrained to be any
357 static const struct encodedInt enums
[] = {
362 /* X509_CRL_REASON_CODE is also an enumerated type, but it's #defined to
365 static const LPCSTR enumeratedTypes
[] = { X509_ENUMERATED
,
366 szOID_CRL_REASON_CODE
};
368 static void test_encodeEnumerated(DWORD dwEncoding
)
372 for (i
= 0; i
< sizeof(enumeratedTypes
) / sizeof(enumeratedTypes
[0]); i
++)
374 for (j
= 0; j
< sizeof(enums
) / sizeof(enums
[0]); j
++)
380 ret
= pCryptEncodeObjectEx(dwEncoding
, enumeratedTypes
[i
],
381 &enums
[j
].val
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
383 ok(ret
, "CryptEncodeObjectEx failed: %d\n", GetLastError());
387 "Got unexpected type %d for enumerated (expected 0xa)\n",
389 ok(buf
[1] == enums
[j
].encoded
[1],
390 "Got length %d, expected %d\n", buf
[1], enums
[j
].encoded
[1]);
391 ok(!memcmp(buf
+ 1, enums
[j
].encoded
+ 1,
392 enums
[j
].encoded
[1] + 1),
393 "Encoded value of 0x%08x didn't match expected\n",
401 static void test_decodeEnumerated(DWORD dwEncoding
)
405 for (i
= 0; i
< sizeof(enumeratedTypes
) / sizeof(enumeratedTypes
[0]); i
++)
407 for (j
= 0; j
< sizeof(enums
) / sizeof(enums
[0]); j
++)
410 DWORD bufSize
= sizeof(int);
413 ret
= pCryptDecodeObjectEx(dwEncoding
, enumeratedTypes
[i
],
414 enums
[j
].encoded
, enums
[j
].encoded
[1] + 2, 0, NULL
,
415 (BYTE
*)&val
, &bufSize
);
416 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
417 ok(bufSize
== sizeof(int),
418 "Got unexpected size %d for enumerated\n", bufSize
);
419 ok(val
== enums
[j
].val
, "Unexpected value %d, expected %d\n",
425 struct encodedFiletime
428 const BYTE
*encodedTime
;
431 static void testTimeEncoding(DWORD dwEncoding
, LPCSTR structType
,
432 const struct encodedFiletime
*time
)
439 ret
= SystemTimeToFileTime(&time
->sysTime
, &ft
);
440 ok(ret
, "SystemTimeToFileTime failed: %d\n", GetLastError());
441 ret
= pCryptEncodeObjectEx(dwEncoding
, structType
, &ft
,
442 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
443 /* years other than 1950-2050 are not allowed for encodings other than
444 * X509_CHOICE_OF_TIME.
446 if (structType
== X509_CHOICE_OF_TIME
||
447 (time
->sysTime
.wYear
>= 1950 && time
->sysTime
.wYear
<= 2050))
449 ok(ret
, "CryptEncodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
451 ok(buf
!= NULL
, "Expected an allocated buffer\n");
454 ok(buf
[0] == time
->encodedTime
[0],
455 "Expected type 0x%02x, got 0x%02x\n", time
->encodedTime
[0],
457 ok(buf
[1] == time
->encodedTime
[1], "Expected %d bytes, got %d\n",
458 time
->encodedTime
[1], bufSize
);
459 ok(!memcmp(time
->encodedTime
+ 2, buf
+ 2, time
->encodedTime
[1]),
460 "Got unexpected value for time encoding\n");
465 ok(!ret
&& GetLastError() == CRYPT_E_BAD_ENCODE
,
466 "Expected CRYPT_E_BAD_ENCODE, got 0x%08x\n", GetLastError());
469 static const char *printSystemTime(const SYSTEMTIME
*st
)
473 sprintf(buf
, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st
->wMonth
, st
->wDay
,
474 st
->wYear
, st
->wHour
, st
->wMinute
, st
->wSecond
, st
->wMilliseconds
);
478 static const char *printFileTime(const FILETIME
*ft
)
483 FileTimeToSystemTime(ft
, &st
);
484 sprintf(buf
, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st
.wMonth
, st
.wDay
,
485 st
.wYear
, st
.wHour
, st
.wMinute
, st
.wSecond
, st
.wMilliseconds
);
489 static void compareTime(const SYSTEMTIME
*expected
, const FILETIME
*got
)
493 FileTimeToSystemTime(got
, &st
);
494 ok(expected
->wYear
== st
.wYear
&&
495 expected
->wMonth
== st
.wMonth
&&
496 expected
->wDay
== st
.wDay
&&
497 expected
->wHour
== st
.wHour
&&
498 expected
->wMinute
== st
.wMinute
&&
499 expected
->wSecond
== st
.wSecond
&&
500 abs(expected
->wMilliseconds
- st
.wMilliseconds
) <= 1,
501 "Got unexpected value for time decoding:\nexpected %s, got %s\n",
502 printSystemTime(expected
), printFileTime(got
));
505 static void testTimeDecoding(DWORD dwEncoding
, LPCSTR structType
,
506 const struct encodedFiletime
*time
)
509 DWORD size
= sizeof(ft
);
512 ret
= pCryptDecodeObjectEx(dwEncoding
, structType
, time
->encodedTime
,
513 time
->encodedTime
[1] + 2, 0, NULL
, &ft
, &size
);
514 /* years other than 1950-2050 are not allowed for encodings other than
515 * X509_CHOICE_OF_TIME.
517 if (structType
== X509_CHOICE_OF_TIME
||
518 (time
->sysTime
.wYear
>= 1950 && time
->sysTime
.wYear
<= 2050))
520 ok(ret
, "CryptDecodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
522 compareTime(&time
->sysTime
, &ft
);
525 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_BADTAG
,
526 "Expected CRYPT_E_ASN1_BADTAG, got 0x%08x\n", GetLastError());
529 static const BYTE bin20
[] = {
530 0x17,0x0d,'0','5','0','6','0','6','1','6','1','0','0','0','Z'};
531 static const BYTE bin21
[] = {
532 0x18,0x0f,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
533 static const BYTE bin22
[] = {
534 0x18,0x0f,'2','1','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
536 static const struct encodedFiletime times
[] = {
537 { { 2005, 6, 1, 6, 16, 10, 0, 0 }, bin20
},
538 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin21
},
539 { { 2145, 6, 1, 6, 16, 10, 0, 0 }, bin22
},
542 static void test_encodeFiletime(DWORD dwEncoding
)
546 for (i
= 0; i
< sizeof(times
) / sizeof(times
[0]); i
++)
548 testTimeEncoding(dwEncoding
, X509_CHOICE_OF_TIME
, ×
[i
]);
549 testTimeEncoding(dwEncoding
, PKCS_UTC_TIME
, ×
[i
]);
550 testTimeEncoding(dwEncoding
, szOID_RSA_signingTime
, ×
[i
]);
554 static const BYTE bin23
[] = {
555 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','0','0','0','Z'};
556 static const BYTE bin24
[] = {
557 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','9','9','9','Z'};
558 static const BYTE bin25
[] = {
559 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','+','0','1','0','0'};
560 static const BYTE bin26
[] = {
561 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','0','0'};
562 static const BYTE bin27
[] = {
563 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','1','5'};
564 static const BYTE bin28
[] = {
565 0x18,0x0a,'2','1','4','5','0','6','0','6','1','6'};
566 static const BYTE bin29
[] = {
567 0x17,0x0a,'4','5','0','6','0','6','1','6','1','0'};
568 static const BYTE bin30
[] = {
569 0x17,0x0b,'4','5','0','6','0','6','1','6','1','0','Z'};
570 static const BYTE bin31
[] = {
571 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','+','0','1'};
572 static const BYTE bin32
[] = {
573 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','-','0','1'};
574 static const BYTE bin33
[] = {
575 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','+','0','1','0','0'};
576 static const BYTE bin34
[] = {
577 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','-','0','1','0','0'};
578 static const BYTE bin35
[] = {
579 0x17,0x08, '4','5','0','6','0','6','1','6'};
580 static const BYTE bin36
[] = {
581 0x18,0x0f, 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','Z'};
582 static const BYTE bin37
[] = {
583 0x18,0x04, '2','1','4','5'};
584 static const BYTE bin38
[] = {
585 0x18,0x08, '2','1','4','5','0','6','0','6'};
587 static void test_decodeFiletime(DWORD dwEncoding
)
589 static const struct encodedFiletime otherTimes
[] = {
590 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin23
},
591 { { 1945, 6, 1, 6, 16, 10, 0, 999 }, bin24
},
592 { { 1945, 6, 1, 6, 17, 10, 0, 0 }, bin25
},
593 { { 1945, 6, 1, 6, 15, 10, 0, 0 }, bin26
},
594 { { 1945, 6, 1, 6, 14, 55, 0, 0 }, bin27
},
595 { { 2145, 6, 1, 6, 16, 0, 0, 0 }, bin28
},
596 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin29
},
597 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin30
},
598 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin31
},
599 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin32
},
600 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin33
},
601 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin34
},
603 /* An oddball case that succeeds in Windows, but doesn't seem correct
604 { { 2145, 6, 1, 2, 11, 31, 0, 0 }, "\x18" "\x13" "21450606161000-9999" },
606 static const unsigned char *bogusTimes
[] = {
607 /* oddly, this succeeds on Windows, with year 2765
608 "\x18" "\x0f" "21r50606161000Z",
616 FILETIME ft1
= { 0 }, ft2
= { 0 };
619 /* Check bogus length with non-NULL buffer */
620 ret
= SystemTimeToFileTime(×
[0].sysTime
, &ft1
);
621 ok(ret
, "SystemTimeToFileTime failed: %d\n", GetLastError());
623 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CHOICE_OF_TIME
,
624 times
[0].encodedTime
, times
[0].encodedTime
[1] + 2, 0, NULL
, &ft2
, &size
);
625 ok(!ret
&& GetLastError() == ERROR_MORE_DATA
,
626 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
628 for (i
= 0; i
< sizeof(times
) / sizeof(times
[0]); i
++)
630 testTimeDecoding(dwEncoding
, X509_CHOICE_OF_TIME
, ×
[i
]);
631 testTimeDecoding(dwEncoding
, PKCS_UTC_TIME
, ×
[i
]);
632 testTimeDecoding(dwEncoding
, szOID_RSA_signingTime
, ×
[i
]);
634 for (i
= 0; i
< sizeof(otherTimes
) / sizeof(otherTimes
[0]); i
++)
636 testTimeDecoding(dwEncoding
, X509_CHOICE_OF_TIME
, &otherTimes
[i
]);
637 testTimeDecoding(dwEncoding
, PKCS_UTC_TIME
, &otherTimes
[i
]);
638 testTimeDecoding(dwEncoding
, szOID_RSA_signingTime
, &otherTimes
[i
]);
640 for (i
= 0; i
< sizeof(bogusTimes
) / sizeof(bogusTimes
[0]); i
++)
643 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CHOICE_OF_TIME
,
644 bogusTimes
[i
], bogusTimes
[i
][1] + 2, 0, NULL
, &ft1
, &size
);
645 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_CORRUPT
,
646 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
650 static const char commonName
[] = "Juan Lang";
651 static const char surName
[] = "Lang";
653 static const BYTE emptySequence
[] = { 0x30, 0 };
654 static const BYTE emptyRDNs
[] = { 0x30, 0x02, 0x31, 0 };
655 static const BYTE twoRDNs
[] = {
656 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
657 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
658 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0};
659 static const BYTE encodedTwoRDNs
[] = {
660 0x30,0x2e,0x31,0x2c,0x30,0x2a,0x06,0x03,0x55,0x04,0x03,0x30,0x23,0x31,0x21,
661 0x30,0x0c,0x06,0x03,0x55,0x04,0x04,0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,
662 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
666 static const BYTE us
[] = { 0x55, 0x53 };
667 static const BYTE minnesota
[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x73, 0x6f,
669 static const BYTE minneapolis
[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x61, 0x70,
670 0x6f, 0x6c, 0x69, 0x73 };
671 static const BYTE codeweavers
[] = { 0x43, 0x6f, 0x64, 0x65, 0x57, 0x65, 0x61,
672 0x76, 0x65, 0x72, 0x73 };
673 static const BYTE wine
[] = { 0x57, 0x69, 0x6e, 0x65, 0x20, 0x44, 0x65, 0x76,
674 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74 };
675 static const BYTE localhostAttr
[] = { 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
677 static const BYTE aric
[] = { 0x61, 0x72, 0x69, 0x63, 0x40, 0x63, 0x6f, 0x64,
678 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d };
680 #define RDNA(arr) oid_ ## arr, CERT_RDN_PRINTABLE_STRING, { sizeof(arr), (LPBYTE)arr }
681 #define RDNIA5(arr) oid_ ## arr, CERT_RDN_IA5_STRING, { sizeof(arr), (LPBYTE)arr }
683 static CHAR oid_us
[] = "2.5.4.6",
684 oid_minnesota
[] = "2.5.4.8",
685 oid_minneapolis
[] = "2.5.4.7",
686 oid_codeweavers
[] = "2.5.4.10",
687 oid_wine
[] = "2.5.4.11",
688 oid_localhostAttr
[] = "2.5.4.3",
689 oid_aric
[] = "1.2.840.113549.1.9.1";
690 static CERT_RDN_ATTR rdnAttrs
[] = { { RDNA(us
) },
692 { RDNA(minneapolis
) },
693 { RDNA(codeweavers
) },
695 { RDNA(localhostAttr
) },
697 static CERT_RDN_ATTR decodedRdnAttrs
[] = { { RDNA(us
) },
698 { RDNA(localhostAttr
) },
700 { RDNA(minneapolis
) },
701 { RDNA(codeweavers
) },
708 static const BYTE encodedRDNAttrs
[] = {
709 0x30,0x81,0x96,0x31,0x81,0x93,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
710 0x53,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x68,
711 0x6f,0x73,0x74,0x30,0x10,0x06,0x03,0x55,0x04,0x08,0x13,0x09,0x4d,0x69,0x6e,0x6e,
712 0x65,0x73,0x6f,0x74,0x61,0x30,0x12,0x06,0x03,0x55,0x04,0x07,0x13,0x0b,0x4d,0x69,
713 0x6e,0x6e,0x65,0x61,0x70,0x6f,0x6c,0x69,0x73,0x30,0x12,0x06,0x03,0x55,0x04,0x0a,
714 0x13,0x0b,0x43,0x6f,0x64,0x65,0x57,0x65,0x61,0x76,0x65,0x72,0x73,0x30,0x17,0x06,
715 0x03,0x55,0x04,0x0b,0x13,0x10,0x57,0x69,0x6e,0x65,0x20,0x44,0x65,0x76,0x65,0x6c,
716 0x6f,0x70,0x6d,0x65,0x6e,0x74,0x30,0x21,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
717 0x01,0x09,0x01,0x16,0x14,0x61,0x72,0x69,0x63,0x40,0x63,0x6f,0x64,0x65,0x77,0x65,
718 0x61,0x76,0x65,0x72,0x73,0x2e,0x63,0x6f,0x6d
721 static void test_encodeName(DWORD dwEncoding
)
723 CERT_RDN_ATTR attrs
[2];
726 static CHAR oid_common_name
[] = szOID_COMMON_NAME
,
727 oid_sur_name
[] = szOID_SUR_NAME
;
732 /* Test with NULL pvStructInfo */
733 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, NULL
,
734 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
735 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
736 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
737 /* Test with empty CERT_NAME_INFO */
740 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
741 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
742 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
745 ok(!memcmp(buf
, emptySequence
, sizeof(emptySequence
)),
746 "Got unexpected encoding for empty name\n");
749 /* Test with bogus CERT_RDN */
751 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
752 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
753 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
754 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
755 /* Test with empty CERT_RDN */
757 rdn
.rgRDNAttr
= NULL
;
760 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
761 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
762 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
765 ok(!memcmp(buf
, emptyRDNs
, sizeof(emptyRDNs
)),
766 "Got unexpected encoding for empty RDN array\n");
769 /* Test with bogus attr array */
771 rdn
.rgRDNAttr
= NULL
;
772 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
773 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
774 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
775 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
776 /* oddly, a bogus OID is accepted by Windows XP; not testing.
777 attrs[0].pszObjId = "bogus";
778 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
779 attrs[0].Value.cbData = sizeof(commonName);
780 attrs[0].Value.pbData = (BYTE *)commonName;
782 rdn.rgRDNAttr = attrs;
783 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
784 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
785 ok(!ret, "Expected failure, got success\n");
787 /* Check with two CERT_RDN_ATTRs. Note DER encoding forces the order of
788 * the encoded attributes to be swapped.
790 attrs
[0].pszObjId
= oid_common_name
;
791 attrs
[0].dwValueType
= CERT_RDN_PRINTABLE_STRING
;
792 attrs
[0].Value
.cbData
= sizeof(commonName
);
793 attrs
[0].Value
.pbData
= (BYTE
*)commonName
;
794 attrs
[1].pszObjId
= oid_sur_name
;
795 attrs
[1].dwValueType
= CERT_RDN_PRINTABLE_STRING
;
796 attrs
[1].Value
.cbData
= sizeof(surName
);
797 attrs
[1].Value
.pbData
= (BYTE
*)surName
;
799 rdn
.rgRDNAttr
= attrs
;
800 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
801 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
802 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
805 ok(!memcmp(buf
, twoRDNs
, sizeof(twoRDNs
)),
806 "Got unexpected encoding for two RDN array\n");
809 /* A name can be "encoded" with previously encoded RDN attrs. */
810 attrs
[0].dwValueType
= CERT_RDN_ENCODED_BLOB
;
811 attrs
[0].Value
.pbData
= (LPBYTE
)twoRDNs
;
812 attrs
[0].Value
.cbData
= sizeof(twoRDNs
);
814 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
815 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
816 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
819 ok(size
== sizeof(encodedTwoRDNs
), "Unexpected size %d\n", size
);
820 ok(!memcmp(buf
, encodedTwoRDNs
, size
),
821 "Unexpected value for re-endoded two RDN array\n");
824 /* CERT_RDN_ANY_TYPE is too vague for X509_NAMEs, check the return */
826 attrs
[0].dwValueType
= CERT_RDN_ANY_TYPE
;
827 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
828 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
829 ok(!ret
&& GetLastError() == E_INVALIDARG
,
830 "Expected E_INVALIDARG, got %08x\n", GetLastError());
831 /* Test a more complex name */
832 rdn
.cRDNAttr
= sizeof(rdnAttrs
) / sizeof(rdnAttrs
[0]);
833 rdn
.rgRDNAttr
= (PCERT_RDN_ATTR
)rdnAttrs
;
838 ret
= pCryptEncodeObjectEx(X509_ASN_ENCODING
, X509_NAME
, &info
,
839 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
840 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
843 ok(size
== sizeof(encodedRDNAttrs
), "Wrong size %d\n", size
);
844 ok(!memcmp(buf
, encodedRDNAttrs
, size
), "Unexpected value\n");
849 static WCHAR commonNameW
[] = { 'J','u','a','n',' ','L','a','n','g',0 };
850 static WCHAR surNameW
[] = { 'L','a','n','g',0 };
852 static const BYTE twoRDNsNoNull
[] = {
853 0x30,0x21,0x31,0x1f,0x30,0x0b,0x06,0x03,0x55,0x04,0x04,0x13,0x04,0x4c,0x61,
854 0x6e,0x67,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,
855 0x20,0x4c,0x61,0x6e,0x67 };
856 static const BYTE anyType
[] = {
857 0x30,0x2f,0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x1e,0x24,0x23,0x30,
858 0x21,0x31,0x0c,0x30,0x03,0x06,0x04,0x55,0x13,0x04,0x4c,0x05,0x6e,0x61,0x00,
859 0x67,0x11,0x30,0x03,0x06,0x04,0x55,0x13,0x03,0x4a,0x0a,0x61,0x75,0x20,0x6e,
860 0x61,0x4c,0x67,0x6e };
862 static void test_encodeUnicodeName(DWORD dwEncoding
)
864 CERT_RDN_ATTR attrs
[2];
867 static CHAR oid_common_name
[] = szOID_COMMON_NAME
,
868 oid_sur_name
[] = szOID_SUR_NAME
;
873 /* Test with NULL pvStructInfo */
874 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, NULL
,
875 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
876 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
877 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
878 /* Test with empty CERT_NAME_INFO */
881 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, &info
,
882 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
883 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
886 ok(!memcmp(buf
, emptySequence
, sizeof(emptySequence
)),
887 "Got unexpected encoding for empty name\n");
890 /* Check with one CERT_RDN_ATTR, that has an invalid character for the
891 * encoding (the NULL).
893 attrs
[0].pszObjId
= oid_common_name
;
894 attrs
[0].dwValueType
= CERT_RDN_PRINTABLE_STRING
;
895 attrs
[0].Value
.cbData
= sizeof(commonNameW
);
896 attrs
[0].Value
.pbData
= (BYTE
*)commonNameW
;
898 rdn
.rgRDNAttr
= attrs
;
901 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, &info
,
902 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
903 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING
,
904 "Expected CRYPT_E_INVALID_PRINTABLE_STRING, got %08x\n", GetLastError());
905 ok(size
== 9, "Unexpected error index %08x\n", size
);
906 /* Check with two NULL-terminated CERT_RDN_ATTRs. Note DER encoding
907 * forces the order of the encoded attributes to be swapped.
909 attrs
[0].pszObjId
= oid_common_name
;
910 attrs
[0].dwValueType
= CERT_RDN_PRINTABLE_STRING
;
911 attrs
[0].Value
.cbData
= 0;
912 attrs
[0].Value
.pbData
= (BYTE
*)commonNameW
;
913 attrs
[1].pszObjId
= oid_sur_name
;
914 attrs
[1].dwValueType
= CERT_RDN_PRINTABLE_STRING
;
915 attrs
[1].Value
.cbData
= 0;
916 attrs
[1].Value
.pbData
= (BYTE
*)surNameW
;
918 rdn
.rgRDNAttr
= attrs
;
921 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, &info
,
922 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
923 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
926 ok(!memcmp(buf
, twoRDNsNoNull
, sizeof(twoRDNsNoNull
)),
927 "Got unexpected encoding for two RDN array\n");
930 /* A name can be "encoded" with previously encoded RDN attrs. */
931 attrs
[0].dwValueType
= CERT_RDN_ENCODED_BLOB
;
932 attrs
[0].Value
.pbData
= (LPBYTE
)twoRDNs
;
933 attrs
[0].Value
.cbData
= sizeof(twoRDNs
);
935 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, &info
,
936 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
937 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
940 ok(size
== sizeof(encodedTwoRDNs
), "Unexpected size %d\n", size
);
941 ok(!memcmp(buf
, encodedTwoRDNs
, size
),
942 "Unexpected value for re-endoded two RDN array\n");
945 /* Unicode names infer the type for CERT_RDN_ANY_TYPE */
947 attrs
[0].dwValueType
= CERT_RDN_ANY_TYPE
;
948 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, &info
,
949 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
950 todo_wine
ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
953 ok(size
== sizeof(anyType
), "Unexpected size %d\n", size
);
954 ok(!memcmp(buf
, anyType
, size
), "Unexpected value\n");
959 static void compareNameValues(const CERT_NAME_VALUE
*expected
,
960 const CERT_NAME_VALUE
*got
)
962 ok(got
->dwValueType
== expected
->dwValueType
,
963 "Expected string type %d, got %d\n", expected
->dwValueType
,
965 ok(got
->Value
.cbData
== expected
->Value
.cbData
,
966 "String type %d: unexpected data size, got %d, expected %d\n",
967 expected
->dwValueType
, got
->Value
.cbData
, expected
->Value
.cbData
);
968 if (got
->Value
.cbData
&& got
->Value
.pbData
)
969 ok(!memcmp(got
->Value
.pbData
, expected
->Value
.pbData
,
970 min(got
->Value
.cbData
, expected
->Value
.cbData
)),
971 "String type %d: unexpected value\n", expected
->dwValueType
);
974 static void compareRDNAttrs(const CERT_RDN_ATTR
*expected
,
975 const CERT_RDN_ATTR
*got
)
977 if (expected
->pszObjId
&& strlen(expected
->pszObjId
))
979 ok(got
->pszObjId
!= NULL
, "Expected OID %s, got NULL\n",
983 ok(!strcmp(got
->pszObjId
, expected
->pszObjId
),
984 "Got unexpected OID %s, expected %s\n", got
->pszObjId
,
988 compareNameValues((const CERT_NAME_VALUE
*)&expected
->dwValueType
,
989 (const CERT_NAME_VALUE
*)&got
->dwValueType
);
992 static void compareRDNs(const CERT_RDN
*expected
, const CERT_RDN
*got
)
994 ok(got
->cRDNAttr
== expected
->cRDNAttr
,
995 "Expected %d RDN attrs, got %d\n", expected
->cRDNAttr
, got
->cRDNAttr
);
1000 for (i
= 0; i
< got
->cRDNAttr
; i
++)
1001 compareRDNAttrs(&expected
->rgRDNAttr
[i
], &got
->rgRDNAttr
[i
]);
1005 static void compareNames(const CERT_NAME_INFO
*expected
,
1006 const CERT_NAME_INFO
*got
)
1008 ok(got
->cRDN
== expected
->cRDN
, "Expected %d RDNs, got %d\n",
1009 expected
->cRDN
, got
->cRDN
);
1014 for (i
= 0; i
< got
->cRDN
; i
++)
1015 compareRDNs(&expected
->rgRDN
[i
], &got
->rgRDN
[i
]);
1019 static const BYTE emptyIndefiniteSequence
[] = { 0x30,0x80,0x00,0x00 };
1020 static const BYTE twoRDNsExtraBytes
[] = {
1021 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
1022 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1023 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0,0,0,0,0,0};
1025 static void test_decodeName(DWORD dwEncoding
)
1031 CERT_NAME_INFO info
= { 1, &rdn
};
1033 /* test empty name */
1035 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME
, emptySequence
,
1036 emptySequence
[1] + 2,
1037 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1038 (BYTE
*)&buf
, &bufSize
);
1039 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1040 /* Interestingly, in Windows, if cRDN is 0, rgRGN may not be NULL. My
1041 * decoder works the same way, so only test the count.
1045 ok(bufSize
== sizeof(CERT_NAME_INFO
), "Wrong bufSize %d\n", bufSize
);
1046 ok(((CERT_NAME_INFO
*)buf
)->cRDN
== 0,
1047 "Expected 0 RDNs in empty info, got %d\n",
1048 ((CERT_NAME_INFO
*)buf
)->cRDN
);
1051 /* test empty name with indefinite-length encoding */
1052 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME
, emptyIndefiniteSequence
,
1053 sizeof(emptyIndefiniteSequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1054 (BYTE
*)&buf
, &bufSize
);
1055 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1058 ok(bufSize
== sizeof(CERT_NAME_INFO
), "Wrong bufSize %d\n", bufSize
);
1059 ok(((CERT_NAME_INFO
*)buf
)->cRDN
== 0,
1060 "Expected 0 RDNs in empty info, got %d\n",
1061 ((CERT_NAME_INFO
*)buf
)->cRDN
);
1064 /* test empty RDN */
1066 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME
, emptyRDNs
,
1068 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1069 (BYTE
*)&buf
, &bufSize
);
1070 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1073 CERT_NAME_INFO
*info
= (CERT_NAME_INFO
*)buf
;
1075 ok(bufSize
== sizeof(CERT_NAME_INFO
) + sizeof(CERT_RDN
) &&
1076 info
->cRDN
== 1 && info
->rgRDN
&& info
->rgRDN
[0].cRDNAttr
== 0,
1077 "Got unexpected value for empty RDN\n");
1080 /* test two RDN attrs */
1082 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME
, twoRDNs
,
1084 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1085 (BYTE
*)&buf
, &bufSize
);
1086 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1089 static CHAR oid_sur_name
[] = szOID_SUR_NAME
,
1090 oid_common_name
[] = szOID_COMMON_NAME
;
1092 CERT_RDN_ATTR attrs
[] = {
1093 { oid_sur_name
, CERT_RDN_PRINTABLE_STRING
, { sizeof(surName
),
1094 (BYTE
*)surName
} },
1095 { oid_common_name
, CERT_RDN_PRINTABLE_STRING
, { sizeof(commonName
),
1096 (BYTE
*)commonName
} },
1099 rdn
.cRDNAttr
= sizeof(attrs
) / sizeof(attrs
[0]);
1100 rdn
.rgRDNAttr
= attrs
;
1101 compareNames(&info
, (CERT_NAME_INFO
*)buf
);
1104 /* test that two RDN attrs with extra bytes succeeds */
1106 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME
, twoRDNsExtraBytes
,
1107 sizeof(twoRDNsExtraBytes
), 0, NULL
, NULL
, &bufSize
);
1108 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1109 /* And, a slightly more complicated name */
1112 ret
= pCryptDecodeObjectEx(X509_ASN_ENCODING
, X509_NAME
, encodedRDNAttrs
,
1113 sizeof(encodedRDNAttrs
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1114 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1117 rdn
.cRDNAttr
= sizeof(decodedRdnAttrs
) / sizeof(decodedRdnAttrs
[0]);
1118 rdn
.rgRDNAttr
= (PCERT_RDN_ATTR
)decodedRdnAttrs
;
1119 compareNames(&info
, (CERT_NAME_INFO
*)buf
);
1124 static void test_decodeUnicodeName(DWORD dwEncoding
)
1130 CERT_NAME_INFO info
= { 1, &rdn
};
1132 /* test empty name */
1134 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, emptySequence
,
1135 emptySequence
[1] + 2,
1136 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1137 (BYTE
*)&buf
, &bufSize
);
1138 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1141 ok(bufSize
== sizeof(CERT_NAME_INFO
),
1142 "Got wrong bufSize %d\n", bufSize
);
1143 ok(((CERT_NAME_INFO
*)buf
)->cRDN
== 0,
1144 "Expected 0 RDNs in empty info, got %d\n",
1145 ((CERT_NAME_INFO
*)buf
)->cRDN
);
1148 /* test empty RDN */
1150 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, emptyRDNs
,
1152 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1153 (BYTE
*)&buf
, &bufSize
);
1154 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1157 CERT_NAME_INFO
*info
= (CERT_NAME_INFO
*)buf
;
1159 ok(bufSize
== sizeof(CERT_NAME_INFO
) + sizeof(CERT_RDN
) &&
1160 info
->cRDN
== 1 && info
->rgRDN
&& info
->rgRDN
[0].cRDNAttr
== 0,
1161 "Got unexpected value for empty RDN\n");
1164 /* test two RDN attrs */
1166 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, twoRDNsNoNull
,
1167 sizeof(twoRDNsNoNull
),
1168 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1169 (BYTE
*)&buf
, &bufSize
);
1170 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1173 static CHAR oid_sur_name
[] = szOID_SUR_NAME
,
1174 oid_common_name
[] = szOID_COMMON_NAME
;
1176 CERT_RDN_ATTR attrs
[] = {
1177 { oid_sur_name
, CERT_RDN_PRINTABLE_STRING
,
1178 { lstrlenW(surNameW
) * sizeof(WCHAR
), (BYTE
*)surNameW
} },
1179 { oid_common_name
, CERT_RDN_PRINTABLE_STRING
,
1180 { lstrlenW(commonNameW
) * sizeof(WCHAR
), (BYTE
*)commonNameW
} },
1183 rdn
.cRDNAttr
= sizeof(attrs
) / sizeof(attrs
[0]);
1184 rdn
.rgRDNAttr
= attrs
;
1185 compareNames(&info
, (CERT_NAME_INFO
*)buf
);
1190 struct EncodedNameValue
1192 CERT_NAME_VALUE value
;
1193 const BYTE
*encoded
;
1197 static const char bogusIA5
[] = "\x80";
1198 static const char bogusPrintable
[] = "~";
1199 static const char bogusNumeric
[] = "A";
1200 static const BYTE bin42
[] = { 0x16,0x02,0x80,0x00 };
1201 static const BYTE bin43
[] = { 0x13,0x02,0x7e,0x00 };
1202 static const BYTE bin44
[] = { 0x12,0x02,0x41,0x00 };
1203 static BYTE octetCommonNameValue
[] = {
1204 0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1205 static BYTE numericCommonNameValue
[] = {
1206 0x12,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1207 static BYTE printableCommonNameValue
[] = {
1208 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1209 static BYTE t61CommonNameValue
[] = {
1210 0x14,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1211 static BYTE videotexCommonNameValue
[] = {
1212 0x15,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1213 static BYTE ia5CommonNameValue
[] = {
1214 0x16,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1215 static BYTE graphicCommonNameValue
[] = {
1216 0x19,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1217 static BYTE visibleCommonNameValue
[] = {
1218 0x1a,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1219 static BYTE generalCommonNameValue
[] = {
1220 0x1b,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1221 static BYTE bmpCommonNameValue
[] = {
1222 0x1e,0x14,0x00,0x4a,0x00,0x75,0x00,0x61,0x00,0x6e,0x00,0x20,0x00,0x4c,0x00,
1223 0x61,0x00,0x6e,0x00,0x67,0x00,0x00 };
1224 static BYTE utf8CommonNameValue
[] = {
1225 0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1227 static struct EncodedNameValue nameValues
[] = {
1228 { { CERT_RDN_OCTET_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1229 octetCommonNameValue
, sizeof(octetCommonNameValue
) },
1230 { { CERT_RDN_NUMERIC_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1231 numericCommonNameValue
, sizeof(numericCommonNameValue
) },
1232 { { CERT_RDN_PRINTABLE_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1233 printableCommonNameValue
, sizeof(printableCommonNameValue
) },
1234 { { CERT_RDN_T61_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1235 t61CommonNameValue
, sizeof(t61CommonNameValue
) },
1236 { { CERT_RDN_VIDEOTEX_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1237 videotexCommonNameValue
, sizeof(videotexCommonNameValue
) },
1238 { { CERT_RDN_IA5_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1239 ia5CommonNameValue
, sizeof(ia5CommonNameValue
) },
1240 { { CERT_RDN_GRAPHIC_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1241 graphicCommonNameValue
, sizeof(graphicCommonNameValue
) },
1242 { { CERT_RDN_VISIBLE_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1243 visibleCommonNameValue
, sizeof(visibleCommonNameValue
) },
1244 { { CERT_RDN_GENERAL_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1245 generalCommonNameValue
, sizeof(generalCommonNameValue
) },
1246 { { CERT_RDN_BMP_STRING
, { sizeof(commonNameW
), (BYTE
*)commonNameW
} },
1247 bmpCommonNameValue
, sizeof(bmpCommonNameValue
) },
1248 { { CERT_RDN_UTF8_STRING
, { sizeof(commonNameW
), (BYTE
*)commonNameW
} },
1249 utf8CommonNameValue
, sizeof(utf8CommonNameValue
) },
1250 /* The following tests succeed under Windows, but really should fail,
1251 * they contain characters that are illegal for the encoding. I'm
1252 * including them to justify my lazy encoding.
1254 { { CERT_RDN_IA5_STRING
, { sizeof(bogusIA5
), (BYTE
*)bogusIA5
} }, bin42
,
1256 { { CERT_RDN_PRINTABLE_STRING
, { sizeof(bogusPrintable
),
1257 (BYTE
*)bogusPrintable
} }, bin43
, sizeof(bin43
) },
1258 { { CERT_RDN_NUMERIC_STRING
, { sizeof(bogusNumeric
), (BYTE
*)bogusNumeric
} },
1259 bin44
, sizeof(bin44
) },
1262 static void test_encodeNameValue(DWORD dwEncoding
)
1267 CERT_NAME_VALUE value
= { 0, { 0, NULL
} };
1269 value
.dwValueType
= CERT_RDN_ENCODED_BLOB
;
1270 value
.Value
.pbData
= printableCommonNameValue
;
1271 value
.Value
.cbData
= sizeof(printableCommonNameValue
);
1272 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_VALUE
, &value
,
1273 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1274 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1277 ok(size
== sizeof(printableCommonNameValue
), "Unexpected size %d\n",
1279 ok(!memcmp(buf
, printableCommonNameValue
, size
),
1280 "Unexpected encoding\n");
1283 for (i
= 0; i
< sizeof(nameValues
) / sizeof(nameValues
[0]); i
++)
1285 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_VALUE
,
1286 &nameValues
[i
].value
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
1288 ok(ret
, "Type %d: CryptEncodeObjectEx failed: %08x\n",
1289 nameValues
[i
].value
.dwValueType
, GetLastError());
1292 ok(size
== nameValues
[i
].encodedSize
,
1293 "Expected size %d, got %d\n", nameValues
[i
].encodedSize
, size
);
1294 ok(!memcmp(buf
, nameValues
[i
].encoded
, size
),
1295 "Got unexpected encoding\n");
1301 static void test_decodeNameValue(DWORD dwEncoding
)
1308 for (i
= 0; i
< sizeof(nameValues
) / sizeof(nameValues
[0]); i
++)
1310 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME_VALUE
,
1311 nameValues
[i
].encoded
, nameValues
[i
].encoded
[1] + 2,
1312 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1313 (BYTE
*)&buf
, &bufSize
);
1314 ok(ret
, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
1315 nameValues
[i
].value
.dwValueType
, GetLastError());
1318 compareNameValues(&nameValues
[i
].value
,
1319 (const CERT_NAME_VALUE
*)buf
);
1325 static const BYTE emptyURL
[] = { 0x30, 0x02, 0x86, 0x00 };
1326 static const BYTE emptyURLExtraBytes
[] = { 0x30, 0x02, 0x86, 0x00, 0, 0, 0 };
1327 static const WCHAR url
[] = { 'h','t','t','p',':','/','/','w','i','n','e',
1328 'h','q','.','o','r','g',0 };
1329 static const BYTE encodedURL
[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74,
1330 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e,
1332 static const WCHAR nihongoURL
[] = { 'h','t','t','p',':','/','/',0x226f,
1334 static const WCHAR dnsName
[] = { 'w','i','n','e','h','q','.','o','r','g',0 };
1335 static const BYTE encodedDnsName
[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69,
1336 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
1337 static const BYTE localhost
[] = { 127, 0, 0, 1 };
1338 static const BYTE encodedIPAddr
[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00,
1340 static const unsigned char encodedCommonName
[] = {
1341 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0};
1342 static const BYTE encodedOidName
[] = { 0x30,0x04,0x88,0x02,0x2a,0x03 };
1343 static const BYTE encodedDirectoryName
[] = {
1344 0x30,0x19,0xa4,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1345 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1347 static void test_encodeAltName(DWORD dwEncoding
)
1349 CERT_ALT_NAME_INFO info
= { 0 };
1350 CERT_ALT_NAME_ENTRY entry
= { 0 };
1354 char oid
[] = "1.2.3";
1356 /* Test with empty info */
1357 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1358 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1361 ok(size
== sizeof(emptySequence
), "Wrong size %d\n", size
);
1362 ok(!memcmp(buf
, emptySequence
, size
), "Unexpected value\n");
1365 /* Test with an empty entry */
1367 info
.rgAltEntry
= &entry
;
1368 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1369 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1370 ok(!ret
&& GetLastError() == E_INVALIDARG
,
1371 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1372 /* Test with an empty pointer */
1373 entry
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
1374 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1375 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1378 ok(size
== sizeof(emptyURL
), "Wrong size %d\n", size
);
1379 ok(!memcmp(buf
, emptyURL
, size
), "Unexpected value\n");
1382 /* Test with a real URL */
1383 U(entry
).pwszURL
= (LPWSTR
)url
;
1384 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1385 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1388 ok(size
== sizeof(encodedURL
), "Wrong size %d\n", size
);
1389 ok(!memcmp(buf
, encodedURL
, size
), "Unexpected value\n");
1392 /* Now with the URL containing an invalid IA5 char */
1393 U(entry
).pwszURL
= (LPWSTR
)nihongoURL
;
1394 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1395 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1396 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_IA5_STRING
,
1397 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
1398 /* The first invalid character is at index 7 */
1399 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size
) == 7,
1400 "Expected invalid char at index 7, got %d\n",
1401 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size
));
1402 /* Now with the URL missing a scheme */
1403 U(entry
).pwszURL
= (LPWSTR
)dnsName
;
1404 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1405 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1406 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1409 /* This succeeds, but it shouldn't, so don't worry about conforming */
1412 /* Now with a DNS name */
1413 entry
.dwAltNameChoice
= CERT_ALT_NAME_DNS_NAME
;
1414 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1415 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1416 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1419 ok(size
== sizeof(encodedDnsName
), "Wrong size %d\n", size
);
1420 ok(!memcmp(buf
, encodedDnsName
, size
), "Unexpected value\n");
1423 /* Test with an IP address */
1424 entry
.dwAltNameChoice
= CERT_ALT_NAME_IP_ADDRESS
;
1425 U(entry
).IPAddress
.cbData
= sizeof(localhost
);
1426 U(entry
).IPAddress
.pbData
= (LPBYTE
)localhost
;
1427 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1428 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1431 ok(size
== sizeof(encodedIPAddr
), "Wrong size %d\n", size
);
1432 ok(!memcmp(buf
, encodedIPAddr
, size
), "Unexpected value\n");
1436 entry
.dwAltNameChoice
= CERT_ALT_NAME_REGISTERED_ID
;
1437 U(entry
).pszRegisteredID
= oid
;
1438 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1439 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1442 ok(size
== sizeof(encodedOidName
), "Wrong size %d\n", size
);
1443 ok(!memcmp(buf
, encodedOidName
, size
), "Unexpected value\n");
1446 /* Test with directory name */
1447 entry
.dwAltNameChoice
= CERT_ALT_NAME_DIRECTORY_NAME
;
1448 U(entry
).DirectoryName
.cbData
= sizeof(encodedCommonName
);
1449 U(entry
).DirectoryName
.pbData
= (LPBYTE
)encodedCommonName
;
1450 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1451 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1454 ok(size
== sizeof(encodedDirectoryName
), "Wrong size %d\n", size
);
1455 ok(!memcmp(buf
, encodedDirectoryName
, size
), "Unexpected value\n");
1460 static void test_decodeAltName(DWORD dwEncoding
)
1462 static const BYTE unimplementedType
[] = { 0x30, 0x06, 0x85, 0x04, 0x7f,
1464 static const BYTE bogusType
[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00,
1469 CERT_ALT_NAME_INFO
*info
;
1471 /* Test some bogus ones first */
1472 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1473 unimplementedType
, sizeof(unimplementedType
), CRYPT_DECODE_ALLOC_FLAG
,
1474 NULL
, (BYTE
*)&buf
, &bufSize
);
1475 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_BADTAG
,
1476 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
1477 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1478 bogusType
, sizeof(bogusType
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
1480 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_CORRUPT
,
1481 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
1482 /* Now expected cases */
1483 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, emptySequence
,
1484 emptySequence
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
1486 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1489 info
= (CERT_ALT_NAME_INFO
*)buf
;
1491 ok(info
->cAltEntry
== 0, "Expected 0 entries, got %d\n",
1495 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, emptyURL
,
1496 emptyURL
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
1498 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1501 info
= (CERT_ALT_NAME_INFO
*)buf
;
1503 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1505 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_URL
,
1506 "Expected CERT_ALT_NAME_URL, got %d\n",
1507 info
->rgAltEntry
[0].dwAltNameChoice
);
1508 ok(U(info
->rgAltEntry
[0]).pwszURL
== NULL
|| !*U(info
->rgAltEntry
[0]).pwszURL
,
1509 "Expected empty URL\n");
1512 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1513 emptyURLExtraBytes
, sizeof(emptyURLExtraBytes
), 0, NULL
, NULL
, &bufSize
);
1514 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1515 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, encodedURL
,
1516 encodedURL
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
1518 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1521 info
= (CERT_ALT_NAME_INFO
*)buf
;
1523 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1525 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_URL
,
1526 "Expected CERT_ALT_NAME_URL, got %d\n",
1527 info
->rgAltEntry
[0].dwAltNameChoice
);
1528 ok(!lstrcmpW(U(info
->rgAltEntry
[0]).pwszURL
, url
), "Unexpected URL\n");
1531 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, encodedDnsName
,
1532 encodedDnsName
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
1534 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1537 info
= (CERT_ALT_NAME_INFO
*)buf
;
1539 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1541 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_DNS_NAME
,
1542 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1543 info
->rgAltEntry
[0].dwAltNameChoice
);
1544 ok(!lstrcmpW(U(info
->rgAltEntry
[0]).pwszDNSName
, dnsName
),
1545 "Unexpected DNS name\n");
1548 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, encodedIPAddr
,
1549 encodedIPAddr
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
1551 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1554 info
= (CERT_ALT_NAME_INFO
*)buf
;
1556 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1558 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_IP_ADDRESS
,
1559 "Expected CERT_ALT_NAME_IP_ADDRESS, got %d\n",
1560 info
->rgAltEntry
[0].dwAltNameChoice
);
1561 ok(U(info
->rgAltEntry
[0]).IPAddress
.cbData
== sizeof(localhost
),
1562 "Unexpected IP address length %d\n",
1563 U(info
->rgAltEntry
[0]).IPAddress
.cbData
);
1564 ok(!memcmp(U(info
->rgAltEntry
[0]).IPAddress
.pbData
, localhost
,
1565 sizeof(localhost
)), "Unexpected IP address value\n");
1568 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, encodedOidName
,
1569 sizeof(encodedOidName
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
1571 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1574 info
= (CERT_ALT_NAME_INFO
*)buf
;
1576 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1578 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_REGISTERED_ID
,
1579 "Expected CERT_ALT_NAME_REGISTERED_ID, got %d\n",
1580 info
->rgAltEntry
[0].dwAltNameChoice
);
1581 ok(!strcmp(U(info
->rgAltEntry
[0]).pszRegisteredID
, "1.2.3"),
1582 "Expected OID 1.2.3, got %s\n", U(info
->rgAltEntry
[0]).pszRegisteredID
);
1585 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1586 encodedDirectoryName
, sizeof(encodedDirectoryName
),
1587 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
1588 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1591 info
= (CERT_ALT_NAME_INFO
*)buf
;
1593 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1595 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_DIRECTORY_NAME
,
1596 "Expected CERT_ALT_NAME_DIRECTORY_NAME, got %d\n",
1597 info
->rgAltEntry
[0].dwAltNameChoice
);
1598 ok(U(info
->rgAltEntry
[0]).DirectoryName
.cbData
==
1599 sizeof(encodedCommonName
), "Unexpected directory name length %d\n",
1600 U(info
->rgAltEntry
[0]).DirectoryName
.cbData
);
1601 ok(!memcmp(U(info
->rgAltEntry
[0]).DirectoryName
.pbData
,
1602 encodedCommonName
, sizeof(encodedCommonName
)),
1603 "Unexpected directory name value\n");
1608 struct UnicodeExpectedError
1616 static const WCHAR oneW
[] = { '1',0 };
1617 static const WCHAR aW
[] = { 'a',0 };
1618 static const WCHAR quoteW
[] = { '"', 0 };
1620 static struct UnicodeExpectedError unicodeErrors
[] = {
1621 { CERT_RDN_ANY_TYPE
, oneW
, 0, CRYPT_E_NOT_CHAR_STRING
},
1622 { CERT_RDN_ENCODED_BLOB
, oneW
, 0, CRYPT_E_NOT_CHAR_STRING
},
1623 { CERT_RDN_OCTET_STRING
, oneW
, 0, CRYPT_E_NOT_CHAR_STRING
},
1624 { CERT_RDN_NUMERIC_STRING
, aW
, 0, CRYPT_E_INVALID_NUMERIC_STRING
},
1625 { CERT_RDN_PRINTABLE_STRING
, quoteW
, 0, CRYPT_E_INVALID_PRINTABLE_STRING
},
1626 { CERT_RDN_IA5_STRING
, nihongoURL
, 7, CRYPT_E_INVALID_IA5_STRING
},
1629 struct UnicodeExpectedResult
1633 CRYPT_DATA_BLOB encoded
;
1636 static BYTE oneNumeric
[] = { 0x12, 0x01, 0x31 };
1637 static BYTE onePrintable
[] = { 0x13, 0x01, 0x31 };
1638 static BYTE oneTeletex
[] = { 0x14, 0x01, 0x31 };
1639 static BYTE oneVideotex
[] = { 0x15, 0x01, 0x31 };
1640 static BYTE oneIA5
[] = { 0x16, 0x01, 0x31 };
1641 static BYTE oneGraphic
[] = { 0x19, 0x01, 0x31 };
1642 static BYTE oneVisible
[] = { 0x1a, 0x01, 0x31 };
1643 static BYTE oneUniversal
[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 };
1644 static BYTE oneGeneral
[] = { 0x1b, 0x01, 0x31 };
1645 static BYTE oneBMP
[] = { 0x1e, 0x02, 0x00, 0x31 };
1646 static BYTE oneUTF8
[] = { 0x0c, 0x01, 0x31 };
1647 static BYTE nihongoT61
[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,
1649 static BYTE nihongoGeneral
[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1651 static BYTE nihongoBMP
[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,
1652 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
1653 static BYTE nihongoUTF8
[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1654 0xe2,0x89,0xaf,0xe5,0x9d,0x9b };
1656 static struct UnicodeExpectedResult unicodeResults
[] = {
1657 { CERT_RDN_NUMERIC_STRING
, oneW
, { sizeof(oneNumeric
), oneNumeric
} },
1658 { CERT_RDN_PRINTABLE_STRING
, oneW
, { sizeof(onePrintable
), onePrintable
} },
1659 { CERT_RDN_TELETEX_STRING
, oneW
, { sizeof(oneTeletex
), oneTeletex
} },
1660 { CERT_RDN_VIDEOTEX_STRING
, oneW
, { sizeof(oneVideotex
), oneVideotex
} },
1661 { CERT_RDN_IA5_STRING
, oneW
, { sizeof(oneIA5
), oneIA5
} },
1662 { CERT_RDN_GRAPHIC_STRING
, oneW
, { sizeof(oneGraphic
), oneGraphic
} },
1663 { CERT_RDN_VISIBLE_STRING
, oneW
, { sizeof(oneVisible
), oneVisible
} },
1664 { CERT_RDN_UNIVERSAL_STRING
, oneW
, { sizeof(oneUniversal
), oneUniversal
} },
1665 { CERT_RDN_GENERAL_STRING
, oneW
, { sizeof(oneGeneral
), oneGeneral
} },
1666 { CERT_RDN_BMP_STRING
, oneW
, { sizeof(oneBMP
), oneBMP
} },
1667 { CERT_RDN_UTF8_STRING
, oneW
, { sizeof(oneUTF8
), oneUTF8
} },
1668 { CERT_RDN_BMP_STRING
, nihongoURL
, { sizeof(nihongoBMP
), nihongoBMP
} },
1669 { CERT_RDN_UTF8_STRING
, nihongoURL
, { sizeof(nihongoUTF8
), nihongoUTF8
} },
1672 static struct UnicodeExpectedResult unicodeWeirdness
[] = {
1673 { CERT_RDN_TELETEX_STRING
, nihongoURL
, { sizeof(nihongoT61
), nihongoT61
} },
1674 { CERT_RDN_GENERAL_STRING
, nihongoURL
, { sizeof(nihongoGeneral
), nihongoGeneral
} },
1677 static void test_encodeUnicodeNameValue(DWORD dwEncoding
)
1682 CERT_NAME_VALUE value
;
1684 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, NULL
,
1685 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1686 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
1687 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1688 /* Have to have a string of some sort */
1689 value
.dwValueType
= 0; /* aka CERT_RDN_ANY_TYPE */
1690 value
.Value
.pbData
= NULL
;
1691 value
.Value
.cbData
= 0;
1692 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1693 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1694 ok(!ret
&& GetLastError() == CRYPT_E_NOT_CHAR_STRING
,
1695 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1696 value
.dwValueType
= CERT_RDN_ENCODED_BLOB
;
1697 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1698 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1699 ok(!ret
&& GetLastError() == CRYPT_E_NOT_CHAR_STRING
,
1700 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1701 value
.dwValueType
= CERT_RDN_ANY_TYPE
;
1702 value
.Value
.pbData
= (LPBYTE
)oneW
;
1703 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1704 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1705 ok(!ret
&& GetLastError() == CRYPT_E_NOT_CHAR_STRING
,
1706 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1707 value
.Value
.cbData
= sizeof(oneW
);
1708 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1709 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1710 ok(!ret
&& GetLastError() == CRYPT_E_NOT_CHAR_STRING
,
1711 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1712 /* An encoded string with specified length isn't good enough either */
1713 value
.dwValueType
= CERT_RDN_ENCODED_BLOB
;
1714 value
.Value
.pbData
= oneUniversal
;
1715 value
.Value
.cbData
= sizeof(oneUniversal
);
1716 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1717 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1718 ok(!ret
&& GetLastError() == CRYPT_E_NOT_CHAR_STRING
,
1719 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1720 /* More failure checking */
1721 value
.Value
.cbData
= 0;
1722 for (i
= 0; i
< sizeof(unicodeErrors
) / sizeof(unicodeErrors
[0]); i
++)
1724 value
.Value
.pbData
= (LPBYTE
)unicodeErrors
[i
].str
;
1725 value
.dwValueType
= unicodeErrors
[i
].valueType
;
1726 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1727 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1728 ok(!ret
&& GetLastError() == unicodeErrors
[i
].error
,
1729 "Value type %d: expected %08x, got %08x\n", value
.dwValueType
,
1730 unicodeErrors
[i
].error
, GetLastError());
1731 ok(size
== unicodeErrors
[i
].errorIndex
,
1732 "Expected error index %d, got %d\n", unicodeErrors
[i
].errorIndex
,
1735 /* cbData can be zero if the string is NULL-terminated */
1736 value
.Value
.cbData
= 0;
1737 for (i
= 0; i
< sizeof(unicodeResults
) / sizeof(unicodeResults
[0]); i
++)
1739 value
.Value
.pbData
= (LPBYTE
)unicodeResults
[i
].str
;
1740 value
.dwValueType
= unicodeResults
[i
].valueType
;
1741 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1742 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1743 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1746 ok(size
== unicodeResults
[i
].encoded
.cbData
,
1747 "Value type %d: expected size %d, got %d\n",
1748 value
.dwValueType
, unicodeResults
[i
].encoded
.cbData
, size
);
1749 ok(!memcmp(unicodeResults
[i
].encoded
.pbData
, buf
, size
),
1750 "Value type %d: unexpected value\n", value
.dwValueType
);
1754 /* These "encode," but they do so by truncating each unicode character
1755 * rather than properly encoding it. Kept separate from the proper results,
1756 * because the encoded forms won't decode to their original strings.
1758 for (i
= 0; i
< sizeof(unicodeWeirdness
) / sizeof(unicodeWeirdness
[0]); i
++)
1760 value
.Value
.pbData
= (LPBYTE
)unicodeWeirdness
[i
].str
;
1761 value
.dwValueType
= unicodeWeirdness
[i
].valueType
;
1762 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1763 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1764 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1767 ok(size
== unicodeWeirdness
[i
].encoded
.cbData
,
1768 "Value type %d: expected size %d, got %d\n",
1769 value
.dwValueType
, unicodeWeirdness
[i
].encoded
.cbData
, size
);
1770 ok(!memcmp(unicodeWeirdness
[i
].encoded
.pbData
, buf
, size
),
1771 "Value type %d: unexpected value\n", value
.dwValueType
);
1777 static inline int strncmpW( const WCHAR
*str1
, const WCHAR
*str2
, int n
)
1779 if (n
<= 0) return 0;
1780 while ((--n
> 0) && *str1
&& (*str1
== *str2
)) { str1
++; str2
++; }
1781 return *str1
- *str2
;
1784 static void test_decodeUnicodeNameValue(DWORD dwEncoding
)
1788 for (i
= 0; i
< sizeof(unicodeResults
) / sizeof(unicodeResults
[0]); i
++)
1794 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
,
1795 unicodeResults
[i
].encoded
.pbData
, unicodeResults
[i
].encoded
.cbData
,
1796 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1797 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1800 PCERT_NAME_VALUE value
= (PCERT_NAME_VALUE
)buf
;
1802 ok(value
->dwValueType
== unicodeResults
[i
].valueType
,
1803 "Expected value type %d, got %d\n", unicodeResults
[i
].valueType
,
1804 value
->dwValueType
);
1805 ok(!strncmpW((LPWSTR
)value
->Value
.pbData
, unicodeResults
[i
].str
,
1806 value
->Value
.cbData
/ sizeof(WCHAR
)),
1807 "Unexpected decoded value for index %d (value type %d)\n", i
,
1808 unicodeResults
[i
].valueType
);
1814 struct encodedOctets
1817 const BYTE
*encoded
;
1820 static const unsigned char bin46
[] = { 'h','i',0 };
1821 static const unsigned char bin47
[] = { 0x04,0x02,'h','i',0 };
1822 static const unsigned char bin48
[] = {
1823 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1824 static const unsigned char bin49
[] = {
1825 0x04,0x0f,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1826 static const unsigned char bin50
[] = { 0 };
1827 static const unsigned char bin51
[] = { 0x04,0x00,0 };
1829 static const struct encodedOctets octets
[] = {
1835 static void test_encodeOctets(DWORD dwEncoding
)
1837 CRYPT_DATA_BLOB blob
;
1840 for (i
= 0; i
< sizeof(octets
) / sizeof(octets
[0]); i
++)
1846 blob
.cbData
= strlen((const char*)octets
[i
].val
);
1847 blob
.pbData
= (BYTE
*)octets
[i
].val
;
1848 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_OCTET_STRING
, &blob
,
1849 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
1850 ok(ret
, "CryptEncodeObjectEx failed: %d\n", GetLastError());
1854 "Got unexpected type %d for octet string (expected 4)\n", buf
[0]);
1855 ok(buf
[1] == octets
[i
].encoded
[1], "Got length %d, expected %d\n",
1856 buf
[1], octets
[i
].encoded
[1]);
1857 ok(!memcmp(buf
+ 1, octets
[i
].encoded
+ 1,
1858 octets
[i
].encoded
[1] + 1), "Got unexpected value\n");
1864 static void test_decodeOctets(DWORD dwEncoding
)
1868 for (i
= 0; i
< sizeof(octets
) / sizeof(octets
[0]); i
++)
1874 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_OCTET_STRING
,
1875 (BYTE
*)octets
[i
].encoded
, octets
[i
].encoded
[1] + 2,
1876 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
1877 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1878 ok(bufSize
>= sizeof(CRYPT_DATA_BLOB
) + octets
[i
].encoded
[1],
1879 "Expected size >= %d, got %d\n",
1880 (int)sizeof(CRYPT_DATA_BLOB
) + octets
[i
].encoded
[1], bufSize
);
1881 ok(buf
!= NULL
, "Expected allocated buffer\n");
1884 CRYPT_DATA_BLOB
*blob
= (CRYPT_DATA_BLOB
*)buf
;
1887 ok(!memcmp(blob
->pbData
, octets
[i
].val
, blob
->cbData
),
1888 "Unexpected value\n");
1894 static const BYTE bytesToEncode
[] = { 0xff, 0xff };
1899 const BYTE
*encoded
;
1901 const BYTE
*decoded
;
1904 static const unsigned char bin52
[] = { 0x03,0x03,0x00,0xff,0xff };
1905 static const unsigned char bin53
[] = { 0xff,0xff };
1906 static const unsigned char bin54
[] = { 0x03,0x03,0x01,0xff,0xfe };
1907 static const unsigned char bin55
[] = { 0xff,0xfe };
1908 static const unsigned char bin56
[] = { 0x03,0x02,0x01,0xfe };
1909 static const unsigned char bin57
[] = { 0xfe };
1910 static const unsigned char bin58
[] = { 0x03,0x01,0x00 };
1912 static const struct encodedBits bits
[] = {
1913 /* normal test cases */
1914 { 0, bin52
, 2, bin53
},
1915 { 1, bin54
, 2, bin55
},
1916 /* strange test case, showing cUnusedBits >= 8 is allowed */
1917 { 9, bin56
, 1, bin57
},
1918 /* even stranger test case, showing cUnusedBits > cbData * 8 is allowed */
1919 { 17, bin58
, 0, NULL
},
1922 static void test_encodeBits(DWORD dwEncoding
)
1926 for (i
= 0; i
< sizeof(bits
) / sizeof(bits
[0]); i
++)
1928 CRYPT_BIT_BLOB blob
;
1933 blob
.cbData
= sizeof(bytesToEncode
);
1934 blob
.pbData
= (BYTE
*)bytesToEncode
;
1935 blob
.cUnusedBits
= bits
[i
].cUnusedBits
;
1936 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_BITS
, &blob
,
1937 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
1938 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1941 ok(bufSize
== bits
[i
].encoded
[1] + 2,
1942 "Got unexpected size %d, expected %d\n", bufSize
,
1943 bits
[i
].encoded
[1] + 2);
1944 ok(!memcmp(buf
, bits
[i
].encoded
, bits
[i
].encoded
[1] + 2),
1945 "Unexpected value\n");
1951 static void test_decodeBits(DWORD dwEncoding
)
1953 static const BYTE ber
[] = "\x03\x02\x01\xff";
1954 static const BYTE berDecoded
= 0xfe;
1961 for (i
= 0; i
< sizeof(bits
) / sizeof(bits
[0]); i
++)
1963 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BITS
, bits
[i
].encoded
,
1964 bits
[i
].encoded
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
1966 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1969 CRYPT_BIT_BLOB
*blob
;
1971 ok(bufSize
>= sizeof(CRYPT_BIT_BLOB
) + bits
[i
].cbDecoded
,
1972 "Got unexpected size %d\n", bufSize
);
1973 blob
= (CRYPT_BIT_BLOB
*)buf
;
1974 ok(blob
->cbData
== bits
[i
].cbDecoded
,
1975 "Got unexpected length %d, expected %d\n", blob
->cbData
,
1977 if (blob
->cbData
&& bits
[i
].cbDecoded
)
1978 ok(!memcmp(blob
->pbData
, bits
[i
].decoded
, bits
[i
].cbDecoded
),
1979 "Unexpected value\n");
1983 /* special case: check that something that's valid in BER but not in DER
1984 * decodes successfully
1986 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BITS
, ber
, ber
[1] + 2,
1987 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
1988 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1991 CRYPT_BIT_BLOB
*blob
;
1993 ok(bufSize
>= sizeof(CRYPT_BIT_BLOB
) + sizeof(berDecoded
),
1994 "Got unexpected size %d\n", bufSize
);
1995 blob
= (CRYPT_BIT_BLOB
*)buf
;
1996 ok(blob
->cbData
== sizeof(berDecoded
),
1997 "Got unexpected length %d\n", blob
->cbData
);
1999 ok(*blob
->pbData
== berDecoded
, "Unexpected value\n");
2006 CERT_BASIC_CONSTRAINTS2_INFO info
;
2007 const BYTE
*encoded
;
2010 static const unsigned char bin59
[] = { 0x30,0x00 };
2011 static const unsigned char bin60
[] = { 0x30,0x03,0x01,0x01,0xff };
2012 static const unsigned char bin61
[] = { 0x30,0x03,0x02,0x01,0x00 };
2013 static const unsigned char bin62
[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2014 static const struct Constraints2 constraints2
[] = {
2015 /* empty constraints */
2016 { { FALSE
, FALSE
, 0}, bin59
},
2018 { { TRUE
, FALSE
, 0}, bin60
},
2019 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well,
2020 * but that's not the case
2022 { { FALSE
, TRUE
, 0}, bin61
},
2023 /* can be a CA and has path length constraints set */
2024 { { TRUE
, TRUE
, 1}, bin62
},
2027 static const BYTE emptyConstraint
[] = { 0x30, 0x03, 0x03, 0x01, 0x00 };
2028 static const BYTE encodedDomainName
[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11,
2029 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
2030 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
2031 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2032 static const BYTE constraintWithDomainName
[] = { 0x30, 0x32, 0x03, 0x01, 0x00,
2033 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
2034 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30,
2035 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
2036 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2038 static void test_encodeBasicConstraints(DWORD dwEncoding
)
2040 DWORD i
, bufSize
= 0;
2041 CERT_BASIC_CONSTRAINTS_INFO info
= { { 0 } };
2042 CERT_NAME_BLOB nameBlob
= { sizeof(encodedDomainName
),
2043 (LPBYTE
)encodedDomainName
};
2047 /* First test with the simpler info2 */
2048 for (i
= 0; i
< sizeof(constraints2
) / sizeof(constraints2
[0]); i
++)
2050 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS2
,
2051 &constraints2
[i
].info
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
2053 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2056 ok(bufSize
== constraints2
[i
].encoded
[1] + 2,
2057 "Expected %d bytes, got %d\n", constraints2
[i
].encoded
[1] + 2,
2059 ok(!memcmp(buf
, constraints2
[i
].encoded
,
2060 constraints2
[i
].encoded
[1] + 2), "Unexpected value\n");
2064 /* Now test with more complex basic constraints */
2065 info
.SubjectType
.cbData
= 0;
2066 info
.fPathLenConstraint
= FALSE
;
2067 info
.cSubtreesConstraint
= 0;
2068 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS
, &info
,
2069 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2070 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2073 ok(bufSize
== sizeof(emptyConstraint
), "Wrong size %d\n", bufSize
);
2074 ok(!memcmp(buf
, emptyConstraint
, sizeof(emptyConstraint
)),
2075 "Unexpected value\n");
2078 /* None of the certs I examined had any subtree constraint, but I test one
2079 * anyway just in case.
2081 info
.cSubtreesConstraint
= 1;
2082 info
.rgSubtreesConstraint
= &nameBlob
;
2083 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS
, &info
,
2084 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2085 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2088 ok(bufSize
== sizeof(constraintWithDomainName
), "Wrong size %d\n", bufSize
);
2089 ok(!memcmp(buf
, constraintWithDomainName
,
2090 sizeof(constraintWithDomainName
)), "Unexpected value\n");
2093 /* FIXME: test encoding with subject type. */
2096 static const unsigned char bin63
[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 };
2098 static void test_decodeBasicConstraints(DWORD dwEncoding
)
2100 static const BYTE inverted
[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01,
2102 static const struct Constraints2 badBool
= { { TRUE
, TRUE
, 1 }, bin63
};
2108 /* First test with simpler info2 */
2109 for (i
= 0; i
< sizeof(constraints2
) / sizeof(constraints2
[0]); i
++)
2111 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS2
,
2112 constraints2
[i
].encoded
, constraints2
[i
].encoded
[1] + 2,
2113 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2114 ok(ret
, "CryptDecodeObjectEx failed for item %d: %08x\n", i
,
2118 CERT_BASIC_CONSTRAINTS2_INFO
*info
=
2119 (CERT_BASIC_CONSTRAINTS2_INFO
*)buf
;
2121 ok(!memcmp(info
, &constraints2
[i
].info
, sizeof(*info
)),
2122 "Unexpected value for item %d\n", i
);
2126 /* Check with the order of encoded elements inverted */
2128 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS2
,
2129 inverted
, inverted
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
2131 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_CORRUPT
,
2132 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2133 ok(!buf
, "Expected buf to be set to NULL\n");
2134 /* Check with a non-DER bool */
2135 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS2
,
2136 badBool
.encoded
, badBool
.encoded
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
2137 (BYTE
*)&buf
, &bufSize
);
2138 ok(ret
, "pCryptDecodeObjectEx failed: %08x\n", GetLastError());
2141 CERT_BASIC_CONSTRAINTS2_INFO
*info
=
2142 (CERT_BASIC_CONSTRAINTS2_INFO
*)buf
;
2144 ok(!memcmp(info
, &badBool
.info
, sizeof(*info
)), "Unexpected value\n");
2147 /* Check with a non-basic constraints value */
2148 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS2
,
2149 (LPBYTE
)encodedCommonName
, encodedCommonName
[1] + 2,
2150 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2151 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_CORRUPT
,
2152 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2153 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */
2154 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS
,
2155 emptyConstraint
, sizeof(emptyConstraint
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
2156 (BYTE
*)&buf
, &bufSize
);
2157 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2160 CERT_BASIC_CONSTRAINTS_INFO
*info
= (CERT_BASIC_CONSTRAINTS_INFO
*)buf
;
2162 ok(info
->SubjectType
.cbData
== 0, "Expected no subject type\n");
2163 ok(!info
->fPathLenConstraint
, "Expected no path length constraint\n");
2164 ok(info
->cSubtreesConstraint
== 0, "Expected no subtree constraints\n");
2167 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS
,
2168 constraintWithDomainName
, sizeof(constraintWithDomainName
),
2169 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2170 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2173 CERT_BASIC_CONSTRAINTS_INFO
*info
= (CERT_BASIC_CONSTRAINTS_INFO
*)buf
;
2175 ok(info
->SubjectType
.cbData
== 0, "Expected no subject type\n");
2176 ok(!info
->fPathLenConstraint
, "Expected no path length constraint\n");
2177 ok(info
->cSubtreesConstraint
== 1, "Expected a subtree constraint\n");
2178 if (info
->cSubtreesConstraint
&& info
->rgSubtreesConstraint
)
2180 ok(info
->rgSubtreesConstraint
[0].cbData
==
2181 sizeof(encodedDomainName
), "Wrong size %d\n",
2182 info
->rgSubtreesConstraint
[0].cbData
);
2183 ok(!memcmp(info
->rgSubtreesConstraint
[0].pbData
, encodedDomainName
,
2184 sizeof(encodedDomainName
)), "Unexpected value\n");
2190 /* These are terrible public keys of course, I'm just testing encoding */
2191 static const BYTE modulus1
[] = { 0,0,0,1,1,1,1,1 };
2192 static const BYTE modulus2
[] = { 1,1,1,1,1,0,0,0 };
2193 static const BYTE modulus3
[] = { 0x80,1,1,1,1,0,0,0 };
2194 static const BYTE modulus4
[] = { 1,1,1,1,1,0,0,0x80 };
2195 static const BYTE mod1_encoded
[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 };
2196 static const BYTE mod2_encoded
[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2197 static const BYTE mod3_encoded
[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 };
2198 static const BYTE mod4_encoded
[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2200 struct EncodedRSAPubKey
2202 const BYTE
*modulus
;
2204 const BYTE
*encoded
;
2205 size_t decodedModulusLen
;
2208 struct EncodedRSAPubKey rsaPubKeys
[] = {
2209 { modulus1
, sizeof(modulus1
), mod1_encoded
, sizeof(modulus1
) },
2210 { modulus2
, sizeof(modulus2
), mod2_encoded
, 5 },
2211 { modulus3
, sizeof(modulus3
), mod3_encoded
, 5 },
2212 { modulus4
, sizeof(modulus4
), mod4_encoded
, 8 },
2215 static void test_encodeRsaPublicKey(DWORD dwEncoding
)
2217 BYTE toEncode
[sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) + sizeof(modulus1
)];
2218 BLOBHEADER
*hdr
= (BLOBHEADER
*)toEncode
;
2219 RSAPUBKEY
*rsaPubKey
= (RSAPUBKEY
*)(toEncode
+ sizeof(BLOBHEADER
));
2222 DWORD bufSize
= 0, i
;
2224 /* Try with a bogus blob type */
2226 hdr
->bVersion
= CUR_BLOB_VERSION
;
2228 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
2229 rsaPubKey
->magic
= 0x31415352;
2230 rsaPubKey
->bitlen
= sizeof(modulus1
) * 8;
2231 rsaPubKey
->pubexp
= 65537;
2232 memcpy(toEncode
+ sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
), modulus1
,
2235 ret
= pCryptEncodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2236 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
2238 ok(!ret
&& GetLastError() == E_INVALIDARG
,
2239 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2240 /* Now with a bogus reserved field */
2241 hdr
->bType
= PUBLICKEYBLOB
;
2243 ret
= pCryptEncodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2244 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
2248 ok(bufSize
== rsaPubKeys
[0].encoded
[1] + 2,
2249 "Expected size %d, got %d\n", rsaPubKeys
[0].encoded
[1] + 2, bufSize
);
2250 ok(!memcmp(buf
, rsaPubKeys
[0].encoded
, bufSize
), "Unexpected value\n");
2253 /* Now with a bogus blob version */
2256 ret
= pCryptEncodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2257 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
2261 ok(bufSize
== rsaPubKeys
[0].encoded
[1] + 2,
2262 "Expected size %d, got %d\n", rsaPubKeys
[0].encoded
[1] + 2, bufSize
);
2263 ok(!memcmp(buf
, rsaPubKeys
[0].encoded
, bufSize
), "Unexpected value\n");
2266 /* And with a bogus alg ID */
2267 hdr
->bVersion
= CUR_BLOB_VERSION
;
2268 hdr
->aiKeyAlg
= CALG_DES
;
2269 ret
= pCryptEncodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2270 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
2274 ok(bufSize
== rsaPubKeys
[0].encoded
[1] + 2,
2275 "Expected size %d, got %d\n", rsaPubKeys
[0].encoded
[1] + 2, bufSize
);
2276 ok(!memcmp(buf
, rsaPubKeys
[0].encoded
, bufSize
), "Unexpected value\n");
2279 /* Check a couple of RSA-related OIDs */
2280 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
2281 ret
= pCryptEncodeObjectEx(dwEncoding
, szOID_RSA_RSA
,
2282 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2283 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
2284 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2285 ret
= pCryptEncodeObjectEx(dwEncoding
, szOID_RSA_SHA1RSA
,
2286 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2287 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
2288 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2289 /* Finally, all valid */
2290 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
2291 for (i
= 0; i
< sizeof(rsaPubKeys
) / sizeof(rsaPubKeys
[0]); i
++)
2293 memcpy(toEncode
+ sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
),
2294 rsaPubKeys
[i
].modulus
, rsaPubKeys
[i
].modulusLen
);
2295 ret
= pCryptEncodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2296 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2297 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2300 ok(bufSize
== rsaPubKeys
[i
].encoded
[1] + 2,
2301 "Expected size %d, got %d\n", rsaPubKeys
[i
].encoded
[1] + 2,
2303 ok(!memcmp(buf
, rsaPubKeys
[i
].encoded
, bufSize
),
2304 "Unexpected value\n");
2310 static void test_decodeRsaPublicKey(DWORD dwEncoding
)
2317 /* Try with a bad length */
2318 ret
= pCryptDecodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2319 rsaPubKeys
[0].encoded
, rsaPubKeys
[0].encoded
[1],
2320 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2321 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_EOD
,
2322 "Expected CRYPT_E_ASN1_EOD, got %08x\n", CRYPT_E_ASN1_EOD
);
2323 /* Try with a couple of RSA-related OIDs */
2324 ret
= pCryptDecodeObjectEx(dwEncoding
, szOID_RSA_RSA
,
2325 rsaPubKeys
[0].encoded
, rsaPubKeys
[0].encoded
[1] + 2,
2326 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2327 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
2328 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2329 ret
= pCryptDecodeObjectEx(dwEncoding
, szOID_RSA_SHA1RSA
,
2330 rsaPubKeys
[0].encoded
, rsaPubKeys
[0].encoded
[1] + 2,
2331 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2332 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
2333 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2334 /* Now try success cases */
2335 for (i
= 0; i
< sizeof(rsaPubKeys
) / sizeof(rsaPubKeys
[0]); i
++)
2338 ret
= pCryptDecodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2339 rsaPubKeys
[i
].encoded
, rsaPubKeys
[i
].encoded
[1] + 2,
2340 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2341 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2344 BLOBHEADER
*hdr
= (BLOBHEADER
*)buf
;
2345 RSAPUBKEY
*rsaPubKey
= (RSAPUBKEY
*)(buf
+ sizeof(BLOBHEADER
));
2347 ok(bufSize
>= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
2348 rsaPubKeys
[i
].decodedModulusLen
,
2349 "Wrong size %d\n", bufSize
);
2350 ok(hdr
->bType
== PUBLICKEYBLOB
,
2351 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB
,
2353 ok(hdr
->bVersion
== CUR_BLOB_VERSION
,
2354 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
2355 CUR_BLOB_VERSION
, hdr
->bVersion
);
2356 ok(hdr
->reserved
== 0, "Expected reserved 0, got %d\n",
2358 ok(hdr
->aiKeyAlg
== CALG_RSA_KEYX
,
2359 "Expected CALG_RSA_KEYX, got %08x\n", hdr
->aiKeyAlg
);
2360 ok(rsaPubKey
->magic
== 0x31415352,
2361 "Expected magic RSA1, got %08x\n", rsaPubKey
->magic
);
2362 ok(rsaPubKey
->bitlen
== rsaPubKeys
[i
].decodedModulusLen
* 8,
2363 "Wrong bit len %d\n", rsaPubKey
->bitlen
);
2364 ok(rsaPubKey
->pubexp
== 65537, "Expected pubexp 65537, got %d\n",
2366 ok(!memcmp(buf
+ sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
),
2367 rsaPubKeys
[i
].modulus
, rsaPubKeys
[i
].decodedModulusLen
),
2368 "Unexpected modulus\n");
2374 static const BYTE intSequence
[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01,
2375 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02,
2376 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2378 static const BYTE mixedSequence
[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
2379 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f,
2380 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02,
2381 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2383 static void test_encodeSequenceOfAny(DWORD dwEncoding
)
2385 CRYPT_DER_BLOB blobs
[sizeof(ints
) / sizeof(ints
[0])];
2386 CRYPT_SEQUENCE_OF_ANY seq
;
2392 /* Encode a homogeneous sequence */
2393 for (i
= 0; i
< sizeof(ints
) / sizeof(ints
[0]); i
++)
2395 blobs
[i
].cbData
= ints
[i
].encoded
[1] + 2;
2396 blobs
[i
].pbData
= (BYTE
*)ints
[i
].encoded
;
2398 seq
.cValue
= sizeof(ints
) / sizeof(ints
[0]);
2399 seq
.rgValue
= blobs
;
2401 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_SEQUENCE_OF_ANY
, &seq
,
2402 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2403 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2406 ok(bufSize
== sizeof(intSequence
), "Wrong size %d\n", bufSize
);
2407 ok(!memcmp(buf
, intSequence
, intSequence
[1] + 2), "Unexpected value\n");
2410 /* Change the type of the first element in the sequence, and give it
2413 blobs
[0].cbData
= times
[0].encodedTime
[1] + 2;
2414 blobs
[0].pbData
= (BYTE
*)times
[0].encodedTime
;
2415 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_SEQUENCE_OF_ANY
, &seq
,
2416 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2417 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2420 ok(bufSize
== sizeof(mixedSequence
), "Wrong size %d\n", bufSize
);
2421 ok(!memcmp(buf
, mixedSequence
, mixedSequence
[1] + 2),
2422 "Unexpected value\n");
2427 static void test_decodeSequenceOfAny(DWORD dwEncoding
)
2433 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_SEQUENCE_OF_ANY
, intSequence
,
2434 intSequence
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2435 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2438 CRYPT_SEQUENCE_OF_ANY
*seq
= (CRYPT_SEQUENCE_OF_ANY
*)buf
;
2441 ok(seq
->cValue
== sizeof(ints
) / sizeof(ints
[0]),
2442 "Wrong elements %d\n", seq
->cValue
);
2443 for (i
= 0; i
< min(seq
->cValue
, sizeof(ints
) / sizeof(ints
[0])); i
++)
2445 ok(seq
->rgValue
[i
].cbData
== ints
[i
].encoded
[1] + 2,
2446 "Expected %d bytes, got %d\n", ints
[i
].encoded
[1] + 2,
2447 seq
->rgValue
[i
].cbData
);
2448 ok(!memcmp(seq
->rgValue
[i
].pbData
, ints
[i
].encoded
,
2449 ints
[i
].encoded
[1] + 2), "Unexpected value\n");
2453 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_SEQUENCE_OF_ANY
, mixedSequence
,
2454 mixedSequence
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
2456 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2459 CRYPT_SEQUENCE_OF_ANY
*seq
= (CRYPT_SEQUENCE_OF_ANY
*)buf
;
2461 ok(seq
->cValue
== sizeof(ints
) / sizeof(ints
[0]),
2462 "Wrong elements %d\n", seq
->cValue
);
2463 /* Just check the first element since it's all that changed */
2464 ok(seq
->rgValue
[0].cbData
== times
[0].encodedTime
[1] + 2,
2465 "Expected %d bytes, got %d\n", times
[0].encodedTime
[1] + 2,
2466 seq
->rgValue
[0].cbData
);
2467 ok(!memcmp(seq
->rgValue
[0].pbData
, times
[0].encodedTime
,
2468 times
[0].encodedTime
[1] + 2), "Unexpected value\n");
2473 struct encodedExtensions
2475 CERT_EXTENSIONS exts
;
2476 const BYTE
*encoded
;
2479 static BYTE crit_ext_data
[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2480 static BYTE noncrit_ext_data
[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2481 static CHAR oid_basic_constraints2
[] = szOID_BASIC_CONSTRAINTS2
;
2482 static CERT_EXTENSION criticalExt
=
2483 { oid_basic_constraints2
, TRUE
, { 8, crit_ext_data
} };
2484 static CERT_EXTENSION nonCriticalExt
=
2485 { oid_basic_constraints2
, FALSE
, { 8, noncrit_ext_data
} };
2487 static const BYTE ext0
[] = { 0x30,0x00 };
2488 static const BYTE ext1
[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2489 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2490 static const BYTE ext2
[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2491 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2493 static const struct encodedExtensions exts
[] = {
2494 { { 0, NULL
}, ext0
},
2495 { { 1, &criticalExt
}, ext1
},
2496 { { 1, &nonCriticalExt
}, ext2
},
2499 static void test_encodeExtensions(DWORD dwEncoding
)
2503 for (i
= 0; i
< sizeof(exts
) / sizeof(exts
[i
]); i
++)
2509 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_EXTENSIONS
, &exts
[i
].exts
,
2510 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2511 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2514 ok(bufSize
== exts
[i
].encoded
[1] + 2,
2515 "Expected %d bytes, got %d\n", exts
[i
].encoded
[1] + 2, bufSize
);
2516 ok(!memcmp(buf
, exts
[i
].encoded
, exts
[i
].encoded
[1] + 2),
2517 "Unexpected value\n");
2523 static void test_decodeExtensions(DWORD dwEncoding
)
2527 for (i
= 0; i
< sizeof(exts
) / sizeof(exts
[i
]); i
++)
2533 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_EXTENSIONS
,
2534 exts
[i
].encoded
, exts
[i
].encoded
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
,
2535 NULL
, (BYTE
*)&buf
, &bufSize
);
2536 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2539 CERT_EXTENSIONS
*ext
= (CERT_EXTENSIONS
*)buf
;
2542 ok(ext
->cExtension
== exts
[i
].exts
.cExtension
,
2543 "Expected %d extensions, see %d\n", exts
[i
].exts
.cExtension
,
2545 for (j
= 0; j
< min(ext
->cExtension
, exts
[i
].exts
.cExtension
); j
++)
2547 ok(!strcmp(ext
->rgExtension
[j
].pszObjId
,
2548 exts
[i
].exts
.rgExtension
[j
].pszObjId
),
2549 "Expected OID %s, got %s\n",
2550 exts
[i
].exts
.rgExtension
[j
].pszObjId
,
2551 ext
->rgExtension
[j
].pszObjId
);
2552 ok(!memcmp(ext
->rgExtension
[j
].Value
.pbData
,
2553 exts
[i
].exts
.rgExtension
[j
].Value
.pbData
,
2554 exts
[i
].exts
.rgExtension
[j
].Value
.cbData
),
2555 "Unexpected value\n");
2562 /* MS encodes public key info with a NULL if the algorithm identifier's
2563 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2564 * it encodes them by omitting the algorithm parameters. This latter approach
2565 * seems more correct, so accept either form.
2567 struct encodedPublicKey
2569 CERT_PUBLIC_KEY_INFO info
;
2570 const BYTE
*encoded
;
2571 const BYTE
*encodedNoNull
;
2572 CERT_PUBLIC_KEY_INFO decoded
;
2575 static const BYTE aKey
[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2577 static const BYTE params
[] = { 0x02, 0x01, 0x01 };
2579 static const unsigned char bin64
[] = {
2580 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2581 static const unsigned char bin65
[] = {
2582 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2583 static const unsigned char bin66
[] = {
2584 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2585 static const unsigned char bin67
[] = {
2586 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2587 static const unsigned char bin68
[] = {
2588 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01,
2589 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2590 static const unsigned char bin69
[] = {
2591 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2592 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2593 static const unsigned char bin70
[] = {
2594 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2595 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2597 static const unsigned char bin71
[] = {
2598 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2599 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2601 static unsigned char bin72
[] = { 0x05,0x00};
2603 static CHAR oid_bogus
[] = "1.2.3",
2604 oid_rsa
[] = szOID_RSA
;
2606 static const struct encodedPublicKey pubKeys
[] = {
2607 /* with a bogus OID */
2608 { { { oid_bogus
, { 0, NULL
} }, { 0, NULL
, 0 } },
2610 { { oid_bogus
, { 2, bin72
} }, { 0, NULL
, 0 } } },
2611 /* some normal keys */
2612 { { { oid_rsa
, { 0, NULL
} }, { 0, NULL
, 0} },
2614 { { oid_rsa
, { 2, bin72
} }, { 0, NULL
, 0 } } },
2615 { { { oid_rsa
, { 0, NULL
} }, { sizeof(aKey
), (BYTE
*)aKey
, 0} },
2617 { { oid_rsa
, { 2, bin72
} }, { sizeof(aKey
), (BYTE
*)aKey
, 0} } },
2618 /* with add'l parameters--note they must be DER-encoded */
2619 { { { oid_rsa
, { sizeof(params
), (BYTE
*)params
} }, { sizeof(aKey
),
2620 (BYTE
*)aKey
, 0 } },
2622 { { oid_rsa
, { sizeof(params
), (BYTE
*)params
} }, { sizeof(aKey
),
2623 (BYTE
*)aKey
, 0 } } },
2626 static void test_encodePublicKeyInfo(DWORD dwEncoding
)
2630 for (i
= 0; i
< sizeof(pubKeys
) / sizeof(pubKeys
[0]); i
++)
2636 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_PUBLIC_KEY_INFO
,
2637 &pubKeys
[i
].info
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
2639 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2642 ok(bufSize
== pubKeys
[i
].encoded
[1] + 2 ||
2643 bufSize
== pubKeys
[i
].encodedNoNull
[1] + 2,
2644 "Expected %d or %d bytes, got %d\n", pubKeys
[i
].encoded
[1] + 2,
2645 pubKeys
[i
].encodedNoNull
[1] + 2, bufSize
);
2646 if (bufSize
== pubKeys
[i
].encoded
[1] + 2)
2647 ok(!memcmp(buf
, pubKeys
[i
].encoded
, pubKeys
[i
].encoded
[1] + 2),
2648 "Unexpected value\n");
2649 else if (bufSize
== pubKeys
[i
].encodedNoNull
[1] + 2)
2650 ok(!memcmp(buf
, pubKeys
[i
].encodedNoNull
,
2651 pubKeys
[i
].encodedNoNull
[1] + 2), "Unexpected value\n");
2657 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO
*expected
,
2658 const CERT_PUBLIC_KEY_INFO
*got
)
2660 ok(!strcmp(expected
->Algorithm
.pszObjId
, got
->Algorithm
.pszObjId
),
2661 "Expected OID %s, got %s\n", expected
->Algorithm
.pszObjId
,
2662 got
->Algorithm
.pszObjId
);
2663 ok(expected
->Algorithm
.Parameters
.cbData
==
2664 got
->Algorithm
.Parameters
.cbData
,
2665 "Expected parameters of %d bytes, got %d\n",
2666 expected
->Algorithm
.Parameters
.cbData
, got
->Algorithm
.Parameters
.cbData
);
2667 if (expected
->Algorithm
.Parameters
.cbData
)
2668 ok(!memcmp(expected
->Algorithm
.Parameters
.pbData
,
2669 got
->Algorithm
.Parameters
.pbData
, got
->Algorithm
.Parameters
.cbData
),
2670 "Unexpected algorithm parameters\n");
2671 ok(expected
->PublicKey
.cbData
== got
->PublicKey
.cbData
,
2672 "Expected public key of %d bytes, got %d\n",
2673 expected
->PublicKey
.cbData
, got
->PublicKey
.cbData
);
2674 if (expected
->PublicKey
.cbData
)
2675 ok(!memcmp(expected
->PublicKey
.pbData
, got
->PublicKey
.pbData
,
2676 got
->PublicKey
.cbData
), "Unexpected public key value\n");
2679 static void test_decodePublicKeyInfo(DWORD dwEncoding
)
2681 static const BYTE bogusPubKeyInfo
[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
2682 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
2683 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
2684 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2690 for (i
= 0; i
< sizeof(pubKeys
) / sizeof(pubKeys
[0]); i
++)
2692 /* The NULL form decodes to the decoded member */
2693 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_PUBLIC_KEY_INFO
,
2694 pubKeys
[i
].encoded
, pubKeys
[i
].encoded
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
,
2695 NULL
, (BYTE
*)&buf
, &bufSize
);
2696 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2699 comparePublicKeyInfo(&pubKeys
[i
].decoded
,
2700 (CERT_PUBLIC_KEY_INFO
*)buf
);
2703 /* The non-NULL form decodes to the original */
2704 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_PUBLIC_KEY_INFO
,
2705 pubKeys
[i
].encodedNoNull
, pubKeys
[i
].encodedNoNull
[1] + 2,
2706 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2707 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2710 comparePublicKeyInfo(&pubKeys
[i
].info
, (CERT_PUBLIC_KEY_INFO
*)buf
);
2714 /* Test with bogus (not valid DER) parameters */
2715 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_PUBLIC_KEY_INFO
,
2716 bogusPubKeyInfo
, bogusPubKeyInfo
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
,
2717 NULL
, (BYTE
*)&buf
, &bufSize
);
2718 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_CORRUPT
,
2719 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2722 static const BYTE v1Cert
[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
2723 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2724 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
2725 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
2726 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2727 static const BYTE v2Cert
[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02,
2728 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2729 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2730 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2731 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2732 static const BYTE v3Cert
[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2733 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2734 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2735 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2736 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2737 static const BYTE v1CertWithConstraints
[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
2738 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2739 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2740 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2741 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2742 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2743 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2744 static const BYTE v1CertWithSerial
[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
2745 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2746 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2747 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2748 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2749 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2750 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2751 static const BYTE bigCert
[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2752 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
2753 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
2754 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
2755 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
2756 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
2757 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
2758 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
2759 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
2760 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2761 static const BYTE v1CertWithPubKey
[] = {
2762 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2763 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2764 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2765 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2766 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2767 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2768 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2769 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2770 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
2771 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
2773 static const BYTE v1CertWithPubKeyNoNull
[] = {
2774 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2775 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2776 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2777 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2778 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2779 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2780 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2781 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2782 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
2783 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2784 static const BYTE v1CertWithSubjectKeyId
[] = {
2785 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2786 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2787 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2788 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2789 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2790 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2791 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
2792 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2793 0x4c,0x61,0x6e,0x67,0x00 };
2795 static const BYTE serialNum
[] = { 0x01 };
2797 static void test_encodeCertToBeSigned(DWORD dwEncoding
)
2802 CERT_INFO info
= { 0 };
2803 static char oid_rsa_rsa
[] = szOID_RSA_RSA
;
2804 static char oid_subject_key_identifier
[] = szOID_SUBJECT_KEY_IDENTIFIER
;
2807 /* Test with NULL pvStructInfo */
2808 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, NULL
,
2809 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
2810 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
2811 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2812 /* Test with a V1 cert */
2813 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
2814 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
2815 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2818 ok(size
== v1Cert
[1] + 2, "Expected size %d, got %d\n",
2819 v1Cert
[1] + 2, size
);
2820 ok(!memcmp(buf
, v1Cert
, size
), "Got unexpected value\n");
2824 info
.dwVersion
= CERT_V2
;
2825 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
2826 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
2827 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2830 ok(size
== sizeof(v2Cert
), "Wrong size %d\n", size
);
2831 ok(!memcmp(buf
, v2Cert
, size
), "Got unexpected value\n");
2835 info
.dwVersion
= CERT_V3
;
2836 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
2837 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
2838 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2841 ok(size
== sizeof(v3Cert
), "Wrong size %d\n", size
);
2842 ok(!memcmp(buf
, v3Cert
, size
), "Got unexpected value\n");
2845 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
2846 * API doesn't prevent it)
2848 info
.dwVersion
= CERT_V1
;
2849 info
.cExtension
= 1;
2850 info
.rgExtension
= &criticalExt
;
2851 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
2852 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
2853 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2856 ok(size
== sizeof(v1CertWithConstraints
), "Wrong size %d\n", size
);
2857 ok(!memcmp(buf
, v1CertWithConstraints
, size
), "Got unexpected value\n");
2860 /* test v1 cert with a serial number */
2861 info
.SerialNumber
.cbData
= sizeof(serialNum
);
2862 info
.SerialNumber
.pbData
= (BYTE
*)serialNum
;
2863 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
2864 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
2867 ok(size
== sizeof(v1CertWithSerial
), "Wrong size %d\n", size
);
2868 ok(!memcmp(buf
, v1CertWithSerial
, size
), "Got unexpected value\n");
2871 /* Test v1 cert with an issuer name, a subject name, and a serial number */
2872 info
.Issuer
.cbData
= sizeof(encodedCommonName
);
2873 info
.Issuer
.pbData
= (BYTE
*)encodedCommonName
;
2874 info
.Subject
.cbData
= sizeof(encodedCommonName
);
2875 info
.Subject
.pbData
= (BYTE
*)encodedCommonName
;
2876 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
2877 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
2880 ok(size
== sizeof(bigCert
), "Wrong size %d\n", size
);
2881 ok(!memcmp(buf
, bigCert
, size
), "Got unexpected value\n");
2884 /* Add a public key */
2885 info
.SubjectPublicKeyInfo
.Algorithm
.pszObjId
= oid_rsa_rsa
;
2886 info
.SubjectPublicKeyInfo
.PublicKey
.cbData
= sizeof(aKey
);
2887 info
.SubjectPublicKeyInfo
.PublicKey
.pbData
= (LPBYTE
)aKey
;
2888 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
2889 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
2892 ok(size
== sizeof(v1CertWithPubKey
) ||
2893 size
== sizeof(v1CertWithPubKeyNoNull
), "Wrong size %d\n", size
);
2894 if (size
== sizeof(v1CertWithPubKey
))
2895 ok(!memcmp(buf
, v1CertWithPubKey
, size
), "Got unexpected value\n");
2896 else if (size
== sizeof(v1CertWithPubKeyNoNull
))
2897 ok(!memcmp(buf
, v1CertWithPubKeyNoNull
, size
),
2898 "Got unexpected value\n");
2901 /* Remove the public key, and add a subject key identifier extension */
2902 info
.SubjectPublicKeyInfo
.Algorithm
.pszObjId
= NULL
;
2903 info
.SubjectPublicKeyInfo
.PublicKey
.cbData
= 0;
2904 info
.SubjectPublicKeyInfo
.PublicKey
.pbData
= NULL
;
2905 ext
.pszObjId
= oid_subject_key_identifier
;
2906 ext
.fCritical
= FALSE
;
2907 ext
.Value
.cbData
= sizeof(octetCommonNameValue
);
2908 ext
.Value
.pbData
= (BYTE
*)octetCommonNameValue
;
2909 info
.cExtension
= 1;
2910 info
.rgExtension
= &ext
;
2911 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
2912 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
2915 ok(size
== sizeof(v1CertWithSubjectKeyId
), "Wrong size %d\n", size
);
2916 ok(!memcmp(buf
, v1CertWithSubjectKeyId
, size
), "Unexpected value\n");
2921 static void test_decodeCertToBeSigned(DWORD dwEncoding
)
2923 static const BYTE
*corruptCerts
[] = { v1Cert
, v2Cert
, v3Cert
,
2924 v1CertWithConstraints
, v1CertWithSerial
};
2929 /* Test with NULL pbEncoded */
2930 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, NULL
, 0,
2931 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
2932 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_EOD
,
2933 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2934 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, NULL
, 1,
2935 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
2936 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
2937 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2938 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT, because at a
2939 * minimum a cert must have a non-zero serial number, an issuer, and a
2942 for (i
= 0; i
< sizeof(corruptCerts
) / sizeof(corruptCerts
[0]); i
++)
2944 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
,
2945 corruptCerts
[i
], corruptCerts
[i
][1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
2946 (BYTE
*)&buf
, &size
);
2947 ok(!ret
, "Expected failure\n");
2949 /* Now check with serial number, subject and issuer specified */
2950 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, bigCert
,
2951 sizeof(bigCert
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
2952 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2955 CERT_INFO
*info
= (CERT_INFO
*)buf
;
2957 ok(size
>= sizeof(CERT_INFO
), "Wrong size %d\n", size
);
2958 ok(info
->SerialNumber
.cbData
== 1,
2959 "Expected serial number size 1, got %d\n", info
->SerialNumber
.cbData
);
2960 ok(*info
->SerialNumber
.pbData
== *serialNum
,
2961 "Expected serial number %d, got %d\n", *serialNum
,
2962 *info
->SerialNumber
.pbData
);
2963 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
2964 "Wrong size %d\n", info
->Issuer
.cbData
);
2965 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
2966 "Unexpected issuer\n");
2967 ok(info
->Subject
.cbData
== sizeof(encodedCommonName
),
2968 "Wrong size %d\n", info
->Subject
.cbData
);
2969 ok(!memcmp(info
->Subject
.pbData
, encodedCommonName
,
2970 info
->Subject
.cbData
), "Unexpected subject\n");
2973 /* Check again with pub key specified */
2974 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
,
2975 v1CertWithPubKey
, sizeof(v1CertWithPubKey
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
2976 (BYTE
*)&buf
, &size
);
2977 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2980 CERT_INFO
*info
= (CERT_INFO
*)buf
;
2982 ok(size
>= sizeof(CERT_INFO
), "Wrong size %d\n", size
);
2983 ok(info
->SerialNumber
.cbData
== 1,
2984 "Expected serial number size 1, got %d\n", info
->SerialNumber
.cbData
);
2985 ok(*info
->SerialNumber
.pbData
== *serialNum
,
2986 "Expected serial number %d, got %d\n", *serialNum
,
2987 *info
->SerialNumber
.pbData
);
2988 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
2989 "Wrong size %d\n", info
->Issuer
.cbData
);
2990 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
2991 "Unexpected issuer\n");
2992 ok(info
->Subject
.cbData
== sizeof(encodedCommonName
),
2993 "Wrong size %d\n", info
->Subject
.cbData
);
2994 ok(!memcmp(info
->Subject
.pbData
, encodedCommonName
,
2995 info
->Subject
.cbData
), "Unexpected subject\n");
2996 ok(!strcmp(info
->SubjectPublicKeyInfo
.Algorithm
.pszObjId
,
2997 szOID_RSA_RSA
), "Expected szOID_RSA_RSA, got %s\n",
2998 info
->SubjectPublicKeyInfo
.Algorithm
.pszObjId
);
2999 ok(info
->SubjectPublicKeyInfo
.PublicKey
.cbData
== sizeof(aKey
),
3000 "Wrong size %d\n", info
->SubjectPublicKeyInfo
.PublicKey
.cbData
);
3001 ok(!memcmp(info
->SubjectPublicKeyInfo
.PublicKey
.pbData
, aKey
,
3002 sizeof(aKey
)), "Unexpected public key\n");
3007 static const BYTE hash
[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
3010 static const BYTE signedBigCert
[] = {
3011 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
3012 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
3013 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
3014 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3015 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
3016 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
3017 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
3018 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
3019 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
3020 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3021 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
3022 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
3024 static void test_encodeCert(DWORD dwEncoding
)
3026 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
3027 * also that bigCert is a NULL-terminated string, so don't count its
3028 * last byte (otherwise the signed cert won't decode.)
3030 CERT_SIGNED_CONTENT_INFO info
= { { sizeof(bigCert
), (BYTE
*)bigCert
},
3031 { NULL
, { 0, NULL
} }, { sizeof(hash
), (BYTE
*)hash
, 0 } };
3036 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT
, &info
,
3037 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
3038 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3041 ok(bufSize
== sizeof(signedBigCert
), "Wrong size %d\n", bufSize
);
3042 ok(!memcmp(buf
, signedBigCert
, bufSize
), "Unexpected cert\n");
3047 static void test_decodeCert(DWORD dwEncoding
)
3053 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT
, signedBigCert
,
3054 sizeof(signedBigCert
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3055 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3058 CERT_SIGNED_CONTENT_INFO
*info
= (CERT_SIGNED_CONTENT_INFO
*)buf
;
3060 ok(info
->ToBeSigned
.cbData
== sizeof(bigCert
),
3061 "Wrong cert size %d\n", info
->ToBeSigned
.cbData
);
3062 ok(!memcmp(info
->ToBeSigned
.pbData
, bigCert
, info
->ToBeSigned
.cbData
),
3063 "Unexpected cert\n");
3064 ok(info
->Signature
.cbData
== sizeof(hash
),
3065 "Wrong signature size %d\n", info
->Signature
.cbData
);
3066 ok(!memcmp(info
->Signature
.pbData
, hash
, info
->Signature
.cbData
),
3067 "Unexpected signature\n");
3070 /* A signed cert decodes as a CERT_INFO too */
3071 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, signedBigCert
,
3072 sizeof(signedBigCert
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3073 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3076 CERT_INFO
*info
= (CERT_INFO
*)buf
;
3078 ok(size
>= sizeof(CERT_INFO
), "Wrong size %d\n", size
);
3079 ok(info
->SerialNumber
.cbData
== 1,
3080 "Expected serial number size 1, got %d\n", info
->SerialNumber
.cbData
);
3081 ok(*info
->SerialNumber
.pbData
== *serialNum
,
3082 "Expected serial number %d, got %d\n", *serialNum
,
3083 *info
->SerialNumber
.pbData
);
3084 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
3085 "Wrong size %d\n", info
->Issuer
.cbData
);
3086 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
3087 "Unexpected issuer\n");
3088 ok(info
->Subject
.cbData
== sizeof(encodedCommonName
),
3089 "Wrong size %d\n", info
->Subject
.cbData
);
3090 ok(!memcmp(info
->Subject
.pbData
, encodedCommonName
,
3091 info
->Subject
.cbData
), "Unexpected subject\n");
3096 static const BYTE emptyDistPoint
[] = { 0x30, 0x02, 0x30, 0x00 };
3097 static const BYTE distPointWithUrl
[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3098 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3099 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3100 static const BYTE distPointWithReason
[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3102 static const BYTE distPointWithIssuer
[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3103 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3104 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3105 static const BYTE distPointWithUrlAndIssuer
[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3106 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3107 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3108 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3109 0x2e, 0x6f, 0x72, 0x67 };
3110 static const BYTE crlReason
= CRL_REASON_KEY_COMPROMISE
|
3111 CRL_REASON_AFFILIATION_CHANGED
;
3113 static void test_encodeCRLDistPoints(DWORD dwEncoding
)
3115 CRL_DIST_POINTS_INFO info
= { 0 };
3116 CRL_DIST_POINT point
= { { 0 } };
3117 CERT_ALT_NAME_ENTRY entry
= { 0 };
3122 /* Test with an empty info */
3123 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3124 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3125 ok(!ret
&& GetLastError() == E_INVALIDARG
,
3126 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3127 /* Test with one empty dist point */
3128 info
.cDistPoint
= 1;
3129 info
.rgDistPoint
= &point
;
3130 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3131 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3134 ok(size
== sizeof(emptyDistPoint
), "Wrong size %d\n", size
);
3135 ok(!memcmp(buf
, emptyDistPoint
, size
), "Unexpected value\n");
3138 /* A dist point with an invalid name */
3139 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3140 entry
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
3141 U(entry
).pwszURL
= (LPWSTR
)nihongoURL
;
3142 U(point
.DistPointName
).FullName
.cAltEntry
= 1;
3143 U(point
.DistPointName
).FullName
.rgAltEntry
= &entry
;
3144 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3145 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3146 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_IA5_STRING
,
3147 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
3148 /* The first invalid character is at index 7 */
3149 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size
) == 7,
3150 "Expected invalid char at index 7, got %d\n",
3151 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size
));
3152 /* A dist point with (just) a valid name */
3153 U(entry
).pwszURL
= (LPWSTR
)url
;
3154 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3155 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3158 ok(size
== sizeof(distPointWithUrl
), "Wrong size %d\n", size
);
3159 ok(!memcmp(buf
, distPointWithUrl
, size
), "Unexpected value\n");
3162 /* A dist point with (just) reason flags */
3163 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
3164 point
.ReasonFlags
.cbData
= sizeof(crlReason
);
3165 point
.ReasonFlags
.pbData
= (LPBYTE
)&crlReason
;
3166 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3167 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3170 ok(size
== sizeof(distPointWithReason
), "Wrong size %d\n", size
);
3171 ok(!memcmp(buf
, distPointWithReason
, size
), "Unexpected value\n");
3174 /* A dist point with just an issuer */
3175 point
.ReasonFlags
.cbData
= 0;
3176 point
.CRLIssuer
.cAltEntry
= 1;
3177 point
.CRLIssuer
.rgAltEntry
= &entry
;
3178 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3179 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3182 ok(size
== sizeof(distPointWithIssuer
), "Wrong size %d\n", size
);
3183 ok(!memcmp(buf
, distPointWithIssuer
, size
), "Unexpected value\n");
3186 /* A dist point with both a name and an issuer */
3187 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3188 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3189 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3192 ok(size
== sizeof(distPointWithUrlAndIssuer
),
3193 "Wrong size %d\n", size
);
3194 ok(!memcmp(buf
, distPointWithUrlAndIssuer
, size
), "Unexpected value\n");
3199 static void test_decodeCRLDistPoints(DWORD dwEncoding
)
3204 PCRL_DIST_POINTS_INFO info
;
3205 PCRL_DIST_POINT point
;
3206 PCERT_ALT_NAME_ENTRY entry
;
3208 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
,
3209 emptyDistPoint
, emptyDistPoint
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3210 (BYTE
*)&buf
, &size
);
3213 info
= (PCRL_DIST_POINTS_INFO
)buf
;
3214 ok(size
>= sizeof(CRL_DIST_POINTS_INFO
) + sizeof(CRL_DIST_POINT
),
3215 "Wrong size %d\n", size
);
3216 ok(info
->cDistPoint
== 1, "Expected 1 dist points, got %d\n",
3218 point
= info
->rgDistPoint
;
3219 ok(point
->DistPointName
.dwDistPointNameChoice
== CRL_DIST_POINT_NO_NAME
,
3220 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3221 point
->DistPointName
.dwDistPointNameChoice
);
3222 ok(point
->ReasonFlags
.cbData
== 0, "Expected no reason\n");
3223 ok(point
->CRLIssuer
.cAltEntry
== 0, "Expected no issuer\n");
3226 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
,
3227 distPointWithUrl
, distPointWithUrl
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3228 (BYTE
*)&buf
, &size
);
3231 info
= (PCRL_DIST_POINTS_INFO
)buf
;
3232 ok(size
>= sizeof(CRL_DIST_POINTS_INFO
) + sizeof(CRL_DIST_POINT
),
3233 "Wrong size %d\n", size
);
3234 ok(info
->cDistPoint
== 1, "Expected 1 dist points, got %d\n",
3236 point
= info
->rgDistPoint
;
3237 ok(point
->DistPointName
.dwDistPointNameChoice
==
3238 CRL_DIST_POINT_FULL_NAME
,
3239 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3240 point
->DistPointName
.dwDistPointNameChoice
);
3241 ok(U(point
->DistPointName
).FullName
.cAltEntry
== 1,
3242 "Expected 1 name entry, got %d\n",
3243 U(point
->DistPointName
).FullName
.cAltEntry
);
3244 entry
= U(point
->DistPointName
).FullName
.rgAltEntry
;
3245 ok(entry
->dwAltNameChoice
== CERT_ALT_NAME_URL
,
3246 "Expected CERT_ALT_NAME_URL, got %d\n", entry
->dwAltNameChoice
);
3247 ok(!lstrcmpW(U(*entry
).pwszURL
, url
), "Unexpected name\n");
3248 ok(point
->ReasonFlags
.cbData
== 0, "Expected no reason\n");
3249 ok(point
->CRLIssuer
.cAltEntry
== 0, "Expected no issuer\n");
3252 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
,
3253 distPointWithReason
, distPointWithReason
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
,
3254 NULL
, (BYTE
*)&buf
, &size
);
3257 info
= (PCRL_DIST_POINTS_INFO
)buf
;
3258 ok(size
>= sizeof(CRL_DIST_POINTS_INFO
) + sizeof(CRL_DIST_POINT
),
3259 "Wrong size %d\n", size
);
3260 ok(info
->cDistPoint
== 1, "Expected 1 dist points, got %d\n",
3262 point
= info
->rgDistPoint
;
3263 ok(point
->DistPointName
.dwDistPointNameChoice
==
3264 CRL_DIST_POINT_NO_NAME
,
3265 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3266 point
->DistPointName
.dwDistPointNameChoice
);
3267 ok(point
->ReasonFlags
.cbData
== sizeof(crlReason
),
3268 "Expected reason length\n");
3269 ok(!memcmp(point
->ReasonFlags
.pbData
, &crlReason
, sizeof(crlReason
)),
3270 "Unexpected reason\n");
3271 ok(point
->CRLIssuer
.cAltEntry
== 0, "Expected no issuer\n");
3274 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
,
3275 distPointWithUrlAndIssuer
, distPointWithUrlAndIssuer
[1] + 2,
3276 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3279 info
= (PCRL_DIST_POINTS_INFO
)buf
;
3280 ok(size
>= sizeof(CRL_DIST_POINTS_INFO
) + sizeof(CRL_DIST_POINT
),
3281 "Wrong size %d\n", size
);
3282 ok(info
->cDistPoint
== 1, "Expected 1 dist points, got %d\n",
3284 point
= info
->rgDistPoint
;
3285 ok(point
->DistPointName
.dwDistPointNameChoice
==
3286 CRL_DIST_POINT_FULL_NAME
,
3287 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3288 point
->DistPointName
.dwDistPointNameChoice
);
3289 ok(U(point
->DistPointName
).FullName
.cAltEntry
== 1,
3290 "Expected 1 name entry, got %d\n",
3291 U(point
->DistPointName
).FullName
.cAltEntry
);
3292 entry
= U(point
->DistPointName
).FullName
.rgAltEntry
;
3293 ok(entry
->dwAltNameChoice
== CERT_ALT_NAME_URL
,
3294 "Expected CERT_ALT_NAME_URL, got %d\n", entry
->dwAltNameChoice
);
3295 ok(!lstrcmpW(U(*entry
).pwszURL
, url
), "Unexpected name\n");
3296 ok(point
->ReasonFlags
.cbData
== 0, "Expected no reason\n");
3297 ok(point
->CRLIssuer
.cAltEntry
== 1,
3298 "Expected 1 issuer entry, got %d\n", point
->CRLIssuer
.cAltEntry
);
3299 entry
= point
->CRLIssuer
.rgAltEntry
;
3300 ok(entry
->dwAltNameChoice
== CERT_ALT_NAME_URL
,
3301 "Expected CERT_ALT_NAME_URL, got %d\n", entry
->dwAltNameChoice
);
3302 ok(!lstrcmpW(U(*entry
).pwszURL
, url
), "Unexpected name\n");
3307 static const BYTE badFlagsIDP
[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3308 static const BYTE emptyNameIDP
[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3309 static const BYTE urlIDP
[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3310 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3313 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding
)
3318 CRL_ISSUING_DIST_POINT point
= { { 0 } };
3319 CERT_ALT_NAME_ENTRY entry
;
3321 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, NULL
,
3322 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3323 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
3325 skip("no X509_ISSUING_DIST_POINT encode support\n");
3328 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
3329 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3330 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, &point
,
3331 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3332 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3335 ok(size
== sizeof(emptySequence
), "Unexpected size %d\n", size
);
3336 ok(!memcmp(buf
, emptySequence
, size
), "Unexpected value\n");
3339 /* nonsensical flags */
3340 point
.fOnlyContainsUserCerts
= TRUE
;
3341 point
.fOnlyContainsCACerts
= TRUE
;
3342 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, &point
,
3343 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3344 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3347 ok(size
== sizeof(badFlagsIDP
), "Unexpected size %d\n", size
);
3348 ok(!memcmp(buf
, badFlagsIDP
, size
), "Unexpected value\n");
3351 /* unimplemented name type */
3352 point
.fOnlyContainsCACerts
= point
.fOnlyContainsUserCerts
= FALSE
;
3353 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_ISSUER_RDN_NAME
;
3354 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, &point
,
3355 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3356 ok(!ret
&& GetLastError() == E_INVALIDARG
,
3357 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3359 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3360 U(point
.DistPointName
).FullName
.cAltEntry
= 0;
3361 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, &point
,
3362 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3363 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3366 ok(size
== sizeof(emptyNameIDP
), "Unexpected size %d\n", size
);
3367 ok(!memcmp(buf
, emptyNameIDP
, size
), "Unexpected value\n");
3370 /* name with URL entry */
3371 entry
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
3372 U(entry
).pwszURL
= (LPWSTR
)url
;
3373 U(point
.DistPointName
).FullName
.cAltEntry
= 1;
3374 U(point
.DistPointName
).FullName
.rgAltEntry
= &entry
;
3375 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, &point
,
3376 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3377 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3380 ok(size
== sizeof(urlIDP
), "Unexpected size %d\n", size
);
3381 ok(!memcmp(buf
, urlIDP
, size
), "Unexpected value\n");
3386 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY
*expected
,
3387 const CERT_ALT_NAME_ENTRY
*got
)
3389 ok(expected
->dwAltNameChoice
== got
->dwAltNameChoice
,
3390 "Expected name choice %d, got %d\n", expected
->dwAltNameChoice
,
3391 got
->dwAltNameChoice
);
3392 if (expected
->dwAltNameChoice
== got
->dwAltNameChoice
)
3394 switch (got
->dwAltNameChoice
)
3396 case CERT_ALT_NAME_RFC822_NAME
:
3397 case CERT_ALT_NAME_DNS_NAME
:
3398 case CERT_ALT_NAME_EDI_PARTY_NAME
:
3399 case CERT_ALT_NAME_URL
:
3400 case CERT_ALT_NAME_REGISTERED_ID
:
3401 ok((!U(*expected
).pwszURL
&& !U(*got
).pwszURL
) ||
3402 (!U(*expected
).pwszURL
&& !lstrlenW(U(*got
).pwszURL
)) ||
3403 (!U(*got
).pwszURL
&& !lstrlenW(U(*expected
).pwszURL
)) ||
3404 !lstrcmpW(U(*expected
).pwszURL
, U(*got
).pwszURL
),
3405 "Unexpected name\n");
3407 case CERT_ALT_NAME_X400_ADDRESS
:
3408 case CERT_ALT_NAME_DIRECTORY_NAME
:
3409 case CERT_ALT_NAME_IP_ADDRESS
:
3410 ok(U(*got
).IPAddress
.cbData
== U(*expected
).IPAddress
.cbData
,
3411 "Unexpected IP address length %d\n", U(*got
).IPAddress
.cbData
);
3412 ok(!memcmp(U(*got
).IPAddress
.pbData
, U(*got
).IPAddress
.pbData
,
3413 U(*got
).IPAddress
.cbData
), "Unexpected value\n");
3419 static void compareAltNameInfo(const CERT_ALT_NAME_INFO
*expected
,
3420 const CERT_ALT_NAME_INFO
*got
)
3424 ok(expected
->cAltEntry
== got
->cAltEntry
, "Expected %d entries, got %d\n",
3425 expected
->cAltEntry
, got
->cAltEntry
);
3426 for (i
= 0; i
< min(expected
->cAltEntry
, got
->cAltEntry
); i
++)
3427 compareAltNameEntry(&expected
->rgAltEntry
[i
], &got
->rgAltEntry
[i
]);
3430 static void compareDistPointName(const CRL_DIST_POINT_NAME
*expected
,
3431 const CRL_DIST_POINT_NAME
*got
)
3433 ok(got
->dwDistPointNameChoice
== expected
->dwDistPointNameChoice
,
3434 "Unexpected name choice %d\n", got
->dwDistPointNameChoice
);
3435 if (got
->dwDistPointNameChoice
== CRL_DIST_POINT_FULL_NAME
)
3436 compareAltNameInfo(&(U(*expected
).FullName
), &(U(*got
).FullName
));
3439 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT
*expected
,
3440 const CRL_ISSUING_DIST_POINT
*got
)
3442 compareDistPointName(&expected
->DistPointName
, &got
->DistPointName
);
3443 ok(got
->fOnlyContainsUserCerts
== expected
->fOnlyContainsUserCerts
,
3444 "Unexpected fOnlyContainsUserCerts\n");
3445 ok(got
->fOnlyContainsCACerts
== expected
->fOnlyContainsCACerts
,
3446 "Unexpected fOnlyContainsCACerts\n");
3447 ok(got
->OnlySomeReasonFlags
.cbData
== expected
->OnlySomeReasonFlags
.cbData
,
3448 "Unexpected reason flags\n");
3449 ok(got
->fIndirectCRL
== expected
->fIndirectCRL
,
3450 "Unexpected fIndirectCRL\n");
3453 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding
)
3458 CRL_ISSUING_DIST_POINT point
= { { 0 } };
3460 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
,
3461 emptySequence
, emptySequence
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3462 (BYTE
*)&buf
, &size
);
3463 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
3465 skip("no X509_ISSUING_DIST_POINT decode support\n");
3468 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3471 compareCRLIssuingDistPoints(&point
, (PCRL_ISSUING_DIST_POINT
)buf
);
3474 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
,
3475 badFlagsIDP
, badFlagsIDP
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3476 (BYTE
*)&buf
, &size
);
3477 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3480 point
.fOnlyContainsUserCerts
= point
.fOnlyContainsCACerts
= TRUE
;
3481 compareCRLIssuingDistPoints(&point
, (PCRL_ISSUING_DIST_POINT
)buf
);
3484 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
,
3485 emptyNameIDP
, emptyNameIDP
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3486 (BYTE
*)&buf
, &size
);
3487 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3490 point
.fOnlyContainsCACerts
= point
.fOnlyContainsUserCerts
= FALSE
;
3491 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3492 U(point
.DistPointName
).FullName
.cAltEntry
= 0;
3493 compareCRLIssuingDistPoints(&point
, (PCRL_ISSUING_DIST_POINT
)buf
);
3496 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
,
3497 urlIDP
, urlIDP
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3498 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3501 CERT_ALT_NAME_ENTRY entry
;
3503 entry
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
3504 U(entry
).pwszURL
= (LPWSTR
)url
;
3505 U(point
.DistPointName
).FullName
.cAltEntry
= 1;
3506 U(point
.DistPointName
).FullName
.rgAltEntry
= &entry
;
3507 compareCRLIssuingDistPoints(&point
, (PCRL_ISSUING_DIST_POINT
)buf
);
3512 static const BYTE v1CRL
[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3513 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3515 static const BYTE v2CRL
[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3516 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3517 0x30, 0x30, 0x30, 0x30, 0x5a };
3518 static const BYTE v1CRLWithIssuer
[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3519 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3520 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3521 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3523 static const BYTE v1CRLWithIssuerAndEmptyEntry
[] = { 0x30, 0x43, 0x30, 0x02,
3524 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3525 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3526 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3527 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3528 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3529 static const BYTE v1CRLWithIssuerAndEntry
[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3530 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3531 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3532 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3533 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3534 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3535 static const BYTE v1CRLWithEntryExt
[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3536 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3537 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3538 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3539 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3540 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3541 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3542 static const BYTE v1CRLWithExt
[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3543 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3544 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3545 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
3546 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3547 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
3548 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3549 static const BYTE v2CRLWithExt
[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
3550 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
3551 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
3552 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
3553 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
3554 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
3555 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3556 static const BYTE v2CRLWithIssuingDistPoint
[] = { 0x30,0x5c,0x02,0x01,0x01,
3557 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
3558 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
3559 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
3560 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3561 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
3562 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3564 static void test_encodeCRLToBeSigned(DWORD dwEncoding
)
3568 static CHAR oid_issuing_dist_point
[] = szOID_ISSUING_DIST_POINT
;
3570 CRL_INFO info
= { 0 };
3571 CRL_ENTRY entry
= { { 0 }, { 0 }, 0, 0 };
3574 /* Test with a V1 CRL */
3575 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3576 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3577 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3580 ok(size
== sizeof(v1CRL
), "Wrong size %d\n", size
);
3581 ok(!memcmp(buf
, v1CRL
, size
), "Got unexpected value\n");
3585 info
.dwVersion
= CRL_V2
;
3586 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3587 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3588 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3591 ok(size
== v2CRL
[1] + 2, "Expected size %d, got %d\n",
3592 v2CRL
[1] + 2, size
);
3593 ok(!memcmp(buf
, v2CRL
, size
), "Got unexpected value\n");
3596 /* v1 CRL with a name */
3597 info
.dwVersion
= CRL_V1
;
3598 info
.Issuer
.cbData
= sizeof(encodedCommonName
);
3599 info
.Issuer
.pbData
= (BYTE
*)encodedCommonName
;
3600 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3601 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3602 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3605 ok(size
== sizeof(v1CRLWithIssuer
), "Wrong size %d\n", size
);
3606 ok(!memcmp(buf
, v1CRLWithIssuer
, size
), "Got unexpected value\n");
3609 /* v1 CRL with a name and a NULL entry pointer */
3611 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3612 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3613 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
3614 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3615 /* now set an empty entry */
3616 info
.rgCRLEntry
= &entry
;
3617 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3618 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3621 ok(size
== sizeof(v1CRLWithIssuerAndEmptyEntry
),
3622 "Wrong size %d\n", size
);
3623 ok(!memcmp(buf
, v1CRLWithIssuerAndEmptyEntry
, size
),
3624 "Got unexpected value\n");
3627 /* an entry with a serial number */
3628 entry
.SerialNumber
.cbData
= sizeof(serialNum
);
3629 entry
.SerialNumber
.pbData
= (BYTE
*)serialNum
;
3630 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3631 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3634 ok(size
== sizeof(v1CRLWithIssuerAndEntry
),
3635 "Wrong size %d\n", size
);
3636 ok(!memcmp(buf
, v1CRLWithIssuerAndEntry
, size
),
3637 "Got unexpected value\n");
3640 /* an entry with an extension */
3641 entry
.cExtension
= 1;
3642 entry
.rgExtension
= &criticalExt
;
3643 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3644 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3645 ok(ret
, "pCryptEncodeObjectEx failed: %08x\n", GetLastError());
3648 ok(size
== sizeof(v1CRLWithEntryExt
), "Wrong size %d\n", size
);
3649 ok(!memcmp(buf
, v1CRLWithEntryExt
, size
), "Got unexpected value\n");
3652 /* a CRL with an extension */
3653 entry
.cExtension
= 0;
3654 info
.cExtension
= 1;
3655 info
.rgExtension
= &criticalExt
;
3656 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3657 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3658 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3661 ok(size
== sizeof(v1CRLWithExt
), "Wrong size %d\n", size
);
3662 ok(!memcmp(buf
, v1CRLWithExt
, size
), "Got unexpected value\n");
3665 /* a v2 CRL with an extension, this time non-critical */
3666 info
.dwVersion
= CRL_V2
;
3667 info
.rgExtension
= &nonCriticalExt
;
3668 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3669 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3670 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3673 ok(size
== sizeof(v2CRLWithExt
), "Wrong size %d\n", size
);
3674 ok(!memcmp(buf
, v2CRLWithExt
, size
), "Got unexpected value\n");
3677 /* a v2 CRL with an issuing dist point extension */
3678 ext
.pszObjId
= oid_issuing_dist_point
;
3679 ext
.fCritical
= TRUE
;
3680 ext
.Value
.cbData
= sizeof(urlIDP
);
3681 ext
.Value
.pbData
= (LPBYTE
)urlIDP
;
3682 entry
.rgExtension
= &ext
;
3683 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3684 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3685 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3688 ok(size
== sizeof(v2CRLWithIssuingDistPoint
), "Wrong size %d\n", size
);
3689 ok(!memcmp(buf
, v2CRLWithIssuingDistPoint
, size
), "Unexpected value\n");
3694 static const BYTE verisignCRL
[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
3695 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
3696 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
3697 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
3698 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
3699 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
3700 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
3701 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
3702 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
3703 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
3704 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
3705 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
3706 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
3707 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
3708 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
3709 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
3710 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
3711 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
3712 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
3713 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
3714 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
3715 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
3716 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
3717 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
3718 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
3719 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
3720 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
3721 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
3722 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
3723 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
3724 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
3725 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
3726 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
3727 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
3729 static const BYTE verisignCRLWithLotsOfEntries
[] = {
3730 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
3731 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
3732 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
3733 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
3734 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
3735 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
3736 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
3737 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
3738 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
3739 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
3740 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
3741 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
3742 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
3743 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
3744 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
3745 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
3746 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3747 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
3748 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
3749 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3750 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
3751 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
3752 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
3753 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
3754 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
3755 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
3756 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
3757 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
3758 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
3759 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
3760 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3761 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
3762 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
3763 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3764 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
3765 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
3766 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
3767 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
3768 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
3769 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
3770 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
3771 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
3772 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
3773 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
3774 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
3775 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
3776 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
3777 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
3778 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
3779 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
3780 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
3781 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
3782 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
3783 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
3784 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3785 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
3786 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
3787 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
3788 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
3789 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
3790 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
3791 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
3792 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
3793 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
3794 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
3795 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
3796 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
3797 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
3798 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
3799 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
3800 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
3801 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
3802 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
3803 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
3804 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
3805 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
3806 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
3807 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
3808 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
3809 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
3810 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
3811 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
3812 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3813 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
3814 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
3815 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
3816 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
3817 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
3818 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
3819 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
3820 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
3821 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
3822 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
3823 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
3824 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
3825 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
3826 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
3827 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
3828 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
3829 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
3830 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
3831 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
3832 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
3833 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
3834 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
3835 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
3836 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
3837 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
3838 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
3839 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
3840 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3841 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
3842 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
3843 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
3844 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
3845 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
3846 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
3847 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
3848 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
3849 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
3850 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
3851 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
3852 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
3853 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
3854 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3855 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
3856 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
3857 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
3858 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
3859 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
3860 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
3861 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
3862 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
3863 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
3864 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
3865 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
3866 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
3867 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
3868 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
3869 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
3870 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
3871 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
3872 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
3873 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
3874 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
3875 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
3876 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
3877 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
3878 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
3879 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
3880 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
3881 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
3882 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
3883 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
3884 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
3885 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
3886 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
3887 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
3888 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
3889 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
3890 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
3891 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
3892 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
3893 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
3894 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
3895 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
3896 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
3897 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
3898 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
3899 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
3900 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
3901 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
3902 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
3903 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
3904 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
3905 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
3906 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
3907 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
3908 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
3909 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
3910 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
3911 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
3912 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
3913 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
3914 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
3915 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
3916 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
3917 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
3918 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
3919 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
3920 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
3921 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
3922 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
3923 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
3924 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
3925 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
3926 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
3927 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
3928 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
3929 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
3930 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
3931 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
3932 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
3933 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
3934 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
3935 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
3936 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
3937 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
3938 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
3939 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
3940 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
3941 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
3942 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
3943 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
3944 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
3945 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
3946 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
3947 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
3948 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
3949 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
3950 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
3951 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
3952 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
3953 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
3954 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
3955 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
3956 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
3957 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
3958 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
3959 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
3960 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
3961 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
3962 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
3963 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
3964 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
3965 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
3966 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
3967 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
3968 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
3969 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
3970 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
3971 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
3972 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
3973 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
3974 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
3975 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
3976 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
3977 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
3978 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
3979 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
3980 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
3981 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
3982 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
3983 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
3984 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
3985 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
3986 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
3987 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
3988 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
3989 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
3990 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
3991 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
3992 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
3993 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
3994 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
3995 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
3996 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
3997 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
3998 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
3999 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
4000 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
4001 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
4002 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
4003 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
4004 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
4005 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
4006 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
4007 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
4008 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
4009 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
4010 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
4011 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
4012 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
4013 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
4014 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
4015 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
4016 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
4017 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
4018 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
4019 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
4020 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
4021 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
4022 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
4023 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
4024 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
4025 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
4026 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
4027 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
4028 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
4029 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
4030 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
4031 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
4032 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
4033 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4034 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4035 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4036 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4037 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4038 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4039 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4040 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4041 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4042 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4043 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4044 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4045 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4046 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4047 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4048 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4049 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4050 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4051 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4052 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4053 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4054 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4055 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4056 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4057 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4058 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4059 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4060 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4061 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4062 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4063 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4064 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4065 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4066 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4067 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4068 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4069 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4070 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4071 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4072 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4073 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4074 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4075 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4076 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4077 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4078 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4079 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4080 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4081 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4082 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4083 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4084 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4085 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4086 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4087 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4088 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4089 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4090 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4091 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4092 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4093 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4094 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4095 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4096 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4097 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4098 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4099 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4100 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4101 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4102 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4103 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4104 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4105 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4106 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4107 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4108 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4109 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4110 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4111 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4112 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4113 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4114 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4115 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4116 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4117 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4118 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4119 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4120 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4121 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4122 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4123 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4124 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4125 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4126 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4127 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4128 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4129 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4130 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4131 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4132 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4133 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4134 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4135 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4136 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4137 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4138 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4139 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4140 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4141 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4142 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4143 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4144 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4145 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4146 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4147 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4148 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4149 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4150 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4151 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4152 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4153 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4154 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4155 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4156 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4157 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4158 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4159 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4160 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4161 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4162 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4163 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4164 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4165 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4166 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4167 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4168 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4169 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4170 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4171 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4172 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4173 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4174 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4175 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4176 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4177 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4178 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4179 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4180 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4181 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4182 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4183 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4184 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4185 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4186 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4187 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4188 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4189 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4190 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4191 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4192 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4193 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4194 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4195 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4196 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4197 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4198 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4199 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4200 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4201 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4202 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4203 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4204 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4205 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4206 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4207 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4208 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4209 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4210 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4211 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4212 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4213 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4214 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4215 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4216 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4217 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4218 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4219 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4220 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4221 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4222 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4223 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4224 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4225 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4226 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4227 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4228 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4229 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4230 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4231 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4232 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4233 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4234 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4235 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4236 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4237 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4239 static void test_decodeCRLToBeSigned(DWORD dwEncoding
)
4241 static const BYTE
*corruptCRLs
[] = { v1CRL
, v2CRL
};
4246 for (i
= 0; i
< sizeof(corruptCRLs
) / sizeof(corruptCRLs
[0]); i
++)
4248 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4249 corruptCRLs
[i
], corruptCRLs
[i
][1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4250 (BYTE
*)&buf
, &size
);
4251 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
),
4252 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
4254 /* at a minimum, a CRL must contain an issuer: */
4255 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4256 v1CRLWithIssuer
, v1CRLWithIssuer
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4257 (BYTE
*)&buf
, &size
);
4258 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4261 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4263 ok(size
>= sizeof(CRL_INFO
), "Wrong size %d\n", size
);
4264 ok(info
->cCRLEntry
== 0, "Expected 0 CRL entries, got %d\n",
4266 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
4267 "Wrong issuer size %d\n", info
->Issuer
.cbData
);
4268 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
4269 "Unexpected issuer\n");
4272 /* check decoding with an empty CRL entry */
4273 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4274 v1CRLWithIssuerAndEmptyEntry
, v1CRLWithIssuerAndEmptyEntry
[1] + 2,
4275 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4276 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_CORRUPT
,
4277 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
4278 /* with a real CRL entry */
4279 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4280 v1CRLWithIssuerAndEntry
, v1CRLWithIssuerAndEntry
[1] + 2,
4281 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4282 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4285 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4288 ok(size
>= sizeof(CRL_INFO
), "Wrong size %d\n", size
);
4289 ok(info
->cCRLEntry
== 1, "Expected 1 CRL entries, got %d\n",
4291 ok(info
->rgCRLEntry
!= NULL
, "Expected a valid CRL entry array\n");
4292 entry
= info
->rgCRLEntry
;
4293 ok(entry
->SerialNumber
.cbData
== 1,
4294 "Expected serial number size 1, got %d\n",
4295 entry
->SerialNumber
.cbData
);
4296 ok(*entry
->SerialNumber
.pbData
== *serialNum
,
4297 "Expected serial number %d, got %d\n", *serialNum
,
4298 *entry
->SerialNumber
.pbData
);
4299 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
4300 "Wrong issuer size %d\n", info
->Issuer
.cbData
);
4301 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
4302 "Unexpected issuer\n");
4305 /* a real CRL from verisign that has extensions */
4306 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4307 verisignCRL
, sizeof(verisignCRL
), CRYPT_DECODE_ALLOC_FLAG
,
4308 NULL
, (BYTE
*)&buf
, &size
);
4309 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4312 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4315 ok(size
>= sizeof(CRL_INFO
), "Wrong size %d\n", size
);
4316 ok(info
->cCRLEntry
== 3, "Expected 3 CRL entries, got %d\n",
4318 ok(info
->rgCRLEntry
!= NULL
, "Expected a valid CRL entry array\n");
4319 entry
= info
->rgCRLEntry
;
4320 ok(info
->cExtension
== 2, "Expected 2 extensions, got %d\n",
4324 /* another real CRL from verisign that has lots of entries */
4325 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4326 verisignCRLWithLotsOfEntries
, sizeof(verisignCRLWithLotsOfEntries
),
4327 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4328 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4331 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4333 ok(size
>= sizeof(CRL_INFO
), "Got size %d\n", size
);
4334 ok(info
->cCRLEntry
== 209, "Expected 209 CRL entries, got %d\n",
4336 ok(info
->cExtension
== 0, "Expected 0 extensions, got %d\n",
4340 /* and finally, with an extension */
4341 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4342 v1CRLWithExt
, sizeof(v1CRLWithExt
), CRYPT_DECODE_ALLOC_FLAG
,
4343 NULL
, (BYTE
*)&buf
, &size
);
4344 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4347 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4350 ok(size
>= sizeof(CRL_INFO
), "Wrong size %d\n", size
);
4351 ok(info
->cCRLEntry
== 1, "Expected 1 CRL entries, got %d\n",
4353 ok(info
->rgCRLEntry
!= NULL
, "Expected a valid CRL entry array\n");
4354 entry
= info
->rgCRLEntry
;
4355 ok(entry
->SerialNumber
.cbData
== 1,
4356 "Expected serial number size 1, got %d\n",
4357 entry
->SerialNumber
.cbData
);
4358 ok(*entry
->SerialNumber
.pbData
== *serialNum
,
4359 "Expected serial number %d, got %d\n", *serialNum
,
4360 *entry
->SerialNumber
.pbData
);
4361 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
4362 "Wrong issuer size %d\n", info
->Issuer
.cbData
);
4363 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
4364 "Unexpected issuer\n");
4365 ok(info
->cExtension
== 1, "Expected 1 extensions, got %d\n",
4369 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4370 v2CRLWithExt
, sizeof(v2CRLWithExt
), CRYPT_DECODE_ALLOC_FLAG
,
4371 NULL
, (BYTE
*)&buf
, &size
);
4372 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4375 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4377 ok(info
->cExtension
== 1, "Expected 1 extensions, got %d\n",
4381 /* And again, with an issuing dist point */
4382 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4383 v2CRLWithIssuingDistPoint
, sizeof(v2CRLWithIssuingDistPoint
),
4384 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4385 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4388 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4390 ok(info
->cExtension
== 1, "Expected 1 extensions, got %d\n",
4396 static const LPCSTR keyUsages
[] = { szOID_PKIX_KP_CODE_SIGNING
,
4397 szOID_PKIX_KP_CLIENT_AUTH
, szOID_RSA_RSA
};
4398 static const BYTE encodedUsage
[] = {
4399 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4400 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4401 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4403 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding
)
4408 CERT_ENHKEY_USAGE usage
;
4410 /* Test with empty usage */
4411 usage
.cUsageIdentifier
= 0;
4412 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ENHANCED_KEY_USAGE
, &usage
,
4413 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4414 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4417 ok(size
== sizeof(emptySequence
), "Wrong size %d\n", size
);
4418 ok(!memcmp(buf
, emptySequence
, size
), "Got unexpected value\n");
4421 /* Test with a few usages */
4422 usage
.cUsageIdentifier
= sizeof(keyUsages
) / sizeof(keyUsages
[0]);
4423 usage
.rgpszUsageIdentifier
= (LPSTR
*)keyUsages
;
4424 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ENHANCED_KEY_USAGE
, &usage
,
4425 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4426 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4429 ok(size
== sizeof(encodedUsage
), "Wrong size %d\n", size
);
4430 ok(!memcmp(buf
, encodedUsage
, size
), "Got unexpected value\n");
4435 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding
)
4441 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ENHANCED_KEY_USAGE
,
4442 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4443 (BYTE
*)&buf
, &size
);
4444 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4447 CERT_ENHKEY_USAGE
*usage
= (CERT_ENHKEY_USAGE
*)buf
;
4449 ok(size
>= sizeof(CERT_ENHKEY_USAGE
),
4450 "Wrong size %d\n", size
);
4451 ok(usage
->cUsageIdentifier
== 0, "Expected 0 CRL entries, got %d\n",
4452 usage
->cUsageIdentifier
);
4455 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ENHANCED_KEY_USAGE
,
4456 encodedUsage
, sizeof(encodedUsage
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4457 (BYTE
*)&buf
, &size
);
4458 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4461 CERT_ENHKEY_USAGE
*usage
= (CERT_ENHKEY_USAGE
*)buf
;
4464 ok(size
>= sizeof(CERT_ENHKEY_USAGE
),
4465 "Wrong size %d\n", size
);
4466 ok(usage
->cUsageIdentifier
== sizeof(keyUsages
) / sizeof(keyUsages
[0]),
4467 "Wrong CRL entries count %d\n", usage
->cUsageIdentifier
);
4468 for (i
= 0; i
< usage
->cUsageIdentifier
; i
++)
4469 ok(!strcmp(usage
->rgpszUsageIdentifier
[i
], keyUsages
[i
]),
4470 "Expected OID %s, got %s\n", keyUsages
[i
],
4471 usage
->rgpszUsageIdentifier
[i
]);
4476 static BYTE keyId
[] = { 1,2,3,4 };
4477 static const BYTE authorityKeyIdWithId
[] = {
4478 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4479 static const BYTE authorityKeyIdWithIssuer
[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4480 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4481 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4482 static const BYTE authorityKeyIdWithSerial
[] = { 0x30,0x03,0x82,0x01,0x01 };
4484 static void test_encodeAuthorityKeyId(DWORD dwEncoding
)
4486 CERT_AUTHORITY_KEY_ID_INFO info
= { { 0 } };
4491 /* Test with empty id */
4492 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
, &info
,
4493 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4494 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4497 ok(size
== sizeof(emptySequence
), "Unexpected size %d\n", size
);
4498 ok(!memcmp(buf
, emptySequence
, size
), "Unexpected value\n");
4501 /* With just a key id */
4502 info
.KeyId
.cbData
= sizeof(keyId
);
4503 info
.KeyId
.pbData
= keyId
;
4504 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
, &info
,
4505 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4506 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4509 ok(size
== sizeof(authorityKeyIdWithId
), "Unexpected size %d\n", size
);
4510 ok(!memcmp(buf
, authorityKeyIdWithId
, size
), "Unexpected value\n");
4513 /* With just an issuer */
4514 info
.KeyId
.cbData
= 0;
4515 info
.CertIssuer
.cbData
= sizeof(encodedCommonName
);
4516 info
.CertIssuer
.pbData
= (BYTE
*)encodedCommonName
;
4517 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
, &info
,
4518 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4519 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4522 ok(size
== sizeof(authorityKeyIdWithIssuer
), "Unexpected size %d\n",
4524 ok(!memcmp(buf
, authorityKeyIdWithIssuer
, size
), "Unexpected value\n");
4527 /* With just a serial number */
4528 info
.CertIssuer
.cbData
= 0;
4529 info
.CertSerialNumber
.cbData
= sizeof(serialNum
);
4530 info
.CertSerialNumber
.pbData
= (BYTE
*)serialNum
;
4531 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
, &info
,
4532 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4533 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4536 ok(size
== sizeof(authorityKeyIdWithSerial
), "Unexpected size %d\n",
4538 ok(!memcmp(buf
, authorityKeyIdWithSerial
, size
), "Unexpected value\n");
4543 static void test_decodeAuthorityKeyId(DWORD dwEncoding
)
4549 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
,
4550 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4551 (BYTE
*)&buf
, &size
);
4552 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4555 CERT_AUTHORITY_KEY_ID_INFO
*info
= (CERT_AUTHORITY_KEY_ID_INFO
*)buf
;
4557 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID_INFO
), "Unexpected size %d\n",
4559 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
4560 ok(info
->CertIssuer
.cbData
== 0, "Expected no issuer name\n");
4561 ok(info
->CertSerialNumber
.cbData
== 0, "Expected no serial number\n");
4564 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
,
4565 authorityKeyIdWithId
, sizeof(authorityKeyIdWithId
),
4566 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4567 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4570 CERT_AUTHORITY_KEY_ID_INFO
*info
= (CERT_AUTHORITY_KEY_ID_INFO
*)buf
;
4572 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID_INFO
), "Unexpected size %d\n",
4574 ok(info
->KeyId
.cbData
== sizeof(keyId
), "Unexpected key id len\n");
4575 ok(!memcmp(info
->KeyId
.pbData
, keyId
, sizeof(keyId
)),
4576 "Unexpected key id\n");
4577 ok(info
->CertIssuer
.cbData
== 0, "Expected no issuer name\n");
4578 ok(info
->CertSerialNumber
.cbData
== 0, "Expected no serial number\n");
4581 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
,
4582 authorityKeyIdWithIssuer
, sizeof(authorityKeyIdWithIssuer
),
4583 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4584 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4587 CERT_AUTHORITY_KEY_ID_INFO
*info
= (CERT_AUTHORITY_KEY_ID_INFO
*)buf
;
4589 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID_INFO
), "Unexpected size %d\n",
4591 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
4592 ok(info
->CertIssuer
.cbData
== sizeof(encodedCommonName
),
4593 "Unexpected issuer len\n");
4594 ok(!memcmp(info
->CertIssuer
.pbData
, encodedCommonName
,
4595 sizeof(encodedCommonName
)), "Unexpected issuer\n");
4596 ok(info
->CertSerialNumber
.cbData
== 0, "Expected no serial number\n");
4599 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
,
4600 authorityKeyIdWithSerial
, sizeof(authorityKeyIdWithSerial
),
4601 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4602 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4605 CERT_AUTHORITY_KEY_ID_INFO
*info
= (CERT_AUTHORITY_KEY_ID_INFO
*)buf
;
4607 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID_INFO
), "Unexpected size %d\n",
4609 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
4610 ok(info
->CertIssuer
.cbData
== 0, "Expected no issuer name\n");
4611 ok(info
->CertSerialNumber
.cbData
== sizeof(serialNum
),
4612 "Unexpected serial number len\n");
4613 ok(!memcmp(info
->CertSerialNumber
.pbData
, serialNum
, sizeof(serialNum
)),
4614 "Unexpected serial number\n");
4619 static const BYTE authorityKeyIdWithIssuerUrl
[] = { 0x30,0x15,0xa1,0x13,0x86,
4620 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
4623 static void test_encodeAuthorityKeyId2(DWORD dwEncoding
)
4625 CERT_AUTHORITY_KEY_ID2_INFO info
= { { 0 } };
4626 CERT_ALT_NAME_ENTRY entry
= { 0 };
4631 /* Test with empty id */
4632 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
, &info
,
4633 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4634 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4637 ok(size
== sizeof(emptySequence
), "Unexpected size %d\n", size
);
4638 ok(!memcmp(buf
, emptySequence
, size
), "Unexpected value\n");
4641 /* With just a key id */
4642 info
.KeyId
.cbData
= sizeof(keyId
);
4643 info
.KeyId
.pbData
= keyId
;
4644 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
, &info
,
4645 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4646 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4649 ok(size
== sizeof(authorityKeyIdWithId
), "Unexpected size %d\n",
4651 ok(!memcmp(buf
, authorityKeyIdWithId
, size
), "Unexpected value\n");
4654 /* With a bogus issuer name */
4655 info
.KeyId
.cbData
= 0;
4656 info
.AuthorityCertIssuer
.cAltEntry
= 1;
4657 info
.AuthorityCertIssuer
.rgAltEntry
= &entry
;
4658 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
, &info
,
4659 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4660 ok(!ret
&& GetLastError() == E_INVALIDARG
,
4661 "Expected E_INVALIDARG, got %08x\n", GetLastError());
4662 /* With an issuer name */
4663 entry
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
4664 U(entry
).pwszURL
= (LPWSTR
)url
;
4665 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
, &info
,
4666 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4667 ok(ret
, "pCryptEncodeObjectEx failed: %08x\n", GetLastError());
4670 ok(size
== sizeof(authorityKeyIdWithIssuerUrl
), "Unexpected size %d\n",
4672 ok(!memcmp(buf
, authorityKeyIdWithIssuerUrl
, size
),
4673 "Unexpected value\n");
4676 /* With just a serial number */
4677 info
.AuthorityCertIssuer
.cAltEntry
= 0;
4678 info
.AuthorityCertSerialNumber
.cbData
= sizeof(serialNum
);
4679 info
.AuthorityCertSerialNumber
.pbData
= (BYTE
*)serialNum
;
4680 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
, &info
,
4681 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4682 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4685 ok(size
== sizeof(authorityKeyIdWithSerial
), "Unexpected size %d\n",
4687 ok(!memcmp(buf
, authorityKeyIdWithSerial
, size
), "Unexpected value\n");
4692 static void test_decodeAuthorityKeyId2(DWORD dwEncoding
)
4698 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
,
4699 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4700 (BYTE
*)&buf
, &size
);
4701 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4704 CERT_AUTHORITY_KEY_ID2_INFO
*info
= (CERT_AUTHORITY_KEY_ID2_INFO
*)buf
;
4706 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID2_INFO
), "Unexpected size %d\n",
4708 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
4709 ok(info
->AuthorityCertIssuer
.cAltEntry
== 0,
4710 "Expected no issuer name entries\n");
4711 ok(info
->AuthorityCertSerialNumber
.cbData
== 0,
4712 "Expected no serial number\n");
4715 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
,
4716 authorityKeyIdWithId
, sizeof(authorityKeyIdWithId
),
4717 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4718 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4721 CERT_AUTHORITY_KEY_ID2_INFO
*info
= (CERT_AUTHORITY_KEY_ID2_INFO
*)buf
;
4723 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID2_INFO
), "Unexpected size %d\n",
4725 ok(info
->KeyId
.cbData
== sizeof(keyId
), "Unexpected key id len\n");
4726 ok(!memcmp(info
->KeyId
.pbData
, keyId
, sizeof(keyId
)),
4727 "Unexpected key id\n");
4728 ok(info
->AuthorityCertIssuer
.cAltEntry
== 0,
4729 "Expected no issuer name entries\n");
4730 ok(info
->AuthorityCertSerialNumber
.cbData
== 0,
4731 "Expected no serial number\n");
4734 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
,
4735 authorityKeyIdWithIssuerUrl
, sizeof(authorityKeyIdWithIssuerUrl
),
4736 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4737 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4740 CERT_AUTHORITY_KEY_ID2_INFO
*info
= (CERT_AUTHORITY_KEY_ID2_INFO
*)buf
;
4742 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID2_INFO
), "Unexpected size %d\n",
4744 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
4745 ok(info
->AuthorityCertIssuer
.cAltEntry
== 1,
4746 "Expected 1 issuer entry, got %d\n",
4747 info
->AuthorityCertIssuer
.cAltEntry
);
4748 ok(info
->AuthorityCertIssuer
.rgAltEntry
[0].dwAltNameChoice
==
4749 CERT_ALT_NAME_URL
, "Expected CERT_ALT_NAME_URL, got %d\n",
4750 info
->AuthorityCertIssuer
.rgAltEntry
[0].dwAltNameChoice
);
4751 ok(!lstrcmpW(U(info
->AuthorityCertIssuer
.rgAltEntry
[0]).pwszURL
,
4752 url
), "Unexpected URL\n");
4753 ok(info
->AuthorityCertSerialNumber
.cbData
== 0,
4754 "Expected no serial number\n");
4757 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
,
4758 authorityKeyIdWithSerial
, sizeof(authorityKeyIdWithSerial
),
4759 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4760 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4763 CERT_AUTHORITY_KEY_ID2_INFO
*info
= (CERT_AUTHORITY_KEY_ID2_INFO
*)buf
;
4765 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID2_INFO
), "Unexpected size %d\n",
4767 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
4768 ok(info
->AuthorityCertIssuer
.cAltEntry
== 0,
4769 "Expected no issuer name entries\n");
4770 ok(info
->AuthorityCertSerialNumber
.cbData
== sizeof(serialNum
),
4771 "Unexpected serial number len\n");
4772 ok(!memcmp(info
->AuthorityCertSerialNumber
.pbData
, serialNum
,
4773 sizeof(serialNum
)), "Unexpected serial number\n");
4778 static const BYTE authorityInfoAccessWithUrl
[] = {
4779 0x30,0x19,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
4780 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
4781 static const BYTE authorityInfoAccessWithUrlAndIPAddr
[] = {
4782 0x30,0x29,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
4783 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x0e,0x06,
4784 0x02,0x2d,0x06,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
4786 static void test_encodeAuthorityInfoAccess(DWORD dwEncoding
)
4788 static char oid1
[] = "1.2.3";
4789 static char oid2
[] = "1.5.6";
4793 CERT_ACCESS_DESCRIPTION accessDescription
[2];
4794 CERT_AUTHORITY_INFO_ACCESS aia
;
4796 memset(accessDescription
, 0, sizeof(accessDescription
));
4798 aia
.rgAccDescr
= NULL
;
4799 /* Having no access descriptions is allowed */
4800 ret
= CryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
, &aia
,
4801 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4802 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4805 ok(size
== sizeof(emptySequence
), "unexpected size %d\n", size
);
4806 ok(!memcmp(buf
, emptySequence
, size
), "unexpected value\n");
4810 /* It can't have an empty access method */
4812 aia
.rgAccDescr
= accessDescription
;
4813 ret
= CryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
, &aia
,
4814 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4815 ok(!ret
&& GetLastError() == E_INVALIDARG
,
4816 "expected E_INVALIDARG, got %08x\n", GetLastError());
4817 /* It can't have an empty location */
4818 accessDescription
[0].pszAccessMethod
= oid1
;
4819 SetLastError(0xdeadbeef);
4820 ret
= CryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
, &aia
,
4821 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4822 ok(!ret
&& GetLastError() == E_INVALIDARG
,
4823 "expected E_INVALIDARG, got %08x\n", GetLastError());
4824 accessDescription
[0].AccessLocation
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
4825 accessDescription
[0].AccessLocation
.pwszURL
= (LPWSTR
)url
;
4826 ret
= CryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
, &aia
,
4827 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4828 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4831 ok(size
== sizeof(authorityInfoAccessWithUrl
), "unexpected size %d\n",
4833 ok(!memcmp(buf
, authorityInfoAccessWithUrl
, size
),
4834 "unexpected value\n");
4838 accessDescription
[1].pszAccessMethod
= oid2
;
4839 accessDescription
[1].AccessLocation
.dwAltNameChoice
=
4840 CERT_ALT_NAME_IP_ADDRESS
;
4841 accessDescription
[1].AccessLocation
.IPAddress
.cbData
=
4842 sizeof(encodedIPAddr
);
4843 accessDescription
[1].AccessLocation
.IPAddress
.pbData
=
4844 (LPBYTE
)encodedIPAddr
;
4846 ret
= CryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
, &aia
,
4847 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4848 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4851 ok(size
== sizeof(authorityInfoAccessWithUrlAndIPAddr
),
4852 "unexpected size %d\n", size
);
4853 ok(!memcmp(buf
, authorityInfoAccessWithUrlAndIPAddr
, size
),
4854 "unexpected value\n");
4860 static void compareAuthorityInfoAccess(LPCSTR header
,
4861 const CERT_AUTHORITY_INFO_ACCESS
*expected
,
4862 const CERT_AUTHORITY_INFO_ACCESS
*got
)
4866 ok(expected
->cAccDescr
== got
->cAccDescr
,
4867 "%s: expected %d access descriptions, got %d\n", header
,
4868 expected
->cAccDescr
, got
->cAccDescr
);
4869 for (i
= 0; i
< expected
->cAccDescr
; i
++)
4871 ok(!strcmp(expected
->rgAccDescr
[i
].pszAccessMethod
,
4872 got
->rgAccDescr
[i
].pszAccessMethod
), "%s[%d]: expected %s, got %s\n",
4873 header
, i
, expected
->rgAccDescr
[i
].pszAccessMethod
,
4874 got
->rgAccDescr
[i
].pszAccessMethod
);
4875 compareAltNameEntry(&expected
->rgAccDescr
[i
].AccessLocation
,
4876 &got
->rgAccDescr
[i
].AccessLocation
);
4880 static void test_decodeAuthorityInfoAccess(DWORD dwEncoding
)
4882 static char oid1
[] = "1.2.3";
4883 static char oid2
[] = "1.5.6";
4888 ret
= CryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
,
4889 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4890 (BYTE
*)&buf
, &size
);
4892 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4895 CERT_AUTHORITY_INFO_ACCESS aia
= { 0, NULL
};
4897 compareAuthorityInfoAccess("empty AIA", &aia
,
4898 (CERT_AUTHORITY_INFO_ACCESS
*)buf
);
4902 ret
= CryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
,
4903 authorityInfoAccessWithUrl
, sizeof(authorityInfoAccessWithUrl
),
4904 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4906 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4909 CERT_ACCESS_DESCRIPTION accessDescription
;
4910 CERT_AUTHORITY_INFO_ACCESS aia
;
4912 accessDescription
.pszAccessMethod
= oid1
;
4913 accessDescription
.AccessLocation
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
4914 accessDescription
.AccessLocation
.pwszURL
= (LPWSTR
)url
;
4916 aia
.rgAccDescr
= &accessDescription
;
4917 compareAuthorityInfoAccess("AIA with URL", &aia
,
4918 (CERT_AUTHORITY_INFO_ACCESS
*)buf
);
4922 ret
= CryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
,
4923 authorityInfoAccessWithUrlAndIPAddr
,
4924 sizeof(authorityInfoAccessWithUrlAndIPAddr
), CRYPT_DECODE_ALLOC_FLAG
,
4925 NULL
, (BYTE
*)&buf
, &size
);
4927 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4930 CERT_ACCESS_DESCRIPTION accessDescription
[2];
4931 CERT_AUTHORITY_INFO_ACCESS aia
;
4933 accessDescription
[0].pszAccessMethod
= oid1
;
4934 accessDescription
[0].AccessLocation
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
4935 accessDescription
[0].AccessLocation
.pwszURL
= (LPWSTR
)url
;
4936 accessDescription
[1].pszAccessMethod
= oid2
;
4937 accessDescription
[1].AccessLocation
.dwAltNameChoice
=
4938 CERT_ALT_NAME_IP_ADDRESS
;
4939 accessDescription
[1].AccessLocation
.IPAddress
.cbData
=
4940 sizeof(encodedIPAddr
);
4941 accessDescription
[1].AccessLocation
.IPAddress
.pbData
=
4942 (LPBYTE
)encodedIPAddr
;
4944 aia
.rgAccDescr
= accessDescription
;
4945 compareAuthorityInfoAccess("AIA with URL and IP addr", &aia
,
4946 (CERT_AUTHORITY_INFO_ACCESS
*)buf
);
4952 static const BYTE emptyPKCSContentInfo
[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
4953 static const BYTE emptyPKCSContentInfoExtraBytes
[] = { 0x30,0x04,0x06,0x02,0x2a,
4955 static const BYTE bogusPKCSContentInfo
[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
4957 static const BYTE intPKCSContentInfo
[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
4958 0x03,0x02,0x01,0x01 };
4959 static BYTE bogusDER
[] = { 1 };
4961 static void test_encodePKCSContentInfo(DWORD dwEncoding
)
4966 CRYPT_CONTENT_INFO info
= { 0 };
4967 char oid1
[] = "1.2.3";
4969 SetLastError(0xdeadbeef);
4970 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
, NULL
,
4971 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4972 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
4973 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
4974 SetLastError(0xdeadbeef);
4975 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
, &info
,
4976 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4977 ok(!ret
&& GetLastError() == E_INVALIDARG
,
4978 "Expected E_INVALIDARG, got %x\n", GetLastError());
4979 info
.pszObjId
= oid1
;
4980 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
, &info
,
4981 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4982 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
4985 ok(size
== sizeof(emptyPKCSContentInfo
), "Unexpected size %d\n", size
);
4986 ok(!memcmp(buf
, emptyPKCSContentInfo
, size
), "Unexpected value\n");
4989 info
.Content
.pbData
= bogusDER
;
4990 info
.Content
.cbData
= sizeof(bogusDER
);
4991 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
, &info
,
4992 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4993 ok(ret
, "CryptEncodeObjectEx failed; %x\n", GetLastError());
4996 ok(size
== sizeof(bogusPKCSContentInfo
), "Unexpected size %d\n", size
);
4997 ok(!memcmp(buf
, bogusPKCSContentInfo
, size
), "Unexpected value\n");
5000 info
.Content
.pbData
= (BYTE
*)ints
[0].encoded
;
5001 info
.Content
.cbData
= ints
[0].encoded
[1] + 2;
5002 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
, &info
,
5003 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5006 ok(size
== sizeof(intPKCSContentInfo
), "Unexpected size %d\n", size
);
5007 ok(!memcmp(buf
, intPKCSContentInfo
, size
), "Unexpected value\n");
5012 static const BYTE indefiniteSignedPKCSContent
[] = {
5013 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
5014 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
5015 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
5016 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
5017 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
5018 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
5019 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5020 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5021 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
5022 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5023 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5024 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
5025 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
5026 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
5027 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
5028 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
5029 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
5030 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
5031 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
5032 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5033 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5034 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
5035 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
5036 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
5037 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
5038 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
5039 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
5040 0x00,0x00,0x00,0x00,0x00,0x00 };
5042 static void test_decodePKCSContentInfo(DWORD dwEncoding
)
5047 CRYPT_CONTENT_INFO
*info
;
5049 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
,
5050 emptyPKCSContentInfo
, sizeof(emptyPKCSContentInfo
),
5051 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5052 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5055 info
= (CRYPT_CONTENT_INFO
*)buf
;
5057 ok(!strcmp(info
->pszObjId
, "1.2.3"), "Expected 1.2.3, got %s\n",
5059 ok(info
->Content
.cbData
== 0, "Expected no data, got %d\n",
5060 info
->Content
.cbData
);
5063 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
,
5064 emptyPKCSContentInfoExtraBytes
, sizeof(emptyPKCSContentInfoExtraBytes
),
5065 0, NULL
, NULL
, &size
);
5066 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5067 SetLastError(0xdeadbeef);
5068 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
,
5069 bogusPKCSContentInfo
, sizeof(bogusPKCSContentInfo
),
5070 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5071 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5072 * I doubt an app depends on that.
5074 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_EOD
||
5075 GetLastError() == CRYPT_E_ASN1_CORRUPT
),
5076 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5078 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
,
5079 intPKCSContentInfo
, sizeof(intPKCSContentInfo
),
5080 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5081 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5084 info
= (CRYPT_CONTENT_INFO
*)buf
;
5086 ok(!strcmp(info
->pszObjId
, "1.2.3"), "Expected 1.2.3, got %s\n",
5088 ok(info
->Content
.cbData
== ints
[0].encoded
[1] + 2,
5089 "Unexpected size %d\n", info
->Content
.cbData
);
5090 ok(!memcmp(info
->Content
.pbData
, ints
[0].encoded
,
5091 info
->Content
.cbData
), "Unexpected value\n");
5094 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
,
5095 indefiniteSignedPKCSContent
, sizeof(indefiniteSignedPKCSContent
),
5096 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5097 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5100 info
= (CRYPT_CONTENT_INFO
*)buf
;
5102 ok(!strcmp(info
->pszObjId
, szOID_RSA_signedData
),
5103 "Expected %s, got %s\n", szOID_RSA_signedData
, info
->pszObjId
);
5104 ok(info
->Content
.cbData
== 392, "Expected 392, got %d\n",
5105 info
->Content
.cbData
);
5110 static const BYTE emptyPKCSAttr
[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
5112 static const BYTE bogusPKCSAttr
[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
5114 static const BYTE intPKCSAttr
[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
5117 static void test_encodePKCSAttribute(DWORD dwEncoding
)
5119 CRYPT_ATTRIBUTE attr
= { 0 };
5123 CRYPT_ATTR_BLOB blob
;
5124 char oid
[] = "1.2.3";
5126 SetLastError(0xdeadbeef);
5127 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
, NULL
,
5128 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5129 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
5130 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5131 SetLastError(0xdeadbeef);
5132 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
, &attr
,
5133 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5134 ok(!ret
&& GetLastError() == E_INVALIDARG
,
5135 "Expected E_INVALIDARG, got %x\n", GetLastError());
5136 attr
.pszObjId
= oid
;
5137 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
, &attr
,
5138 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5139 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5142 ok(size
== sizeof(emptyPKCSAttr
), "Unexpected size %d\n", size
);
5143 ok(!memcmp(buf
, emptyPKCSAttr
, size
), "Unexpected value\n");
5146 blob
.cbData
= sizeof(bogusDER
);
5147 blob
.pbData
= bogusDER
;
5149 attr
.rgValue
= &blob
;
5150 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
, &attr
,
5151 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5152 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5155 ok(size
== sizeof(bogusPKCSAttr
), "Unexpected size %d\n", size
);
5156 ok(!memcmp(buf
, bogusPKCSAttr
, size
), "Unexpected value\n");
5159 blob
.pbData
= (BYTE
*)ints
[0].encoded
;
5160 blob
.cbData
= ints
[0].encoded
[1] + 2;
5161 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
, &attr
,
5162 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5165 ok(size
== sizeof(intPKCSAttr
), "Unexpected size %d\n", size
);
5166 ok(!memcmp(buf
, intPKCSAttr
, size
), "Unexpected value\n");
5171 static void test_decodePKCSAttribute(DWORD dwEncoding
)
5176 CRYPT_ATTRIBUTE
*attr
;
5178 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
,
5179 emptyPKCSAttr
, sizeof(emptyPKCSAttr
),
5180 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5181 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5184 attr
= (CRYPT_ATTRIBUTE
*)buf
;
5186 ok(!strcmp(attr
->pszObjId
, "1.2.3"), "Expected 1.2.3, got %s\n",
5188 ok(attr
->cValue
== 0, "Expected no value, got %d\n", attr
->cValue
);
5191 SetLastError(0xdeadbeef);
5192 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
,
5193 bogusPKCSAttr
, sizeof(bogusPKCSAttr
),
5194 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5195 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5196 * I doubt an app depends on that.
5198 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_EOD
||
5199 GetLastError() == CRYPT_E_ASN1_CORRUPT
),
5200 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5202 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
,
5203 intPKCSAttr
, sizeof(intPKCSAttr
),
5204 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5205 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5208 attr
= (CRYPT_ATTRIBUTE
*)buf
;
5210 ok(!strcmp(attr
->pszObjId
, "1.2.3"), "Expected 1.2.3, got %s\n",
5212 ok(attr
->cValue
== 1, "Expected 1 value, got %d\n", attr
->cValue
);
5213 ok(attr
->rgValue
[0].cbData
== ints
[0].encoded
[1] + 2,
5214 "Unexpected size %d\n", attr
->rgValue
[0].cbData
);
5215 ok(!memcmp(attr
->rgValue
[0].pbData
, ints
[0].encoded
,
5216 attr
->rgValue
[0].cbData
), "Unexpected value\n");
5221 static const BYTE emptyPKCSAttributes
[] = { 0x31,0x00 };
5222 static const BYTE singlePKCSAttributes
[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
5223 0x2a,0x03,0x31,0x00 };
5224 static const BYTE doublePKCSAttributes
[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
5225 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
5227 static void test_encodePKCSAttributes(DWORD dwEncoding
)
5229 CRYPT_ATTRIBUTES attributes
= { 0 };
5230 CRYPT_ATTRIBUTE attr
[2] = { { 0 } };
5231 CRYPT_ATTR_BLOB blob
;
5235 char oid1
[] = "1.2.3", oid2
[] = "1.5.6";
5237 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
, &attributes
,
5238 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5239 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5242 ok(size
== sizeof(emptyPKCSAttributes
), "Unexpected size %d\n", size
);
5243 ok(!memcmp(buf
, emptyPKCSAttributes
, size
), "Unexpected value\n");
5246 attributes
.cAttr
= 1;
5247 attributes
.rgAttr
= attr
;
5248 SetLastError(0xdeadbeef);
5249 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
, &attributes
,
5250 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5251 ok(!ret
&& GetLastError() == E_INVALIDARG
,
5252 "Expected E_INVALIDARG, got %x\n", GetLastError());
5253 attr
[0].pszObjId
= oid1
;
5254 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
, &attributes
,
5255 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5258 ok(size
== sizeof(singlePKCSAttributes
), "Unexpected size %d\n", size
);
5259 ok(!memcmp(buf
, singlePKCSAttributes
, size
), "Unexpected value\n");
5262 attr
[1].pszObjId
= oid2
;
5264 attr
[1].rgValue
= &blob
;
5265 blob
.pbData
= (BYTE
*)ints
[0].encoded
;
5266 blob
.cbData
= ints
[0].encoded
[1] + 2;
5267 attributes
.cAttr
= 2;
5268 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
, &attributes
,
5269 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5270 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5273 ok(size
== sizeof(doublePKCSAttributes
), "Unexpected size %d\n", size
);
5274 ok(!memcmp(buf
, doublePKCSAttributes
, size
), "Unexpected value\n");
5279 static void test_decodePKCSAttributes(DWORD dwEncoding
)
5284 CRYPT_ATTRIBUTES
*attributes
;
5286 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
,
5287 emptyPKCSAttributes
, sizeof(emptyPKCSAttributes
),
5288 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5289 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5292 attributes
= (CRYPT_ATTRIBUTES
*)buf
;
5293 ok(attributes
->cAttr
== 0, "Expected no attributes, got %d\n",
5297 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
,
5298 singlePKCSAttributes
, sizeof(singlePKCSAttributes
),
5299 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5300 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5303 attributes
= (CRYPT_ATTRIBUTES
*)buf
;
5304 ok(attributes
->cAttr
== 1, "Expected 1 attribute, got %d\n",
5306 ok(!strcmp(attributes
->rgAttr
[0].pszObjId
, "1.2.3"),
5307 "Expected 1.2.3, got %s\n", attributes
->rgAttr
[0].pszObjId
);
5308 ok(attributes
->rgAttr
[0].cValue
== 0,
5309 "Expected no attributes, got %d\n", attributes
->rgAttr
[0].cValue
);
5312 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
,
5313 doublePKCSAttributes
, sizeof(doublePKCSAttributes
),
5314 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5315 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5318 attributes
= (CRYPT_ATTRIBUTES
*)buf
;
5319 ok(attributes
->cAttr
== 2, "Expected 2 attributes, got %d\n",
5321 ok(!strcmp(attributes
->rgAttr
[0].pszObjId
, "1.2.3"),
5322 "Expected 1.2.3, got %s\n", attributes
->rgAttr
[0].pszObjId
);
5323 ok(attributes
->rgAttr
[0].cValue
== 0,
5324 "Expected no attributes, got %d\n", attributes
->rgAttr
[0].cValue
);
5325 ok(!strcmp(attributes
->rgAttr
[1].pszObjId
, "1.5.6"),
5326 "Expected 1.5.6, got %s\n", attributes
->rgAttr
[1].pszObjId
);
5327 ok(attributes
->rgAttr
[1].cValue
== 1,
5328 "Expected 1 attribute, got %d\n", attributes
->rgAttr
[1].cValue
);
5329 ok(attributes
->rgAttr
[1].rgValue
[0].cbData
== ints
[0].encoded
[1] + 2,
5330 "Unexpected size %d\n", attributes
->rgAttr
[1].rgValue
[0].cbData
);
5331 ok(!memcmp(attributes
->rgAttr
[1].rgValue
[0].pbData
, ints
[0].encoded
,
5332 attributes
->rgAttr
[1].rgValue
[0].cbData
), "Unexpected value\n");
5337 static const BYTE singleCapability
[] = {
5338 0x30,0x06,0x30,0x04,0x06,0x02,0x2d,0x06 };
5339 static const BYTE twoCapabilities
[] = {
5340 0x30,0x0c,0x30,0x04,0x06,0x02,0x2d,0x06,0x30,0x04,0x06,0x02,0x2a,0x03 };
5341 static const BYTE singleCapabilitywithNULL
[] = {
5342 0x30,0x08,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5344 static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding
)
5346 static char oid1
[] = "1.5.6", oid2
[] = "1.2.3";
5350 CRYPT_SMIME_CAPABILITY capability
[2];
5351 CRYPT_SMIME_CAPABILITIES capabilities
;
5353 /* An empty capabilities is allowed */
5354 capabilities
.cCapability
= 0;
5355 ret
= CryptEncodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
5356 &capabilities
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5357 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5360 ok(size
== sizeof(emptySequence
), "unexpected size %d\n", size
);
5361 ok(!memcmp(buf
, emptySequence
, size
), "unexpected value\n");
5364 /* A non-empty capabilities with an empty capability (lacking an OID) is
5367 capability
[0].pszObjId
= NULL
;
5368 capability
[0].Parameters
.cbData
= 0;
5369 capabilities
.cCapability
= 1;
5370 capabilities
.rgCapability
= capability
;
5371 SetLastError(0xdeadbeef);
5372 ret
= CryptEncodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
5373 &capabilities
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5374 ok(!ret
&& GetLastError() == E_INVALIDARG
,
5375 "expected E_INVALIDARG, got %08x\n", GetLastError());
5376 capability
[0].pszObjId
= oid1
;
5377 ret
= CryptEncodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
5378 &capabilities
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5379 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5382 ok(size
== sizeof(singleCapability
), "unexpected size %d\n", size
);
5383 ok(!memcmp(buf
, singleCapability
, size
), "unexpected value\n");
5386 capability
[1].pszObjId
= oid2
;
5387 capability
[1].Parameters
.cbData
= 0;
5388 capabilities
.cCapability
= 2;
5389 ret
= CryptEncodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
5390 &capabilities
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5391 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5394 ok(size
== sizeof(twoCapabilities
), "unexpected size %d\n", size
);
5395 ok(!memcmp(buf
, twoCapabilities
, size
), "unexpected value\n");
5400 static void compareSMimeCapabilities(LPCSTR header
,
5401 const CRYPT_SMIME_CAPABILITIES
*expected
, const CRYPT_SMIME_CAPABILITIES
*got
)
5405 ok(got
->cCapability
== expected
->cCapability
,
5406 "%s: expected %d capabilities, got %d\n", header
, expected
->cCapability
,
5408 for (i
= 0; i
< expected
->cCapability
; i
++)
5410 ok(!strcmp(expected
->rgCapability
[i
].pszObjId
,
5411 got
->rgCapability
[i
].pszObjId
), "%s[%d]: expected %s, got %s\n",
5412 header
, i
, expected
->rgCapability
[i
].pszObjId
,
5413 got
->rgCapability
[i
].pszObjId
);
5414 ok(expected
->rgCapability
[i
].Parameters
.cbData
==
5415 got
->rgCapability
[i
].Parameters
.cbData
,
5416 "%s[%d]: expected %d bytes, got %d\n", header
, i
,
5417 expected
->rgCapability
[i
].Parameters
.cbData
,
5418 got
->rgCapability
[i
].Parameters
.cbData
);
5419 if (expected
->rgCapability
[i
].Parameters
.cbData
)
5420 ok(!memcmp(expected
->rgCapability
[i
].Parameters
.pbData
,
5421 got
->rgCapability
[i
].Parameters
.pbData
,
5422 expected
->rgCapability
[i
].Parameters
.cbData
),
5423 "%s[%d]: unexpected value\n", header
, i
);
5427 static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding
)
5429 static char oid1
[] = "1.5.6", oid2
[] = "1.2.3";
5432 CRYPT_SMIME_CAPABILITY capability
[2];
5433 CRYPT_SMIME_CAPABILITIES capabilities
, *ptr
;
5435 SetLastError(0xdeadbeef);
5436 ret
= CryptDecodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
5437 emptySequence
, sizeof(emptySequence
),
5438 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&ptr
, &size
);
5439 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5442 capabilities
.cCapability
= 0;
5443 compareSMimeCapabilities("empty capabilities", &capabilities
, ptr
);
5446 SetLastError(0xdeadbeef);
5447 ret
= CryptDecodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
5448 singleCapability
, sizeof(singleCapability
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5449 (BYTE
*)&ptr
, &size
);
5450 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5453 capability
[0].pszObjId
= oid1
;
5454 capability
[0].Parameters
.cbData
= 0;
5455 capabilities
.cCapability
= 1;
5456 capabilities
.rgCapability
= capability
;
5457 compareSMimeCapabilities("single capability", &capabilities
, ptr
);
5460 SetLastError(0xdeadbeef);
5461 ret
= CryptDecodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
5462 singleCapabilitywithNULL
, sizeof(singleCapabilitywithNULL
),
5463 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&ptr
, &size
);
5464 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5467 BYTE NULLparam
[] = {0x05, 0x00};
5468 capability
[0].pszObjId
= oid1
;
5469 capability
[0].Parameters
.cbData
= 2;
5470 capability
[0].Parameters
.pbData
= NULLparam
;
5471 capabilities
.cCapability
= 1;
5472 capabilities
.rgCapability
= capability
;
5473 compareSMimeCapabilities("single capability with NULL", &capabilities
,
5477 SetLastError(0xdeadbeef);
5478 ret
= CryptDecodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
5479 twoCapabilities
, sizeof(twoCapabilities
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5480 (BYTE
*)&ptr
, &size
);
5481 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5484 capability
[0].Parameters
.cbData
= 0;
5485 capability
[1].pszObjId
= oid2
;
5486 capability
[1].Parameters
.cbData
= 0;
5487 capabilities
.cCapability
= 2;
5488 compareSMimeCapabilities("two capabilities", &capabilities
, ptr
);
5493 static BYTE encodedCommonNameNoNull
[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
5494 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5496 static const BYTE minimalPKCSSigner
[] = {
5497 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5498 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5499 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
5500 static const BYTE PKCSSignerWithSerial
[] = {
5501 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5502 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5503 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5505 static const BYTE PKCSSignerWithHashAlgo
[] = {
5506 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5507 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5508 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5510 static const BYTE PKCSSignerWithHashAndEncryptionAlgo
[] = {
5511 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5512 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5513 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
5514 0x06,0x05,0x00,0x04,0x00 };
5515 static const BYTE PKCSSignerWithHash
[] = {
5516 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5517 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5518 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
5519 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
5520 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
5521 static const BYTE PKCSSignerWithAuthAttr
[] = {
5522 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5523 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5524 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
5525 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
5526 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
5527 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
5528 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
5530 static void test_encodePKCSSignerInfo(DWORD dwEncoding
)
5532 static char oid1
[] = "1.2.3", oid2
[] = "1.5.6";
5536 CMSG_SIGNER_INFO info
= { 0 };
5537 char oid_common_name
[] = szOID_COMMON_NAME
;
5538 CRYPT_ATTR_BLOB commonName
= { sizeof(encodedCommonName
),
5539 (LPBYTE
)encodedCommonName
};
5540 CRYPT_ATTRIBUTE attr
= { oid_common_name
, 1, &commonName
};
5542 SetLastError(0xdeadbeef);
5543 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
5544 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5545 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
5547 skip("no PKCS7_SIGNER_INFO encode support\n");
5550 ok(!ret
&& GetLastError() == E_INVALIDARG
,
5551 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5552 /* To be encoded, a signer must have an issuer at least, and the encoding
5553 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
5554 * see decoding tests.)
5556 info
.Issuer
.cbData
= sizeof(encodedCommonNameNoNull
);
5557 info
.Issuer
.pbData
= encodedCommonNameNoNull
;
5558 SetLastError(0xdeadbeef);
5559 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
5560 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5561 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
5562 ok(!ret
&& GetLastError() == E_INVALIDARG
,
5563 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5566 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5569 ok(size
== sizeof(minimalPKCSSigner
), "Unexpected size %d\n", size
);
5570 if (size
== sizeof(minimalPKCSSigner
))
5571 ok(!memcmp(buf
, minimalPKCSSigner
, size
), "Unexpected value\n");
5573 ok(0, "Unexpected value\n");
5577 info
.SerialNumber
.cbData
= sizeof(serialNum
);
5578 info
.SerialNumber
.pbData
= (BYTE
*)serialNum
;
5579 SetLastError(0xdeadbeef);
5580 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
5581 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5582 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
5583 ok(!ret
&& GetLastError() == E_INVALIDARG
,
5584 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5587 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5590 ok(size
== sizeof(PKCSSignerWithSerial
), "Unexpected size %d\n",
5592 if (size
== sizeof(PKCSSignerWithSerial
))
5593 ok(!memcmp(buf
, PKCSSignerWithSerial
, size
),
5594 "Unexpected value\n");
5596 ok(0, "Unexpected value\n");
5600 info
.HashAlgorithm
.pszObjId
= oid1
;
5601 SetLastError(0xdeadbeef);
5602 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
5603 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5604 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
5605 ok(!ret
&& GetLastError() == E_INVALIDARG
,
5606 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5609 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5612 ok(size
== sizeof(PKCSSignerWithHashAlgo
), "Unexpected size %d\n",
5614 if (size
== sizeof(PKCSSignerWithHashAlgo
))
5615 ok(!memcmp(buf
, PKCSSignerWithHashAlgo
, size
),
5616 "Unexpected value\n");
5618 ok(0, "Unexpected value\n");
5622 info
.HashEncryptionAlgorithm
.pszObjId
= oid2
;
5623 SetLastError(0xdeadbeef);
5624 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
5625 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5626 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
5627 ok(!ret
&& GetLastError() == E_INVALIDARG
,
5628 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5631 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5634 ok(size
== sizeof(PKCSSignerWithHashAndEncryptionAlgo
),
5635 "Unexpected size %d\n", size
);
5636 if (size
== sizeof(PKCSSignerWithHashAndEncryptionAlgo
))
5637 ok(!memcmp(buf
, PKCSSignerWithHashAndEncryptionAlgo
, size
),
5638 "Unexpected value\n");
5640 ok(0, "Unexpected value\n");
5644 info
.EncryptedHash
.cbData
= sizeof(hash
);
5645 info
.EncryptedHash
.pbData
= (BYTE
*)hash
;
5646 SetLastError(0xdeadbeef);
5647 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
5648 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5649 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
5650 ok(!ret
&& GetLastError() == E_INVALIDARG
,
5651 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5654 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5657 ok(size
== sizeof(PKCSSignerWithHash
), "Unexpected size %d\n",
5659 if (size
== sizeof(PKCSSignerWithHash
))
5660 ok(!memcmp(buf
, PKCSSignerWithHash
, size
),
5661 "Unexpected value\n");
5663 ok(0, "Unexpected value\n");
5667 info
.AuthAttrs
.cAttr
= 1;
5668 info
.AuthAttrs
.rgAttr
= &attr
;
5669 SetLastError(0xdeadbeef);
5670 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
5671 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5672 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
5673 ok(!ret
&& GetLastError() == E_INVALIDARG
,
5674 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5677 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5680 ok(size
== sizeof(PKCSSignerWithAuthAttr
), "Unexpected size %d\n",
5682 if (size
== sizeof(PKCSSignerWithAuthAttr
))
5683 ok(!memcmp(buf
, PKCSSignerWithAuthAttr
, size
),
5684 "Unexpected value\n");
5686 ok(0, "Unexpected value\n");
5692 static void test_decodePKCSSignerInfo(DWORD dwEncoding
)
5697 CMSG_SIGNER_INFO
*info
;
5699 /* A PKCS signer can't be decoded without a serial number. */
5700 SetLastError(0xdeadbeef);
5701 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
5702 minimalPKCSSigner
, sizeof(minimalPKCSSigner
),
5703 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5704 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_CORRUPT
,
5705 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
5706 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
5707 PKCSSignerWithSerial
, sizeof(PKCSSignerWithSerial
),
5708 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5709 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5712 info
= (CMSG_SIGNER_INFO
*)buf
;
5713 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
5715 ok(info
->Issuer
.cbData
== sizeof(encodedCommonNameNoNull
),
5716 "Unexpected size %d\n", info
->Issuer
.cbData
);
5717 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonNameNoNull
,
5718 info
->Issuer
.cbData
), "Unexpected value\n");
5719 ok(info
->SerialNumber
.cbData
== sizeof(serialNum
),
5720 "Unexpected size %d\n", info
->SerialNumber
.cbData
);
5721 ok(!memcmp(info
->SerialNumber
.pbData
, serialNum
, sizeof(serialNum
)),
5722 "Unexpected value\n");
5725 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
5726 PKCSSignerWithHashAlgo
, sizeof(PKCSSignerWithHashAlgo
),
5727 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5730 info
= (CMSG_SIGNER_INFO
*)buf
;
5731 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
5733 ok(info
->Issuer
.cbData
== sizeof(encodedCommonNameNoNull
),
5734 "Unexpected size %d\n", info
->Issuer
.cbData
);
5735 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonNameNoNull
,
5736 info
->Issuer
.cbData
), "Unexpected value\n");
5737 ok(info
->SerialNumber
.cbData
== sizeof(serialNum
),
5738 "Unexpected size %d\n", info
->SerialNumber
.cbData
);
5739 ok(!memcmp(info
->SerialNumber
.pbData
, serialNum
, sizeof(serialNum
)),
5740 "Unexpected value\n");
5741 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, "1.2.3"),
5742 "Expected 1.2.3, got %s\n", info
->HashAlgorithm
.pszObjId
);
5745 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
5746 PKCSSignerWithHashAndEncryptionAlgo
,
5747 sizeof(PKCSSignerWithHashAndEncryptionAlgo
), CRYPT_DECODE_ALLOC_FLAG
,
5748 NULL
, (BYTE
*)&buf
, &size
);
5751 info
= (CMSG_SIGNER_INFO
*)buf
;
5752 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
5754 ok(info
->Issuer
.cbData
== sizeof(encodedCommonNameNoNull
),
5755 "Unexpected size %d\n", info
->Issuer
.cbData
);
5756 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonNameNoNull
,
5757 info
->Issuer
.cbData
), "Unexpected value\n");
5758 ok(info
->SerialNumber
.cbData
== sizeof(serialNum
),
5759 "Unexpected size %d\n", info
->SerialNumber
.cbData
);
5760 ok(!memcmp(info
->SerialNumber
.pbData
, serialNum
, sizeof(serialNum
)),
5761 "Unexpected value\n");
5762 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, "1.2.3"),
5763 "Expected 1.2.3, got %s\n", info
->HashAlgorithm
.pszObjId
);
5764 ok(!strcmp(info
->HashEncryptionAlgorithm
.pszObjId
, "1.5.6"),
5765 "Expected 1.5.6, got %s\n", info
->HashEncryptionAlgorithm
.pszObjId
);
5768 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
5769 PKCSSignerWithHash
, sizeof(PKCSSignerWithHash
),
5770 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5773 info
= (CMSG_SIGNER_INFO
*)buf
;
5774 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
5776 ok(info
->Issuer
.cbData
== sizeof(encodedCommonNameNoNull
),
5777 "Unexpected size %d\n", info
->Issuer
.cbData
);
5778 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonNameNoNull
,
5779 info
->Issuer
.cbData
), "Unexpected value\n");
5780 ok(info
->SerialNumber
.cbData
== sizeof(serialNum
),
5781 "Unexpected size %d\n", info
->SerialNumber
.cbData
);
5782 ok(!memcmp(info
->SerialNumber
.pbData
, serialNum
, sizeof(serialNum
)),
5783 "Unexpected value\n");
5784 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, "1.2.3"),
5785 "Expected 1.2.3, got %s\n", info
->HashAlgorithm
.pszObjId
);
5786 ok(!strcmp(info
->HashEncryptionAlgorithm
.pszObjId
, "1.5.6"),
5787 "Expected 1.5.6, got %s\n", info
->HashEncryptionAlgorithm
.pszObjId
);
5788 ok(info
->EncryptedHash
.cbData
== sizeof(hash
), "Unexpected size %d\n",
5789 info
->EncryptedHash
.cbData
);
5790 ok(!memcmp(info
->EncryptedHash
.pbData
, hash
, sizeof(hash
)),
5791 "Unexpected value\n");
5794 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
5795 PKCSSignerWithAuthAttr
, sizeof(PKCSSignerWithAuthAttr
),
5796 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5799 info
= (CMSG_SIGNER_INFO
*)buf
;
5800 ok(info
->AuthAttrs
.cAttr
== 1, "Expected 1 attribute, got %d\n",
5801 info
->AuthAttrs
.cAttr
);
5802 ok(!strcmp(info
->AuthAttrs
.rgAttr
[0].pszObjId
, szOID_COMMON_NAME
),
5803 "Expected %s, got %s\n", szOID_COMMON_NAME
,
5804 info
->AuthAttrs
.rgAttr
[0].pszObjId
);
5805 ok(info
->AuthAttrs
.rgAttr
[0].cValue
== 1, "Expected 1 value, got %d\n",
5806 info
->AuthAttrs
.rgAttr
[0].cValue
);
5807 ok(info
->AuthAttrs
.rgAttr
[0].rgValue
[0].cbData
==
5808 sizeof(encodedCommonName
), "Unexpected size %d\n",
5809 info
->AuthAttrs
.rgAttr
[0].rgValue
[0].cbData
);
5810 ok(!memcmp(info
->AuthAttrs
.rgAttr
[0].rgValue
[0].pbData
,
5811 encodedCommonName
, sizeof(encodedCommonName
)), "Unexpected value\n");
5816 static const BYTE CMSSignerWithKeyId
[] = {
5817 0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,
5818 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
5820 static void test_encodeCMSSignerInfo(DWORD dwEncoding
)
5825 CMSG_CMS_SIGNER_INFO info
= { 0 };
5826 static char oid1
[] = "1.2.3", oid2
[] = "1.5.6";
5828 SetLastError(0xdeadbeef);
5829 ret
= CryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
5830 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5831 ok(!ret
&& GetLastError() == E_INVALIDARG
,
5832 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5833 info
.SignerId
.dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5834 SetLastError(0xdeadbeef);
5835 ret
= CryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
5836 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5837 ok(!ret
&& GetLastError() == E_INVALIDARG
,
5838 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5839 /* To be encoded, a signer must have a valid cert ID, where a valid ID may
5840 * be a key id or a issuer serial number with at least the issuer set, and
5841 * the encoding must include PKCS_7_ASN_ENCODING.
5842 * (That isn't enough to be decoded, see decoding tests.)
5844 info
.SignerId
.IssuerSerialNumber
.Issuer
.cbData
=
5845 sizeof(encodedCommonNameNoNull
);
5846 info
.SignerId
.IssuerSerialNumber
.Issuer
.pbData
= encodedCommonNameNoNull
;
5847 SetLastError(0xdeadbeef);
5848 ret
= CryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
5849 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5850 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
5851 ok(!ret
&& GetLastError() == E_INVALIDARG
,
5852 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5855 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5858 ok(size
== sizeof(minimalPKCSSigner
), "Unexpected size %d\n", size
);
5859 ok(!memcmp(buf
, minimalPKCSSigner
, size
), "Unexpected value\n");
5863 info
.SignerId
.IssuerSerialNumber
.SerialNumber
.cbData
= sizeof(serialNum
);
5864 info
.SignerId
.IssuerSerialNumber
.SerialNumber
.pbData
= (BYTE
*)serialNum
;
5865 SetLastError(0xdeadbeef);
5866 ret
= CryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
5867 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5868 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
5869 ok(!ret
&& GetLastError() == E_INVALIDARG
,
5870 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5873 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5876 ok(size
== sizeof(PKCSSignerWithSerial
), "Unexpected size %d\n",
5878 ok(!memcmp(buf
, PKCSSignerWithSerial
, size
), "Unexpected value\n");
5882 info
.SignerId
.dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
5883 info
.SignerId
.KeyId
.cbData
= sizeof(serialNum
);
5884 info
.SignerId
.KeyId
.pbData
= (BYTE
*)serialNum
;
5885 SetLastError(0xdeadbeef);
5886 ret
= CryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
5887 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5888 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
5889 ok(!ret
&& GetLastError() == E_INVALIDARG
,
5890 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5893 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5896 ok(size
== sizeof(CMSSignerWithKeyId
), "Unexpected size %d\n",
5898 ok(!memcmp(buf
, CMSSignerWithKeyId
, size
), "Unexpected value\n");
5902 /* While a CERT_ID can have a hash type, that's not allowed in CMS, where
5903 * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed
5904 * (see RFC 3852, section 5.3.)
5906 info
.SignerId
.dwIdChoice
= CERT_ID_SHA1_HASH
;
5907 info
.SignerId
.HashId
.cbData
= sizeof(hash
);
5908 info
.SignerId
.HashId
.pbData
= (BYTE
*)hash
;
5909 SetLastError(0xdeadbeef);
5910 ret
= CryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
5911 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5912 ok(!ret
&& GetLastError() == E_INVALIDARG
,
5913 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5914 /* Now with a hash algo */
5915 info
.SignerId
.dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5916 info
.SignerId
.IssuerSerialNumber
.Issuer
.cbData
=
5917 sizeof(encodedCommonNameNoNull
);
5918 info
.SignerId
.IssuerSerialNumber
.Issuer
.pbData
= encodedCommonNameNoNull
;
5919 info
.HashAlgorithm
.pszObjId
= oid1
;
5920 SetLastError(0xdeadbeef);
5921 ret
= CryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
5922 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5923 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
5924 ok(!ret
&& GetLastError() == E_INVALIDARG
,
5925 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5928 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5931 ok(size
== sizeof(PKCSSignerWithHashAlgo
), "Unexpected size %d\n",
5933 ok(!memcmp(buf
, PKCSSignerWithHashAlgo
, size
),
5934 "Unexpected value\n");
5938 info
.HashEncryptionAlgorithm
.pszObjId
= oid2
;
5939 SetLastError(0xdeadbeef);
5940 ret
= CryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
5941 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5942 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
5943 ok(!ret
&& GetLastError() == E_INVALIDARG
,
5944 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5947 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5950 ok(size
== sizeof(PKCSSignerWithHashAndEncryptionAlgo
),
5951 "Unexpected size %d\n", size
);
5952 ok(!memcmp(buf
, PKCSSignerWithHashAndEncryptionAlgo
, size
),
5953 "Unexpected value\n");
5957 info
.EncryptedHash
.cbData
= sizeof(hash
);
5958 info
.EncryptedHash
.pbData
= (BYTE
*)hash
;
5959 SetLastError(0xdeadbeef);
5960 ret
= CryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
5961 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5962 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
5963 ok(!ret
&& GetLastError() == E_INVALIDARG
,
5964 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5967 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5970 ok(size
== sizeof(PKCSSignerWithHash
), "Unexpected size %d\n",
5972 ok(!memcmp(buf
, PKCSSignerWithHash
, size
), "Unexpected value\n");
5978 static void test_decodeCMSSignerInfo(DWORD dwEncoding
)
5983 CMSG_CMS_SIGNER_INFO
*info
;
5984 static char oid1
[] = "1.2.3", oid2
[] = "1.5.6";
5986 /* A CMS signer can't be decoded without a serial number. */
5987 SetLastError(0xdeadbeef);
5988 ret
= CryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
5989 minimalPKCSSigner
, sizeof(minimalPKCSSigner
),
5990 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5991 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_CORRUPT
,
5992 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
5993 ret
= CryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
5994 PKCSSignerWithSerial
, sizeof(PKCSSignerWithSerial
),
5995 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5996 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5999 info
= (CMSG_CMS_SIGNER_INFO
*)buf
;
6000 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6002 ok(info
->SignerId
.dwIdChoice
== CERT_ID_ISSUER_SERIAL_NUMBER
,
6003 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6004 info
->SignerId
.dwIdChoice
);
6005 ok(info
->SignerId
.IssuerSerialNumber
.Issuer
.cbData
==
6006 sizeof(encodedCommonNameNoNull
), "Unexpected size %d\n",
6007 info
->SignerId
.IssuerSerialNumber
.Issuer
.cbData
);
6008 ok(!memcmp(info
->SignerId
.IssuerSerialNumber
.Issuer
.pbData
,
6009 encodedCommonNameNoNull
,
6010 info
->SignerId
.IssuerSerialNumber
.Issuer
.cbData
),
6011 "Unexpected value\n");
6012 ok(info
->SignerId
.IssuerSerialNumber
.SerialNumber
.cbData
==
6013 sizeof(serialNum
), "Unexpected size %d\n",
6014 info
->SignerId
.IssuerSerialNumber
.SerialNumber
.cbData
);
6015 ok(!memcmp(info
->SignerId
.IssuerSerialNumber
.SerialNumber
.pbData
,
6016 serialNum
, sizeof(serialNum
)), "Unexpected value\n");
6019 ret
= CryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
6020 PKCSSignerWithHashAlgo
, sizeof(PKCSSignerWithHashAlgo
),
6021 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6022 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6025 info
= (CMSG_CMS_SIGNER_INFO
*)buf
;
6026 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6028 ok(info
->SignerId
.dwIdChoice
== CERT_ID_ISSUER_SERIAL_NUMBER
,
6029 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6030 info
->SignerId
.dwIdChoice
);
6031 ok(info
->SignerId
.IssuerSerialNumber
.Issuer
.cbData
==
6032 sizeof(encodedCommonNameNoNull
), "Unexpected size %d\n",
6033 info
->SignerId
.IssuerSerialNumber
.Issuer
.cbData
);
6034 ok(!memcmp(info
->SignerId
.IssuerSerialNumber
.Issuer
.pbData
,
6035 encodedCommonNameNoNull
,
6036 info
->SignerId
.IssuerSerialNumber
.Issuer
.cbData
),
6037 "Unexpected value\n");
6038 ok(info
->SignerId
.IssuerSerialNumber
.SerialNumber
.cbData
==
6039 sizeof(serialNum
), "Unexpected size %d\n",
6040 info
->SignerId
.IssuerSerialNumber
.SerialNumber
.cbData
);
6041 ok(!memcmp(info
->SignerId
.IssuerSerialNumber
.SerialNumber
.pbData
,
6042 serialNum
, sizeof(serialNum
)), "Unexpected value\n");
6043 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, oid1
),
6044 "Expected %s, got %s\n", oid1
, info
->HashAlgorithm
.pszObjId
);
6047 ret
= CryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
6048 PKCSSignerWithHashAndEncryptionAlgo
,
6049 sizeof(PKCSSignerWithHashAndEncryptionAlgo
), CRYPT_DECODE_ALLOC_FLAG
,
6050 NULL
, (BYTE
*)&buf
, &size
);
6051 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6054 info
= (CMSG_CMS_SIGNER_INFO
*)buf
;
6055 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6057 ok(info
->SignerId
.dwIdChoice
== CERT_ID_ISSUER_SERIAL_NUMBER
,
6058 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6059 info
->SignerId
.dwIdChoice
);
6060 ok(info
->SignerId
.IssuerSerialNumber
.Issuer
.cbData
==
6061 sizeof(encodedCommonNameNoNull
), "Unexpected size %d\n",
6062 info
->SignerId
.IssuerSerialNumber
.Issuer
.cbData
);
6063 ok(!memcmp(info
->SignerId
.IssuerSerialNumber
.Issuer
.pbData
,
6064 encodedCommonNameNoNull
,
6065 info
->SignerId
.IssuerSerialNumber
.Issuer
.cbData
),
6066 "Unexpected value\n");
6067 ok(info
->SignerId
.IssuerSerialNumber
.SerialNumber
.cbData
==
6068 sizeof(serialNum
), "Unexpected size %d\n",
6069 info
->SignerId
.IssuerSerialNumber
.SerialNumber
.cbData
);
6070 ok(!memcmp(info
->SignerId
.IssuerSerialNumber
.SerialNumber
.pbData
,
6071 serialNum
, sizeof(serialNum
)), "Unexpected value\n");
6072 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, oid1
),
6073 "Expected %s, got %s\n", oid1
, info
->HashAlgorithm
.pszObjId
);
6074 ok(!strcmp(info
->HashEncryptionAlgorithm
.pszObjId
, oid2
),
6075 "Expected %s, got %s\n", oid2
, info
->HashEncryptionAlgorithm
.pszObjId
);
6078 ret
= CryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
6079 PKCSSignerWithHash
, sizeof(PKCSSignerWithHash
),
6080 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6081 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6084 info
= (CMSG_CMS_SIGNER_INFO
*)buf
;
6085 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6087 ok(info
->SignerId
.dwIdChoice
== CERT_ID_ISSUER_SERIAL_NUMBER
,
6088 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6089 info
->SignerId
.dwIdChoice
);
6090 ok(info
->SignerId
.IssuerSerialNumber
.Issuer
.cbData
==
6091 sizeof(encodedCommonNameNoNull
), "Unexpected size %d\n",
6092 info
->SignerId
.IssuerSerialNumber
.Issuer
.cbData
);
6093 ok(!memcmp(info
->SignerId
.IssuerSerialNumber
.Issuer
.pbData
,
6094 encodedCommonNameNoNull
,
6095 info
->SignerId
.IssuerSerialNumber
.Issuer
.cbData
),
6096 "Unexpected value\n");
6097 ok(info
->SignerId
.IssuerSerialNumber
.SerialNumber
.cbData
==
6098 sizeof(serialNum
), "Unexpected size %d\n",
6099 info
->SignerId
.IssuerSerialNumber
.SerialNumber
.cbData
);
6100 ok(!memcmp(info
->SignerId
.IssuerSerialNumber
.SerialNumber
.pbData
,
6101 serialNum
, sizeof(serialNum
)), "Unexpected value\n");
6102 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, oid1
),
6103 "Expected %s, got %s\n", oid1
, info
->HashAlgorithm
.pszObjId
);
6104 ok(!strcmp(info
->HashEncryptionAlgorithm
.pszObjId
, oid2
),
6105 "Expected %s, got %s\n", oid2
, info
->HashEncryptionAlgorithm
.pszObjId
);
6106 ok(info
->EncryptedHash
.cbData
== sizeof(hash
), "Unexpected size %d\n",
6107 info
->EncryptedHash
.cbData
);
6108 ok(!memcmp(info
->EncryptedHash
.pbData
, hash
, sizeof(hash
)),
6109 "Unexpected value\n");
6112 ret
= CryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
6113 CMSSignerWithKeyId
, sizeof(CMSSignerWithKeyId
),
6114 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6115 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6118 info
= (CMSG_CMS_SIGNER_INFO
*)buf
;
6119 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6121 ok(info
->SignerId
.dwIdChoice
== CERT_ID_KEY_IDENTIFIER
,
6122 "Expected CERT_ID_KEY_IDENTIFIER, got %d\n",
6123 info
->SignerId
.dwIdChoice
);
6124 ok(info
->SignerId
.KeyId
.cbData
== sizeof(serialNum
),
6125 "Unexpected size %d\n", info
->SignerId
.KeyId
.cbData
);
6126 ok(!memcmp(info
->SignerId
.KeyId
.pbData
, serialNum
, sizeof(serialNum
)),
6127 "Unexpected value\n");
6132 static BYTE emptyDNSPermittedConstraints
[] = {
6133 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
6134 static BYTE emptyDNSExcludedConstraints
[] = {
6135 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
6136 static BYTE DNSExcludedConstraints
[] = {
6137 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
6138 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6139 static BYTE permittedAndExcludedConstraints
[] = {
6140 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6141 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
6142 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6143 static BYTE permittedAndExcludedWithMinConstraints
[] = {
6144 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6145 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
6146 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6147 static BYTE permittedAndExcludedWithMinMaxConstraints
[] = {
6148 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6149 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
6150 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6152 static void test_encodeNameConstraints(DWORD dwEncoding
)
6155 CERT_NAME_CONSTRAINTS_INFO constraints
= { 0 };
6156 CERT_GENERAL_SUBTREE permitted
= { { 0 } };
6157 CERT_GENERAL_SUBTREE excluded
= { { 0 } };
6161 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
6162 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6163 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
6165 skip("no X509_NAME_CONSTRAINTS encode support\n");
6168 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6171 ok(size
== sizeof(emptySequence
), "Unexpected size\n");
6172 ok(!memcmp(buf
, emptySequence
, size
), "Unexpected value\n");
6175 constraints
.cPermittedSubtree
= 1;
6176 constraints
.rgPermittedSubtree
= &permitted
;
6177 SetLastError(0xdeadbeef);
6178 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
6179 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6180 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6181 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6182 permitted
.Base
.dwAltNameChoice
= CERT_ALT_NAME_DNS_NAME
;
6183 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
6184 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6185 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6188 ok(size
== sizeof(emptyDNSPermittedConstraints
), "Unexpected size\n");
6189 ok(!memcmp(buf
, emptyDNSPermittedConstraints
, size
),
6190 "Unexpected value\n");
6193 constraints
.cPermittedSubtree
= 0;
6194 constraints
.cExcludedSubtree
= 1;
6195 constraints
.rgExcludedSubtree
= &excluded
;
6196 excluded
.Base
.dwAltNameChoice
= CERT_ALT_NAME_DNS_NAME
;
6197 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
6198 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6199 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6202 ok(size
== sizeof(emptyDNSExcludedConstraints
), "Unexpected size\n");
6203 ok(!memcmp(buf
, emptyDNSExcludedConstraints
, size
),
6204 "Unexpected value\n");
6207 U(excluded
.Base
).pwszURL
= (LPWSTR
)url
;
6208 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
6209 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6210 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6213 ok(size
== sizeof(DNSExcludedConstraints
), "Unexpected size\n");
6214 ok(!memcmp(buf
, DNSExcludedConstraints
, size
),
6215 "Unexpected value\n");
6218 permitted
.Base
.dwAltNameChoice
= CERT_ALT_NAME_IP_ADDRESS
;
6219 U(permitted
.Base
).IPAddress
.cbData
= sizeof(encodedIPAddr
);
6220 U(permitted
.Base
).IPAddress
.pbData
= (LPBYTE
)encodedIPAddr
;
6221 constraints
.cPermittedSubtree
= 1;
6222 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
6223 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6224 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6227 ok(size
== sizeof(permittedAndExcludedConstraints
),
6228 "Unexpected size\n");
6229 ok(!memcmp(buf
, permittedAndExcludedConstraints
, size
),
6230 "Unexpected value\n");
6233 permitted
.dwMinimum
= 5;
6234 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
6235 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6236 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6239 ok(size
== sizeof(permittedAndExcludedWithMinConstraints
),
6240 "Unexpected size\n");
6241 ok(!memcmp(buf
, permittedAndExcludedWithMinConstraints
, size
),
6242 "Unexpected value\n");
6245 permitted
.fMaximum
= TRUE
;
6246 permitted
.dwMaximum
= 3;
6247 SetLastError(0xdeadbeef);
6248 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
6249 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6250 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6253 ok(size
== sizeof(permittedAndExcludedWithMinMaxConstraints
),
6254 "Unexpected size\n");
6255 ok(!memcmp(buf
, permittedAndExcludedWithMinMaxConstraints
, size
),
6256 "Unexpected value\n");
6261 struct EncodedNameConstraints
6263 CRYPT_DATA_BLOB encoded
;
6264 CERT_NAME_CONSTRAINTS_INFO constraints
;
6267 static CERT_GENERAL_SUBTREE emptyDNSSubtree
= {
6268 { CERT_ALT_NAME_DNS_NAME
, { 0 } }, 0 };
6269 static CERT_GENERAL_SUBTREE DNSSubtree
= {
6270 { CERT_ALT_NAME_DNS_NAME
, { 0 } }, 0 };
6271 static CERT_GENERAL_SUBTREE IPAddressSubtree
= {
6272 { CERT_ALT_NAME_IP_ADDRESS
, { 0 } }, 0 };
6273 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree
= {
6274 { CERT_ALT_NAME_IP_ADDRESS
, { 0 } }, 5, 0 };
6275 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree
= {
6276 { CERT_ALT_NAME_IP_ADDRESS
, { 0 } }, 5, TRUE
, 3 };
6278 struct EncodedNameConstraints encodedNameConstraints
[] = {
6279 { { sizeof(emptySequence
), (LPBYTE
)emptySequence
}, { 0 } },
6280 { { sizeof(emptyDNSPermittedConstraints
), emptyDNSPermittedConstraints
},
6281 { 1, &emptyDNSSubtree
, 0, NULL
} },
6282 { { sizeof(emptyDNSExcludedConstraints
), emptyDNSExcludedConstraints
},
6283 { 0, NULL
, 1, &emptyDNSSubtree
} },
6284 { { sizeof(DNSExcludedConstraints
), DNSExcludedConstraints
},
6285 { 0, NULL
, 1, &DNSSubtree
} },
6286 { { sizeof(permittedAndExcludedConstraints
), permittedAndExcludedConstraints
},
6287 { 1, &IPAddressSubtree
, 1, &DNSSubtree
} },
6288 { { sizeof(permittedAndExcludedWithMinConstraints
),
6289 permittedAndExcludedWithMinConstraints
},
6290 { 1, &IPAddressWithMinSubtree
, 1, &DNSSubtree
} },
6291 { { sizeof(permittedAndExcludedWithMinMaxConstraints
),
6292 permittedAndExcludedWithMinMaxConstraints
},
6293 { 1, &IPAddressWithMinMaxSubtree
, 1, &DNSSubtree
} },
6296 static void test_decodeNameConstraints(DWORD dwEncoding
)
6300 CERT_NAME_CONSTRAINTS_INFO
*constraints
;
6302 U(DNSSubtree
.Base
).pwszURL
= (LPWSTR
)url
;
6303 U(IPAddressSubtree
.Base
).IPAddress
.cbData
= sizeof(encodedIPAddr
);
6304 U(IPAddressSubtree
.Base
).IPAddress
.pbData
= (LPBYTE
)encodedIPAddr
;
6305 U(IPAddressWithMinSubtree
.Base
).IPAddress
.cbData
= sizeof(encodedIPAddr
);
6306 U(IPAddressWithMinSubtree
.Base
).IPAddress
.pbData
= (LPBYTE
)encodedIPAddr
;
6307 U(IPAddressWithMinMaxSubtree
.Base
).IPAddress
.cbData
= sizeof(encodedIPAddr
);
6308 U(IPAddressWithMinMaxSubtree
.Base
).IPAddress
.pbData
= (LPBYTE
)encodedIPAddr
;
6310 i
< sizeof(encodedNameConstraints
) / sizeof(encodedNameConstraints
[0]);
6315 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
,
6316 encodedNameConstraints
[i
].encoded
.pbData
,
6317 encodedNameConstraints
[i
].encoded
.cbData
,
6318 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &constraints
, &size
);
6319 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
6321 skip("no X509_NAME_CONSTRAINTS decode support\n");
6324 ok(ret
, "%d: CryptDecodeObjectEx failed: %08x\n", i
, GetLastError());
6329 if (constraints
->cPermittedSubtree
!=
6330 encodedNameConstraints
[i
].constraints
.cPermittedSubtree
)
6331 fprintf(stderr
, "%d: expected %d permitted, got %d\n", i
,
6332 encodedNameConstraints
[i
].constraints
.cPermittedSubtree
,
6333 constraints
->cPermittedSubtree
);
6334 if (constraints
->cPermittedSubtree
==
6335 encodedNameConstraints
[i
].constraints
.cPermittedSubtree
)
6337 for (j
= 0; j
< constraints
->cPermittedSubtree
; j
++)
6339 compareAltNameEntry(&constraints
->rgPermittedSubtree
[j
].Base
,
6340 &encodedNameConstraints
[i
].constraints
.rgPermittedSubtree
[j
].Base
);
6343 if (constraints
->cExcludedSubtree
!=
6344 encodedNameConstraints
[i
].constraints
.cExcludedSubtree
)
6345 fprintf(stderr
, "%d: expected %d excluded, got %d\n", i
,
6346 encodedNameConstraints
[i
].constraints
.cExcludedSubtree
,
6347 constraints
->cExcludedSubtree
);
6348 if (constraints
->cExcludedSubtree
==
6349 encodedNameConstraints
[i
].constraints
.cExcludedSubtree
)
6351 for (j
= 0; j
< constraints
->cExcludedSubtree
; j
++)
6353 compareAltNameEntry(&constraints
->rgExcludedSubtree
[j
].Base
,
6354 &encodedNameConstraints
[i
].constraints
.rgExcludedSubtree
[j
].Base
);
6357 LocalFree(constraints
);
6362 /* Free *pInfo with HeapFree */
6363 static void testExportPublicKey(HCRYPTPROV csp
, PCERT_PUBLIC_KEY_INFO
*pInfo
)
6370 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
6372 ret
= CryptExportPublicKeyInfoEx(0, 0, 0, NULL
, 0, NULL
, NULL
, &size
);
6373 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
6374 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
6375 ret
= CryptExportPublicKeyInfoEx(0, AT_SIGNATURE
, 0, NULL
, 0, NULL
, NULL
,
6377 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
6378 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
6379 ret
= CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING
, NULL
, 0, NULL
,
6381 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
6382 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
6383 ret
= CryptExportPublicKeyInfoEx(0, AT_SIGNATURE
, X509_ASN_ENCODING
, NULL
,
6384 0, NULL
, NULL
, &size
);
6385 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
6386 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
6387 /* Test with no key */
6388 ret
= CryptExportPublicKeyInfoEx(csp
, AT_SIGNATURE
, X509_ASN_ENCODING
, NULL
,
6389 0, NULL
, NULL
, &size
);
6390 ok(!ret
&& GetLastError() == NTE_NO_KEY
, "Expected NTE_NO_KEY, got %08x\n",
6392 ret
= CryptGenKey(csp
, AT_SIGNATURE
, 0, &key
);
6393 ok(ret
, "CryptGenKey failed: %08x\n", GetLastError());
6396 ret
= CryptExportPublicKeyInfoEx(csp
, AT_SIGNATURE
, X509_ASN_ENCODING
,
6397 NULL
, 0, NULL
, NULL
, &size
);
6398 ok(ret
, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
6399 *pInfo
= HeapAlloc(GetProcessHeap(), 0, size
);
6402 ret
= CryptExportPublicKeyInfoEx(csp
, AT_SIGNATURE
,
6403 X509_ASN_ENCODING
, NULL
, 0, NULL
, *pInfo
, &size
);
6404 ok(ret
, "CryptExportPublicKeyInfoEx failed: %08x\n",
6408 /* By default (we passed NULL as the OID) the OID is
6411 ok(!strcmp((*pInfo
)->Algorithm
.pszObjId
, szOID_RSA_RSA
),
6412 "Expected %s, got %s\n", szOID_RSA_RSA
,
6413 (*pInfo
)->Algorithm
.pszObjId
);
6417 CryptDestroyKey(key
);
6420 static const BYTE expiredCert
[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
6421 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
6422 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
6423 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
6424 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
6425 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
6426 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
6427 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
6428 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
6429 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
6430 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
6431 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
6432 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
6433 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
6434 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
6435 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
6436 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
6437 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
6438 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
6439 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
6440 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
6441 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
6442 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
6443 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
6444 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
6446 static void testImportPublicKey(HCRYPTPROV csp
, PCERT_PUBLIC_KEY_INFO info
)
6450 PCCERT_CONTEXT context
;
6455 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
6456 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
6457 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
6458 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
6461 ret
= CryptImportPublicKeyInfoEx(0, 0, info
, 0, 0, NULL
, &key
);
6462 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
6463 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
6464 ret
= CryptImportPublicKeyInfoEx(csp
, 0, info
, 0, 0, NULL
, &key
);
6465 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
6466 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
6467 ret
= CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING
, info
, 0, 0, NULL
,
6469 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
6470 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
6472 /* Export key with standard algorithm (CALG_RSA_KEYX) */
6473 ret
= CryptImportPublicKeyInfoEx(csp
, X509_ASN_ENCODING
, info
, 0, 0, NULL
,
6475 ok(ret
, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
6477 dwSize
= sizeof(ai
);
6478 CryptGetKeyParam(key
, KP_ALGID
, (LPVOID
)&ai
, &dwSize
, 0);
6479 ok(ret
, "CryptGetKeyParam failed: %08x\n", GetLastError());
6482 ok(dwSize
== sizeof(ai
), "CryptGetKeyParam returned size %d\n",dwSize
);
6483 ok(ai
== CALG_RSA_KEYX
, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai
);
6486 CryptDestroyKey(key
);
6488 /* Repeat with forced algorithm */
6489 ret
= CryptImportPublicKeyInfoEx(csp
, X509_ASN_ENCODING
, info
, CALG_RSA_SIGN
, 0, NULL
,
6491 ok(ret
, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
6493 dwSize
= sizeof(ai
);
6494 CryptGetKeyParam(key
, KP_ALGID
, (LPVOID
)&ai
, &dwSize
, 0);
6495 ok(ret
, "CryptGetKeyParam failed: %08x\n", GetLastError());
6498 ok(dwSize
== sizeof(ai
), "CryptGetKeyParam returned size %d\n",dwSize
);
6499 ok(ai
== CALG_RSA_SIGN
, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai
);
6502 CryptDestroyKey(key
);
6504 /* Test importing a public key from a certificate context */
6505 context
= CertCreateCertificateContext(X509_ASN_ENCODING
, expiredCert
,
6506 sizeof(expiredCert
));
6507 ok(context
!= NULL
, "CertCreateCertificateContext failed: %08x\n",
6511 ok(!strcmp(szOID_RSA_RSA
,
6512 context
->pCertInfo
->SubjectPublicKeyInfo
.Algorithm
.pszObjId
),
6513 "Expected %s, got %s\n", szOID_RSA_RSA
,
6514 context
->pCertInfo
->SubjectPublicKeyInfo
.Algorithm
.pszObjId
);
6515 ret
= CryptImportPublicKeyInfoEx(csp
, X509_ASN_ENCODING
,
6516 &context
->pCertInfo
->SubjectPublicKeyInfo
, 0, 0, NULL
, &key
);
6517 ok(ret
, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
6518 CryptDestroyKey(key
);
6519 CertFreeCertificateContext(context
);
6523 static const char cspName
[] = "WineCryptTemp";
6525 static void testPortPublicKeyInfo(void)
6529 PCERT_PUBLIC_KEY_INFO info
= NULL
;
6531 /* Just in case a previous run failed, delete this thing */
6532 CryptAcquireContextA(&csp
, cspName
, MS_DEF_PROV
, PROV_RSA_FULL
,
6533 CRYPT_DELETEKEYSET
);
6534 ret
= CryptAcquireContextA(&csp
, cspName
, MS_DEF_PROV
, PROV_RSA_FULL
,
6537 testExportPublicKey(csp
, &info
);
6538 testImportPublicKey(csp
, info
);
6540 HeapFree(GetProcessHeap(), 0, info
);
6541 CryptReleaseContext(csp
, 0);
6542 ret
= CryptAcquireContextA(&csp
, cspName
, MS_DEF_PROV
, PROV_RSA_FULL
,
6543 CRYPT_DELETEKEYSET
);
6548 static const DWORD encodings
[] = { X509_ASN_ENCODING
, PKCS_7_ASN_ENCODING
,
6549 X509_ASN_ENCODING
| PKCS_7_ASN_ENCODING
};
6553 hCrypt32
= GetModuleHandleA("crypt32.dll");
6554 pCryptDecodeObjectEx
= (void*)GetProcAddress(hCrypt32
, "CryptDecodeObjectEx");
6555 pCryptEncodeObjectEx
= (void*)GetProcAddress(hCrypt32
, "CryptEncodeObjectEx");
6556 if (!pCryptDecodeObjectEx
|| !pCryptEncodeObjectEx
)
6558 skip("CryptDecodeObjectEx() is not available\n");
6562 for (i
= 0; i
< sizeof(encodings
) / sizeof(encodings
[0]); i
++)
6564 test_encodeInt(encodings
[i
]);
6565 test_decodeInt(encodings
[i
]);
6566 test_encodeEnumerated(encodings
[i
]);
6567 test_decodeEnumerated(encodings
[i
]);
6568 test_encodeFiletime(encodings
[i
]);
6569 test_decodeFiletime(encodings
[i
]);
6570 test_encodeName(encodings
[i
]);
6571 test_decodeName(encodings
[i
]);
6572 test_encodeUnicodeName(encodings
[i
]);
6573 test_decodeUnicodeName(encodings
[i
]);
6574 test_encodeNameValue(encodings
[i
]);
6575 test_decodeNameValue(encodings
[i
]);
6576 test_encodeUnicodeNameValue(encodings
[i
]);
6577 test_decodeUnicodeNameValue(encodings
[i
]);
6578 test_encodeAltName(encodings
[i
]);
6579 test_decodeAltName(encodings
[i
]);
6580 test_encodeOctets(encodings
[i
]);
6581 test_decodeOctets(encodings
[i
]);
6582 test_encodeBits(encodings
[i
]);
6583 test_decodeBits(encodings
[i
]);
6584 test_encodeBasicConstraints(encodings
[i
]);
6585 test_decodeBasicConstraints(encodings
[i
]);
6586 test_encodeRsaPublicKey(encodings
[i
]);
6587 test_decodeRsaPublicKey(encodings
[i
]);
6588 test_encodeSequenceOfAny(encodings
[i
]);
6589 test_decodeSequenceOfAny(encodings
[i
]);
6590 test_encodeExtensions(encodings
[i
]);
6591 test_decodeExtensions(encodings
[i
]);
6592 test_encodePublicKeyInfo(encodings
[i
]);
6593 test_decodePublicKeyInfo(encodings
[i
]);
6594 test_encodeCertToBeSigned(encodings
[i
]);
6595 test_decodeCertToBeSigned(encodings
[i
]);
6596 test_encodeCert(encodings
[i
]);
6597 test_decodeCert(encodings
[i
]);
6598 test_encodeCRLDistPoints(encodings
[i
]);
6599 test_decodeCRLDistPoints(encodings
[i
]);
6600 test_encodeCRLIssuingDistPoint(encodings
[i
]);
6601 test_decodeCRLIssuingDistPoint(encodings
[i
]);
6602 test_encodeCRLToBeSigned(encodings
[i
]);
6603 test_decodeCRLToBeSigned(encodings
[i
]);
6604 test_encodeEnhancedKeyUsage(encodings
[i
]);
6605 test_decodeEnhancedKeyUsage(encodings
[i
]);
6606 test_encodeAuthorityKeyId(encodings
[i
]);
6607 test_decodeAuthorityKeyId(encodings
[i
]);
6608 test_encodeAuthorityKeyId2(encodings
[i
]);
6609 test_decodeAuthorityKeyId2(encodings
[i
]);
6610 test_encodeAuthorityInfoAccess(encodings
[i
]);
6611 test_decodeAuthorityInfoAccess(encodings
[i
]);
6612 test_encodePKCSContentInfo(encodings
[i
]);
6613 test_decodePKCSContentInfo(encodings
[i
]);
6614 test_encodePKCSAttribute(encodings
[i
]);
6615 test_decodePKCSAttribute(encodings
[i
]);
6616 test_encodePKCSAttributes(encodings
[i
]);
6617 test_decodePKCSAttributes(encodings
[i
]);
6618 test_encodePKCSSMimeCapabilities(encodings
[i
]);
6619 test_decodePKCSSMimeCapabilities(encodings
[i
]);
6620 test_encodePKCSSignerInfo(encodings
[i
]);
6621 test_decodePKCSSignerInfo(encodings
[i
]);
6622 test_encodeCMSSignerInfo(encodings
[i
]);
6623 test_decodeCMSSignerInfo(encodings
[i
]);
6624 test_encodeNameConstraints(encodings
[i
]);
6625 test_decodeNameConstraints(encodings
[i
]);
6627 testPortPublicKeyInfo();