2 * Unit test suite for crypt32.dll's CryptEncodeObjectEx/CryptDecodeObjectEx
4 * Copyright 2005 Juan Lang
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wine/test.h"
30 static BOOL (WINAPI
*pCryptDecodeObjectEx
)(DWORD
,LPCSTR
,const BYTE
*,DWORD
,DWORD
,PCRYPT_DECODE_PARA
,void*,DWORD
*);
31 static BOOL (WINAPI
*pCryptEncodeObjectEx
)(DWORD
,LPCSTR
,const void*,DWORD
,PCRYPT_ENCODE_PARA
,void*,DWORD
*);
39 static const BYTE bin1
[] = {0x02,0x01,0x01};
40 static const BYTE bin2
[] = {0x02,0x01,0x7f};
41 static const BYTE bin3
[] = {0x02,0x02,0x00,0x80};
42 static const BYTE bin4
[] = {0x02,0x02,0x01,0x00};
43 static const BYTE bin5
[] = {0x02,0x01,0x80};
44 static const BYTE bin6
[] = {0x02,0x02,0xff,0x7f};
45 static const BYTE bin7
[] = {0x02,0x04,0xba,0xdd,0xf0,0x0d};
47 static const struct encodedInt ints
[] = {
64 static const BYTE bin8
[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
65 static const BYTE bin9
[] = {0x02,0x0a,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0};
66 static const BYTE bin10
[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
68 static const BYTE bin11
[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0xff,0};
69 static const BYTE bin12
[] = {0x02,0x09,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
70 static const BYTE bin13
[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0};
72 static const struct encodedBigInt bigInts
[] = {
73 { bin8
, bin9
, bin10
},
74 { bin11
, bin12
, bin13
},
77 static const BYTE bin14
[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
78 static const BYTE bin15
[] = {0x02,0x0a,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0};
79 static const BYTE bin16
[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0xff,0};
80 static const BYTE bin17
[] = {0x02,0x0c,0x00,0xff,0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
82 /* Decoded is the same as original, so don't bother storing a separate copy */
83 static const struct encodedBigInt bigUInts
[] = {
84 { bin14
, bin15
, NULL
},
85 { bin16
, bin17
, NULL
},
88 static void test_encodeInt(DWORD dwEncoding
)
93 CRYPT_INTEGER_BLOB blob
;
96 /* CryptEncodeObjectEx with NULL bufSize crashes..
97 ret = pCryptEncodeObjectEx(3, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
100 /* check bogus encoding */
101 ret
= pCryptEncodeObjectEx(0, X509_INTEGER
, &ints
[0].val
, 0, NULL
, NULL
,
103 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
104 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
107 /* check with NULL integer buffer. Windows XP incorrectly returns an
108 * NTSTATUS (crashes on win9x).
110 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_INTEGER
, NULL
, 0, NULL
, NULL
,
112 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
113 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
115 for (i
= 0; i
< sizeof(ints
) / sizeof(ints
[0]); i
++)
117 /* encode as normal integer */
118 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_INTEGER
, &ints
[i
].val
, 0,
119 NULL
, NULL
, &bufSize
);
120 ok(ret
, "Expected success, got %d\n", GetLastError());
121 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_INTEGER
, &ints
[i
].val
,
122 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
123 ok(ret
, "CryptEncodeObjectEx failed: %d\n", GetLastError());
126 ok(buf
[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
128 ok(buf
[1] == ints
[i
].encoded
[1], "Got length %d, expected %d\n",
129 buf
[1], ints
[i
].encoded
[1]);
130 ok(!memcmp(buf
+ 1, ints
[i
].encoded
+ 1, ints
[i
].encoded
[1] + 1),
131 "Encoded value of 0x%08x didn't match expected\n", ints
[i
].val
);
134 /* encode as multibyte integer */
135 blob
.cbData
= sizeof(ints
[i
].val
);
136 blob
.pbData
= (BYTE
*)&ints
[i
].val
;
137 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_MULTI_BYTE_INTEGER
, &blob
,
138 0, NULL
, NULL
, &bufSize
);
139 ok(ret
, "Expected success, got %d\n", GetLastError());
140 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_MULTI_BYTE_INTEGER
, &blob
,
141 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
142 ok(ret
, "CryptEncodeObjectEx failed: %d\n", GetLastError());
145 ok(buf
[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
147 ok(buf
[1] == ints
[i
].encoded
[1], "Got length %d, expected %d\n",
148 buf
[1], ints
[i
].encoded
[1]);
149 ok(!memcmp(buf
+ 1, ints
[i
].encoded
+ 1, ints
[i
].encoded
[1] + 1),
150 "Encoded value of 0x%08x didn't match expected\n", ints
[i
].val
);
154 /* encode a couple bigger ints, just to show it's little-endian and leading
155 * sign bytes are dropped
157 for (i
= 0; i
< sizeof(bigInts
) / sizeof(bigInts
[0]); i
++)
159 blob
.cbData
= strlen((const char*)bigInts
[i
].val
);
160 blob
.pbData
= (BYTE
*)bigInts
[i
].val
;
161 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_MULTI_BYTE_INTEGER
, &blob
,
162 0, NULL
, NULL
, &bufSize
);
163 ok(ret
, "Expected success, got %d\n", GetLastError());
164 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_MULTI_BYTE_INTEGER
, &blob
,
165 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
166 ok(ret
, "CryptEncodeObjectEx failed: %d\n", GetLastError());
169 ok(buf
[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
171 ok(buf
[1] == bigInts
[i
].encoded
[1], "Got length %d, expected %d\n",
172 buf
[1], bigInts
[i
].encoded
[1]);
173 ok(!memcmp(buf
+ 1, bigInts
[i
].encoded
+ 1,
174 bigInts
[i
].encoded
[1] + 1),
175 "Encoded value didn't match expected\n");
179 /* and, encode some uints */
180 for (i
= 0; i
< sizeof(bigUInts
) / sizeof(bigUInts
[0]); i
++)
182 blob
.cbData
= strlen((const char*)bigUInts
[i
].val
);
183 blob
.pbData
= (BYTE
*)bigUInts
[i
].val
;
184 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_MULTI_BYTE_UINT
, &blob
,
185 0, NULL
, NULL
, &bufSize
);
186 ok(ret
, "Expected success, got %d\n", GetLastError());
187 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_MULTI_BYTE_UINT
, &blob
,
188 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
189 ok(ret
, "CryptEncodeObjectEx failed: %d\n", GetLastError());
192 ok(buf
[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
194 ok(buf
[1] == bigUInts
[i
].encoded
[1], "Got length %d, expected %d\n",
195 buf
[1], bigUInts
[i
].encoded
[1]);
196 ok(!memcmp(buf
+ 1, bigUInts
[i
].encoded
+ 1,
197 bigUInts
[i
].encoded
[1] + 1),
198 "Encoded value didn't match expected\n");
204 static void test_decodeInt(DWORD dwEncoding
)
206 static const BYTE bigInt
[] = { 2, 5, 0xff, 0xfe, 0xff, 0xfe, 0xff };
207 static const BYTE testStr
[] = { 0x16, 4, 't', 'e', 's', 't' };
208 static const BYTE longForm
[] = { 2, 0x81, 0x01, 0x01 };
209 static const BYTE bigBogus
[] = { 0x02, 0x84, 0x01, 0xff, 0xff, 0xf9 };
210 static const BYTE extraBytes
[] = { 2, 1, 1, 0, 0, 0, 0 };
216 /* CryptDecodeObjectEx with NULL bufSize crashes..
217 ret = pCryptDecodeObjectEx(3, X509_INTEGER, &ints[0].encoded,
218 ints[0].encoded[1] + 2, 0, NULL, NULL, NULL);
220 /* check bogus encoding */
221 ret
= pCryptDecodeObjectEx(3, X509_INTEGER
, (BYTE
*)&ints
[0].encoded
,
222 ints
[0].encoded
[1] + 2, 0, NULL
, NULL
, &bufSize
);
223 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
224 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
225 /* check with NULL integer buffer */
226 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_INTEGER
, NULL
, 0, 0, NULL
, NULL
,
228 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_EOD
||
229 GetLastError() == OSS_BAD_ARG
/* Win9x */),
230 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
231 /* check with a valid, but too large, integer */
232 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_INTEGER
, bigInt
, bigInt
[1] + 2,
233 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
234 ok((!ret
&& GetLastError() == CRYPT_E_ASN1_LARGE
) ||
235 broken(ret
) /* Win9x */,
236 "Expected CRYPT_E_ASN1_LARGE, got %d\n", GetLastError());
237 /* check with a DER-encoded string */
238 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_INTEGER
, testStr
, testStr
[1] + 2,
239 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
240 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_BADTAG
||
241 GetLastError() == OSS_PDU_MISMATCH
/* Win9x */ ),
242 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %08x\n",
244 for (i
= 0; i
< sizeof(ints
) / sizeof(ints
[0]); i
++)
246 /* When the output buffer is NULL, this always succeeds */
247 SetLastError(0xdeadbeef);
248 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_INTEGER
,
249 ints
[i
].encoded
, ints
[i
].encoded
[1] + 2, 0, NULL
, NULL
,
251 ok(ret
&& GetLastError() == NOERROR
,
252 "Expected success and NOERROR, got %d\n", GetLastError());
253 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_INTEGER
,
254 ints
[i
].encoded
, ints
[i
].encoded
[1] + 2,
255 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
256 ok(ret
, "CryptDecodeObjectEx failed: %d\n", GetLastError());
257 ok(bufSize
== sizeof(int), "Wrong size %d\n", bufSize
);
258 ok(buf
!= NULL
, "Expected allocated buffer\n");
261 ok(!memcmp(buf
, &ints
[i
].val
, bufSize
), "Expected %d, got %d\n",
262 ints
[i
].val
, *(int *)buf
);
266 for (i
= 0; i
< sizeof(bigInts
) / sizeof(bigInts
[0]); i
++)
268 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_MULTI_BYTE_INTEGER
,
269 bigInts
[i
].encoded
, bigInts
[i
].encoded
[1] + 2, 0, NULL
, NULL
,
271 ok(ret
&& GetLastError() == NOERROR
,
272 "Expected success and NOERROR, got %d\n", GetLastError());
273 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_MULTI_BYTE_INTEGER
,
274 bigInts
[i
].encoded
, bigInts
[i
].encoded
[1] + 2,
275 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
276 ok(ret
, "CryptDecodeObjectEx failed: %d\n", GetLastError());
277 ok(bufSize
>= sizeof(CRYPT_INTEGER_BLOB
), "Wrong size %d\n", bufSize
);
278 ok(buf
!= NULL
, "Expected allocated buffer\n");
281 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)buf
;
283 ok(blob
->cbData
== strlen((const char*)bigInts
[i
].decoded
),
284 "Expected len %d, got %d\n", lstrlenA((const char*)bigInts
[i
].decoded
),
286 ok(!memcmp(blob
->pbData
, bigInts
[i
].decoded
, blob
->cbData
),
287 "Unexpected value\n");
291 for (i
= 0; i
< sizeof(bigUInts
) / sizeof(bigUInts
[0]); i
++)
293 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_MULTI_BYTE_UINT
,
294 bigUInts
[i
].encoded
, bigUInts
[i
].encoded
[1] + 2, 0, NULL
, NULL
,
296 ok(ret
&& GetLastError() == NOERROR
,
297 "Expected success and NOERROR, got %d\n", GetLastError());
298 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_MULTI_BYTE_UINT
,
299 bigUInts
[i
].encoded
, bigUInts
[i
].encoded
[1] + 2,
300 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
301 ok(ret
, "CryptDecodeObjectEx failed: %d\n", GetLastError());
302 ok(bufSize
>= sizeof(CRYPT_INTEGER_BLOB
), "Wrong size %d\n", bufSize
);
303 ok(buf
!= NULL
, "Expected allocated buffer\n");
306 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)buf
;
308 ok(blob
->cbData
== strlen((const char*)bigUInts
[i
].val
),
309 "Expected len %d, got %d\n", lstrlenA((const char*)bigUInts
[i
].val
),
311 ok(!memcmp(blob
->pbData
, bigUInts
[i
].val
, blob
->cbData
),
312 "Unexpected value\n");
316 /* Decode the value 1 with long-form length */
317 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_MULTI_BYTE_INTEGER
, longForm
,
318 sizeof(longForm
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
319 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
322 ok(*(int *)buf
== 1, "Expected 1, got %d\n", *(int *)buf
);
325 /* check with extra bytes at the end */
326 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_INTEGER
, extraBytes
,
327 sizeof(extraBytes
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
328 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
331 ok(*(int *)buf
== 1, "Expected 1, got %d\n", *(int *)buf
);
334 /* Try to decode some bogus large items */
335 /* The buffer size is smaller than the encoded length, so this should fail
336 * with CRYPT_E_ASN1_EOD if it's being decoded.
337 * Under XP it fails with CRYPT_E_ASN1_LARGE, which means there's a limit
338 * on the size decoded, but in ME it fails with CRYPT_E_ASN1_EOD or crashes.
339 * So this test unfortunately isn't useful.
340 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, tooBig,
341 0x7fffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
342 ok(!ret && GetLastError() == CRYPT_E_ASN1_LARGE,
343 "Expected CRYPT_E_ASN1_LARGE, got %08x\n", GetLastError());
345 /* This will try to decode the buffer and overflow it, check that it's
350 /* a large buffer isn't guaranteed to crash, it depends on memory allocation order */
351 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_MULTI_BYTE_INTEGER
, bigBogus
,
352 0x01ffffff, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
353 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
354 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
358 static const BYTE bin18
[] = {0x0a,0x01,0x01};
359 static const BYTE bin19
[] = {0x0a,0x05,0x00,0xff,0xff,0xff,0x80};
361 /* These are always encoded unsigned, and aren't constrained to be any
364 static const struct encodedInt enums
[] = {
369 /* X509_CRL_REASON_CODE is also an enumerated type, but it's #defined to
372 static const LPCSTR enumeratedTypes
[] = { X509_ENUMERATED
,
373 szOID_CRL_REASON_CODE
};
375 static void test_encodeEnumerated(DWORD dwEncoding
)
379 for (i
= 0; i
< sizeof(enumeratedTypes
) / sizeof(enumeratedTypes
[0]); i
++)
381 for (j
= 0; j
< sizeof(enums
) / sizeof(enums
[0]); j
++)
387 ret
= pCryptEncodeObjectEx(dwEncoding
, enumeratedTypes
[i
],
388 &enums
[j
].val
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
,
390 ok(ret
, "CryptEncodeObjectEx failed: %d\n", GetLastError());
394 "Got unexpected type %d for enumerated (expected 0xa)\n",
396 ok(buf
[1] == enums
[j
].encoded
[1],
397 "Got length %d, expected %d\n", buf
[1], enums
[j
].encoded
[1]);
398 ok(!memcmp(buf
+ 1, enums
[j
].encoded
+ 1,
399 enums
[j
].encoded
[1] + 1),
400 "Encoded value of 0x%08x didn't match expected\n",
408 static void test_decodeEnumerated(DWORD dwEncoding
)
412 for (i
= 0; i
< sizeof(enumeratedTypes
) / sizeof(enumeratedTypes
[0]); i
++)
414 for (j
= 0; j
< sizeof(enums
) / sizeof(enums
[0]); j
++)
417 DWORD bufSize
= sizeof(int);
420 ret
= pCryptDecodeObjectEx(dwEncoding
, enumeratedTypes
[i
],
421 enums
[j
].encoded
, enums
[j
].encoded
[1] + 2, 0, NULL
,
423 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
424 ok(bufSize
== sizeof(int),
425 "Got unexpected size %d for enumerated\n", bufSize
);
426 ok(val
== enums
[j
].val
, "Unexpected value %d, expected %d\n",
432 struct encodedFiletime
435 const BYTE
*encodedTime
;
438 static void testTimeEncoding(DWORD dwEncoding
, LPCSTR structType
,
439 const struct encodedFiletime
*time
)
446 ret
= SystemTimeToFileTime(&time
->sysTime
, &ft
);
447 ok(ret
, "SystemTimeToFileTime failed: %d\n", GetLastError());
448 ret
= pCryptEncodeObjectEx(dwEncoding
, structType
, &ft
,
449 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
450 /* years other than 1950-2050 are not allowed for encodings other than
451 * X509_CHOICE_OF_TIME.
453 if (structType
== X509_CHOICE_OF_TIME
||
454 (time
->sysTime
.wYear
>= 1950 && time
->sysTime
.wYear
<= 2050))
456 ok(ret
, "CryptEncodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
458 ok(buf
!= NULL
, "Expected an allocated buffer\n");
461 ok(buf
[0] == time
->encodedTime
[0],
462 "Expected type 0x%02x, got 0x%02x\n", time
->encodedTime
[0],
464 ok(buf
[1] == time
->encodedTime
[1], "Expected %d bytes, got %d\n",
465 time
->encodedTime
[1], bufSize
);
466 ok(!memcmp(time
->encodedTime
+ 2, buf
+ 2, time
->encodedTime
[1]),
467 "Got unexpected value for time encoding\n");
472 ok((!ret
&& GetLastError() == CRYPT_E_BAD_ENCODE
) ||
473 broken(GetLastError() == ERROR_SUCCESS
),
474 "Expected CRYPT_E_BAD_ENCODE, got 0x%08x\n", GetLastError());
477 static const char *printSystemTime(const SYSTEMTIME
*st
)
481 sprintf(buf
, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st
->wMonth
, st
->wDay
,
482 st
->wYear
, st
->wHour
, st
->wMinute
, st
->wSecond
, st
->wMilliseconds
);
486 static const char *printFileTime(const FILETIME
*ft
)
491 FileTimeToSystemTime(ft
, &st
);
492 sprintf(buf
, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st
.wMonth
, st
.wDay
,
493 st
.wYear
, st
.wHour
, st
.wMinute
, st
.wSecond
, st
.wMilliseconds
);
497 static void compareTime(const SYSTEMTIME
*expected
, const FILETIME
*got
)
501 FileTimeToSystemTime(got
, &st
);
502 ok((expected
->wYear
== st
.wYear
&&
503 expected
->wMonth
== st
.wMonth
&&
504 expected
->wDay
== st
.wDay
&&
505 expected
->wHour
== st
.wHour
&&
506 expected
->wMinute
== st
.wMinute
&&
507 expected
->wSecond
== st
.wSecond
&&
508 abs(expected
->wMilliseconds
- st
.wMilliseconds
) <= 1) ||
509 /* Some Windows systems only seem to be accurate in their time decoding to
510 * within about an hour.
512 broken(expected
->wYear
== st
.wYear
&&
513 expected
->wMonth
== st
.wMonth
&&
514 expected
->wDay
== st
.wDay
&&
515 abs(expected
->wHour
- st
.wHour
) <= 1),
516 "Got unexpected value for time decoding:\nexpected %s, got %s\n",
517 printSystemTime(expected
), printFileTime(got
));
520 static void testTimeDecoding(DWORD dwEncoding
, LPCSTR structType
,
521 const struct encodedFiletime
*time
)
524 DWORD size
= sizeof(ft
);
527 ret
= pCryptDecodeObjectEx(dwEncoding
, structType
, time
->encodedTime
,
528 time
->encodedTime
[1] + 2, 0, NULL
, &ft
, &size
);
529 /* years other than 1950-2050 are not allowed for encodings other than
530 * X509_CHOICE_OF_TIME.
532 if (structType
== X509_CHOICE_OF_TIME
||
533 (time
->sysTime
.wYear
>= 1950 && time
->sysTime
.wYear
<= 2050))
535 ok(ret
|| broken(GetLastError() == OSS_DATA_ERROR
),
536 "CryptDecodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
539 compareTime(&time
->sysTime
, &ft
);
542 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_BADTAG
||
543 GetLastError() == OSS_PDU_MISMATCH
/* Win9x */ ),
544 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %08x\n",
548 static const BYTE bin20
[] = {
549 0x17,0x0d,'0','5','0','6','0','6','1','6','1','0','0','0','Z'};
550 static const BYTE bin21
[] = {
551 0x18,0x0f,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
552 static const BYTE bin22
[] = {
553 0x18,0x0f,'2','1','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
555 static const struct encodedFiletime times
[] = {
556 { { 2005, 6, 1, 6, 16, 10, 0, 0 }, bin20
},
557 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin21
},
558 { { 2145, 6, 1, 6, 16, 10, 0, 0 }, bin22
},
561 static void test_encodeFiletime(DWORD dwEncoding
)
565 for (i
= 0; i
< sizeof(times
) / sizeof(times
[0]); i
++)
567 testTimeEncoding(dwEncoding
, X509_CHOICE_OF_TIME
, ×
[i
]);
568 testTimeEncoding(dwEncoding
, PKCS_UTC_TIME
, ×
[i
]);
569 testTimeEncoding(dwEncoding
, szOID_RSA_signingTime
, ×
[i
]);
573 static const BYTE bin23
[] = {
574 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','0','0','0','Z'};
575 static const BYTE bin24
[] = {
576 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','9','9','9','Z'};
577 static const BYTE bin25
[] = {
578 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','+','0','1','0','0'};
579 static const BYTE bin26
[] = {
580 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','0','0'};
581 static const BYTE bin27
[] = {
582 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','1','5'};
583 static const BYTE bin28
[] = {
584 0x18,0x0a,'2','1','4','5','0','6','0','6','1','6'};
585 static const BYTE bin29
[] = {
586 0x17,0x0a,'4','5','0','6','0','6','1','6','1','0'};
587 static const BYTE bin30
[] = {
588 0x17,0x0b,'4','5','0','6','0','6','1','6','1','0','Z'};
589 static const BYTE bin31
[] = {
590 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','+','0','1'};
591 static const BYTE bin32
[] = {
592 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','-','0','1'};
593 static const BYTE bin33
[] = {
594 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','+','0','1','0','0'};
595 static const BYTE bin34
[] = {
596 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','-','0','1','0','0'};
597 static const BYTE bin35
[] = {
598 0x17,0x08, '4','5','0','6','0','6','1','6'};
599 static const BYTE bin36
[] = {
600 0x18,0x0f, 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','Z'};
601 static const BYTE bin37
[] = {
602 0x18,0x04, '2','1','4','5'};
603 static const BYTE bin38
[] = {
604 0x18,0x08, '2','1','4','5','0','6','0','6'};
606 static void test_decodeFiletime(DWORD dwEncoding
)
608 static const struct encodedFiletime otherTimes
[] = {
609 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin23
},
610 { { 1945, 6, 1, 6, 16, 10, 0, 999 }, bin24
},
611 { { 1945, 6, 1, 6, 17, 10, 0, 0 }, bin25
},
612 { { 1945, 6, 1, 6, 15, 10, 0, 0 }, bin26
},
613 { { 1945, 6, 1, 6, 14, 55, 0, 0 }, bin27
},
614 { { 2145, 6, 1, 6, 16, 0, 0, 0 }, bin28
},
615 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin29
},
616 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin30
},
617 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin31
},
618 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin32
},
619 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin33
},
620 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin34
},
622 /* An oddball case that succeeds in Windows, but doesn't seem correct
623 { { 2145, 6, 1, 2, 11, 31, 0, 0 }, "\x18" "\x13" "21450606161000-9999" },
625 static const unsigned char *bogusTimes
[] = {
626 /* oddly, this succeeds on Windows, with year 2765
627 "\x18" "\x0f" "21r50606161000Z",
635 FILETIME ft1
= { 0 }, ft2
= { 0 };
638 /* Check bogus length with non-NULL buffer */
639 ret
= SystemTimeToFileTime(×
[0].sysTime
, &ft1
);
640 ok(ret
, "SystemTimeToFileTime failed: %d\n", GetLastError());
642 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CHOICE_OF_TIME
,
643 times
[0].encodedTime
, times
[0].encodedTime
[1] + 2, 0, NULL
, &ft2
, &size
);
644 ok(!ret
&& GetLastError() == ERROR_MORE_DATA
,
645 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
647 for (i
= 0; i
< sizeof(times
) / sizeof(times
[0]); i
++)
649 testTimeDecoding(dwEncoding
, X509_CHOICE_OF_TIME
, ×
[i
]);
650 testTimeDecoding(dwEncoding
, PKCS_UTC_TIME
, ×
[i
]);
651 testTimeDecoding(dwEncoding
, szOID_RSA_signingTime
, ×
[i
]);
653 for (i
= 0; i
< sizeof(otherTimes
) / sizeof(otherTimes
[0]); i
++)
655 testTimeDecoding(dwEncoding
, X509_CHOICE_OF_TIME
, &otherTimes
[i
]);
656 testTimeDecoding(dwEncoding
, PKCS_UTC_TIME
, &otherTimes
[i
]);
657 testTimeDecoding(dwEncoding
, szOID_RSA_signingTime
, &otherTimes
[i
]);
659 for (i
= 0; i
< sizeof(bogusTimes
) / sizeof(bogusTimes
[0]); i
++)
662 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CHOICE_OF_TIME
,
663 bogusTimes
[i
], bogusTimes
[i
][1] + 2, 0, NULL
, &ft1
, &size
);
664 ok((!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
665 GetLastError() == OSS_DATA_ERROR
/* Win9x */)) ||
666 broken(ret
), /* Win9x and NT4 for bin38 */
667 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
672 static const char commonName
[] = "Juan Lang";
673 static const char surName
[] = "Lang";
675 static const BYTE emptySequence
[] = { 0x30, 0 };
676 static const BYTE emptyRDNs
[] = { 0x30, 0x02, 0x31, 0 };
677 static const BYTE twoRDNs
[] = {
678 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
679 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
680 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0};
681 static const BYTE encodedTwoRDNs
[] = {
682 0x30,0x2e,0x31,0x2c,0x30,0x2a,0x06,0x03,0x55,0x04,0x03,0x30,0x23,0x31,0x21,
683 0x30,0x0c,0x06,0x03,0x55,0x04,0x04,0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,
684 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
688 static const BYTE us
[] = { 0x55, 0x53 };
689 static const BYTE minnesota
[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x73, 0x6f,
691 static const BYTE minneapolis
[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x61, 0x70,
692 0x6f, 0x6c, 0x69, 0x73 };
693 static const BYTE codeweavers
[] = { 0x43, 0x6f, 0x64, 0x65, 0x57, 0x65, 0x61,
694 0x76, 0x65, 0x72, 0x73 };
695 static const BYTE wine
[] = { 0x57, 0x69, 0x6e, 0x65, 0x20, 0x44, 0x65, 0x76,
696 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74 };
697 static const BYTE localhostAttr
[] = { 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
699 static const BYTE aric
[] = { 0x61, 0x72, 0x69, 0x63, 0x40, 0x63, 0x6f, 0x64,
700 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d };
702 #define RDNA(arr) oid_ ## arr, CERT_RDN_PRINTABLE_STRING, { sizeof(arr), (LPBYTE)arr }
703 #define RDNIA5(arr) oid_ ## arr, CERT_RDN_IA5_STRING, { sizeof(arr), (LPBYTE)arr }
705 static CHAR oid_us
[] = "2.5.4.6",
706 oid_minnesota
[] = "2.5.4.8",
707 oid_minneapolis
[] = "2.5.4.7",
708 oid_codeweavers
[] = "2.5.4.10",
709 oid_wine
[] = "2.5.4.11",
710 oid_localhostAttr
[] = "2.5.4.3",
711 oid_aric
[] = "1.2.840.113549.1.9.1";
712 static CERT_RDN_ATTR rdnAttrs
[] = { { RDNA(us
) },
714 { RDNA(minneapolis
) },
715 { RDNA(codeweavers
) },
717 { RDNA(localhostAttr
) },
719 static CERT_RDN_ATTR decodedRdnAttrs
[] = { { RDNA(us
) },
720 { RDNA(localhostAttr
) },
722 { RDNA(minneapolis
) },
723 { RDNA(codeweavers
) },
730 static const BYTE encodedRDNAttrs
[] = {
731 0x30,0x81,0x96,0x31,0x81,0x93,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
732 0x53,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x68,
733 0x6f,0x73,0x74,0x30,0x10,0x06,0x03,0x55,0x04,0x08,0x13,0x09,0x4d,0x69,0x6e,0x6e,
734 0x65,0x73,0x6f,0x74,0x61,0x30,0x12,0x06,0x03,0x55,0x04,0x07,0x13,0x0b,0x4d,0x69,
735 0x6e,0x6e,0x65,0x61,0x70,0x6f,0x6c,0x69,0x73,0x30,0x12,0x06,0x03,0x55,0x04,0x0a,
736 0x13,0x0b,0x43,0x6f,0x64,0x65,0x57,0x65,0x61,0x76,0x65,0x72,0x73,0x30,0x17,0x06,
737 0x03,0x55,0x04,0x0b,0x13,0x10,0x57,0x69,0x6e,0x65,0x20,0x44,0x65,0x76,0x65,0x6c,
738 0x6f,0x70,0x6d,0x65,0x6e,0x74,0x30,0x21,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
739 0x01,0x09,0x01,0x16,0x14,0x61,0x72,0x69,0x63,0x40,0x63,0x6f,0x64,0x65,0x77,0x65,
740 0x61,0x76,0x65,0x72,0x73,0x2e,0x63,0x6f,0x6d
743 static void test_encodeName(DWORD dwEncoding
)
745 CERT_RDN_ATTR attrs
[2];
748 static CHAR oid_common_name
[] = szOID_COMMON_NAME
,
749 oid_sur_name
[] = szOID_SUR_NAME
;
756 /* Test with NULL pvStructInfo (crashes on win9x) */
757 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, NULL
,
758 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
759 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
760 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
762 /* Test with empty CERT_NAME_INFO */
765 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
766 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
767 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
770 ok(!memcmp(buf
, emptySequence
, sizeof(emptySequence
)),
771 "Got unexpected encoding for empty name\n");
776 /* Test with bogus CERT_RDN (crashes on win9x) */
778 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
779 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
780 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
781 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
783 /* Test with empty CERT_RDN */
785 rdn
.rgRDNAttr
= NULL
;
788 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
789 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
790 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
793 ok(!memcmp(buf
, emptyRDNs
, sizeof(emptyRDNs
)),
794 "Got unexpected encoding for empty RDN array\n");
799 /* Test with bogus attr array (crashes on win9x) */
801 rdn
.rgRDNAttr
= NULL
;
802 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
803 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
804 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
805 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
807 /* oddly, a bogus OID is accepted by Windows XP; not testing.
808 attrs[0].pszObjId = "bogus";
809 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
810 attrs[0].Value.cbData = sizeof(commonName);
811 attrs[0].Value.pbData = commonName;
813 rdn.rgRDNAttr = attrs;
814 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
815 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
816 ok(!ret, "Expected failure, got success\n");
818 /* Check with two CERT_RDN_ATTRs. Note DER encoding forces the order of
819 * the encoded attributes to be swapped.
821 attrs
[0].pszObjId
= oid_common_name
;
822 attrs
[0].dwValueType
= CERT_RDN_PRINTABLE_STRING
;
823 attrs
[0].Value
.cbData
= sizeof(commonName
);
824 attrs
[0].Value
.pbData
= (BYTE
*)commonName
;
825 attrs
[1].pszObjId
= oid_sur_name
;
826 attrs
[1].dwValueType
= CERT_RDN_PRINTABLE_STRING
;
827 attrs
[1].Value
.cbData
= sizeof(surName
);
828 attrs
[1].Value
.pbData
= (BYTE
*)surName
;
830 rdn
.rgRDNAttr
= attrs
;
831 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
832 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
833 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
836 ok(!memcmp(buf
, twoRDNs
, sizeof(twoRDNs
)),
837 "Got unexpected encoding for two RDN array\n");
840 /* A name can be "encoded" with previously encoded RDN attrs. */
841 attrs
[0].dwValueType
= CERT_RDN_ENCODED_BLOB
;
842 attrs
[0].Value
.pbData
= (LPBYTE
)twoRDNs
;
843 attrs
[0].Value
.cbData
= sizeof(twoRDNs
);
845 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
846 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
847 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
850 ok(size
== sizeof(encodedTwoRDNs
), "Unexpected size %d\n", size
);
851 ok(!memcmp(buf
, encodedTwoRDNs
, size
),
852 "Unexpected value for re-endoded two RDN array\n");
855 /* CERT_RDN_ANY_TYPE is too vague for X509_NAMEs, check the return */
857 attrs
[0].dwValueType
= CERT_RDN_ANY_TYPE
;
858 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
859 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
860 ok(!ret
&& GetLastError() == E_INVALIDARG
,
861 "Expected E_INVALIDARG, got %08x\n", GetLastError());
862 /* Test a more complex name */
863 rdn
.cRDNAttr
= sizeof(rdnAttrs
) / sizeof(rdnAttrs
[0]);
864 rdn
.rgRDNAttr
= rdnAttrs
;
869 ret
= pCryptEncodeObjectEx(X509_ASN_ENCODING
, X509_NAME
, &info
,
870 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
871 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
874 ok(size
== sizeof(encodedRDNAttrs
), "Wrong size %d\n", size
);
875 ok(!memcmp(buf
, encodedRDNAttrs
, size
), "Unexpected value\n");
880 static WCHAR commonNameW
[] = { 'J','u','a','n',' ','L','a','n','g',0 };
881 static WCHAR surNameW
[] = { 'L','a','n','g',0 };
883 static const BYTE twoRDNsNoNull
[] = {
884 0x30,0x21,0x31,0x1f,0x30,0x0b,0x06,0x03,0x55,0x04,0x04,0x13,0x04,0x4c,0x61,
885 0x6e,0x67,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,
886 0x20,0x4c,0x61,0x6e,0x67 };
887 static const BYTE anyType
[] = {
888 0x30,0x2f,0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x1e,0x24,0x23,0x30,
889 0x21,0x31,0x0c,0x30,0x03,0x06,0x04,0x55,0x13,0x04,0x4c,0x05,0x6e,0x61,0x00,
890 0x67,0x11,0x30,0x03,0x06,0x04,0x55,0x13,0x03,0x4a,0x0a,0x61,0x75,0x20,0x6e,
891 0x61,0x4c,0x67,0x6e };
893 static void test_encodeUnicodeName(DWORD dwEncoding
)
895 CERT_RDN_ATTR attrs
[2];
898 static CHAR oid_common_name
[] = szOID_COMMON_NAME
,
899 oid_sur_name
[] = szOID_SUR_NAME
;
906 /* Test with NULL pvStructInfo (crashes on win9x) */
907 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, NULL
,
908 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
909 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
910 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
912 /* Test with empty CERT_NAME_INFO */
915 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, &info
,
916 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
917 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
920 ok(!memcmp(buf
, emptySequence
, sizeof(emptySequence
)),
921 "Got unexpected encoding for empty name\n");
924 /* Check with one CERT_RDN_ATTR, that has an invalid character for the
925 * encoding (the NULL).
927 attrs
[0].pszObjId
= oid_common_name
;
928 attrs
[0].dwValueType
= CERT_RDN_PRINTABLE_STRING
;
929 attrs
[0].Value
.cbData
= sizeof(commonNameW
);
930 attrs
[0].Value
.pbData
= (BYTE
*)commonNameW
;
932 rdn
.rgRDNAttr
= attrs
;
935 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, &info
,
936 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
937 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING
,
938 "Expected CRYPT_E_INVALID_PRINTABLE_STRING, got %08x\n", GetLastError());
939 ok(size
== 9, "Unexpected error index %08x\n", size
);
940 /* Check with two NULL-terminated CERT_RDN_ATTRs. Note DER encoding
941 * forces the order of the encoded attributes to be swapped.
943 attrs
[0].pszObjId
= oid_common_name
;
944 attrs
[0].dwValueType
= CERT_RDN_PRINTABLE_STRING
;
945 attrs
[0].Value
.cbData
= 0;
946 attrs
[0].Value
.pbData
= (BYTE
*)commonNameW
;
947 attrs
[1].pszObjId
= oid_sur_name
;
948 attrs
[1].dwValueType
= CERT_RDN_PRINTABLE_STRING
;
949 attrs
[1].Value
.cbData
= 0;
950 attrs
[1].Value
.pbData
= (BYTE
*)surNameW
;
952 rdn
.rgRDNAttr
= attrs
;
955 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, &info
,
956 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
957 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
960 ok(!memcmp(buf
, twoRDNsNoNull
, sizeof(twoRDNsNoNull
)),
961 "Got unexpected encoding for two RDN array\n");
964 /* A name can be "encoded" with previously encoded RDN attrs. */
965 attrs
[0].dwValueType
= CERT_RDN_ENCODED_BLOB
;
966 attrs
[0].Value
.pbData
= (LPBYTE
)twoRDNs
;
967 attrs
[0].Value
.cbData
= sizeof(twoRDNs
);
969 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, &info
,
970 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
971 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
974 ok(size
== sizeof(encodedTwoRDNs
), "Unexpected size %d\n", size
);
975 ok(!memcmp(buf
, encodedTwoRDNs
, size
),
976 "Unexpected value for re-endoded two RDN array\n");
979 /* Unicode names infer the type for CERT_RDN_ANY_TYPE */
981 attrs
[0].dwValueType
= CERT_RDN_ANY_TYPE
;
982 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, &info
,
983 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
984 todo_wine
ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
987 ok(size
== sizeof(anyType
), "Unexpected size %d\n", size
);
988 ok(!memcmp(buf
, anyType
, size
), "Unexpected value\n");
993 static void compareNameValues(const CERT_NAME_VALUE
*expected
,
994 const CERT_NAME_VALUE
*got
)
996 if (expected
->dwValueType
== CERT_RDN_UTF8_STRING
&&
997 got
->dwValueType
== CERT_RDN_ENCODED_BLOB
)
999 win_skip("Can't handle CERT_RDN_UTF8_STRING\n");
1003 ok(got
->dwValueType
== expected
->dwValueType
,
1004 "Expected string type %d, got %d\n", expected
->dwValueType
,
1006 ok(got
->Value
.cbData
== expected
->Value
.cbData
,
1007 "String type %d: unexpected data size, got %d, expected %d\n",
1008 expected
->dwValueType
, got
->Value
.cbData
, expected
->Value
.cbData
);
1009 if (got
->Value
.cbData
&& got
->Value
.pbData
)
1010 ok(!memcmp(got
->Value
.pbData
, expected
->Value
.pbData
,
1011 min(got
->Value
.cbData
, expected
->Value
.cbData
)),
1012 "String type %d: unexpected value\n", expected
->dwValueType
);
1015 static void compareRDNAttrs(const CERT_RDN_ATTR
*expected
,
1016 const CERT_RDN_ATTR
*got
)
1018 if (expected
->pszObjId
&& strlen(expected
->pszObjId
))
1020 ok(got
->pszObjId
!= NULL
, "Expected OID %s, got NULL\n",
1021 expected
->pszObjId
);
1024 ok(!strcmp(got
->pszObjId
, expected
->pszObjId
),
1025 "Got unexpected OID %s, expected %s\n", got
->pszObjId
,
1026 expected
->pszObjId
);
1029 compareNameValues((const CERT_NAME_VALUE
*)&expected
->dwValueType
,
1030 (const CERT_NAME_VALUE
*)&got
->dwValueType
);
1033 static void compareRDNs(const CERT_RDN
*expected
, const CERT_RDN
*got
)
1035 ok(got
->cRDNAttr
== expected
->cRDNAttr
,
1036 "Expected %d RDN attrs, got %d\n", expected
->cRDNAttr
, got
->cRDNAttr
);
1041 for (i
= 0; i
< got
->cRDNAttr
; i
++)
1042 compareRDNAttrs(&expected
->rgRDNAttr
[i
], &got
->rgRDNAttr
[i
]);
1046 static void compareNames(const CERT_NAME_INFO
*expected
,
1047 const CERT_NAME_INFO
*got
)
1049 ok(got
->cRDN
== expected
->cRDN
, "Expected %d RDNs, got %d\n",
1050 expected
->cRDN
, got
->cRDN
);
1055 for (i
= 0; i
< got
->cRDN
; i
++)
1056 compareRDNs(&expected
->rgRDN
[i
], &got
->rgRDN
[i
]);
1060 static const BYTE emptyIndefiniteSequence
[] = { 0x30,0x80,0x00,0x00 };
1061 static const BYTE twoRDNsExtraBytes
[] = {
1062 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
1063 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1064 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0,0,0,0,0,0};
1066 static void test_decodeName(DWORD dwEncoding
)
1072 CERT_NAME_INFO info
= { 1, &rdn
};
1074 /* test empty name */
1076 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME
, emptySequence
,
1077 emptySequence
[1] + 2,
1078 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1080 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1081 /* Interestingly, in Windows, if cRDN is 0, rgRGN may not be NULL. My
1082 * decoder works the same way, so only test the count.
1086 ok(bufSize
== sizeof(CERT_NAME_INFO
), "Wrong bufSize %d\n", bufSize
);
1087 ok(((CERT_NAME_INFO
*)buf
)->cRDN
== 0,
1088 "Expected 0 RDNs in empty info, got %d\n",
1089 ((CERT_NAME_INFO
*)buf
)->cRDN
);
1092 /* test empty name with indefinite-length encoding */
1093 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME
, emptyIndefiniteSequence
,
1094 sizeof(emptyIndefiniteSequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1096 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1099 ok(bufSize
== sizeof(CERT_NAME_INFO
), "Wrong bufSize %d\n", bufSize
);
1100 ok(((CERT_NAME_INFO
*)buf
)->cRDN
== 0,
1101 "Expected 0 RDNs in empty info, got %d\n",
1102 ((CERT_NAME_INFO
*)buf
)->cRDN
);
1105 /* test empty RDN */
1107 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME
, emptyRDNs
,
1109 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1111 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1114 CERT_NAME_INFO
*info
= (CERT_NAME_INFO
*)buf
;
1116 ok(bufSize
== sizeof(CERT_NAME_INFO
) + sizeof(CERT_RDN
) &&
1117 info
->cRDN
== 1 && info
->rgRDN
&& info
->rgRDN
[0].cRDNAttr
== 0,
1118 "Got unexpected value for empty RDN\n");
1121 /* test two RDN attrs */
1123 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME
, twoRDNs
,
1125 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1127 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1130 static CHAR oid_sur_name
[] = szOID_SUR_NAME
,
1131 oid_common_name
[] = szOID_COMMON_NAME
;
1133 CERT_RDN_ATTR attrs
[] = {
1134 { oid_sur_name
, CERT_RDN_PRINTABLE_STRING
, { sizeof(surName
),
1135 (BYTE
*)surName
} },
1136 { oid_common_name
, CERT_RDN_PRINTABLE_STRING
, { sizeof(commonName
),
1137 (BYTE
*)commonName
} },
1140 rdn
.cRDNAttr
= sizeof(attrs
) / sizeof(attrs
[0]);
1141 rdn
.rgRDNAttr
= attrs
;
1142 compareNames(&info
, (CERT_NAME_INFO
*)buf
);
1145 /* test that two RDN attrs with extra bytes succeeds */
1147 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME
, twoRDNsExtraBytes
,
1148 sizeof(twoRDNsExtraBytes
), 0, NULL
, NULL
, &bufSize
);
1149 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1150 /* And, a slightly more complicated name */
1153 ret
= pCryptDecodeObjectEx(X509_ASN_ENCODING
, X509_NAME
, encodedRDNAttrs
,
1154 sizeof(encodedRDNAttrs
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1155 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1158 rdn
.cRDNAttr
= sizeof(decodedRdnAttrs
) / sizeof(decodedRdnAttrs
[0]);
1159 rdn
.rgRDNAttr
= decodedRdnAttrs
;
1160 compareNames(&info
, (CERT_NAME_INFO
*)buf
);
1165 static void test_decodeUnicodeName(DWORD dwEncoding
)
1171 CERT_NAME_INFO info
= { 1, &rdn
};
1173 /* test empty name */
1175 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, emptySequence
,
1176 emptySequence
[1] + 2,
1177 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1179 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1182 ok(bufSize
== sizeof(CERT_NAME_INFO
),
1183 "Got wrong bufSize %d\n", bufSize
);
1184 ok(((CERT_NAME_INFO
*)buf
)->cRDN
== 0,
1185 "Expected 0 RDNs in empty info, got %d\n",
1186 ((CERT_NAME_INFO
*)buf
)->cRDN
);
1189 /* test empty RDN */
1191 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, emptyRDNs
,
1193 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1195 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1198 CERT_NAME_INFO
*info
= (CERT_NAME_INFO
*)buf
;
1200 ok(bufSize
== sizeof(CERT_NAME_INFO
) + sizeof(CERT_RDN
) &&
1201 info
->cRDN
== 1 && info
->rgRDN
&& info
->rgRDN
[0].cRDNAttr
== 0,
1202 "Got unexpected value for empty RDN\n");
1205 /* test two RDN attrs */
1207 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, twoRDNsNoNull
,
1208 sizeof(twoRDNsNoNull
),
1209 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1211 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1214 static CHAR oid_sur_name
[] = szOID_SUR_NAME
,
1215 oid_common_name
[] = szOID_COMMON_NAME
;
1217 CERT_RDN_ATTR attrs
[] = {
1218 { oid_sur_name
, CERT_RDN_PRINTABLE_STRING
,
1219 { lstrlenW(surNameW
) * sizeof(WCHAR
), (BYTE
*)surNameW
} },
1220 { oid_common_name
, CERT_RDN_PRINTABLE_STRING
,
1221 { lstrlenW(commonNameW
) * sizeof(WCHAR
), (BYTE
*)commonNameW
} },
1224 rdn
.cRDNAttr
= sizeof(attrs
) / sizeof(attrs
[0]);
1225 rdn
.rgRDNAttr
= attrs
;
1226 compareNames(&info
, (CERT_NAME_INFO
*)buf
);
1231 struct EncodedNameValue
1233 CERT_NAME_VALUE value
;
1234 const BYTE
*encoded
;
1238 static const char bogusIA5
[] = "\x80";
1239 static const char bogusPrintable
[] = "~";
1240 static const char bogusNumeric
[] = "A";
1241 static const BYTE bin42
[] = { 0x16,0x02,0x80,0x00 };
1242 static const BYTE bin43
[] = { 0x13,0x02,0x7e,0x00 };
1243 static const BYTE bin44
[] = { 0x12,0x02,0x41,0x00 };
1244 static BYTE octetCommonNameValue
[] = {
1245 0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1246 static BYTE numericCommonNameValue
[] = {
1247 0x12,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1248 static BYTE printableCommonNameValue
[] = {
1249 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1250 static BYTE t61CommonNameValue
[] = {
1251 0x14,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1252 static BYTE videotexCommonNameValue
[] = {
1253 0x15,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1254 static BYTE ia5CommonNameValue
[] = {
1255 0x16,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1256 static BYTE graphicCommonNameValue
[] = {
1257 0x19,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1258 static BYTE visibleCommonNameValue
[] = {
1259 0x1a,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1260 static BYTE generalCommonNameValue
[] = {
1261 0x1b,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1262 static BYTE bmpCommonNameValue
[] = {
1263 0x1e,0x14,0x00,0x4a,0x00,0x75,0x00,0x61,0x00,0x6e,0x00,0x20,0x00,0x4c,0x00,
1264 0x61,0x00,0x6e,0x00,0x67,0x00,0x00 };
1265 static BYTE utf8CommonNameValue
[] = {
1266 0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1267 static char embedded_null
[] = "foo\0com";
1268 static BYTE ia5EmbeddedNull
[] = {
1269 0x16,0x07,0x66,0x6f,0x6f,0x00,0x63,0x6f,0x6d };
1271 static struct EncodedNameValue nameValues
[] = {
1272 { { CERT_RDN_OCTET_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1273 octetCommonNameValue
, sizeof(octetCommonNameValue
) },
1274 { { CERT_RDN_NUMERIC_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1275 numericCommonNameValue
, sizeof(numericCommonNameValue
) },
1276 { { CERT_RDN_PRINTABLE_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1277 printableCommonNameValue
, sizeof(printableCommonNameValue
) },
1278 { { CERT_RDN_T61_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1279 t61CommonNameValue
, sizeof(t61CommonNameValue
) },
1280 { { CERT_RDN_VIDEOTEX_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1281 videotexCommonNameValue
, sizeof(videotexCommonNameValue
) },
1282 { { CERT_RDN_IA5_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1283 ia5CommonNameValue
, sizeof(ia5CommonNameValue
) },
1284 { { CERT_RDN_GRAPHIC_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1285 graphicCommonNameValue
, sizeof(graphicCommonNameValue
) },
1286 { { CERT_RDN_VISIBLE_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1287 visibleCommonNameValue
, sizeof(visibleCommonNameValue
) },
1288 { { CERT_RDN_GENERAL_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1289 generalCommonNameValue
, sizeof(generalCommonNameValue
) },
1290 { { CERT_RDN_BMP_STRING
, { sizeof(commonNameW
), (BYTE
*)commonNameW
} },
1291 bmpCommonNameValue
, sizeof(bmpCommonNameValue
) },
1292 { { CERT_RDN_UTF8_STRING
, { sizeof(commonNameW
), (BYTE
*)commonNameW
} },
1293 utf8CommonNameValue
, sizeof(utf8CommonNameValue
) },
1294 /* The following tests succeed under Windows, but really should fail,
1295 * they contain characters that are illegal for the encoding. I'm
1296 * including them to justify my lazy encoding.
1298 { { CERT_RDN_IA5_STRING
, { sizeof(bogusIA5
), (BYTE
*)bogusIA5
} }, bin42
,
1300 { { CERT_RDN_PRINTABLE_STRING
, { sizeof(bogusPrintable
),
1301 (BYTE
*)bogusPrintable
} }, bin43
, sizeof(bin43
) },
1302 { { CERT_RDN_NUMERIC_STRING
, { sizeof(bogusNumeric
), (BYTE
*)bogusNumeric
} },
1303 bin44
, sizeof(bin44
) },
1305 /* This is kept separate, because the decoding doesn't return to the original
1308 static struct EncodedNameValue embeddedNullNameValue
= {
1309 { CERT_RDN_IA5_STRING
, { sizeof(embedded_null
) - 1, (BYTE
*)embedded_null
} },
1310 ia5EmbeddedNull
, sizeof(ia5EmbeddedNull
) };
1312 static void test_encodeNameValue(DWORD dwEncoding
)
1317 CERT_NAME_VALUE value
= { 0, { 0, NULL
} };
1319 value
.dwValueType
= CERT_RDN_ENCODED_BLOB
;
1320 value
.Value
.pbData
= printableCommonNameValue
;
1321 value
.Value
.cbData
= sizeof(printableCommonNameValue
);
1322 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_VALUE
, &value
,
1323 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1324 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1327 ok(size
== sizeof(printableCommonNameValue
), "Unexpected size %d\n",
1329 ok(!memcmp(buf
, printableCommonNameValue
, size
),
1330 "Unexpected encoding\n");
1333 for (i
= 0; i
< sizeof(nameValues
) / sizeof(nameValues
[0]); i
++)
1335 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_VALUE
,
1336 &nameValues
[i
].value
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1337 ok(ret
|| broken(GetLastError() == OSS_PDU_MISMATCH
) /* NT4/Win9x */,
1338 "Type %d: CryptEncodeObjectEx failed: %08x\n",
1339 nameValues
[i
].value
.dwValueType
, GetLastError());
1342 ok(size
== nameValues
[i
].encodedSize
,
1343 "Expected size %d, got %d\n", nameValues
[i
].encodedSize
, size
);
1344 ok(!memcmp(buf
, nameValues
[i
].encoded
, size
),
1345 "Got unexpected encoding\n");
1349 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_VALUE
,
1350 &embeddedNullNameValue
.value
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1351 ok(ret
|| broken(GetLastError() == OSS_PDU_MISMATCH
) /* NT4/Win9x */,
1352 "Type %d: CryptEncodeObjectEx failed: %08x\n",
1353 embeddedNullNameValue
.value
.dwValueType
, GetLastError());
1356 ok(size
== embeddedNullNameValue
.encodedSize
,
1357 "Expected size %d, got %d\n", embeddedNullNameValue
.encodedSize
, size
);
1358 ok(!memcmp(buf
, embeddedNullNameValue
.encoded
, size
),
1359 "Got unexpected encoding\n");
1364 static void test_decodeNameValue(DWORD dwEncoding
)
1371 for (i
= 0; i
< sizeof(nameValues
) / sizeof(nameValues
[0]); i
++)
1373 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME_VALUE
,
1374 nameValues
[i
].encoded
, nameValues
[i
].encoded
[1] + 2,
1375 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1377 ok(ret
, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
1378 nameValues
[i
].value
.dwValueType
, GetLastError());
1381 compareNameValues(&nameValues
[i
].value
,
1382 (const CERT_NAME_VALUE
*)buf
);
1386 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME_VALUE
,
1387 embeddedNullNameValue
.encoded
, embeddedNullNameValue
.encodedSize
,
1388 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1390 ok(ret
, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
1391 embeddedNullNameValue
.value
.dwValueType
, GetLastError());
1394 CERT_NAME_VALUE rdnEncodedValue
= { CERT_RDN_ENCODED_BLOB
,
1395 { sizeof(ia5EmbeddedNull
), ia5EmbeddedNull
} };
1396 CERT_NAME_VALUE embeddedNullValue
= { CERT_RDN_IA5_STRING
,
1397 { sizeof(embedded_null
) - 1, (BYTE
*)embedded_null
} };
1398 const CERT_NAME_VALUE
*got
= (const CERT_NAME_VALUE
*)buf
,
1401 /* Some Windows versions decode name values with embedded NULLs,
1402 * others leave them encoded, even with the same version of crypt32.
1405 ok(got
->dwValueType
== CERT_RDN_ENCODED_BLOB
||
1406 got
->dwValueType
== CERT_RDN_IA5_STRING
,
1407 "Expected CERT_RDN_ENCODED_BLOB or CERT_RDN_IA5_STRING, got %d\n",
1409 if (got
->dwValueType
== CERT_RDN_ENCODED_BLOB
)
1410 expected
= &rdnEncodedValue
;
1411 else if (got
->dwValueType
== CERT_RDN_IA5_STRING
)
1412 expected
= &embeddedNullValue
;
1415 ok(got
->Value
.cbData
== expected
->Value
.cbData
,
1416 "String type %d: unexpected data size, got %d, expected %d\n",
1417 got
->dwValueType
, got
->Value
.cbData
, expected
->Value
.cbData
);
1418 if (got
->Value
.cbData
&& got
->Value
.pbData
)
1419 ok(!memcmp(got
->Value
.pbData
, expected
->Value
.pbData
,
1420 min(got
->Value
.cbData
, expected
->Value
.cbData
)),
1421 "String type %d: unexpected value\n", expected
->dwValueType
);
1427 static const BYTE emptyURL
[] = { 0x30, 0x02, 0x86, 0x00 };
1428 static const BYTE emptyURLExtraBytes
[] = { 0x30, 0x02, 0x86, 0x00, 0, 0, 0 };
1429 static const WCHAR url
[] = { 'h','t','t','p',':','/','/','w','i','n','e',
1430 'h','q','.','o','r','g',0 };
1431 static const BYTE encodedURL
[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74,
1432 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e,
1434 static const WCHAR nihongoURL
[] = { 'h','t','t','p',':','/','/',0x226f,
1436 static const WCHAR dnsName
[] = { 'w','i','n','e','h','q','.','o','r','g',0 };
1437 static const BYTE encodedDnsName
[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69,
1438 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
1439 static const BYTE localhost
[] = { 127, 0, 0, 1 };
1440 static const BYTE encodedIPAddr
[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00,
1442 static const unsigned char encodedCommonName
[] = {
1443 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0};
1444 static const BYTE encodedOidName
[] = { 0x30,0x04,0x88,0x02,0x2a,0x03 };
1445 static const BYTE encodedDirectoryName
[] = {
1446 0x30,0x19,0xa4,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1447 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1449 static void test_encodeAltName(DWORD dwEncoding
)
1451 CERT_ALT_NAME_INFO info
= { 0 };
1452 CERT_ALT_NAME_ENTRY entry
= { 0 };
1456 char oid
[] = "1.2.3";
1458 /* Test with empty info */
1459 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1460 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1463 ok(size
== sizeof(emptySequence
), "Wrong size %d\n", size
);
1464 ok(!memcmp(buf
, emptySequence
, size
), "Unexpected value\n");
1467 /* Test with an empty entry */
1469 info
.rgAltEntry
= &entry
;
1470 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1471 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1472 ok(!ret
&& GetLastError() == E_INVALIDARG
,
1473 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1474 /* Test with an empty pointer */
1475 entry
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
1476 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1477 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1480 ok(size
== sizeof(emptyURL
), "Wrong size %d\n", size
);
1481 ok(!memcmp(buf
, emptyURL
, size
), "Unexpected value\n");
1484 /* Test with a real URL */
1485 U(entry
).pwszURL
= (LPWSTR
)url
;
1486 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1487 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1490 ok(size
== sizeof(encodedURL
), "Wrong size %d\n", size
);
1491 ok(!memcmp(buf
, encodedURL
, size
), "Unexpected value\n");
1494 /* Now with the URL containing an invalid IA5 char */
1495 U(entry
).pwszURL
= (LPWSTR
)nihongoURL
;
1496 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1497 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1498 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_IA5_STRING
,
1499 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
1500 /* The first invalid character is at index 7 */
1501 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size
) == 7,
1502 "Expected invalid char at index 7, got %d\n",
1503 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size
));
1504 /* Now with the URL missing a scheme */
1505 U(entry
).pwszURL
= (LPWSTR
)dnsName
;
1506 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1507 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1508 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1511 /* This succeeds, but it shouldn't, so don't worry about conforming */
1514 /* Now with a DNS name */
1515 entry
.dwAltNameChoice
= CERT_ALT_NAME_DNS_NAME
;
1516 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1517 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1518 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1521 ok(size
== sizeof(encodedDnsName
), "Wrong size %d\n", size
);
1522 ok(!memcmp(buf
, encodedDnsName
, size
), "Unexpected value\n");
1525 /* Test with an IP address */
1526 entry
.dwAltNameChoice
= CERT_ALT_NAME_IP_ADDRESS
;
1527 U(entry
).IPAddress
.cbData
= sizeof(localhost
);
1528 U(entry
).IPAddress
.pbData
= (LPBYTE
)localhost
;
1529 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1530 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1533 ok(size
== sizeof(encodedIPAddr
), "Wrong size %d\n", size
);
1534 ok(!memcmp(buf
, encodedIPAddr
, size
), "Unexpected value\n");
1538 entry
.dwAltNameChoice
= CERT_ALT_NAME_REGISTERED_ID
;
1539 U(entry
).pszRegisteredID
= oid
;
1540 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1541 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1544 ok(size
== sizeof(encodedOidName
), "Wrong size %d\n", size
);
1545 ok(!memcmp(buf
, encodedOidName
, size
), "Unexpected value\n");
1548 /* Test with directory name */
1549 entry
.dwAltNameChoice
= CERT_ALT_NAME_DIRECTORY_NAME
;
1550 U(entry
).DirectoryName
.cbData
= sizeof(encodedCommonName
);
1551 U(entry
).DirectoryName
.pbData
= (LPBYTE
)encodedCommonName
;
1552 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1553 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1556 ok(size
== sizeof(encodedDirectoryName
), "Wrong size %d\n", size
);
1557 ok(!memcmp(buf
, encodedDirectoryName
, size
), "Unexpected value\n");
1562 static void test_decodeAltName(DWORD dwEncoding
)
1564 static const BYTE unimplementedType
[] = { 0x30, 0x06, 0x85, 0x04, 0x7f,
1566 static const BYTE bogusType
[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00,
1568 static const BYTE dns_embedded_null
[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f,
1569 0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 };
1570 static const BYTE dns_embedded_bell
[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f,
1571 0x6f,0x2e,0x63,0x6f,0x6d,0x07,0x62,0x61,0x64,0x64,0x69,0x65 };
1572 static const BYTE url_embedded_null
[] = { 0x30,0x10,0x86,0x0e,0x66,0x6f,
1573 0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 };
1577 CERT_ALT_NAME_INFO
*info
;
1579 /* Test some bogus ones first */
1580 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1581 unimplementedType
, sizeof(unimplementedType
), CRYPT_DECODE_ALLOC_FLAG
,
1582 NULL
, &buf
, &bufSize
);
1583 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_BADTAG
||
1584 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
1585 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
1587 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1588 bogusType
, sizeof(bogusType
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
,
1590 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
1591 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
1592 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
1594 /* Now expected cases */
1595 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, emptySequence
,
1596 emptySequence
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1597 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1600 info
= (CERT_ALT_NAME_INFO
*)buf
;
1602 ok(info
->cAltEntry
== 0, "Expected 0 entries, got %d\n",
1606 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, emptyURL
,
1607 emptyURL
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1608 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1611 info
= (CERT_ALT_NAME_INFO
*)buf
;
1613 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1615 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_URL
,
1616 "Expected CERT_ALT_NAME_URL, got %d\n",
1617 info
->rgAltEntry
[0].dwAltNameChoice
);
1618 ok(U(info
->rgAltEntry
[0]).pwszURL
== NULL
|| !*U(info
->rgAltEntry
[0]).pwszURL
,
1619 "Expected empty URL\n");
1622 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1623 emptyURLExtraBytes
, sizeof(emptyURLExtraBytes
), 0, NULL
, NULL
, &bufSize
);
1624 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1625 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, encodedURL
,
1626 encodedURL
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1627 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1630 info
= (CERT_ALT_NAME_INFO
*)buf
;
1632 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1634 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_URL
,
1635 "Expected CERT_ALT_NAME_URL, got %d\n",
1636 info
->rgAltEntry
[0].dwAltNameChoice
);
1637 ok(!lstrcmpW(U(info
->rgAltEntry
[0]).pwszURL
, url
), "Unexpected URL\n");
1640 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, encodedDnsName
,
1641 encodedDnsName
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1642 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1645 info
= (CERT_ALT_NAME_INFO
*)buf
;
1647 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1649 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_DNS_NAME
,
1650 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1651 info
->rgAltEntry
[0].dwAltNameChoice
);
1652 ok(!lstrcmpW(U(info
->rgAltEntry
[0]).pwszDNSName
, dnsName
),
1653 "Unexpected DNS name\n");
1656 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, encodedIPAddr
,
1657 encodedIPAddr
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1658 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1661 info
= (CERT_ALT_NAME_INFO
*)buf
;
1663 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1665 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_IP_ADDRESS
,
1666 "Expected CERT_ALT_NAME_IP_ADDRESS, got %d\n",
1667 info
->rgAltEntry
[0].dwAltNameChoice
);
1668 ok(U(info
->rgAltEntry
[0]).IPAddress
.cbData
== sizeof(localhost
),
1669 "Unexpected IP address length %d\n",
1670 U(info
->rgAltEntry
[0]).IPAddress
.cbData
);
1671 ok(!memcmp(U(info
->rgAltEntry
[0]).IPAddress
.pbData
, localhost
,
1672 sizeof(localhost
)), "Unexpected IP address value\n");
1675 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, encodedOidName
,
1676 sizeof(encodedOidName
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1677 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1680 info
= (CERT_ALT_NAME_INFO
*)buf
;
1682 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1684 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_REGISTERED_ID
,
1685 "Expected CERT_ALT_NAME_REGISTERED_ID, got %d\n",
1686 info
->rgAltEntry
[0].dwAltNameChoice
);
1687 ok(!strcmp(U(info
->rgAltEntry
[0]).pszRegisteredID
, "1.2.3"),
1688 "Expected OID 1.2.3, got %s\n", U(info
->rgAltEntry
[0]).pszRegisteredID
);
1691 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1692 encodedDirectoryName
, sizeof(encodedDirectoryName
),
1693 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1694 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1697 info
= (CERT_ALT_NAME_INFO
*)buf
;
1699 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1701 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_DIRECTORY_NAME
,
1702 "Expected CERT_ALT_NAME_DIRECTORY_NAME, got %d\n",
1703 info
->rgAltEntry
[0].dwAltNameChoice
);
1704 ok(U(info
->rgAltEntry
[0]).DirectoryName
.cbData
==
1705 sizeof(encodedCommonName
), "Unexpected directory name length %d\n",
1706 U(info
->rgAltEntry
[0]).DirectoryName
.cbData
);
1707 ok(!memcmp(U(info
->rgAltEntry
[0]).DirectoryName
.pbData
,
1708 encodedCommonName
, sizeof(encodedCommonName
)),
1709 "Unexpected directory name value\n");
1712 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1713 dns_embedded_null
, sizeof(dns_embedded_null
), CRYPT_DECODE_ALLOC_FLAG
,
1714 NULL
, &buf
, &bufSize
);
1715 /* Fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned about the
1716 * particular failure, just that it doesn't decode.
1717 * It succeeds on (broken) Windows versions that haven't addressed
1718 * embedded NULLs in alternate names.
1720 ok(!ret
|| broken(ret
), "expected failure\n");
1721 /* An embedded bell character is allowed, however. */
1722 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1723 dns_embedded_bell
, sizeof(dns_embedded_bell
), CRYPT_DECODE_ALLOC_FLAG
,
1724 NULL
, &buf
, &bufSize
);
1725 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1728 info
= (CERT_ALT_NAME_INFO
*)buf
;
1730 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1732 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_DNS_NAME
,
1733 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1734 info
->rgAltEntry
[0].dwAltNameChoice
);
1737 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1738 url_embedded_null
, sizeof(dns_embedded_null
), CRYPT_DECODE_ALLOC_FLAG
,
1739 NULL
, &buf
, &bufSize
);
1740 /* Again, fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned
1741 * about the particular failure, just that it doesn't decode.
1742 * It succeeds on (broken) Windows versions that haven't addressed
1743 * embedded NULLs in alternate names.
1745 ok(!ret
|| broken(ret
), "expected failure\n");
1748 struct UnicodeExpectedError
1756 static const WCHAR oneW
[] = { '1',0 };
1757 static const WCHAR aW
[] = { 'a',0 };
1758 static const WCHAR quoteW
[] = { '"', 0 };
1760 static struct UnicodeExpectedError unicodeErrors
[] = {
1761 { CERT_RDN_ANY_TYPE
, oneW
, 0, CRYPT_E_NOT_CHAR_STRING
},
1762 { CERT_RDN_ENCODED_BLOB
, oneW
, 0, CRYPT_E_NOT_CHAR_STRING
},
1763 { CERT_RDN_OCTET_STRING
, oneW
, 0, CRYPT_E_NOT_CHAR_STRING
},
1764 { CERT_RDN_NUMERIC_STRING
, aW
, 0, CRYPT_E_INVALID_NUMERIC_STRING
},
1765 { CERT_RDN_PRINTABLE_STRING
, quoteW
, 0, CRYPT_E_INVALID_PRINTABLE_STRING
},
1766 { CERT_RDN_IA5_STRING
, nihongoURL
, 7, CRYPT_E_INVALID_IA5_STRING
},
1769 struct UnicodeExpectedResult
1773 CRYPT_DATA_BLOB encoded
;
1776 static BYTE oneNumeric
[] = { 0x12, 0x01, 0x31 };
1777 static BYTE onePrintable
[] = { 0x13, 0x01, 0x31 };
1778 static BYTE oneTeletex
[] = { 0x14, 0x01, 0x31 };
1779 static BYTE oneVideotex
[] = { 0x15, 0x01, 0x31 };
1780 static BYTE oneIA5
[] = { 0x16, 0x01, 0x31 };
1781 static BYTE oneGraphic
[] = { 0x19, 0x01, 0x31 };
1782 static BYTE oneVisible
[] = { 0x1a, 0x01, 0x31 };
1783 static BYTE oneUniversal
[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 };
1784 static BYTE oneGeneral
[] = { 0x1b, 0x01, 0x31 };
1785 static BYTE oneBMP
[] = { 0x1e, 0x02, 0x00, 0x31 };
1786 static BYTE oneUTF8
[] = { 0x0c, 0x01, 0x31 };
1787 static BYTE nihongoT61
[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,
1789 static BYTE nihongoGeneral
[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1791 static BYTE nihongoBMP
[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,
1792 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
1793 static BYTE nihongoUTF8
[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1794 0xe2,0x89,0xaf,0xe5,0x9d,0x9b };
1796 static struct UnicodeExpectedResult unicodeResults
[] = {
1797 { CERT_RDN_NUMERIC_STRING
, oneW
, { sizeof(oneNumeric
), oneNumeric
} },
1798 { CERT_RDN_PRINTABLE_STRING
, oneW
, { sizeof(onePrintable
), onePrintable
} },
1799 { CERT_RDN_TELETEX_STRING
, oneW
, { sizeof(oneTeletex
), oneTeletex
} },
1800 { CERT_RDN_VIDEOTEX_STRING
, oneW
, { sizeof(oneVideotex
), oneVideotex
} },
1801 { CERT_RDN_IA5_STRING
, oneW
, { sizeof(oneIA5
), oneIA5
} },
1802 { CERT_RDN_GRAPHIC_STRING
, oneW
, { sizeof(oneGraphic
), oneGraphic
} },
1803 { CERT_RDN_VISIBLE_STRING
, oneW
, { sizeof(oneVisible
), oneVisible
} },
1804 { CERT_RDN_UNIVERSAL_STRING
, oneW
, { sizeof(oneUniversal
), oneUniversal
} },
1805 { CERT_RDN_GENERAL_STRING
, oneW
, { sizeof(oneGeneral
), oneGeneral
} },
1806 { CERT_RDN_BMP_STRING
, oneW
, { sizeof(oneBMP
), oneBMP
} },
1807 { CERT_RDN_UTF8_STRING
, oneW
, { sizeof(oneUTF8
), oneUTF8
} },
1808 { CERT_RDN_BMP_STRING
, nihongoURL
, { sizeof(nihongoBMP
), nihongoBMP
} },
1809 { CERT_RDN_UTF8_STRING
, nihongoURL
, { sizeof(nihongoUTF8
), nihongoUTF8
} },
1812 static struct UnicodeExpectedResult unicodeWeirdness
[] = {
1813 { CERT_RDN_TELETEX_STRING
, nihongoURL
, { sizeof(nihongoT61
), nihongoT61
} },
1814 { CERT_RDN_GENERAL_STRING
, nihongoURL
, { sizeof(nihongoGeneral
), nihongoGeneral
} },
1817 static void test_encodeUnicodeNameValue(DWORD dwEncoding
)
1822 CERT_NAME_VALUE value
;
1826 /* Crashes on win9x */
1827 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, NULL
,
1828 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1829 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
1830 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1832 /* Have to have a string of some sort */
1833 value
.dwValueType
= 0; /* aka CERT_RDN_ANY_TYPE */
1834 value
.Value
.pbData
= NULL
;
1835 value
.Value
.cbData
= 0;
1836 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1837 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1838 ok(!ret
&& GetLastError() == CRYPT_E_NOT_CHAR_STRING
,
1839 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1840 value
.dwValueType
= CERT_RDN_ENCODED_BLOB
;
1841 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1842 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1843 ok(!ret
&& GetLastError() == CRYPT_E_NOT_CHAR_STRING
,
1844 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1845 value
.dwValueType
= CERT_RDN_ANY_TYPE
;
1846 value
.Value
.pbData
= (LPBYTE
)oneW
;
1847 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1848 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1849 ok(!ret
&& GetLastError() == CRYPT_E_NOT_CHAR_STRING
,
1850 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1851 value
.Value
.cbData
= sizeof(oneW
);
1852 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1853 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1854 ok(!ret
&& GetLastError() == CRYPT_E_NOT_CHAR_STRING
,
1855 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1856 /* An encoded string with specified length isn't good enough either */
1857 value
.dwValueType
= CERT_RDN_ENCODED_BLOB
;
1858 value
.Value
.pbData
= oneUniversal
;
1859 value
.Value
.cbData
= sizeof(oneUniversal
);
1860 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1861 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1862 ok(!ret
&& GetLastError() == CRYPT_E_NOT_CHAR_STRING
,
1863 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1864 /* More failure checking */
1865 value
.Value
.cbData
= 0;
1866 for (i
= 0; i
< sizeof(unicodeErrors
) / sizeof(unicodeErrors
[0]); i
++)
1868 value
.Value
.pbData
= (LPBYTE
)unicodeErrors
[i
].str
;
1869 value
.dwValueType
= unicodeErrors
[i
].valueType
;
1870 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1871 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1872 ok(!ret
&& GetLastError() == unicodeErrors
[i
].error
,
1873 "Value type %d: expected %08x, got %08x\n", value
.dwValueType
,
1874 unicodeErrors
[i
].error
, GetLastError());
1875 ok(size
== unicodeErrors
[i
].errorIndex
,
1876 "Expected error index %d, got %d\n", unicodeErrors
[i
].errorIndex
,
1879 /* cbData can be zero if the string is NULL-terminated */
1880 value
.Value
.cbData
= 0;
1881 for (i
= 0; i
< sizeof(unicodeResults
) / sizeof(unicodeResults
[0]); i
++)
1883 value
.Value
.pbData
= (LPBYTE
)unicodeResults
[i
].str
;
1884 value
.dwValueType
= unicodeResults
[i
].valueType
;
1885 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1886 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1887 ok(ret
|| broken(GetLastError() == OSS_PDU_MISMATCH
/* Win9x */),
1888 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1891 ok(size
== unicodeResults
[i
].encoded
.cbData
,
1892 "Value type %d: expected size %d, got %d\n",
1893 value
.dwValueType
, unicodeResults
[i
].encoded
.cbData
, size
);
1894 ok(!memcmp(unicodeResults
[i
].encoded
.pbData
, buf
, size
),
1895 "Value type %d: unexpected value\n", value
.dwValueType
);
1899 /* These "encode," but they do so by truncating each unicode character
1900 * rather than properly encoding it. Kept separate from the proper results,
1901 * because the encoded forms won't decode to their original strings.
1903 for (i
= 0; i
< sizeof(unicodeWeirdness
) / sizeof(unicodeWeirdness
[0]); i
++)
1905 value
.Value
.pbData
= (LPBYTE
)unicodeWeirdness
[i
].str
;
1906 value
.dwValueType
= unicodeWeirdness
[i
].valueType
;
1907 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1908 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1909 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1912 ok(size
== unicodeWeirdness
[i
].encoded
.cbData
,
1913 "Value type %d: expected size %d, got %d\n",
1914 value
.dwValueType
, unicodeWeirdness
[i
].encoded
.cbData
, size
);
1915 ok(!memcmp(unicodeWeirdness
[i
].encoded
.pbData
, buf
, size
),
1916 "Value type %d: unexpected value\n", value
.dwValueType
);
1922 static inline int strncmpW( const WCHAR
*str1
, const WCHAR
*str2
, int n
)
1924 if (n
<= 0) return 0;
1925 while ((--n
> 0) && *str1
&& (*str1
== *str2
)) { str1
++; str2
++; }
1926 return *str1
- *str2
;
1929 static void test_decodeUnicodeNameValue(DWORD dwEncoding
)
1933 for (i
= 0; i
< sizeof(unicodeResults
) / sizeof(unicodeResults
[0]); i
++)
1939 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
,
1940 unicodeResults
[i
].encoded
.pbData
, unicodeResults
[i
].encoded
.cbData
,
1941 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1942 ok(ret
|| broken(GetLastError() == CRYPT_E_NOT_CHAR_STRING
/* Win9x */),
1943 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1946 PCERT_NAME_VALUE value
= (PCERT_NAME_VALUE
)buf
;
1948 ok(value
->dwValueType
== unicodeResults
[i
].valueType
,
1949 "Expected value type %d, got %d\n", unicodeResults
[i
].valueType
,
1950 value
->dwValueType
);
1951 ok(!strncmpW((LPWSTR
)value
->Value
.pbData
, unicodeResults
[i
].str
,
1952 value
->Value
.cbData
/ sizeof(WCHAR
)),
1953 "Unexpected decoded value for index %d (value type %d)\n", i
,
1954 unicodeResults
[i
].valueType
);
1960 struct encodedOctets
1963 const BYTE
*encoded
;
1966 static const unsigned char bin46
[] = { 'h','i',0 };
1967 static const unsigned char bin47
[] = { 0x04,0x02,'h','i',0 };
1968 static const unsigned char bin48
[] = {
1969 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1970 static const unsigned char bin49
[] = {
1971 0x04,0x0f,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1972 static const unsigned char bin50
[] = { 0 };
1973 static const unsigned char bin51
[] = { 0x04,0x00,0 };
1975 static const struct encodedOctets octets
[] = {
1981 static void test_encodeOctets(DWORD dwEncoding
)
1983 CRYPT_DATA_BLOB blob
;
1986 for (i
= 0; i
< sizeof(octets
) / sizeof(octets
[0]); i
++)
1992 blob
.cbData
= strlen((const char*)octets
[i
].val
);
1993 blob
.pbData
= (BYTE
*)octets
[i
].val
;
1994 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_OCTET_STRING
, &blob
,
1995 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1996 ok(ret
, "CryptEncodeObjectEx failed: %d\n", GetLastError());
2000 "Got unexpected type %d for octet string (expected 4)\n", buf
[0]);
2001 ok(buf
[1] == octets
[i
].encoded
[1], "Got length %d, expected %d\n",
2002 buf
[1], octets
[i
].encoded
[1]);
2003 ok(!memcmp(buf
+ 1, octets
[i
].encoded
+ 1,
2004 octets
[i
].encoded
[1] + 1), "Got unexpected value\n");
2010 static void test_decodeOctets(DWORD dwEncoding
)
2014 for (i
= 0; i
< sizeof(octets
) / sizeof(octets
[0]); i
++)
2020 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_OCTET_STRING
,
2021 octets
[i
].encoded
, octets
[i
].encoded
[1] + 2,
2022 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2023 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2024 ok(bufSize
>= sizeof(CRYPT_DATA_BLOB
) + octets
[i
].encoded
[1],
2025 "Expected size >= %d, got %d\n",
2026 (int)sizeof(CRYPT_DATA_BLOB
) + octets
[i
].encoded
[1], bufSize
);
2027 ok(buf
!= NULL
, "Expected allocated buffer\n");
2030 CRYPT_DATA_BLOB
*blob
= (CRYPT_DATA_BLOB
*)buf
;
2033 ok(!memcmp(blob
->pbData
, octets
[i
].val
, blob
->cbData
),
2034 "Unexpected value\n");
2040 static const BYTE bytesToEncode
[] = { 0xff, 0xff };
2045 const BYTE
*encoded
;
2047 const BYTE
*decoded
;
2050 static const unsigned char bin52
[] = { 0x03,0x03,0x00,0xff,0xff };
2051 static const unsigned char bin53
[] = { 0xff,0xff };
2052 static const unsigned char bin54
[] = { 0x03,0x03,0x01,0xff,0xfe };
2053 static const unsigned char bin55
[] = { 0xff,0xfe };
2054 static const unsigned char bin56
[] = { 0x03,0x02,0x01,0xfe };
2055 static const unsigned char bin57
[] = { 0xfe };
2056 static const unsigned char bin58
[] = { 0x03,0x01,0x00 };
2058 static const struct encodedBits bits
[] = {
2059 /* normal test cases */
2060 { 0, bin52
, 2, bin53
},
2061 { 1, bin54
, 2, bin55
},
2062 /* strange test case, showing cUnusedBits >= 8 is allowed */
2063 { 9, bin56
, 1, bin57
},
2066 static void test_encodeBits(DWORD dwEncoding
)
2070 for (i
= 0; i
< sizeof(bits
) / sizeof(bits
[0]); i
++)
2072 CRYPT_BIT_BLOB blob
;
2077 blob
.cbData
= sizeof(bytesToEncode
);
2078 blob
.pbData
= (BYTE
*)bytesToEncode
;
2079 blob
.cUnusedBits
= bits
[i
].cUnusedBits
;
2080 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_BITS
, &blob
,
2081 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2082 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2085 ok(bufSize
== bits
[i
].encoded
[1] + 2,
2086 "%d: Got unexpected size %d, expected %d\n", i
, bufSize
,
2087 bits
[i
].encoded
[1] + 2);
2088 ok(!memcmp(buf
, bits
[i
].encoded
, bits
[i
].encoded
[1] + 2),
2089 "%d: Unexpected value\n", i
);
2095 static void test_decodeBits(DWORD dwEncoding
)
2097 static const BYTE ber
[] = "\x03\x02\x01\xff";
2098 static const BYTE berDecoded
= 0xfe;
2105 for (i
= 0; i
< sizeof(bits
) / sizeof(bits
[0]); i
++)
2107 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BITS
, bits
[i
].encoded
,
2108 bits
[i
].encoded
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
,
2110 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2113 CRYPT_BIT_BLOB
*blob
;
2115 ok(bufSize
>= sizeof(CRYPT_BIT_BLOB
) + bits
[i
].cbDecoded
,
2116 "Got unexpected size %d\n", bufSize
);
2117 blob
= (CRYPT_BIT_BLOB
*)buf
;
2118 ok(blob
->cbData
== bits
[i
].cbDecoded
,
2119 "Got unexpected length %d, expected %d\n", blob
->cbData
,
2121 if (blob
->cbData
&& bits
[i
].cbDecoded
)
2122 ok(!memcmp(blob
->pbData
, bits
[i
].decoded
, bits
[i
].cbDecoded
),
2123 "Unexpected value\n");
2127 /* special case: check that something that's valid in BER but not in DER
2128 * decodes successfully
2130 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BITS
, ber
, ber
[1] + 2,
2131 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2132 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2135 CRYPT_BIT_BLOB
*blob
;
2137 ok(bufSize
>= sizeof(CRYPT_BIT_BLOB
) + sizeof(berDecoded
),
2138 "Got unexpected size %d\n", bufSize
);
2139 blob
= (CRYPT_BIT_BLOB
*)buf
;
2140 ok(blob
->cbData
== sizeof(berDecoded
),
2141 "Got unexpected length %d\n", blob
->cbData
);
2143 ok(*blob
->pbData
== berDecoded
, "Unexpected value\n");
2150 CERT_BASIC_CONSTRAINTS2_INFO info
;
2151 const BYTE
*encoded
;
2154 static const unsigned char bin59
[] = { 0x30,0x00 };
2155 static const unsigned char bin60
[] = { 0x30,0x03,0x01,0x01,0xff };
2156 static const unsigned char bin61
[] = { 0x30,0x03,0x02,0x01,0x00 };
2157 static const unsigned char bin62
[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2158 static const struct Constraints2 constraints2
[] = {
2159 /* empty constraints */
2160 { { FALSE
, FALSE
, 0}, bin59
},
2162 { { TRUE
, FALSE
, 0}, bin60
},
2163 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well,
2164 * but that's not the case
2166 { { FALSE
, TRUE
, 0}, bin61
},
2167 /* can be a CA and has path length constraints set */
2168 { { TRUE
, TRUE
, 1}, bin62
},
2171 static const BYTE emptyConstraint
[] = { 0x30, 0x03, 0x03, 0x01, 0x00 };
2172 static const BYTE encodedDomainName
[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11,
2173 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
2174 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
2175 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2176 static const BYTE constraintWithDomainName
[] = { 0x30, 0x32, 0x03, 0x01, 0x00,
2177 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
2178 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30,
2179 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
2180 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2182 static void test_encodeBasicConstraints(DWORD dwEncoding
)
2184 DWORD i
, bufSize
= 0;
2185 CERT_BASIC_CONSTRAINTS_INFO info
= { { 0 } };
2186 CERT_NAME_BLOB nameBlob
= { sizeof(encodedDomainName
),
2187 (LPBYTE
)encodedDomainName
};
2191 /* First test with the simpler info2 */
2192 for (i
= 0; i
< sizeof(constraints2
) / sizeof(constraints2
[0]); i
++)
2194 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS2
,
2195 &constraints2
[i
].info
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
,
2197 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2200 ok(bufSize
== constraints2
[i
].encoded
[1] + 2,
2201 "Expected %d bytes, got %d\n", constraints2
[i
].encoded
[1] + 2,
2203 ok(!memcmp(buf
, constraints2
[i
].encoded
,
2204 constraints2
[i
].encoded
[1] + 2), "Unexpected value\n");
2208 /* Now test with more complex basic constraints */
2209 info
.SubjectType
.cbData
= 0;
2210 info
.fPathLenConstraint
= FALSE
;
2211 info
.cSubtreesConstraint
= 0;
2212 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS
, &info
,
2213 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2214 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
2215 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2218 ok(bufSize
== sizeof(emptyConstraint
), "Wrong size %d\n", bufSize
);
2219 ok(!memcmp(buf
, emptyConstraint
, sizeof(emptyConstraint
)),
2220 "Unexpected value\n");
2223 /* None of the certs I examined had any subtree constraint, but I test one
2224 * anyway just in case.
2226 info
.cSubtreesConstraint
= 1;
2227 info
.rgSubtreesConstraint
= &nameBlob
;
2228 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS
, &info
,
2229 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2230 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
2231 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2234 ok(bufSize
== sizeof(constraintWithDomainName
), "Wrong size %d\n", bufSize
);
2235 ok(!memcmp(buf
, constraintWithDomainName
,
2236 sizeof(constraintWithDomainName
)), "Unexpected value\n");
2239 /* FIXME: test encoding with subject type. */
2242 static const unsigned char bin63
[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 };
2244 static void test_decodeBasicConstraints(DWORD dwEncoding
)
2246 static const BYTE inverted
[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01,
2248 static const struct Constraints2 badBool
= { { TRUE
, TRUE
, 1 }, bin63
};
2254 /* First test with simpler info2 */
2255 for (i
= 0; i
< sizeof(constraints2
) / sizeof(constraints2
[0]); i
++)
2257 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS2
,
2258 constraints2
[i
].encoded
, constraints2
[i
].encoded
[1] + 2,
2259 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2260 ok(ret
, "CryptDecodeObjectEx failed for item %d: %08x\n", i
,
2264 CERT_BASIC_CONSTRAINTS2_INFO
*info
=
2265 (CERT_BASIC_CONSTRAINTS2_INFO
*)buf
;
2267 ok(!memcmp(info
, &constraints2
[i
].info
, sizeof(*info
)),
2268 "Unexpected value for item %d\n", i
);
2272 /* Check with the order of encoded elements inverted */
2274 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS2
,
2275 inverted
, inverted
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
,
2277 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
2278 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
2279 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2281 ok(!buf
, "Expected buf to be set to NULL\n");
2282 /* Check with a non-DER bool */
2283 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS2
,
2284 badBool
.encoded
, badBool
.encoded
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
2286 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2289 CERT_BASIC_CONSTRAINTS2_INFO
*info
=
2290 (CERT_BASIC_CONSTRAINTS2_INFO
*)buf
;
2292 ok(!memcmp(info
, &badBool
.info
, sizeof(*info
)), "Unexpected value\n");
2295 /* Check with a non-basic constraints value */
2296 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS2
,
2297 encodedCommonName
, encodedCommonName
[1] + 2,
2298 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2299 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
2300 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
2301 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2303 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */
2304 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS
,
2305 emptyConstraint
, sizeof(emptyConstraint
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
2307 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2310 CERT_BASIC_CONSTRAINTS_INFO
*info
= (CERT_BASIC_CONSTRAINTS_INFO
*)buf
;
2312 ok(info
->SubjectType
.cbData
== 0, "Expected no subject type\n");
2313 ok(!info
->fPathLenConstraint
, "Expected no path length constraint\n");
2314 ok(info
->cSubtreesConstraint
== 0, "Expected no subtree constraints\n");
2317 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS
,
2318 constraintWithDomainName
, sizeof(constraintWithDomainName
),
2319 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2320 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2323 CERT_BASIC_CONSTRAINTS_INFO
*info
= (CERT_BASIC_CONSTRAINTS_INFO
*)buf
;
2325 ok(info
->SubjectType
.cbData
== 0, "Expected no subject type\n");
2326 ok(!info
->fPathLenConstraint
, "Expected no path length constraint\n");
2327 ok(info
->cSubtreesConstraint
== 1, "Expected a subtree constraint\n");
2328 if (info
->cSubtreesConstraint
&& info
->rgSubtreesConstraint
)
2330 ok(info
->rgSubtreesConstraint
[0].cbData
==
2331 sizeof(encodedDomainName
), "Wrong size %d\n",
2332 info
->rgSubtreesConstraint
[0].cbData
);
2333 ok(!memcmp(info
->rgSubtreesConstraint
[0].pbData
, encodedDomainName
,
2334 sizeof(encodedDomainName
)), "Unexpected value\n");
2340 /* These are terrible public keys of course, I'm just testing encoding */
2341 static const BYTE modulus1
[] = { 0,0,0,1,1,1,1,1 };
2342 static const BYTE modulus2
[] = { 1,1,1,1,1,0,0,0 };
2343 static const BYTE modulus3
[] = { 0x80,1,1,1,1,0,0,0 };
2344 static const BYTE modulus4
[] = { 1,1,1,1,1,0,0,0x80 };
2345 static const BYTE mod1_encoded
[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 };
2346 static const BYTE mod2_encoded
[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2347 static const BYTE mod3_encoded
[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 };
2348 static const BYTE mod4_encoded
[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2350 struct EncodedRSAPubKey
2352 const BYTE
*modulus
;
2354 const BYTE
*encoded
;
2355 size_t decodedModulusLen
;
2358 struct EncodedRSAPubKey rsaPubKeys
[] = {
2359 { modulus1
, sizeof(modulus1
), mod1_encoded
, sizeof(modulus1
) },
2360 { modulus2
, sizeof(modulus2
), mod2_encoded
, 5 },
2361 { modulus3
, sizeof(modulus3
), mod3_encoded
, 5 },
2362 { modulus4
, sizeof(modulus4
), mod4_encoded
, 8 },
2365 static void test_encodeRsaPublicKey(DWORD dwEncoding
)
2367 BYTE toEncode
[sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) + sizeof(modulus1
)];
2368 BLOBHEADER
*hdr
= (BLOBHEADER
*)toEncode
;
2369 RSAPUBKEY
*rsaPubKey
= (RSAPUBKEY
*)(toEncode
+ sizeof(BLOBHEADER
));
2372 DWORD bufSize
= 0, i
;
2374 /* Try with a bogus blob type */
2376 hdr
->bVersion
= CUR_BLOB_VERSION
;
2378 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
2379 rsaPubKey
->magic
= 0x31415352;
2380 rsaPubKey
->bitlen
= sizeof(modulus1
) * 8;
2381 rsaPubKey
->pubexp
= 65537;
2382 memcpy(toEncode
+ sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
), modulus1
,
2385 ret
= pCryptEncodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2386 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2387 ok(!ret
&& GetLastError() == E_INVALIDARG
,
2388 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2389 /* Now with a bogus reserved field */
2390 hdr
->bType
= PUBLICKEYBLOB
;
2392 ret
= pCryptEncodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2393 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2396 ok(bufSize
== rsaPubKeys
[0].encoded
[1] + 2,
2397 "Expected size %d, got %d\n", rsaPubKeys
[0].encoded
[1] + 2, bufSize
);
2398 ok(!memcmp(buf
, rsaPubKeys
[0].encoded
, bufSize
), "Unexpected value\n");
2401 /* Now with a bogus blob version */
2404 ret
= pCryptEncodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2405 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2408 ok(bufSize
== rsaPubKeys
[0].encoded
[1] + 2,
2409 "Expected size %d, got %d\n", rsaPubKeys
[0].encoded
[1] + 2, bufSize
);
2410 ok(!memcmp(buf
, rsaPubKeys
[0].encoded
, bufSize
), "Unexpected value\n");
2413 /* And with a bogus alg ID */
2414 hdr
->bVersion
= CUR_BLOB_VERSION
;
2415 hdr
->aiKeyAlg
= CALG_DES
;
2416 ret
= pCryptEncodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2417 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2420 ok(bufSize
== rsaPubKeys
[0].encoded
[1] + 2,
2421 "Expected size %d, got %d\n", rsaPubKeys
[0].encoded
[1] + 2, bufSize
);
2422 ok(!memcmp(buf
, rsaPubKeys
[0].encoded
, bufSize
), "Unexpected value\n");
2425 /* Check a couple of RSA-related OIDs */
2426 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
2427 ret
= pCryptEncodeObjectEx(dwEncoding
, szOID_RSA_RSA
,
2428 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2429 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
2430 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2431 ret
= pCryptEncodeObjectEx(dwEncoding
, szOID_RSA_SHA1RSA
,
2432 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2433 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
2434 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2435 /* Finally, all valid */
2436 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
2437 for (i
= 0; i
< sizeof(rsaPubKeys
) / sizeof(rsaPubKeys
[0]); i
++)
2439 memcpy(toEncode
+ sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
),
2440 rsaPubKeys
[i
].modulus
, rsaPubKeys
[i
].modulusLen
);
2441 ret
= pCryptEncodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2442 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2443 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2446 ok(bufSize
== rsaPubKeys
[i
].encoded
[1] + 2,
2447 "Expected size %d, got %d\n", rsaPubKeys
[i
].encoded
[1] + 2,
2449 ok(!memcmp(buf
, rsaPubKeys
[i
].encoded
, bufSize
),
2450 "Unexpected value\n");
2456 static void test_decodeRsaPublicKey(DWORD dwEncoding
)
2463 /* Try with a bad length */
2464 ret
= pCryptDecodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2465 rsaPubKeys
[0].encoded
, rsaPubKeys
[0].encoded
[1],
2466 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2467 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_EOD
||
2468 GetLastError() == OSS_MORE_INPUT
/* Win9x/NT4 */),
2469 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n",
2471 /* Try with a couple of RSA-related OIDs */
2472 ret
= pCryptDecodeObjectEx(dwEncoding
, szOID_RSA_RSA
,
2473 rsaPubKeys
[0].encoded
, rsaPubKeys
[0].encoded
[1] + 2,
2474 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2475 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
2476 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2477 ret
= pCryptDecodeObjectEx(dwEncoding
, szOID_RSA_SHA1RSA
,
2478 rsaPubKeys
[0].encoded
, rsaPubKeys
[0].encoded
[1] + 2,
2479 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2480 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
2481 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2482 /* Now try success cases */
2483 for (i
= 0; i
< sizeof(rsaPubKeys
) / sizeof(rsaPubKeys
[0]); i
++)
2486 ret
= pCryptDecodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2487 rsaPubKeys
[i
].encoded
, rsaPubKeys
[i
].encoded
[1] + 2,
2488 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2489 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2492 BLOBHEADER
*hdr
= (BLOBHEADER
*)buf
;
2493 RSAPUBKEY
*rsaPubKey
= (RSAPUBKEY
*)(buf
+ sizeof(BLOBHEADER
));
2495 ok(bufSize
>= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
2496 rsaPubKeys
[i
].decodedModulusLen
,
2497 "Wrong size %d\n", bufSize
);
2498 ok(hdr
->bType
== PUBLICKEYBLOB
,
2499 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB
,
2501 ok(hdr
->bVersion
== CUR_BLOB_VERSION
,
2502 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
2503 CUR_BLOB_VERSION
, hdr
->bVersion
);
2504 ok(hdr
->reserved
== 0, "Expected reserved 0, got %d\n",
2506 ok(hdr
->aiKeyAlg
== CALG_RSA_KEYX
,
2507 "Expected CALG_RSA_KEYX, got %08x\n", hdr
->aiKeyAlg
);
2508 ok(rsaPubKey
->magic
== 0x31415352,
2509 "Expected magic RSA1, got %08x\n", rsaPubKey
->magic
);
2510 ok(rsaPubKey
->bitlen
== rsaPubKeys
[i
].decodedModulusLen
* 8,
2511 "Wrong bit len %d\n", rsaPubKey
->bitlen
);
2512 ok(rsaPubKey
->pubexp
== 65537, "Expected pubexp 65537, got %d\n",
2514 ok(!memcmp(buf
+ sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
),
2515 rsaPubKeys
[i
].modulus
, rsaPubKeys
[i
].decodedModulusLen
),
2516 "Unexpected modulus\n");
2522 static const BYTE intSequence
[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01,
2523 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02,
2524 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2526 static const BYTE mixedSequence
[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
2527 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f,
2528 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02,
2529 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2531 static void test_encodeSequenceOfAny(DWORD dwEncoding
)
2533 CRYPT_DER_BLOB blobs
[sizeof(ints
) / sizeof(ints
[0])];
2534 CRYPT_SEQUENCE_OF_ANY seq
;
2540 /* Encode a homogeneous sequence */
2541 for (i
= 0; i
< sizeof(ints
) / sizeof(ints
[0]); i
++)
2543 blobs
[i
].cbData
= ints
[i
].encoded
[1] + 2;
2544 blobs
[i
].pbData
= (BYTE
*)ints
[i
].encoded
;
2546 seq
.cValue
= sizeof(ints
) / sizeof(ints
[0]);
2547 seq
.rgValue
= blobs
;
2549 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_SEQUENCE_OF_ANY
, &seq
,
2550 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2551 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2554 ok(bufSize
== sizeof(intSequence
), "Wrong size %d\n", bufSize
);
2555 ok(!memcmp(buf
, intSequence
, intSequence
[1] + 2), "Unexpected value\n");
2558 /* Change the type of the first element in the sequence, and give it
2561 blobs
[0].cbData
= times
[0].encodedTime
[1] + 2;
2562 blobs
[0].pbData
= (BYTE
*)times
[0].encodedTime
;
2563 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_SEQUENCE_OF_ANY
, &seq
,
2564 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2565 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2568 ok(bufSize
== sizeof(mixedSequence
), "Wrong size %d\n", bufSize
);
2569 ok(!memcmp(buf
, mixedSequence
, mixedSequence
[1] + 2),
2570 "Unexpected value\n");
2575 static void test_decodeSequenceOfAny(DWORD dwEncoding
)
2581 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_SEQUENCE_OF_ANY
, intSequence
,
2582 intSequence
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2583 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2586 CRYPT_SEQUENCE_OF_ANY
*seq
= (CRYPT_SEQUENCE_OF_ANY
*)buf
;
2589 ok(seq
->cValue
== sizeof(ints
) / sizeof(ints
[0]),
2590 "Wrong elements %d\n", seq
->cValue
);
2591 for (i
= 0; i
< min(seq
->cValue
, sizeof(ints
) / sizeof(ints
[0])); i
++)
2593 ok(seq
->rgValue
[i
].cbData
== ints
[i
].encoded
[1] + 2,
2594 "Expected %d bytes, got %d\n", ints
[i
].encoded
[1] + 2,
2595 seq
->rgValue
[i
].cbData
);
2596 ok(!memcmp(seq
->rgValue
[i
].pbData
, ints
[i
].encoded
,
2597 ints
[i
].encoded
[1] + 2), "Unexpected value\n");
2601 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_SEQUENCE_OF_ANY
, mixedSequence
,
2602 mixedSequence
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
,
2604 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2607 CRYPT_SEQUENCE_OF_ANY
*seq
= (CRYPT_SEQUENCE_OF_ANY
*)buf
;
2609 ok(seq
->cValue
== sizeof(ints
) / sizeof(ints
[0]),
2610 "Wrong elements %d\n", seq
->cValue
);
2611 /* Just check the first element since it's all that changed */
2612 ok(seq
->rgValue
[0].cbData
== times
[0].encodedTime
[1] + 2,
2613 "Expected %d bytes, got %d\n", times
[0].encodedTime
[1] + 2,
2614 seq
->rgValue
[0].cbData
);
2615 ok(!memcmp(seq
->rgValue
[0].pbData
, times
[0].encodedTime
,
2616 times
[0].encodedTime
[1] + 2), "Unexpected value\n");
2621 struct encodedExtensions
2623 CERT_EXTENSIONS exts
;
2624 const BYTE
*encoded
;
2627 static BYTE crit_ext_data
[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2628 static BYTE noncrit_ext_data
[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2629 static CHAR oid_basic_constraints2
[] = szOID_BASIC_CONSTRAINTS2
;
2630 static CERT_EXTENSION criticalExt
=
2631 { oid_basic_constraints2
, TRUE
, { 8, crit_ext_data
} };
2632 static CERT_EXTENSION nonCriticalExt
=
2633 { oid_basic_constraints2
, FALSE
, { 8, noncrit_ext_data
} };
2634 static CHAR oid_short
[] = "1.1";
2635 static CERT_EXTENSION extWithShortOid
=
2636 { oid_short
, FALSE
, { 0, NULL
} };
2638 static const BYTE ext0
[] = { 0x30,0x00 };
2639 static const BYTE ext1
[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2640 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2641 static const BYTE ext2
[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2642 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2643 static const BYTE ext3
[] = { 0x30,0x07,0x30,0x05,0x06,0x01,0x29,0x04,0x00 };
2645 static const struct encodedExtensions exts
[] = {
2646 { { 0, NULL
}, ext0
},
2647 { { 1, &criticalExt
}, ext1
},
2648 { { 1, &nonCriticalExt
}, ext2
},
2649 { { 1, &extWithShortOid
}, ext3
}
2652 static void test_encodeExtensions(DWORD dwEncoding
)
2656 for (i
= 0; i
< sizeof(exts
) / sizeof(exts
[i
]); i
++)
2662 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_EXTENSIONS
, &exts
[i
].exts
,
2663 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2664 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2667 ok(bufSize
== exts
[i
].encoded
[1] + 2,
2668 "Expected %d bytes, got %d\n", exts
[i
].encoded
[1] + 2, bufSize
);
2669 ok(!memcmp(buf
, exts
[i
].encoded
, exts
[i
].encoded
[1] + 2),
2670 "Unexpected value\n");
2676 static void test_decodeExtensions(DWORD dwEncoding
)
2680 for (i
= 0; i
< sizeof(exts
) / sizeof(exts
[i
]); i
++)
2686 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_EXTENSIONS
,
2687 exts
[i
].encoded
, exts
[i
].encoded
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
,
2688 NULL
, &buf
, &bufSize
);
2689 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2692 CERT_EXTENSIONS
*ext
= (CERT_EXTENSIONS
*)buf
;
2695 ok(ext
->cExtension
== exts
[i
].exts
.cExtension
,
2696 "Expected %d extensions, see %d\n", exts
[i
].exts
.cExtension
,
2698 for (j
= 0; j
< min(ext
->cExtension
, exts
[i
].exts
.cExtension
); j
++)
2700 ok(!strcmp(ext
->rgExtension
[j
].pszObjId
,
2701 exts
[i
].exts
.rgExtension
[j
].pszObjId
),
2702 "Expected OID %s, got %s\n",
2703 exts
[i
].exts
.rgExtension
[j
].pszObjId
,
2704 ext
->rgExtension
[j
].pszObjId
);
2705 ok(!memcmp(ext
->rgExtension
[j
].Value
.pbData
,
2706 exts
[i
].exts
.rgExtension
[j
].Value
.pbData
,
2707 exts
[i
].exts
.rgExtension
[j
].Value
.cbData
),
2708 "Unexpected value\n");
2715 /* MS encodes public key info with a NULL if the algorithm identifier's
2716 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2717 * it encodes them by omitting the algorithm parameters. It accepts either
2718 * form for decoding.
2720 struct encodedPublicKey
2722 CERT_PUBLIC_KEY_INFO info
;
2723 const BYTE
*encoded
;
2724 const BYTE
*encodedNoNull
;
2725 CERT_PUBLIC_KEY_INFO decoded
;
2728 static const BYTE aKey
[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2730 static const BYTE params
[] = { 0x02, 0x01, 0x01 };
2732 static const unsigned char bin64
[] = {
2733 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2734 static const unsigned char bin65
[] = {
2735 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2736 static const unsigned char bin66
[] = {
2737 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2738 static const unsigned char bin67
[] = {
2739 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2740 static const unsigned char bin68
[] = {
2741 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01,
2742 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2743 static const unsigned char bin69
[] = {
2744 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2745 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2746 static const unsigned char bin70
[] = {
2747 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2748 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2750 static const unsigned char bin71
[] = {
2751 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2752 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2754 static unsigned char bin72
[] = { 0x05,0x00};
2756 static CHAR oid_bogus
[] = "1.2.3",
2757 oid_rsa
[] = szOID_RSA
;
2759 static const struct encodedPublicKey pubKeys
[] = {
2760 /* with a bogus OID */
2761 { { { oid_bogus
, { 0, NULL
} }, { 0, NULL
, 0 } },
2763 { { oid_bogus
, { 2, bin72
} }, { 0, NULL
, 0 } } },
2764 /* some normal keys */
2765 { { { oid_rsa
, { 0, NULL
} }, { 0, NULL
, 0} },
2767 { { oid_rsa
, { 2, bin72
} }, { 0, NULL
, 0 } } },
2768 { { { oid_rsa
, { 0, NULL
} }, { sizeof(aKey
), (BYTE
*)aKey
, 0} },
2770 { { oid_rsa
, { 2, bin72
} }, { sizeof(aKey
), (BYTE
*)aKey
, 0} } },
2771 /* with add'l parameters--note they must be DER-encoded */
2772 { { { oid_rsa
, { sizeof(params
), (BYTE
*)params
} }, { sizeof(aKey
),
2773 (BYTE
*)aKey
, 0 } },
2775 { { oid_rsa
, { sizeof(params
), (BYTE
*)params
} }, { sizeof(aKey
),
2776 (BYTE
*)aKey
, 0 } } },
2779 static void test_encodePublicKeyInfo(DWORD dwEncoding
)
2783 for (i
= 0; i
< sizeof(pubKeys
) / sizeof(pubKeys
[0]); i
++)
2789 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_PUBLIC_KEY_INFO
,
2790 &pubKeys
[i
].info
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
,
2792 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
2793 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2796 ok(bufSize
== pubKeys
[i
].encoded
[1] + 2,
2797 "Expected %d bytes, got %d\n", pubKeys
[i
].encoded
[1] + 2, bufSize
);
2798 if (bufSize
== pubKeys
[i
].encoded
[1] + 2)
2799 ok(!memcmp(buf
, pubKeys
[i
].encoded
, pubKeys
[i
].encoded
[1] + 2),
2800 "Unexpected value\n");
2806 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO
*expected
,
2807 const CERT_PUBLIC_KEY_INFO
*got
)
2809 ok(!strcmp(expected
->Algorithm
.pszObjId
, got
->Algorithm
.pszObjId
),
2810 "Expected OID %s, got %s\n", expected
->Algorithm
.pszObjId
,
2811 got
->Algorithm
.pszObjId
);
2812 ok(expected
->Algorithm
.Parameters
.cbData
==
2813 got
->Algorithm
.Parameters
.cbData
,
2814 "Expected parameters of %d bytes, got %d\n",
2815 expected
->Algorithm
.Parameters
.cbData
, got
->Algorithm
.Parameters
.cbData
);
2816 if (expected
->Algorithm
.Parameters
.cbData
)
2817 ok(!memcmp(expected
->Algorithm
.Parameters
.pbData
,
2818 got
->Algorithm
.Parameters
.pbData
, got
->Algorithm
.Parameters
.cbData
),
2819 "Unexpected algorithm parameters\n");
2820 ok(expected
->PublicKey
.cbData
== got
->PublicKey
.cbData
,
2821 "Expected public key of %d bytes, got %d\n",
2822 expected
->PublicKey
.cbData
, got
->PublicKey
.cbData
);
2823 if (expected
->PublicKey
.cbData
)
2824 ok(!memcmp(expected
->PublicKey
.pbData
, got
->PublicKey
.pbData
,
2825 got
->PublicKey
.cbData
), "Unexpected public key value\n");
2828 static void test_decodePublicKeyInfo(DWORD dwEncoding
)
2830 static const BYTE bogusPubKeyInfo
[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
2831 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
2832 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
2833 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2839 for (i
= 0; i
< sizeof(pubKeys
) / sizeof(pubKeys
[0]); i
++)
2841 /* The NULL form decodes to the decoded member */
2842 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_PUBLIC_KEY_INFO
,
2843 pubKeys
[i
].encoded
, pubKeys
[i
].encoded
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
,
2844 NULL
, &buf
, &bufSize
);
2845 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2848 comparePublicKeyInfo(&pubKeys
[i
].decoded
,
2849 (CERT_PUBLIC_KEY_INFO
*)buf
);
2852 /* The non-NULL form decodes to the original */
2853 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_PUBLIC_KEY_INFO
,
2854 pubKeys
[i
].encodedNoNull
, pubKeys
[i
].encodedNoNull
[1] + 2,
2855 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2856 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2859 comparePublicKeyInfo(&pubKeys
[i
].info
, (CERT_PUBLIC_KEY_INFO
*)buf
);
2863 /* Test with bogus (not valid DER) parameters */
2864 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_PUBLIC_KEY_INFO
,
2865 bogusPubKeyInfo
, bogusPubKeyInfo
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
,
2866 NULL
, &buf
, &bufSize
);
2867 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
2868 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
2869 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2873 static const BYTE v1Cert
[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
2874 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2875 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
2876 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
2877 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2878 static const BYTE v2Cert
[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02,
2879 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2880 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2881 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2882 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2883 static const BYTE v3Cert
[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2884 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2885 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2886 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2887 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2888 static const BYTE v4Cert
[] = {
2889 0x30,0x38,0xa0,0x03,0x02,0x01,0x03,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,
2890 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
2891 0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
2892 0x30,0x30,0x30,0x5a,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00 };
2893 static const BYTE v1CertWithConstraints
[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
2894 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2895 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2896 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2897 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2898 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2899 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2900 static const BYTE v1CertWithSerial
[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
2901 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2902 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2903 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2904 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2905 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2906 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2907 static const BYTE bigCert
[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2908 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
2909 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
2910 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
2911 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
2912 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
2913 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
2914 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
2915 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
2916 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2917 static const BYTE v1CertWithPubKey
[] = {
2918 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2919 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2920 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2921 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2922 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2923 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2924 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2925 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2926 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
2927 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
2929 static const BYTE v1CertWithPubKeyNoNull
[] = {
2930 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2931 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2932 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2933 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2934 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2935 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2936 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2937 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2938 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
2939 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2940 static const BYTE v1CertWithSubjectKeyId
[] = {
2941 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2942 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2943 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2944 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2945 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2946 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2947 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
2948 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2949 0x4c,0x61,0x6e,0x67,0x00 };
2950 static const BYTE v1CertWithIssuerUniqueId
[] = {
2951 0x30,0x38,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
2952 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
2953 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
2954 0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x81,0x02,0x00,0x01 };
2955 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueId
[] = {
2956 0x30,0x81,0x99,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2957 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2958 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2959 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2960 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2961 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2962 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2963 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2964 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,
2965 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
2966 0x01,0x01,0xff,0x02,0x01,0x01 };
2967 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull
[] = {
2968 0x30,0x81,0x97,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2969 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2970 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2971 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2972 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2973 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2974 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2975 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2976 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
2977 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
2978 0xff,0x02,0x01,0x01 };
2980 static const BYTE serialNum
[] = { 0x01 };
2982 static void test_encodeCertToBeSigned(DWORD dwEncoding
)
2987 CERT_INFO info
= { 0 };
2988 static char oid_rsa_rsa
[] = szOID_RSA_RSA
;
2989 static char oid_subject_key_identifier
[] = szOID_SUBJECT_KEY_IDENTIFIER
;
2994 /* Test with NULL pvStructInfo (crashes on win9x) */
2995 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, NULL
,
2996 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
2997 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
2998 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3000 /* Test with a V1 cert */
3001 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3002 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3003 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
3004 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3007 ok(size
== v1Cert
[1] + 2, "Expected size %d, got %d\n",
3008 v1Cert
[1] + 2, size
);
3009 ok(!memcmp(buf
, v1Cert
, size
), "Got unexpected value\n");
3013 info
.dwVersion
= CERT_V2
;
3014 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3015 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3016 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
3017 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3020 ok(size
== sizeof(v2Cert
), "Wrong size %d\n", size
);
3021 ok(!memcmp(buf
, v2Cert
, size
), "Got unexpected value\n");
3025 info
.dwVersion
= CERT_V3
;
3026 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3027 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3028 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
3029 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3032 ok(size
== sizeof(v3Cert
), "Wrong size %d\n", size
);
3033 ok(!memcmp(buf
, v3Cert
, size
), "Got unexpected value\n");
3037 info
.dwVersion
= 3; /* Not a typo, CERT_V3 is 2 */
3038 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3039 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3042 ok(size
== sizeof(v4Cert
), "Wrong size %d\n", size
);
3043 ok(!memcmp(buf
, v4Cert
, size
), "Unexpected value\n");
3046 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
3047 * API doesn't prevent it)
3049 info
.dwVersion
= CERT_V1
;
3050 info
.cExtension
= 1;
3051 info
.rgExtension
= &criticalExt
;
3052 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3053 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3054 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
3055 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3058 ok(size
== sizeof(v1CertWithConstraints
), "Wrong size %d\n", size
);
3059 ok(!memcmp(buf
, v1CertWithConstraints
, size
), "Got unexpected value\n");
3062 /* test v1 cert with a serial number */
3063 info
.SerialNumber
.cbData
= sizeof(serialNum
);
3064 info
.SerialNumber
.pbData
= (BYTE
*)serialNum
;
3065 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3066 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3069 ok(size
== sizeof(v1CertWithSerial
), "Wrong size %d\n", size
);
3070 ok(!memcmp(buf
, v1CertWithSerial
, size
), "Got unexpected value\n");
3073 /* Test v1 cert with an issuer name, serial number, and issuer unique id */
3074 info
.dwVersion
= CERT_V1
;
3075 info
.cExtension
= 0;
3076 info
.IssuerUniqueId
.cbData
= sizeof(serialNum
);
3077 info
.IssuerUniqueId
.pbData
= (BYTE
*)serialNum
;
3078 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3079 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3080 ok(ret
|| broken(GetLastError() == OSS_BAD_PTR
/* Win98 */),
3081 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3084 ok(size
== sizeof(v1CertWithIssuerUniqueId
), "Wrong size %d\n", size
);
3085 ok(!memcmp(buf
, v1CertWithIssuerUniqueId
, size
),
3086 "Got unexpected value\n");
3089 /* Test v1 cert with an issuer name, a subject name, and a serial number */
3090 info
.IssuerUniqueId
.cbData
= 0;
3091 info
.IssuerUniqueId
.pbData
= NULL
;
3092 info
.cExtension
= 1;
3093 info
.rgExtension
= &criticalExt
;
3094 info
.Issuer
.cbData
= sizeof(encodedCommonName
);
3095 info
.Issuer
.pbData
= (BYTE
*)encodedCommonName
;
3096 info
.Subject
.cbData
= sizeof(encodedCommonName
);
3097 info
.Subject
.pbData
= (BYTE
*)encodedCommonName
;
3098 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3099 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3102 ok(size
== sizeof(bigCert
), "Wrong size %d\n", size
);
3103 ok(!memcmp(buf
, bigCert
, size
), "Got unexpected value\n");
3106 /* Add a public key */
3107 info
.SubjectPublicKeyInfo
.Algorithm
.pszObjId
= oid_rsa_rsa
;
3108 info
.SubjectPublicKeyInfo
.PublicKey
.cbData
= sizeof(aKey
);
3109 info
.SubjectPublicKeyInfo
.PublicKey
.pbData
= (LPBYTE
)aKey
;
3110 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3111 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3114 ok(size
== sizeof(v1CertWithPubKey
) ||
3115 size
== sizeof(v1CertWithPubKeyNoNull
), "Wrong size %d\n", size
);
3116 if (size
== sizeof(v1CertWithPubKey
))
3117 ok(!memcmp(buf
, v1CertWithPubKey
, size
), "Got unexpected value\n");
3118 else if (size
== sizeof(v1CertWithPubKeyNoNull
))
3119 ok(!memcmp(buf
, v1CertWithPubKeyNoNull
, size
),
3120 "Got unexpected value\n");
3123 /* Again add an issuer unique id */
3124 info
.IssuerUniqueId
.cbData
= sizeof(serialNum
);
3125 info
.IssuerUniqueId
.pbData
= (BYTE
*)serialNum
;
3126 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3127 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3128 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3131 ok(size
== sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId
) ||
3132 size
== sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull
),
3133 "Wrong size %d\n", size
);
3134 if (size
== sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId
))
3135 ok(!memcmp(buf
, v1CertWithSubjectIssuerSerialAndIssuerUniqueId
,
3136 size
), "unexpected value\n");
3138 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull
))
3140 v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull
, size
),
3141 "unexpected value\n");
3144 /* Remove the public key, and add a subject key identifier extension */
3145 info
.IssuerUniqueId
.cbData
= 0;
3146 info
.IssuerUniqueId
.pbData
= NULL
;
3147 info
.SubjectPublicKeyInfo
.Algorithm
.pszObjId
= NULL
;
3148 info
.SubjectPublicKeyInfo
.PublicKey
.cbData
= 0;
3149 info
.SubjectPublicKeyInfo
.PublicKey
.pbData
= NULL
;
3150 ext
.pszObjId
= oid_subject_key_identifier
;
3151 ext
.fCritical
= FALSE
;
3152 ext
.Value
.cbData
= sizeof(octetCommonNameValue
);
3153 ext
.Value
.pbData
= octetCommonNameValue
;
3154 info
.cExtension
= 1;
3155 info
.rgExtension
= &ext
;
3156 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3157 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3160 ok(size
== sizeof(v1CertWithSubjectKeyId
), "Wrong size %d\n", size
);
3161 ok(!memcmp(buf
, v1CertWithSubjectKeyId
, size
), "Unexpected value\n");
3166 static void test_decodeCertToBeSigned(DWORD dwEncoding
)
3168 static const BYTE
*corruptCerts
[] = { v1Cert
, v2Cert
, v3Cert
, v4Cert
,
3169 v1CertWithConstraints
, v1CertWithSerial
, v1CertWithIssuerUniqueId
};
3174 /* Test with NULL pbEncoded */
3175 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, NULL
, 0,
3176 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3177 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_EOD
||
3178 GetLastError() == OSS_BAD_ARG
/* Win9x */),
3179 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
3182 /* Crashes on win9x */
3183 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, NULL
, 1,
3184 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3185 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
3186 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3188 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT or
3189 * CRYPT_E_ASN1_BADTAG, because at a minimum a cert must have a non-zero
3190 * serial number, an issuer, a subject, and a public key.
3192 for (i
= 0; i
< sizeof(corruptCerts
) / sizeof(corruptCerts
[0]); i
++)
3194 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
,
3195 corruptCerts
[i
], corruptCerts
[i
][1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3197 ok(!ret
, "Expected failure\n");
3199 /* The following succeeds, even though v1 certs are not allowed to have
3202 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
,
3203 v1CertWithSubjectKeyId
, sizeof(v1CertWithSubjectKeyId
),
3204 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3205 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3208 CERT_INFO
*info
= (CERT_INFO
*)buf
;
3210 ok(size
>= sizeof(CERT_INFO
), "Wrong size %d\n", size
);
3211 ok(info
->dwVersion
== CERT_V1
, "expected CERT_V1, got %d\n",
3213 ok(info
->cExtension
== 1, "expected 1 extension, got %d\n",
3217 /* The following also succeeds, even though V1 certs are not allowed to
3218 * have issuer unique ids.
3220 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
,
3221 v1CertWithSubjectIssuerSerialAndIssuerUniqueId
,
3222 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId
),
3223 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3224 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3227 CERT_INFO
*info
= (CERT_INFO
*)buf
;
3229 ok(size
>= sizeof(CERT_INFO
), "Wrong size %d\n", size
);
3230 ok(info
->dwVersion
== CERT_V1
, "expected CERT_V1, got %d\n",
3232 ok(info
->IssuerUniqueId
.cbData
== sizeof(serialNum
),
3233 "unexpected issuer unique id size %d\n", info
->IssuerUniqueId
.cbData
);
3234 ok(!memcmp(info
->IssuerUniqueId
.pbData
, serialNum
, sizeof(serialNum
)),
3235 "unexpected issuer unique id value\n");
3238 /* Now check with serial number, subject and issuer specified */
3239 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, bigCert
,
3240 sizeof(bigCert
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3241 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3244 CERT_INFO
*info
= (CERT_INFO
*)buf
;
3246 ok(size
>= sizeof(CERT_INFO
), "Wrong size %d\n", size
);
3247 ok(info
->SerialNumber
.cbData
== 1,
3248 "Expected serial number size 1, got %d\n", info
->SerialNumber
.cbData
);
3249 ok(*info
->SerialNumber
.pbData
== *serialNum
,
3250 "Expected serial number %d, got %d\n", *serialNum
,
3251 *info
->SerialNumber
.pbData
);
3252 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
3253 "Wrong size %d\n", info
->Issuer
.cbData
);
3254 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
3255 "Unexpected issuer\n");
3256 ok(info
->Subject
.cbData
== sizeof(encodedCommonName
),
3257 "Wrong size %d\n", info
->Subject
.cbData
);
3258 ok(!memcmp(info
->Subject
.pbData
, encodedCommonName
,
3259 info
->Subject
.cbData
), "Unexpected subject\n");
3262 /* Check again with pub key specified */
3263 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
,
3264 v1CertWithPubKey
, sizeof(v1CertWithPubKey
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3266 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3269 CERT_INFO
*info
= (CERT_INFO
*)buf
;
3271 ok(size
>= sizeof(CERT_INFO
), "Wrong size %d\n", size
);
3272 ok(info
->SerialNumber
.cbData
== 1,
3273 "Expected serial number size 1, got %d\n", info
->SerialNumber
.cbData
);
3274 ok(*info
->SerialNumber
.pbData
== *serialNum
,
3275 "Expected serial number %d, got %d\n", *serialNum
,
3276 *info
->SerialNumber
.pbData
);
3277 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
3278 "Wrong size %d\n", info
->Issuer
.cbData
);
3279 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
3280 "Unexpected issuer\n");
3281 ok(info
->Subject
.cbData
== sizeof(encodedCommonName
),
3282 "Wrong size %d\n", info
->Subject
.cbData
);
3283 ok(!memcmp(info
->Subject
.pbData
, encodedCommonName
,
3284 info
->Subject
.cbData
), "Unexpected subject\n");
3285 ok(!strcmp(info
->SubjectPublicKeyInfo
.Algorithm
.pszObjId
,
3286 szOID_RSA_RSA
), "Expected szOID_RSA_RSA, got %s\n",
3287 info
->SubjectPublicKeyInfo
.Algorithm
.pszObjId
);
3288 ok(info
->SubjectPublicKeyInfo
.PublicKey
.cbData
== sizeof(aKey
),
3289 "Wrong size %d\n", info
->SubjectPublicKeyInfo
.PublicKey
.cbData
);
3290 ok(!memcmp(info
->SubjectPublicKeyInfo
.PublicKey
.pbData
, aKey
,
3291 sizeof(aKey
)), "Unexpected public key\n");
3296 static const BYTE hash
[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
3299 static const BYTE signedBigCert
[] = {
3300 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
3301 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
3302 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
3303 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3304 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
3305 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
3306 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
3307 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
3308 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
3309 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3310 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
3311 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
3313 static void test_encodeCert(DWORD dwEncoding
)
3315 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
3316 * also that bigCert is a NULL-terminated string, so don't count its
3317 * last byte (otherwise the signed cert won't decode.)
3319 CERT_SIGNED_CONTENT_INFO info
= { { sizeof(bigCert
), (BYTE
*)bigCert
},
3320 { NULL
, { 0, NULL
} }, { sizeof(hash
), (BYTE
*)hash
, 0 } };
3325 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT
, &info
,
3326 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
3327 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3330 ok(bufSize
== sizeof(signedBigCert
), "Wrong size %d\n", bufSize
);
3331 ok(!memcmp(buf
, signedBigCert
, bufSize
), "Unexpected cert\n");
3336 static void test_decodeCert(DWORD dwEncoding
)
3342 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT
, signedBigCert
,
3343 sizeof(signedBigCert
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3344 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3347 CERT_SIGNED_CONTENT_INFO
*info
= (CERT_SIGNED_CONTENT_INFO
*)buf
;
3349 ok(info
->ToBeSigned
.cbData
== sizeof(bigCert
),
3350 "Wrong cert size %d\n", info
->ToBeSigned
.cbData
);
3351 ok(!memcmp(info
->ToBeSigned
.pbData
, bigCert
, info
->ToBeSigned
.cbData
),
3352 "Unexpected cert\n");
3353 ok(info
->Signature
.cbData
== sizeof(hash
),
3354 "Wrong signature size %d\n", info
->Signature
.cbData
);
3355 ok(!memcmp(info
->Signature
.pbData
, hash
, info
->Signature
.cbData
),
3356 "Unexpected signature\n");
3359 /* A signed cert decodes as a CERT_INFO too */
3360 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, signedBigCert
,
3361 sizeof(signedBigCert
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3362 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3365 CERT_INFO
*info
= (CERT_INFO
*)buf
;
3367 ok(size
>= sizeof(CERT_INFO
), "Wrong size %d\n", size
);
3368 ok(info
->SerialNumber
.cbData
== 1,
3369 "Expected serial number size 1, got %d\n", info
->SerialNumber
.cbData
);
3370 ok(*info
->SerialNumber
.pbData
== *serialNum
,
3371 "Expected serial number %d, got %d\n", *serialNum
,
3372 *info
->SerialNumber
.pbData
);
3373 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
3374 "Wrong size %d\n", info
->Issuer
.cbData
);
3375 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
3376 "Unexpected issuer\n");
3377 ok(info
->Subject
.cbData
== sizeof(encodedCommonName
),
3378 "Wrong size %d\n", info
->Subject
.cbData
);
3379 ok(!memcmp(info
->Subject
.pbData
, encodedCommonName
,
3380 info
->Subject
.cbData
), "Unexpected subject\n");
3385 static const BYTE emptyDistPoint
[] = { 0x30, 0x02, 0x30, 0x00 };
3386 static const BYTE distPointWithUrl
[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3387 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3388 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3389 static const BYTE distPointWithReason
[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3391 static const BYTE distPointWithIssuer
[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3392 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3393 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3394 static const BYTE distPointWithUrlAndIssuer
[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3395 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3396 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3397 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3398 0x2e, 0x6f, 0x72, 0x67 };
3399 static const BYTE crlReason
= CRL_REASON_KEY_COMPROMISE
|
3400 CRL_REASON_AFFILIATION_CHANGED
;
3402 static void test_encodeCRLDistPoints(DWORD dwEncoding
)
3404 CRL_DIST_POINTS_INFO info
= { 0 };
3405 CRL_DIST_POINT point
= { { 0 } };
3406 CERT_ALT_NAME_ENTRY entry
= { 0 };
3411 /* Test with an empty info */
3412 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3413 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3414 ok(!ret
&& GetLastError() == E_INVALIDARG
,
3415 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3416 /* Test with one empty dist point */
3417 info
.cDistPoint
= 1;
3418 info
.rgDistPoint
= &point
;
3419 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3420 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3421 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3424 ok(size
== sizeof(emptyDistPoint
), "Wrong size %d\n", size
);
3425 ok(!memcmp(buf
, emptyDistPoint
, size
), "Unexpected value\n");
3428 /* A dist point with an invalid name */
3429 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3430 entry
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
3431 U(entry
).pwszURL
= (LPWSTR
)nihongoURL
;
3432 U(point
.DistPointName
).FullName
.cAltEntry
= 1;
3433 U(point
.DistPointName
).FullName
.rgAltEntry
= &entry
;
3434 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3435 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3436 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_IA5_STRING
,
3437 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
3438 /* The first invalid character is at index 7 */
3439 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size
) == 7,
3440 "Expected invalid char at index 7, got %d\n",
3441 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size
));
3442 /* A dist point with (just) a valid name */
3443 U(entry
).pwszURL
= (LPWSTR
)url
;
3444 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3445 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3446 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3449 ok(size
== sizeof(distPointWithUrl
), "Wrong size %d\n", size
);
3450 ok(!memcmp(buf
, distPointWithUrl
, size
), "Unexpected value\n");
3453 /* A dist point with (just) reason flags */
3454 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
3455 point
.ReasonFlags
.cbData
= sizeof(crlReason
);
3456 point
.ReasonFlags
.pbData
= (LPBYTE
)&crlReason
;
3457 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3458 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3459 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3462 ok(size
== sizeof(distPointWithReason
), "Wrong size %d\n", size
);
3463 ok(!memcmp(buf
, distPointWithReason
, size
), "Unexpected value\n");
3466 /* A dist point with just an issuer */
3467 point
.ReasonFlags
.cbData
= 0;
3468 point
.CRLIssuer
.cAltEntry
= 1;
3469 point
.CRLIssuer
.rgAltEntry
= &entry
;
3470 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3471 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3472 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3475 ok(size
== sizeof(distPointWithIssuer
), "Wrong size %d\n", size
);
3476 ok(!memcmp(buf
, distPointWithIssuer
, size
), "Unexpected value\n");
3479 /* A dist point with both a name and an issuer */
3480 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3481 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3482 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3483 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3486 ok(size
== sizeof(distPointWithUrlAndIssuer
),
3487 "Wrong size %d\n", size
);
3488 ok(!memcmp(buf
, distPointWithUrlAndIssuer
, size
), "Unexpected value\n");
3493 static void test_decodeCRLDistPoints(DWORD dwEncoding
)
3498 PCRL_DIST_POINTS_INFO info
;
3499 PCRL_DIST_POINT point
;
3500 PCERT_ALT_NAME_ENTRY entry
;
3502 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
,
3503 emptyDistPoint
, emptyDistPoint
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3505 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3508 info
= (PCRL_DIST_POINTS_INFO
)buf
;
3509 ok(size
>= sizeof(CRL_DIST_POINTS_INFO
) + sizeof(CRL_DIST_POINT
),
3510 "Wrong size %d\n", size
);
3511 ok(info
->cDistPoint
== 1, "Expected 1 dist points, got %d\n",
3513 point
= info
->rgDistPoint
;
3514 ok(point
->DistPointName
.dwDistPointNameChoice
== CRL_DIST_POINT_NO_NAME
,
3515 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3516 point
->DistPointName
.dwDistPointNameChoice
);
3517 ok(point
->ReasonFlags
.cbData
== 0, "Expected no reason\n");
3518 ok(point
->CRLIssuer
.cAltEntry
== 0, "Expected no issuer\n");
3521 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
,
3522 distPointWithUrl
, distPointWithUrl
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3524 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3527 info
= (PCRL_DIST_POINTS_INFO
)buf
;
3528 ok(size
>= sizeof(CRL_DIST_POINTS_INFO
) + sizeof(CRL_DIST_POINT
),
3529 "Wrong size %d\n", size
);
3530 ok(info
->cDistPoint
== 1, "Expected 1 dist points, got %d\n",
3532 point
= info
->rgDistPoint
;
3533 ok(point
->DistPointName
.dwDistPointNameChoice
==
3534 CRL_DIST_POINT_FULL_NAME
,
3535 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3536 point
->DistPointName
.dwDistPointNameChoice
);
3537 ok(U(point
->DistPointName
).FullName
.cAltEntry
== 1,
3538 "Expected 1 name entry, got %d\n",
3539 U(point
->DistPointName
).FullName
.cAltEntry
);
3540 entry
= U(point
->DistPointName
).FullName
.rgAltEntry
;
3541 ok(entry
->dwAltNameChoice
== CERT_ALT_NAME_URL
,
3542 "Expected CERT_ALT_NAME_URL, got %d\n", entry
->dwAltNameChoice
);
3543 ok(!lstrcmpW(U(*entry
).pwszURL
, url
), "Unexpected name\n");
3544 ok(point
->ReasonFlags
.cbData
== 0, "Expected no reason\n");
3545 ok(point
->CRLIssuer
.cAltEntry
== 0, "Expected no issuer\n");
3548 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
,
3549 distPointWithReason
, distPointWithReason
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
,
3551 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3554 info
= (PCRL_DIST_POINTS_INFO
)buf
;
3555 ok(size
>= sizeof(CRL_DIST_POINTS_INFO
) + sizeof(CRL_DIST_POINT
),
3556 "Wrong size %d\n", size
);
3557 ok(info
->cDistPoint
== 1, "Expected 1 dist points, got %d\n",
3559 point
= info
->rgDistPoint
;
3560 ok(point
->DistPointName
.dwDistPointNameChoice
==
3561 CRL_DIST_POINT_NO_NAME
,
3562 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3563 point
->DistPointName
.dwDistPointNameChoice
);
3564 ok(point
->ReasonFlags
.cbData
== sizeof(crlReason
),
3565 "Expected reason length\n");
3566 ok(!memcmp(point
->ReasonFlags
.pbData
, &crlReason
, sizeof(crlReason
)),
3567 "Unexpected reason\n");
3568 ok(point
->CRLIssuer
.cAltEntry
== 0, "Expected no issuer\n");
3571 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
,
3572 distPointWithUrlAndIssuer
, distPointWithUrlAndIssuer
[1] + 2,
3573 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3574 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3577 info
= (PCRL_DIST_POINTS_INFO
)buf
;
3578 ok(size
>= sizeof(CRL_DIST_POINTS_INFO
) + sizeof(CRL_DIST_POINT
),
3579 "Wrong size %d\n", size
);
3580 ok(info
->cDistPoint
== 1, "Expected 1 dist points, got %d\n",
3582 point
= info
->rgDistPoint
;
3583 ok(point
->DistPointName
.dwDistPointNameChoice
==
3584 CRL_DIST_POINT_FULL_NAME
,
3585 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3586 point
->DistPointName
.dwDistPointNameChoice
);
3587 ok(U(point
->DistPointName
).FullName
.cAltEntry
== 1,
3588 "Expected 1 name entry, got %d\n",
3589 U(point
->DistPointName
).FullName
.cAltEntry
);
3590 entry
= U(point
->DistPointName
).FullName
.rgAltEntry
;
3591 ok(entry
->dwAltNameChoice
== CERT_ALT_NAME_URL
,
3592 "Expected CERT_ALT_NAME_URL, got %d\n", entry
->dwAltNameChoice
);
3593 ok(!lstrcmpW(U(*entry
).pwszURL
, url
), "Unexpected name\n");
3594 ok(point
->ReasonFlags
.cbData
== 0, "Expected no reason\n");
3595 ok(point
->CRLIssuer
.cAltEntry
== 1,
3596 "Expected 1 issuer entry, got %d\n", point
->CRLIssuer
.cAltEntry
);
3597 entry
= point
->CRLIssuer
.rgAltEntry
;
3598 ok(entry
->dwAltNameChoice
== CERT_ALT_NAME_URL
,
3599 "Expected CERT_ALT_NAME_URL, got %d\n", entry
->dwAltNameChoice
);
3600 ok(!lstrcmpW(U(*entry
).pwszURL
, url
), "Unexpected name\n");
3605 static const BYTE badFlagsIDP
[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3606 static const BYTE emptyNameIDP
[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3607 static const BYTE urlIDP
[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3608 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3611 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding
)
3616 CRL_ISSUING_DIST_POINT point
= { { 0 } };
3617 CERT_ALT_NAME_ENTRY entry
;
3619 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, NULL
,
3620 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3621 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
3623 skip("no X509_ISSUING_DIST_POINT encode support\n");
3626 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
3627 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3628 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, &point
,
3629 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3630 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3633 ok(size
== sizeof(emptySequence
), "Unexpected size %d\n", size
);
3634 ok(!memcmp(buf
, emptySequence
, size
), "Unexpected value\n");
3637 /* nonsensical flags */
3638 point
.fOnlyContainsUserCerts
= TRUE
;
3639 point
.fOnlyContainsCACerts
= TRUE
;
3640 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, &point
,
3641 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3642 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3645 ok(size
== sizeof(badFlagsIDP
), "Unexpected size %d\n", size
);
3646 ok(!memcmp(buf
, badFlagsIDP
, size
), "Unexpected value\n");
3649 /* unimplemented name type */
3650 point
.fOnlyContainsCACerts
= point
.fOnlyContainsUserCerts
= FALSE
;
3651 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_ISSUER_RDN_NAME
;
3652 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, &point
,
3653 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3654 ok(!ret
&& GetLastError() == E_INVALIDARG
,
3655 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3657 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3658 U(point
.DistPointName
).FullName
.cAltEntry
= 0;
3659 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, &point
,
3660 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3661 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3664 ok(size
== sizeof(emptyNameIDP
), "Unexpected size %d\n", size
);
3665 ok(!memcmp(buf
, emptyNameIDP
, size
), "Unexpected value\n");
3668 /* name with URL entry */
3669 entry
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
3670 U(entry
).pwszURL
= (LPWSTR
)url
;
3671 U(point
.DistPointName
).FullName
.cAltEntry
= 1;
3672 U(point
.DistPointName
).FullName
.rgAltEntry
= &entry
;
3673 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, &point
,
3674 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3675 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3678 ok(size
== sizeof(urlIDP
), "Unexpected size %d\n", size
);
3679 ok(!memcmp(buf
, urlIDP
, size
), "Unexpected value\n");
3684 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY
*expected
,
3685 const CERT_ALT_NAME_ENTRY
*got
)
3687 ok(expected
->dwAltNameChoice
== got
->dwAltNameChoice
,
3688 "Expected name choice %d, got %d\n", expected
->dwAltNameChoice
,
3689 got
->dwAltNameChoice
);
3690 if (expected
->dwAltNameChoice
== got
->dwAltNameChoice
)
3692 switch (got
->dwAltNameChoice
)
3694 case CERT_ALT_NAME_RFC822_NAME
:
3695 case CERT_ALT_NAME_DNS_NAME
:
3696 case CERT_ALT_NAME_EDI_PARTY_NAME
:
3697 case CERT_ALT_NAME_URL
:
3698 case CERT_ALT_NAME_REGISTERED_ID
:
3699 ok((!U(*expected
).pwszURL
&& !U(*got
).pwszURL
) ||
3700 (!U(*expected
).pwszURL
&& !lstrlenW(U(*got
).pwszURL
)) ||
3701 (!U(*got
).pwszURL
&& !lstrlenW(U(*expected
).pwszURL
)) ||
3702 !lstrcmpW(U(*expected
).pwszURL
, U(*got
).pwszURL
),
3703 "Unexpected name\n");
3705 case CERT_ALT_NAME_X400_ADDRESS
:
3706 case CERT_ALT_NAME_DIRECTORY_NAME
:
3707 case CERT_ALT_NAME_IP_ADDRESS
:
3708 ok(U(*got
).IPAddress
.cbData
== U(*expected
).IPAddress
.cbData
,
3709 "Unexpected IP address length %d\n", U(*got
).IPAddress
.cbData
);
3710 ok(!memcmp(U(*got
).IPAddress
.pbData
, U(*got
).IPAddress
.pbData
,
3711 U(*got
).IPAddress
.cbData
), "Unexpected value\n");
3717 static void compareAltNameInfo(const CERT_ALT_NAME_INFO
*expected
,
3718 const CERT_ALT_NAME_INFO
*got
)
3722 ok(expected
->cAltEntry
== got
->cAltEntry
, "Expected %d entries, got %d\n",
3723 expected
->cAltEntry
, got
->cAltEntry
);
3724 for (i
= 0; i
< min(expected
->cAltEntry
, got
->cAltEntry
); i
++)
3725 compareAltNameEntry(&expected
->rgAltEntry
[i
], &got
->rgAltEntry
[i
]);
3728 static void compareDistPointName(const CRL_DIST_POINT_NAME
*expected
,
3729 const CRL_DIST_POINT_NAME
*got
)
3731 ok(got
->dwDistPointNameChoice
== expected
->dwDistPointNameChoice
,
3732 "Unexpected name choice %d\n", got
->dwDistPointNameChoice
);
3733 if (got
->dwDistPointNameChoice
== CRL_DIST_POINT_FULL_NAME
)
3734 compareAltNameInfo(&(U(*expected
).FullName
), &(U(*got
).FullName
));
3737 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT
*expected
,
3738 const CRL_ISSUING_DIST_POINT
*got
)
3740 compareDistPointName(&expected
->DistPointName
, &got
->DistPointName
);
3741 ok(got
->fOnlyContainsUserCerts
== expected
->fOnlyContainsUserCerts
,
3742 "Unexpected fOnlyContainsUserCerts\n");
3743 ok(got
->fOnlyContainsCACerts
== expected
->fOnlyContainsCACerts
,
3744 "Unexpected fOnlyContainsCACerts\n");
3745 ok(got
->OnlySomeReasonFlags
.cbData
== expected
->OnlySomeReasonFlags
.cbData
,
3746 "Unexpected reason flags\n");
3747 ok(got
->fIndirectCRL
== expected
->fIndirectCRL
,
3748 "Unexpected fIndirectCRL\n");
3751 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding
)
3756 CRL_ISSUING_DIST_POINT point
= { { 0 } };
3758 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
,
3759 emptySequence
, emptySequence
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3761 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
3763 skip("no X509_ISSUING_DIST_POINT decode support\n");
3766 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3769 compareCRLIssuingDistPoints(&point
, (PCRL_ISSUING_DIST_POINT
)buf
);
3772 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
,
3773 badFlagsIDP
, badFlagsIDP
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3775 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3778 point
.fOnlyContainsUserCerts
= point
.fOnlyContainsCACerts
= TRUE
;
3779 compareCRLIssuingDistPoints(&point
, (PCRL_ISSUING_DIST_POINT
)buf
);
3782 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
,
3783 emptyNameIDP
, emptyNameIDP
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3785 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3788 point
.fOnlyContainsCACerts
= point
.fOnlyContainsUserCerts
= FALSE
;
3789 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3790 U(point
.DistPointName
).FullName
.cAltEntry
= 0;
3791 compareCRLIssuingDistPoints(&point
, (PCRL_ISSUING_DIST_POINT
)buf
);
3794 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
,
3795 urlIDP
, urlIDP
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3796 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3799 CERT_ALT_NAME_ENTRY entry
;
3801 entry
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
3802 U(entry
).pwszURL
= (LPWSTR
)url
;
3803 U(point
.DistPointName
).FullName
.cAltEntry
= 1;
3804 U(point
.DistPointName
).FullName
.rgAltEntry
= &entry
;
3805 compareCRLIssuingDistPoints(&point
, (PCRL_ISSUING_DIST_POINT
)buf
);
3810 static const BYTE v1CRL
[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3811 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3813 static const BYTE v2CRL
[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3814 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3815 0x30, 0x30, 0x30, 0x30, 0x5a };
3816 static const BYTE v1CRLWithIssuer
[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3817 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3818 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3819 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3821 static const BYTE v1CRLWithIssuerAndEmptyEntry
[] = { 0x30, 0x43, 0x30, 0x02,
3822 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3823 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3824 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3825 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3826 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3827 static const BYTE v1CRLWithIssuerAndEntry
[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3828 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3829 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3830 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3831 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3832 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3833 static const BYTE v1CRLWithEntryExt
[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3834 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3835 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3836 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3837 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3838 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3839 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3840 static const BYTE v1CRLWithExt
[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3841 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3842 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3843 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
3844 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3845 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
3846 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3847 static const BYTE v2CRLWithExt
[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
3848 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
3849 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
3850 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
3851 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
3852 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
3853 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3854 static const BYTE v2CRLWithIssuingDistPoint
[] = { 0x30,0x5c,0x02,0x01,0x01,
3855 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
3856 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
3857 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
3858 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3859 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
3860 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3862 static void test_encodeCRLToBeSigned(DWORD dwEncoding
)
3866 static CHAR oid_issuing_dist_point
[] = szOID_ISSUING_DIST_POINT
;
3868 CRL_INFO info
= { 0 };
3869 CRL_ENTRY entry
= { { 0 }, { 0 }, 0, 0 };
3872 /* Test with a V1 CRL */
3873 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3874 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3875 ok(ret
|| broken(GetLastError() == OSS_DATA_ERROR
/* Win9x */),
3876 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3879 ok(size
== sizeof(v1CRL
), "Wrong size %d\n", size
);
3880 ok(!memcmp(buf
, v1CRL
, size
), "Got unexpected value\n");
3884 info
.dwVersion
= CRL_V2
;
3885 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3886 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3887 ok(ret
|| broken(GetLastError() == OSS_DATA_ERROR
/* Win9x */),
3888 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3891 ok(size
== v2CRL
[1] + 2, "Expected size %d, got %d\n",
3892 v2CRL
[1] + 2, size
);
3893 ok(!memcmp(buf
, v2CRL
, size
), "Got unexpected value\n");
3896 /* v1 CRL with a name */
3897 info
.dwVersion
= CRL_V1
;
3898 info
.Issuer
.cbData
= sizeof(encodedCommonName
);
3899 info
.Issuer
.pbData
= (BYTE
*)encodedCommonName
;
3900 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3901 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3902 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3905 ok(size
== sizeof(v1CRLWithIssuer
), "Wrong size %d\n", size
);
3906 ok(!memcmp(buf
, v1CRLWithIssuer
, size
), "Got unexpected value\n");
3911 /* v1 CRL with a name and a NULL entry pointer (crashes on win9x) */
3913 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3914 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3915 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
3916 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3918 /* now set an empty entry */
3920 info
.rgCRLEntry
= &entry
;
3921 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3922 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3925 ok(size
== sizeof(v1CRLWithIssuerAndEmptyEntry
),
3926 "Wrong size %d\n", size
);
3927 ok(!memcmp(buf
, v1CRLWithIssuerAndEmptyEntry
, size
),
3928 "Got unexpected value\n");
3931 /* an entry with a serial number */
3932 entry
.SerialNumber
.cbData
= sizeof(serialNum
);
3933 entry
.SerialNumber
.pbData
= (BYTE
*)serialNum
;
3934 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3935 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3938 ok(size
== sizeof(v1CRLWithIssuerAndEntry
),
3939 "Wrong size %d\n", size
);
3940 ok(!memcmp(buf
, v1CRLWithIssuerAndEntry
, size
),
3941 "Got unexpected value\n");
3944 /* an entry with an extension */
3945 entry
.cExtension
= 1;
3946 entry
.rgExtension
= &criticalExt
;
3947 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3948 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3949 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3952 ok(size
== sizeof(v1CRLWithEntryExt
), "Wrong size %d\n", size
);
3953 ok(!memcmp(buf
, v1CRLWithEntryExt
, size
), "Got unexpected value\n");
3956 /* a CRL with an extension */
3957 entry
.cExtension
= 0;
3958 info
.cExtension
= 1;
3959 info
.rgExtension
= &criticalExt
;
3960 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3961 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3962 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3965 ok(size
== sizeof(v1CRLWithExt
), "Wrong size %d\n", size
);
3966 ok(!memcmp(buf
, v1CRLWithExt
, size
), "Got unexpected value\n");
3969 /* a v2 CRL with an extension, this time non-critical */
3970 info
.dwVersion
= CRL_V2
;
3971 info
.rgExtension
= &nonCriticalExt
;
3972 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3973 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3974 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3977 ok(size
== sizeof(v2CRLWithExt
), "Wrong size %d\n", size
);
3978 ok(!memcmp(buf
, v2CRLWithExt
, size
), "Got unexpected value\n");
3981 /* a v2 CRL with an issuing dist point extension */
3982 ext
.pszObjId
= oid_issuing_dist_point
;
3983 ext
.fCritical
= TRUE
;
3984 ext
.Value
.cbData
= sizeof(urlIDP
);
3985 ext
.Value
.pbData
= (LPBYTE
)urlIDP
;
3986 entry
.rgExtension
= &ext
;
3987 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3988 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3989 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3992 ok(size
== sizeof(v2CRLWithIssuingDistPoint
), "Wrong size %d\n", size
);
3993 ok(!memcmp(buf
, v2CRLWithIssuingDistPoint
, size
), "Unexpected value\n");
3998 static const BYTE verisignCRL
[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
3999 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
4000 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
4001 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
4002 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
4003 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
4004 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
4005 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
4006 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
4007 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
4008 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
4009 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
4010 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
4011 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
4012 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
4013 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
4014 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
4015 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
4016 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
4017 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
4018 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
4019 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
4020 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
4021 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
4022 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
4023 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
4024 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
4025 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
4026 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
4027 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
4028 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
4029 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
4030 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
4031 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
4033 static const BYTE verisignCRLWithLotsOfEntries
[] = {
4034 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
4035 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
4036 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
4037 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
4038 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
4039 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
4040 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
4041 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
4042 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
4043 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
4044 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
4045 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
4046 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
4047 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
4048 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
4049 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
4050 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
4051 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
4052 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
4053 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
4054 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
4055 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
4056 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
4057 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
4058 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
4059 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
4060 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
4061 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
4062 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
4063 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
4064 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
4065 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
4066 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
4067 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
4068 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
4069 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
4070 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
4071 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
4072 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
4073 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
4074 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
4075 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
4076 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
4077 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
4078 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
4079 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
4080 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
4081 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
4082 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
4083 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
4084 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
4085 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
4086 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
4087 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
4088 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
4089 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
4090 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
4091 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
4092 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
4093 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
4094 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
4095 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
4096 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
4097 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
4098 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
4099 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
4100 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
4101 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
4102 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
4103 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
4104 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
4105 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
4106 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
4107 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
4108 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
4109 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
4110 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
4111 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
4112 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
4113 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
4114 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
4115 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
4116 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
4117 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
4118 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
4119 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
4120 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
4121 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
4122 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
4123 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
4124 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
4125 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
4126 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
4127 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
4128 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
4129 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
4130 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
4131 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
4132 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
4133 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
4134 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
4135 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
4136 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
4137 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
4138 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
4139 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
4140 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
4141 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
4142 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
4143 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
4144 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
4145 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
4146 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
4147 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
4148 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
4149 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
4150 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
4151 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
4152 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
4153 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
4154 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
4155 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
4156 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
4157 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
4158 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
4159 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
4160 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
4161 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
4162 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
4163 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
4164 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
4165 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
4166 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
4167 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
4168 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
4169 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
4170 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
4171 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
4172 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
4173 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
4174 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
4175 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
4176 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
4177 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
4178 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
4179 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
4180 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
4181 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
4182 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
4183 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
4184 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
4185 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
4186 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
4187 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
4188 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
4189 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
4190 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
4191 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
4192 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
4193 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
4194 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
4195 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
4196 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
4197 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
4198 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
4199 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
4200 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
4201 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
4202 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
4203 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
4204 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
4205 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
4206 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
4207 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
4208 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
4209 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
4210 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
4211 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
4212 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
4213 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
4214 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
4215 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
4216 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
4217 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
4218 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
4219 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
4220 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
4221 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
4222 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
4223 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
4224 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
4225 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
4226 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
4227 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
4228 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
4229 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
4230 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
4231 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
4232 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
4233 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
4234 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
4235 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
4236 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
4237 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
4238 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
4239 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
4240 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
4241 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
4242 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
4243 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
4244 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
4245 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
4246 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
4247 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
4248 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
4249 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
4250 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
4251 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
4252 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
4253 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
4254 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
4255 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
4256 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
4257 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
4258 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
4259 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
4260 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
4261 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
4262 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
4263 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
4264 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
4265 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
4266 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
4267 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
4268 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
4269 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
4270 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
4271 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
4272 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
4273 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
4274 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
4275 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
4276 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
4277 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
4278 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
4279 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
4280 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
4281 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
4282 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
4283 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
4284 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
4285 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
4286 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
4287 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
4288 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
4289 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
4290 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
4291 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
4292 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
4293 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
4294 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
4295 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
4296 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
4297 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
4298 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
4299 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
4300 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
4301 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
4302 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
4303 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
4304 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
4305 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
4306 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
4307 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
4308 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
4309 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
4310 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
4311 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
4312 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
4313 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
4314 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
4315 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
4316 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
4317 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
4318 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
4319 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
4320 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
4321 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
4322 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
4323 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
4324 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
4325 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
4326 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
4327 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
4328 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
4329 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
4330 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
4331 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
4332 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
4333 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
4334 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
4335 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
4336 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
4337 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4338 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4339 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4340 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4341 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4342 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4343 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4344 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4345 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4346 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4347 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4348 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4349 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4350 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4351 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4352 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4353 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4354 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4355 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4356 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4357 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4358 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4359 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4360 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4361 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4362 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4363 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4364 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4365 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4366 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4367 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4368 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4369 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4370 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4371 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4372 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4373 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4374 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4375 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4376 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4377 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4378 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4379 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4380 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4381 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4382 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4383 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4384 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4385 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4386 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4387 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4388 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4389 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4390 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4391 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4392 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4393 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4394 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4395 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4396 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4397 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4398 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4399 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4400 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4401 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4402 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4403 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4404 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4405 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4406 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4407 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4408 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4409 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4410 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4411 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4412 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4413 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4414 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4415 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4416 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4417 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4418 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4419 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4420 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4421 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4422 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4423 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4424 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4425 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4426 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4427 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4428 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4429 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4430 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4431 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4432 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4433 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4434 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4435 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4436 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4437 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4438 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4439 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4440 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4441 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4442 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4443 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4444 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4445 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4446 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4447 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4448 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4449 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4450 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4451 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4452 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4453 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4454 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4455 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4456 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4457 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4458 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4459 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4460 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4461 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4462 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4463 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4464 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4465 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4466 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4467 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4468 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4469 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4470 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4471 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4472 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4473 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4474 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4475 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4476 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4477 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4478 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4479 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4480 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4481 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4482 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4483 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4484 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4485 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4486 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4487 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4488 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4489 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4490 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4491 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4492 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4493 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4494 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4495 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4496 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4497 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4498 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4499 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4500 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4501 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4502 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4503 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4504 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4505 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4506 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4507 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4508 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4509 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4510 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4511 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4512 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4513 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4514 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4515 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4516 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4517 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4518 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4519 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4520 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4521 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4522 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4523 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4524 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4525 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4526 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4527 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4528 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4529 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4530 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4531 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4532 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4533 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4534 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4535 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4536 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4537 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4538 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4539 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4540 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4541 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4543 static void test_decodeCRLToBeSigned(DWORD dwEncoding
)
4545 static const BYTE
*corruptCRLs
[] = { v1CRL
, v2CRL
};
4550 for (i
= 0; i
< sizeof(corruptCRLs
) / sizeof(corruptCRLs
[0]); i
++)
4552 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4553 corruptCRLs
[i
], corruptCRLs
[i
][1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4555 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
4556 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
4557 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4560 /* at a minimum, a CRL must contain an issuer: */
4561 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4562 v1CRLWithIssuer
, v1CRLWithIssuer
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4564 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4567 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4569 ok(size
>= sizeof(CRL_INFO
), "Wrong size %d\n", size
);
4570 ok(info
->cCRLEntry
== 0, "Expected 0 CRL entries, got %d\n",
4572 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
4573 "Wrong issuer size %d\n", info
->Issuer
.cbData
);
4574 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
4575 "Unexpected issuer\n");
4578 /* check decoding with an empty CRL entry */
4579 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4580 v1CRLWithIssuerAndEmptyEntry
, v1CRLWithIssuerAndEmptyEntry
[1] + 2,
4581 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4582 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
4583 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
4584 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4586 /* with a real CRL entry */
4587 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4588 v1CRLWithIssuerAndEntry
, v1CRLWithIssuerAndEntry
[1] + 2,
4589 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4590 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4593 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4596 ok(size
>= sizeof(CRL_INFO
), "Wrong size %d\n", size
);
4597 ok(info
->cCRLEntry
== 1, "Expected 1 CRL entries, got %d\n",
4599 ok(info
->rgCRLEntry
!= NULL
, "Expected a valid CRL entry array\n");
4600 entry
= info
->rgCRLEntry
;
4601 ok(entry
->SerialNumber
.cbData
== 1,
4602 "Expected serial number size 1, got %d\n",
4603 entry
->SerialNumber
.cbData
);
4604 ok(*entry
->SerialNumber
.pbData
== *serialNum
,
4605 "Expected serial number %d, got %d\n", *serialNum
,
4606 *entry
->SerialNumber
.pbData
);
4607 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
4608 "Wrong issuer size %d\n", info
->Issuer
.cbData
);
4609 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
4610 "Unexpected issuer\n");
4613 /* a real CRL from verisign that has extensions */
4614 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4615 verisignCRL
, sizeof(verisignCRL
), CRYPT_DECODE_ALLOC_FLAG
,
4617 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4620 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4623 ok(size
>= sizeof(CRL_INFO
), "Wrong size %d\n", size
);
4624 ok(info
->cCRLEntry
== 3, "Expected 3 CRL entries, got %d\n",
4626 ok(info
->rgCRLEntry
!= NULL
, "Expected a valid CRL entry array\n");
4627 entry
= info
->rgCRLEntry
;
4628 ok(info
->cExtension
== 2, "Expected 2 extensions, got %d\n",
4632 /* another real CRL from verisign that has lots of entries */
4633 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4634 verisignCRLWithLotsOfEntries
, sizeof(verisignCRLWithLotsOfEntries
),
4635 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4636 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4639 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4641 ok(size
>= sizeof(CRL_INFO
), "Got size %d\n", size
);
4642 ok(info
->cCRLEntry
== 209, "Expected 209 CRL entries, got %d\n",
4644 ok(info
->cExtension
== 0, "Expected 0 extensions, got %d\n",
4648 /* and finally, with an extension */
4649 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4650 v1CRLWithExt
, sizeof(v1CRLWithExt
), CRYPT_DECODE_ALLOC_FLAG
,
4652 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4655 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4658 ok(size
>= sizeof(CRL_INFO
), "Wrong size %d\n", size
);
4659 ok(info
->cCRLEntry
== 1, "Expected 1 CRL entries, got %d\n",
4661 ok(info
->rgCRLEntry
!= NULL
, "Expected a valid CRL entry array\n");
4662 entry
= info
->rgCRLEntry
;
4663 ok(entry
->SerialNumber
.cbData
== 1,
4664 "Expected serial number size 1, got %d\n",
4665 entry
->SerialNumber
.cbData
);
4666 ok(*entry
->SerialNumber
.pbData
== *serialNum
,
4667 "Expected serial number %d, got %d\n", *serialNum
,
4668 *entry
->SerialNumber
.pbData
);
4669 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
4670 "Wrong issuer size %d\n", info
->Issuer
.cbData
);
4671 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
4672 "Unexpected issuer\n");
4673 ok(info
->cExtension
== 1, "Expected 1 extensions, got %d\n",
4677 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4678 v2CRLWithExt
, sizeof(v2CRLWithExt
), CRYPT_DECODE_ALLOC_FLAG
,
4680 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4683 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4685 ok(info
->cExtension
== 1, "Expected 1 extensions, got %d\n",
4689 /* And again, with an issuing dist point */
4690 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4691 v2CRLWithIssuingDistPoint
, sizeof(v2CRLWithIssuingDistPoint
),
4692 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4693 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4696 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4698 ok(info
->cExtension
== 1, "Expected 1 extensions, got %d\n",
4704 static const LPCSTR keyUsages
[] = { szOID_PKIX_KP_CODE_SIGNING
,
4705 szOID_PKIX_KP_CLIENT_AUTH
, szOID_RSA_RSA
};
4706 static const BYTE encodedUsage
[] = {
4707 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4708 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4709 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4711 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding
)
4716 CERT_ENHKEY_USAGE usage
;
4718 /* Test with empty usage */
4719 usage
.cUsageIdentifier
= 0;
4720 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ENHANCED_KEY_USAGE
, &usage
,
4721 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4722 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4725 ok(size
== sizeof(emptySequence
), "Wrong size %d\n", size
);
4726 ok(!memcmp(buf
, emptySequence
, size
), "Got unexpected value\n");
4729 /* Test with a few usages */
4730 usage
.cUsageIdentifier
= sizeof(keyUsages
) / sizeof(keyUsages
[0]);
4731 usage
.rgpszUsageIdentifier
= (LPSTR
*)keyUsages
;
4732 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ENHANCED_KEY_USAGE
, &usage
,
4733 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4734 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4737 ok(size
== sizeof(encodedUsage
), "Wrong size %d\n", size
);
4738 ok(!memcmp(buf
, encodedUsage
, size
), "Got unexpected value\n");
4743 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding
)
4749 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ENHANCED_KEY_USAGE
,
4750 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4752 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4755 CERT_ENHKEY_USAGE
*usage
= (CERT_ENHKEY_USAGE
*)buf
;
4757 ok(size
>= sizeof(CERT_ENHKEY_USAGE
),
4758 "Wrong size %d\n", size
);
4759 ok(usage
->cUsageIdentifier
== 0, "Expected 0 CRL entries, got %d\n",
4760 usage
->cUsageIdentifier
);
4763 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ENHANCED_KEY_USAGE
,
4764 encodedUsage
, sizeof(encodedUsage
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4766 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4769 CERT_ENHKEY_USAGE
*usage
= (CERT_ENHKEY_USAGE
*)buf
;
4772 ok(size
>= sizeof(CERT_ENHKEY_USAGE
),
4773 "Wrong size %d\n", size
);
4774 ok(usage
->cUsageIdentifier
== sizeof(keyUsages
) / sizeof(keyUsages
[0]),
4775 "Wrong CRL entries count %d\n", usage
->cUsageIdentifier
);
4776 for (i
= 0; i
< usage
->cUsageIdentifier
; i
++)
4777 ok(!strcmp(usage
->rgpszUsageIdentifier
[i
], keyUsages
[i
]),
4778 "Expected OID %s, got %s\n", keyUsages
[i
],
4779 usage
->rgpszUsageIdentifier
[i
]);
4784 static BYTE keyId
[] = { 1,2,3,4 };
4785 static const BYTE authorityKeyIdWithId
[] = {
4786 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4787 static const BYTE authorityKeyIdWithIssuer
[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4788 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4789 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4790 static const BYTE authorityKeyIdWithSerial
[] = { 0x30,0x03,0x82,0x01,0x01 };
4792 static void test_encodeAuthorityKeyId(DWORD dwEncoding
)
4794 CERT_AUTHORITY_KEY_ID_INFO info
= { { 0 } };
4799 /* Test with empty id */
4800 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
, &info
,
4801 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &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");
4809 /* With just a key id */
4810 info
.KeyId
.cbData
= sizeof(keyId
);
4811 info
.KeyId
.pbData
= keyId
;
4812 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
, &info
,
4813 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4814 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4817 ok(size
== sizeof(authorityKeyIdWithId
), "Unexpected size %d\n", size
);
4818 ok(!memcmp(buf
, authorityKeyIdWithId
, size
), "Unexpected value\n");
4821 /* With just an issuer */
4822 info
.KeyId
.cbData
= 0;
4823 info
.CertIssuer
.cbData
= sizeof(encodedCommonName
);
4824 info
.CertIssuer
.pbData
= (BYTE
*)encodedCommonName
;
4825 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
, &info
,
4826 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4827 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4830 ok(size
== sizeof(authorityKeyIdWithIssuer
), "Unexpected size %d\n",
4832 ok(!memcmp(buf
, authorityKeyIdWithIssuer
, size
), "Unexpected value\n");
4835 /* With just a serial number */
4836 info
.CertIssuer
.cbData
= 0;
4837 info
.CertSerialNumber
.cbData
= sizeof(serialNum
);
4838 info
.CertSerialNumber
.pbData
= (BYTE
*)serialNum
;
4839 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
, &info
,
4840 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4841 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4844 ok(size
== sizeof(authorityKeyIdWithSerial
), "Unexpected size %d\n",
4846 ok(!memcmp(buf
, authorityKeyIdWithSerial
, size
), "Unexpected value\n");
4851 static void test_decodeAuthorityKeyId(DWORD dwEncoding
)
4857 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
,
4858 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4860 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4863 CERT_AUTHORITY_KEY_ID_INFO
*info
= (CERT_AUTHORITY_KEY_ID_INFO
*)buf
;
4865 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID_INFO
), "Unexpected size %d\n",
4867 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
4868 ok(info
->CertIssuer
.cbData
== 0, "Expected no issuer name\n");
4869 ok(info
->CertSerialNumber
.cbData
== 0, "Expected no serial number\n");
4872 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
,
4873 authorityKeyIdWithId
, sizeof(authorityKeyIdWithId
),
4874 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4875 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4878 CERT_AUTHORITY_KEY_ID_INFO
*info
= (CERT_AUTHORITY_KEY_ID_INFO
*)buf
;
4880 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID_INFO
), "Unexpected size %d\n",
4882 ok(info
->KeyId
.cbData
== sizeof(keyId
), "Unexpected key id len\n");
4883 ok(!memcmp(info
->KeyId
.pbData
, keyId
, sizeof(keyId
)),
4884 "Unexpected key id\n");
4885 ok(info
->CertIssuer
.cbData
== 0, "Expected no issuer name\n");
4886 ok(info
->CertSerialNumber
.cbData
== 0, "Expected no serial number\n");
4889 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
,
4890 authorityKeyIdWithIssuer
, sizeof(authorityKeyIdWithIssuer
),
4891 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4892 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4895 CERT_AUTHORITY_KEY_ID_INFO
*info
= (CERT_AUTHORITY_KEY_ID_INFO
*)buf
;
4897 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID_INFO
), "Unexpected size %d\n",
4899 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
4900 ok(info
->CertIssuer
.cbData
== sizeof(encodedCommonName
),
4901 "Unexpected issuer len\n");
4902 ok(!memcmp(info
->CertIssuer
.pbData
, encodedCommonName
,
4903 sizeof(encodedCommonName
)), "Unexpected issuer\n");
4904 ok(info
->CertSerialNumber
.cbData
== 0, "Expected no serial number\n");
4907 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
,
4908 authorityKeyIdWithSerial
, sizeof(authorityKeyIdWithSerial
),
4909 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4910 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4913 CERT_AUTHORITY_KEY_ID_INFO
*info
= (CERT_AUTHORITY_KEY_ID_INFO
*)buf
;
4915 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID_INFO
), "Unexpected size %d\n",
4917 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
4918 ok(info
->CertIssuer
.cbData
== 0, "Expected no issuer name\n");
4919 ok(info
->CertSerialNumber
.cbData
== sizeof(serialNum
),
4920 "Unexpected serial number len\n");
4921 ok(!memcmp(info
->CertSerialNumber
.pbData
, serialNum
, sizeof(serialNum
)),
4922 "Unexpected serial number\n");
4927 static const BYTE authorityKeyIdWithIssuerUrl
[] = { 0x30,0x15,0xa1,0x13,0x86,
4928 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
4931 static void test_encodeAuthorityKeyId2(DWORD dwEncoding
)
4933 CERT_AUTHORITY_KEY_ID2_INFO info
= { { 0 } };
4934 CERT_ALT_NAME_ENTRY entry
= { 0 };
4939 /* Test with empty id */
4940 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
, &info
,
4941 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4942 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4945 ok(size
== sizeof(emptySequence
), "Unexpected size %d\n", size
);
4946 ok(!memcmp(buf
, emptySequence
, size
), "Unexpected value\n");
4949 /* With just a key id */
4950 info
.KeyId
.cbData
= sizeof(keyId
);
4951 info
.KeyId
.pbData
= keyId
;
4952 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
, &info
,
4953 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4954 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4957 ok(size
== sizeof(authorityKeyIdWithId
), "Unexpected size %d\n",
4959 ok(!memcmp(buf
, authorityKeyIdWithId
, size
), "Unexpected value\n");
4962 /* With a bogus issuer name */
4963 info
.KeyId
.cbData
= 0;
4964 info
.AuthorityCertIssuer
.cAltEntry
= 1;
4965 info
.AuthorityCertIssuer
.rgAltEntry
= &entry
;
4966 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
, &info
,
4967 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4968 ok(!ret
&& GetLastError() == E_INVALIDARG
,
4969 "Expected E_INVALIDARG, got %08x\n", GetLastError());
4970 /* With an issuer name */
4971 entry
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
4972 U(entry
).pwszURL
= (LPWSTR
)url
;
4973 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
, &info
,
4974 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4975 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4978 ok(size
== sizeof(authorityKeyIdWithIssuerUrl
), "Unexpected size %d\n",
4980 ok(!memcmp(buf
, authorityKeyIdWithIssuerUrl
, size
),
4981 "Unexpected value\n");
4984 /* With just a serial number */
4985 info
.AuthorityCertIssuer
.cAltEntry
= 0;
4986 info
.AuthorityCertSerialNumber
.cbData
= sizeof(serialNum
);
4987 info
.AuthorityCertSerialNumber
.pbData
= (BYTE
*)serialNum
;
4988 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
, &info
,
4989 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4990 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4993 ok(size
== sizeof(authorityKeyIdWithSerial
), "Unexpected size %d\n",
4995 ok(!memcmp(buf
, authorityKeyIdWithSerial
, size
), "Unexpected value\n");
5000 static void test_decodeAuthorityKeyId2(DWORD dwEncoding
)
5006 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
,
5007 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5009 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5012 CERT_AUTHORITY_KEY_ID2_INFO
*info
= (CERT_AUTHORITY_KEY_ID2_INFO
*)buf
;
5014 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID2_INFO
), "Unexpected size %d\n",
5016 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
5017 ok(info
->AuthorityCertIssuer
.cAltEntry
== 0,
5018 "Expected no issuer name entries\n");
5019 ok(info
->AuthorityCertSerialNumber
.cbData
== 0,
5020 "Expected no serial number\n");
5023 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
,
5024 authorityKeyIdWithId
, sizeof(authorityKeyIdWithId
),
5025 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5026 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5029 CERT_AUTHORITY_KEY_ID2_INFO
*info
= (CERT_AUTHORITY_KEY_ID2_INFO
*)buf
;
5031 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID2_INFO
), "Unexpected size %d\n",
5033 ok(info
->KeyId
.cbData
== sizeof(keyId
), "Unexpected key id len\n");
5034 ok(!memcmp(info
->KeyId
.pbData
, keyId
, sizeof(keyId
)),
5035 "Unexpected key id\n");
5036 ok(info
->AuthorityCertIssuer
.cAltEntry
== 0,
5037 "Expected no issuer name entries\n");
5038 ok(info
->AuthorityCertSerialNumber
.cbData
== 0,
5039 "Expected no serial number\n");
5042 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
,
5043 authorityKeyIdWithIssuerUrl
, sizeof(authorityKeyIdWithIssuerUrl
),
5044 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5045 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5048 CERT_AUTHORITY_KEY_ID2_INFO
*info
= (CERT_AUTHORITY_KEY_ID2_INFO
*)buf
;
5050 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID2_INFO
), "Unexpected size %d\n",
5052 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
5053 ok(info
->AuthorityCertIssuer
.cAltEntry
== 1,
5054 "Expected 1 issuer entry, got %d\n",
5055 info
->AuthorityCertIssuer
.cAltEntry
);
5056 ok(info
->AuthorityCertIssuer
.rgAltEntry
[0].dwAltNameChoice
==
5057 CERT_ALT_NAME_URL
, "Expected CERT_ALT_NAME_URL, got %d\n",
5058 info
->AuthorityCertIssuer
.rgAltEntry
[0].dwAltNameChoice
);
5059 ok(!lstrcmpW(U(info
->AuthorityCertIssuer
.rgAltEntry
[0]).pwszURL
,
5060 url
), "Unexpected URL\n");
5061 ok(info
->AuthorityCertSerialNumber
.cbData
== 0,
5062 "Expected no serial number\n");
5065 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
,
5066 authorityKeyIdWithSerial
, sizeof(authorityKeyIdWithSerial
),
5067 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5068 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5071 CERT_AUTHORITY_KEY_ID2_INFO
*info
= (CERT_AUTHORITY_KEY_ID2_INFO
*)buf
;
5073 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID2_INFO
), "Unexpected size %d\n",
5075 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
5076 ok(info
->AuthorityCertIssuer
.cAltEntry
== 0,
5077 "Expected no issuer name entries\n");
5078 ok(info
->AuthorityCertSerialNumber
.cbData
== sizeof(serialNum
),
5079 "Unexpected serial number len\n");
5080 ok(!memcmp(info
->AuthorityCertSerialNumber
.pbData
, serialNum
,
5081 sizeof(serialNum
)), "Unexpected serial number\n");
5086 static const BYTE authorityInfoAccessWithUrl
[] = {
5087 0x30,0x19,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
5088 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5089 static const BYTE authorityInfoAccessWithUrlAndIPAddr
[] = {
5090 0x30,0x29,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
5091 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x0e,0x06,
5092 0x02,0x2d,0x06,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5094 static void test_encodeAuthorityInfoAccess(DWORD dwEncoding
)
5096 static char oid1
[] = "1.2.3";
5097 static char oid2
[] = "1.5.6";
5101 CERT_ACCESS_DESCRIPTION accessDescription
[2];
5102 CERT_AUTHORITY_INFO_ACCESS aia
;
5104 memset(accessDescription
, 0, sizeof(accessDescription
));
5106 aia
.rgAccDescr
= NULL
;
5107 /* Having no access descriptions is allowed */
5108 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
, &aia
,
5109 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5110 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5113 ok(size
== sizeof(emptySequence
), "unexpected size %d\n", size
);
5114 ok(!memcmp(buf
, emptySequence
, size
), "unexpected value\n");
5118 /* It can't have an empty access method */
5120 aia
.rgAccDescr
= accessDescription
;
5121 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
, &aia
,
5122 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5123 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
5124 GetLastError() == OSS_LIMITED
/* Win9x */),
5125 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
5126 /* It can't have an empty location */
5127 accessDescription
[0].pszAccessMethod
= oid1
;
5128 SetLastError(0xdeadbeef);
5129 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
, &aia
,
5130 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5131 ok(!ret
&& GetLastError() == E_INVALIDARG
,
5132 "expected E_INVALIDARG, got %08x\n", GetLastError());
5133 accessDescription
[0].AccessLocation
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
5134 U(accessDescription
[0].AccessLocation
).pwszURL
= (LPWSTR
)url
;
5135 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
, &aia
,
5136 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5137 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5140 ok(size
== sizeof(authorityInfoAccessWithUrl
), "unexpected size %d\n",
5142 ok(!memcmp(buf
, authorityInfoAccessWithUrl
, size
),
5143 "unexpected value\n");
5147 accessDescription
[1].pszAccessMethod
= oid2
;
5148 accessDescription
[1].AccessLocation
.dwAltNameChoice
=
5149 CERT_ALT_NAME_IP_ADDRESS
;
5150 U(accessDescription
[1].AccessLocation
).IPAddress
.cbData
=
5151 sizeof(encodedIPAddr
);
5152 U(accessDescription
[1].AccessLocation
).IPAddress
.pbData
=
5153 (LPBYTE
)encodedIPAddr
;
5155 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
, &aia
,
5156 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5157 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5160 ok(size
== sizeof(authorityInfoAccessWithUrlAndIPAddr
),
5161 "unexpected size %d\n", size
);
5162 ok(!memcmp(buf
, authorityInfoAccessWithUrlAndIPAddr
, size
),
5163 "unexpected value\n");
5169 static void compareAuthorityInfoAccess(LPCSTR header
,
5170 const CERT_AUTHORITY_INFO_ACCESS
*expected
,
5171 const CERT_AUTHORITY_INFO_ACCESS
*got
)
5175 ok(expected
->cAccDescr
== got
->cAccDescr
,
5176 "%s: expected %d access descriptions, got %d\n", header
,
5177 expected
->cAccDescr
, got
->cAccDescr
);
5178 for (i
= 0; i
< expected
->cAccDescr
; i
++)
5180 ok(!strcmp(expected
->rgAccDescr
[i
].pszAccessMethod
,
5181 got
->rgAccDescr
[i
].pszAccessMethod
), "%s[%d]: expected %s, got %s\n",
5182 header
, i
, expected
->rgAccDescr
[i
].pszAccessMethod
,
5183 got
->rgAccDescr
[i
].pszAccessMethod
);
5184 compareAltNameEntry(&expected
->rgAccDescr
[i
].AccessLocation
,
5185 &got
->rgAccDescr
[i
].AccessLocation
);
5189 static void test_decodeAuthorityInfoAccess(DWORD dwEncoding
)
5191 static char oid1
[] = "1.2.3";
5192 static char oid2
[] = "1.5.6";
5197 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
,
5198 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5200 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5203 CERT_AUTHORITY_INFO_ACCESS aia
= { 0, NULL
};
5205 compareAuthorityInfoAccess("empty AIA", &aia
,
5206 (CERT_AUTHORITY_INFO_ACCESS
*)buf
);
5210 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
,
5211 authorityInfoAccessWithUrl
, sizeof(authorityInfoAccessWithUrl
),
5212 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5213 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5216 CERT_ACCESS_DESCRIPTION accessDescription
;
5217 CERT_AUTHORITY_INFO_ACCESS aia
;
5219 accessDescription
.pszAccessMethod
= oid1
;
5220 accessDescription
.AccessLocation
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
5221 U(accessDescription
.AccessLocation
).pwszURL
= (LPWSTR
)url
;
5223 aia
.rgAccDescr
= &accessDescription
;
5224 compareAuthorityInfoAccess("AIA with URL", &aia
,
5225 (CERT_AUTHORITY_INFO_ACCESS
*)buf
);
5229 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
,
5230 authorityInfoAccessWithUrlAndIPAddr
,
5231 sizeof(authorityInfoAccessWithUrlAndIPAddr
), CRYPT_DECODE_ALLOC_FLAG
,
5233 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5236 CERT_ACCESS_DESCRIPTION accessDescription
[2];
5237 CERT_AUTHORITY_INFO_ACCESS aia
;
5239 accessDescription
[0].pszAccessMethod
= oid1
;
5240 accessDescription
[0].AccessLocation
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
5241 U(accessDescription
[0].AccessLocation
).pwszURL
= (LPWSTR
)url
;
5242 accessDescription
[1].pszAccessMethod
= oid2
;
5243 accessDescription
[1].AccessLocation
.dwAltNameChoice
=
5244 CERT_ALT_NAME_IP_ADDRESS
;
5245 U(accessDescription
[1].AccessLocation
).IPAddress
.cbData
=
5246 sizeof(encodedIPAddr
);
5247 U(accessDescription
[1].AccessLocation
).IPAddress
.pbData
=
5248 (LPBYTE
)encodedIPAddr
;
5250 aia
.rgAccDescr
= accessDescription
;
5251 compareAuthorityInfoAccess("AIA with URL and IP addr", &aia
,
5252 (CERT_AUTHORITY_INFO_ACCESS
*)buf
);
5258 static const BYTE emptyCTL
[] = {
5259 0x30,0x17,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5260 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5261 static const BYTE emptyCTLWithVersion1
[] = {
5262 0x30,0x1a,0x02,0x01,0x01,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5263 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5264 static const BYTE ctlWithUsageIdentifier
[] = {
5265 0x30,0x1b,0x30,0x04,0x06,0x02,0x2a,0x03,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
5266 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5267 static const BYTE ctlWithListIdentifier
[] = {
5268 0x30,0x1a,0x30,0x00,0x04,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5269 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5270 static const BYTE ctlWithSequenceNumber
[] = {
5271 0x30,0x1a,0x30,0x00,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5272 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5273 static const BYTE ctlWithThisUpdate
[] = {
5274 0x30,0x15,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5275 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5276 static const BYTE ctlWithThisAndNextUpdate
[] = {
5277 0x30,0x24,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5278 0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5279 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5280 static const BYTE ctlWithAlgId
[] = {
5281 0x30,0x1b,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5282 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5283 static const BYTE ctlWithBogusEntry
[] = {
5284 0x30,0x29,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5285 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x10,0x30,0x0e,0x04,
5286 0x01,0x01,0x31,0x09,0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,0x01 };
5287 static const BYTE ctlWithOneEntry
[] = {
5288 0x30,0x2a,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5289 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x11,0x30,0x0f,0x04,
5290 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00 };
5291 static const BYTE ctlWithTwoEntries
[] = {
5292 0x30,0x41,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5293 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x28,0x30,0x0f,0x04,
5294 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00,0x30,
5295 0x15,0x04,0x01,0x01,0x31,0x10,0x30,0x0e,0x06,0x02,0x2d,0x06,0x31,0x08,0x30,
5296 0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5298 static void test_encodeCTL(DWORD dwEncoding
)
5300 static char oid1
[] = "1.2.3";
5301 static char oid2
[] = "1.5.6";
5307 SYSTEMTIME thisUpdate
= { 2005, 6, 1, 6, 16, 10, 0, 0 };
5308 CTL_ENTRY ctlEntry
[2];
5309 CRYPT_ATTRIBUTE attr1
, attr2
;
5310 CRYPT_ATTR_BLOB value1
, value2
;
5312 memset(&info
, 0, sizeof(info
));
5313 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5314 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5315 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5318 ok(size
== sizeof(emptyCTL
), "unexpected size %d\n", size
);
5319 ok(!memcmp(buf
, emptyCTL
, size
), "unexpected value\n");
5324 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5325 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5326 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5329 ok(size
== sizeof(emptyCTLWithVersion1
), "unexpected size %d\n", size
);
5330 ok(!memcmp(buf
, emptyCTLWithVersion1
, size
), "unexpected value\n");
5335 info
.SubjectUsage
.cUsageIdentifier
= 1;
5336 info
.SubjectUsage
.rgpszUsageIdentifier
= &pOid1
;
5337 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5338 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5339 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5342 ok(size
== sizeof(ctlWithUsageIdentifier
), "unexpected size %d\n",
5344 ok(!memcmp(buf
, ctlWithUsageIdentifier
, size
), "unexpected value\n");
5348 info
.SubjectUsage
.cUsageIdentifier
= 0;
5349 info
.ListIdentifier
.cbData
= sizeof(serialNum
);
5350 info
.ListIdentifier
.pbData
= (LPBYTE
)serialNum
;
5351 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5352 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5353 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5356 ok(size
== sizeof(ctlWithListIdentifier
), "unexpected size %d\n", size
);
5357 ok(!memcmp(buf
, ctlWithListIdentifier
, size
), "unexpected value\n");
5361 info
.ListIdentifier
.cbData
= 0;
5362 info
.SequenceNumber
.cbData
= sizeof(serialNum
);
5363 info
.SequenceNumber
.pbData
= (LPBYTE
)serialNum
;
5364 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5365 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5366 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5369 ok(size
== sizeof(ctlWithSequenceNumber
), "unexpected size %d\n",
5371 ok(!memcmp(buf
, ctlWithSequenceNumber
, size
), "unexpected value\n");
5375 info
.SequenceNumber
.cbData
= 0;
5376 SystemTimeToFileTime(&thisUpdate
, &info
.ThisUpdate
);
5377 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5378 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5379 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5382 ok(size
== sizeof(ctlWithThisUpdate
), "unexpected size %d\n", size
);
5383 ok(!memcmp(buf
, ctlWithThisUpdate
, size
), "unexpected value\n");
5387 SystemTimeToFileTime(&thisUpdate
, &info
.NextUpdate
);
5388 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5389 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5390 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5393 ok(size
== sizeof(ctlWithThisAndNextUpdate
), "unexpected size %d\n",
5395 ok(!memcmp(buf
, ctlWithThisAndNextUpdate
, size
), "unexpected value\n");
5399 info
.ThisUpdate
.dwLowDateTime
= info
.ThisUpdate
.dwHighDateTime
= 0;
5400 info
.NextUpdate
.dwLowDateTime
= info
.NextUpdate
.dwHighDateTime
= 0;
5401 info
.SubjectAlgorithm
.pszObjId
= oid2
;
5402 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5403 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5404 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5407 ok(size
== sizeof(ctlWithAlgId
), "unexpected size %d\n", size
);
5408 ok(!memcmp(buf
, ctlWithAlgId
, size
), "unexpected value\n");
5412 /* The value is supposed to be asn.1 encoded, so this'll fail to decode
5413 * (see tests below) but it'll encode fine.
5415 info
.SubjectAlgorithm
.pszObjId
= NULL
;
5416 value1
.cbData
= sizeof(serialNum
);
5417 value1
.pbData
= (LPBYTE
)serialNum
;
5418 attr1
.pszObjId
= oid1
;
5420 attr1
.rgValue
= &value1
;
5421 ctlEntry
[0].SubjectIdentifier
.cbData
= sizeof(serialNum
);
5422 ctlEntry
[0].SubjectIdentifier
.pbData
= (LPBYTE
)serialNum
;
5423 ctlEntry
[0].cAttribute
= 1;
5424 ctlEntry
[0].rgAttribute
= &attr1
;
5426 info
.rgCTLEntry
= ctlEntry
;
5427 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5428 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5429 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5432 ok(size
== sizeof(ctlWithBogusEntry
), "unexpected size %d\n", size
);
5433 ok(!memcmp(buf
, ctlWithBogusEntry
, size
), "unexpected value\n");
5437 value1
.cbData
= sizeof(emptySequence
);
5438 value1
.pbData
= (LPBYTE
)emptySequence
;
5439 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5440 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5441 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5444 ok(size
== sizeof(ctlWithOneEntry
), "unexpected size %d\n", size
);
5445 ok(!memcmp(buf
, ctlWithOneEntry
, size
), "unexpected value\n");
5449 value2
.cbData
= sizeof(encodedIPAddr
);
5450 value2
.pbData
= (LPBYTE
)encodedIPAddr
;
5451 attr2
.pszObjId
= oid2
;
5453 attr2
.rgValue
= &value2
;
5454 ctlEntry
[1].SubjectIdentifier
.cbData
= sizeof(serialNum
);
5455 ctlEntry
[1].SubjectIdentifier
.pbData
= (LPBYTE
)serialNum
;
5456 ctlEntry
[1].cAttribute
= 1;
5457 ctlEntry
[1].rgAttribute
= &attr2
;
5459 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5460 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5461 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5464 ok(size
== sizeof(ctlWithTwoEntries
), "unexpected size %d\n", size
);
5465 ok(!memcmp(buf
, ctlWithTwoEntries
, size
), "unexpected value\n");
5471 static void compareCTLInfo(LPCSTR header
, const CTL_INFO
*expected
,
5472 const CTL_INFO
*got
)
5476 ok(expected
->dwVersion
== got
->dwVersion
,
5477 "%s: expected version %d, got %d\n", header
, expected
->dwVersion
,
5479 ok(expected
->SubjectUsage
.cUsageIdentifier
==
5480 got
->SubjectUsage
.cUsageIdentifier
,
5481 "%s: expected %d usage identifiers, got %d\n", header
,
5482 expected
->SubjectUsage
.cUsageIdentifier
,
5483 got
->SubjectUsage
.cUsageIdentifier
);
5484 for (i
= 0; i
< expected
->SubjectUsage
.cUsageIdentifier
; i
++)
5485 ok(!strcmp(expected
->SubjectUsage
.rgpszUsageIdentifier
[i
],
5486 got
->SubjectUsage
.rgpszUsageIdentifier
[i
]),
5487 "%s[%d]: expected %s, got %s\n", header
, i
,
5488 expected
->SubjectUsage
.rgpszUsageIdentifier
[i
],
5489 got
->SubjectUsage
.rgpszUsageIdentifier
[i
]);
5490 ok(expected
->ListIdentifier
.cbData
== got
->ListIdentifier
.cbData
,
5491 "%s: expected list identifier of %d bytes, got %d\n", header
,
5492 expected
->ListIdentifier
.cbData
, got
->ListIdentifier
.cbData
);
5493 if (expected
->ListIdentifier
.cbData
)
5494 ok(!memcmp(expected
->ListIdentifier
.pbData
, got
->ListIdentifier
.pbData
,
5495 expected
->ListIdentifier
.cbData
),
5496 "%s: unexpected list identifier value\n", header
);
5497 ok(expected
->SequenceNumber
.cbData
== got
->SequenceNumber
.cbData
,
5498 "%s: expected sequence number of %d bytes, got %d\n", header
,
5499 expected
->SequenceNumber
.cbData
, got
->SequenceNumber
.cbData
);
5500 if (expected
->SequenceNumber
.cbData
)
5501 ok(!memcmp(expected
->SequenceNumber
.pbData
, got
->SequenceNumber
.pbData
,
5502 expected
->SequenceNumber
.cbData
),
5503 "%s: unexpected sequence number value\n", header
);
5504 ok(!memcmp(&expected
->ThisUpdate
, &got
->ThisUpdate
, sizeof(FILETIME
)),
5505 "%s: expected this update = (%d, %d), got (%d, %d)\n", header
,
5506 expected
->ThisUpdate
.dwLowDateTime
, expected
->ThisUpdate
.dwHighDateTime
,
5507 got
->ThisUpdate
.dwLowDateTime
, got
->ThisUpdate
.dwHighDateTime
);
5508 ok(!memcmp(&expected
->NextUpdate
, &got
->NextUpdate
, sizeof(FILETIME
)),
5509 "%s: expected next update = (%d, %d), got (%d, %d)\n", header
,
5510 expected
->NextUpdate
.dwLowDateTime
, expected
->NextUpdate
.dwHighDateTime
,
5511 got
->NextUpdate
.dwLowDateTime
, got
->NextUpdate
.dwHighDateTime
);
5512 if (expected
->SubjectAlgorithm
.pszObjId
&&
5513 *expected
->SubjectAlgorithm
.pszObjId
&& !got
->SubjectAlgorithm
.pszObjId
)
5514 ok(0, "%s: expected subject algorithm %s, got NULL\n", header
,
5515 expected
->SubjectAlgorithm
.pszObjId
);
5516 if (expected
->SubjectAlgorithm
.pszObjId
&& got
->SubjectAlgorithm
.pszObjId
)
5517 ok(!strcmp(expected
->SubjectAlgorithm
.pszObjId
,
5518 got
->SubjectAlgorithm
.pszObjId
),
5519 "%s: expected subject algorithm %s, got %s\n", header
,
5520 expected
->SubjectAlgorithm
.pszObjId
, got
->SubjectAlgorithm
.pszObjId
);
5521 ok(expected
->SubjectAlgorithm
.Parameters
.cbData
==
5522 got
->SubjectAlgorithm
.Parameters
.cbData
,
5523 "%s: expected subject algorithm parameters of %d bytes, got %d\n", header
,
5524 expected
->SubjectAlgorithm
.Parameters
.cbData
,
5525 got
->SubjectAlgorithm
.Parameters
.cbData
);
5526 if (expected
->SubjectAlgorithm
.Parameters
.cbData
)
5527 ok(!memcmp(expected
->SubjectAlgorithm
.Parameters
.pbData
,
5528 got
->SubjectAlgorithm
.Parameters
.pbData
,
5529 expected
->SubjectAlgorithm
.Parameters
.cbData
),
5530 "%s: unexpected subject algorithm parameter value\n", header
);
5531 ok(expected
->cCTLEntry
== got
->cCTLEntry
,
5532 "%s: expected %d CTL entries, got %d\n", header
, expected
->cCTLEntry
,
5534 for (i
= 0; i
< expected
->cCTLEntry
; i
++)
5536 ok(expected
->rgCTLEntry
[i
].SubjectIdentifier
.cbData
==
5537 got
->rgCTLEntry
[i
].SubjectIdentifier
.cbData
,
5538 "%s[%d]: expected subject identifier of %d bytes, got %d\n",
5539 header
, i
, expected
->rgCTLEntry
[i
].SubjectIdentifier
.cbData
,
5540 got
->rgCTLEntry
[i
].SubjectIdentifier
.cbData
);
5541 if (expected
->rgCTLEntry
[i
].SubjectIdentifier
.cbData
)
5542 ok(!memcmp(expected
->rgCTLEntry
[i
].SubjectIdentifier
.pbData
,
5543 got
->rgCTLEntry
[i
].SubjectIdentifier
.pbData
,
5544 expected
->rgCTLEntry
[i
].SubjectIdentifier
.cbData
),
5545 "%s[%d]: unexpected subject identifier value\n",
5547 for (j
= 0; j
< expected
->rgCTLEntry
[i
].cAttribute
; j
++)
5549 ok(!strcmp(expected
->rgCTLEntry
[i
].rgAttribute
[j
].pszObjId
,
5550 got
->rgCTLEntry
[i
].rgAttribute
[j
].pszObjId
),
5551 "%s[%d][%d]: expected attribute OID %s, got %s\n", header
, i
, j
,
5552 expected
->rgCTLEntry
[i
].rgAttribute
[j
].pszObjId
,
5553 got
->rgCTLEntry
[i
].rgAttribute
[j
].pszObjId
);
5554 for (k
= 0; k
< expected
->rgCTLEntry
[i
].rgAttribute
[j
].cValue
; k
++)
5556 ok(expected
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].cbData
==
5557 got
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].cbData
,
5558 "%s[%d][%d][%d]: expected value of %d bytes, got %d\n",
5560 expected
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].cbData
,
5561 got
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].cbData
);
5562 if (expected
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].cbData
)
5564 expected
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].pbData
,
5565 got
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].pbData
,
5566 expected
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].cbData
),
5567 "%s[%d][%d][%d]: unexpected value\n",
5572 ok(expected
->cExtension
== got
->cExtension
,
5573 "%s: expected %d extensions, got %d\n", header
, expected
->cExtension
,
5575 for (i
= 0; i
< expected
->cExtension
; i
++)
5577 ok(!strcmp(expected
->rgExtension
[i
].pszObjId
,
5578 got
->rgExtension
[i
].pszObjId
), "%s[%d]: expected %s, got %s\n",
5579 header
, i
, expected
->rgExtension
[i
].pszObjId
,
5580 got
->rgExtension
[i
].pszObjId
);
5581 ok(expected
->rgExtension
[i
].fCritical
== got
->rgExtension
[i
].fCritical
,
5582 "%s[%d]: expected fCritical = %d, got %d\n", header
, i
,
5583 expected
->rgExtension
[i
].fCritical
, got
->rgExtension
[i
].fCritical
);
5584 ok(expected
->rgExtension
[i
].Value
.cbData
==
5585 got
->rgExtension
[i
].Value
.cbData
,
5586 "%s[%d]: expected extension value to have %d bytes, got %d\n",
5587 header
, i
, expected
->rgExtension
[i
].Value
.cbData
,
5588 got
->rgExtension
[i
].Value
.cbData
);
5589 if (expected
->rgExtension
[i
].Value
.cbData
)
5590 ok(!memcmp(expected
->rgExtension
[i
].Value
.pbData
,
5591 got
->rgExtension
[i
].Value
.pbData
,
5592 expected
->rgExtension
[i
].Value
.cbData
),
5593 "%s[%d]: unexpected extension value\n", header
, i
);
5597 static const BYTE signedCTL
[] = {
5598 0x30,0x81,0xc7,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
5599 0x81,0xb9,0x30,0x81,0xb6,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
5600 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x28,0x06,0x09,0x2a,0x86,
5601 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x1b,0x04,0x19,0x30,0x17,0x30,0x00,
5602 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5603 0x30,0x5a,0x30,0x02,0x06,0x00,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
5604 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
5605 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
5606 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5607 0x00,0x04,0x40,0xca,0xd8,0x32,0xd1,0xbd,0x97,0x61,0x54,0xd6,0x80,0xcf,0x0d,
5608 0xbd,0xa2,0x42,0xc7,0xca,0x37,0x91,0x7d,0x9d,0xac,0x8c,0xdf,0x05,0x8a,0x39,
5609 0xc6,0x07,0xc1,0x37,0xe6,0xb9,0xd1,0x0d,0x26,0xec,0xa5,0xb0,0x8a,0x51,0x26,
5610 0x2b,0x4f,0x73,0x44,0x86,0x83,0x5e,0x2b,0x6e,0xcc,0xf8,0x1b,0x85,0x53,0xe9,
5611 0x7a,0x80,0x8f,0x6b,0x42,0x19,0x93 };
5612 static const BYTE signedCTLWithCTLInnerContent
[] = {
5613 0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
5614 0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
5615 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
5616 0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
5617 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5618 0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
5619 0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
5620 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
5621 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
5622 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
5623 0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
5624 0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
5625 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
5626 0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5627 0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
5628 0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
5629 0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
5630 0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
5631 0x57,0x6c,0x0b,0x47,0xb8 };
5633 static void test_decodeCTL(DWORD dwEncoding
)
5635 static char oid1
[] = "1.2.3";
5636 static char oid2
[] = "1.5.6";
5637 static BYTE nullData
[] = { 5,0 };
5643 SYSTEMTIME thisUpdate
= { 2005, 6, 1, 6, 16, 10, 0, 0 };
5644 CTL_ENTRY ctlEntry
[2];
5645 CRYPT_ATTRIBUTE attr1
, attr2
;
5646 CRYPT_ATTR_BLOB value1
, value2
;
5648 memset(&info
, 0, sizeof(info
));
5649 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, emptyCTL
, sizeof(emptyCTL
),
5650 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5651 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5654 compareCTLInfo("empty CTL", &info
, (CTL_INFO
*)buf
);
5659 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, emptyCTLWithVersion1
,
5660 sizeof(emptyCTLWithVersion1
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
,
5662 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5665 compareCTLInfo("v1 CTL", &info
, (CTL_INFO
*)buf
);
5670 info
.SubjectUsage
.cUsageIdentifier
= 1;
5671 info
.SubjectUsage
.rgpszUsageIdentifier
= &pOid1
;
5672 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithUsageIdentifier
,
5673 sizeof(ctlWithUsageIdentifier
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5675 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5678 compareCTLInfo("CTL with usage identifier", &info
, (CTL_INFO
*)buf
);
5682 info
.SubjectUsage
.cUsageIdentifier
= 0;
5683 info
.ListIdentifier
.cbData
= sizeof(serialNum
);
5684 info
.ListIdentifier
.pbData
= (LPBYTE
)serialNum
;
5685 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithListIdentifier
,
5686 sizeof(ctlWithListIdentifier
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5687 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5690 compareCTLInfo("CTL with list identifier", &info
, (CTL_INFO
*)buf
);
5694 info
.ListIdentifier
.cbData
= 0;
5695 info
.SequenceNumber
.cbData
= sizeof(serialNum
);
5696 info
.SequenceNumber
.pbData
= (LPBYTE
)serialNum
;
5697 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithSequenceNumber
,
5698 sizeof(ctlWithSequenceNumber
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5699 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5702 compareCTLInfo("CTL with sequence number", &info
, (CTL_INFO
*)buf
);
5706 info
.SequenceNumber
.cbData
= 0;
5707 SystemTimeToFileTime(&thisUpdate
, &info
.ThisUpdate
);
5708 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithThisUpdate
,
5709 sizeof(ctlWithThisUpdate
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5710 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5713 compareCTLInfo("CTL with this update", &info
, (CTL_INFO
*)buf
);
5717 SystemTimeToFileTime(&thisUpdate
, &info
.NextUpdate
);
5718 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithThisAndNextUpdate
,
5719 sizeof(ctlWithThisAndNextUpdate
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5721 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5724 compareCTLInfo("CTL with this and next update", &info
, (CTL_INFO
*)buf
);
5728 info
.ThisUpdate
.dwLowDateTime
= info
.ThisUpdate
.dwHighDateTime
= 0;
5729 info
.NextUpdate
.dwLowDateTime
= info
.NextUpdate
.dwHighDateTime
= 0;
5730 info
.SubjectAlgorithm
.pszObjId
= oid2
;
5731 info
.SubjectAlgorithm
.Parameters
.cbData
= sizeof(nullData
);
5732 info
.SubjectAlgorithm
.Parameters
.pbData
= nullData
;
5733 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithAlgId
,
5734 sizeof(ctlWithAlgId
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5735 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5738 compareCTLInfo("CTL with algorithm identifier", &info
, (CTL_INFO
*)buf
);
5742 SetLastError(0xdeadbeef);
5743 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithBogusEntry
,
5744 sizeof(ctlWithBogusEntry
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5746 (GetLastError() == CRYPT_E_ASN1_EOD
||
5747 GetLastError() == CRYPT_E_ASN1_CORRUPT
||
5748 GetLastError() == OSS_MORE_INPUT
), /* Win9x */
5749 "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n",
5751 info
.SubjectAlgorithm
.Parameters
.cbData
= 0;
5752 info
.ThisUpdate
.dwLowDateTime
= info
.ThisUpdate
.dwHighDateTime
= 0;
5753 info
.NextUpdate
.dwLowDateTime
= info
.NextUpdate
.dwHighDateTime
= 0;
5754 info
.SubjectAlgorithm
.pszObjId
= oid2
;
5755 info
.SubjectAlgorithm
.pszObjId
= NULL
;
5756 value1
.cbData
= sizeof(emptySequence
);
5757 value1
.pbData
= (LPBYTE
)emptySequence
;
5758 attr1
.pszObjId
= oid1
;
5760 attr1
.rgValue
= &value1
;
5761 ctlEntry
[0].SubjectIdentifier
.cbData
= sizeof(serialNum
);
5762 ctlEntry
[0].SubjectIdentifier
.pbData
= (LPBYTE
)serialNum
;
5763 ctlEntry
[0].cAttribute
= 1;
5764 ctlEntry
[0].rgAttribute
= &attr1
;
5766 info
.rgCTLEntry
= ctlEntry
;
5767 SetLastError(0xdeadbeef);
5768 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithOneEntry
,
5769 sizeof(ctlWithOneEntry
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5770 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5773 compareCTLInfo("CTL with one entry", &info
, (CTL_INFO
*)buf
);
5777 value2
.cbData
= sizeof(encodedIPAddr
);
5778 value2
.pbData
= (LPBYTE
)encodedIPAddr
;
5779 attr2
.pszObjId
= oid2
;
5781 attr2
.rgValue
= &value2
;
5782 ctlEntry
[1].SubjectIdentifier
.cbData
= sizeof(serialNum
);
5783 ctlEntry
[1].SubjectIdentifier
.pbData
= (LPBYTE
)serialNum
;
5784 ctlEntry
[1].cAttribute
= 1;
5785 ctlEntry
[1].rgAttribute
= &attr2
;
5787 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithTwoEntries
,
5788 sizeof(ctlWithTwoEntries
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5789 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5792 compareCTLInfo("CTL with two entries", &info
, (CTL_INFO
*)buf
);
5796 /* A signed CTL isn't decodable, even if the inner content is a CTL */
5797 SetLastError(0xdeadbeef);
5798 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, signedCTL
,
5799 sizeof(signedCTL
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5800 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_BADTAG
||
5801 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
5802 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5804 SetLastError(0xdeadbeef);
5805 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
,
5806 signedCTLWithCTLInnerContent
, sizeof(signedCTLWithCTLInnerContent
),
5807 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5808 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_BADTAG
||
5809 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
5810 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5814 static const BYTE emptyPKCSContentInfo
[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
5815 static const BYTE emptyPKCSContentInfoExtraBytes
[] = { 0x30,0x04,0x06,0x02,0x2a,
5817 static const BYTE bogusPKCSContentInfo
[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
5819 static const BYTE intPKCSContentInfo
[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
5820 0x03,0x02,0x01,0x01 };
5821 static BYTE bogusDER
[] = { 1 };
5823 static void test_encodePKCSContentInfo(DWORD dwEncoding
)
5828 CRYPT_CONTENT_INFO info
= { 0 };
5829 char oid1
[] = "1.2.3";
5833 /* Crashes on win9x */
5834 SetLastError(0xdeadbeef);
5835 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
, NULL
,
5836 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5837 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
5838 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5840 SetLastError(0xdeadbeef);
5841 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
, &info
,
5842 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5843 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
5844 GetLastError() == OSS_LIMITED
/* Win9x */),
5845 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5846 info
.pszObjId
= oid1
;
5847 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
, &info
,
5848 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5849 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5852 ok(size
== sizeof(emptyPKCSContentInfo
), "Unexpected size %d\n", size
);
5853 ok(!memcmp(buf
, emptyPKCSContentInfo
, size
), "Unexpected value\n");
5856 info
.Content
.pbData
= bogusDER
;
5857 info
.Content
.cbData
= sizeof(bogusDER
);
5858 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
, &info
,
5859 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5860 ok(ret
, "CryptEncodeObjectEx failed; %x\n", GetLastError());
5863 ok(size
== sizeof(bogusPKCSContentInfo
), "Unexpected size %d\n", size
);
5864 ok(!memcmp(buf
, bogusPKCSContentInfo
, size
), "Unexpected value\n");
5867 info
.Content
.pbData
= (BYTE
*)ints
[0].encoded
;
5868 info
.Content
.cbData
= ints
[0].encoded
[1] + 2;
5869 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
, &info
,
5870 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5873 ok(size
== sizeof(intPKCSContentInfo
), "Unexpected size %d\n", size
);
5874 ok(!memcmp(buf
, intPKCSContentInfo
, size
), "Unexpected value\n");
5879 static const BYTE indefiniteSignedPKCSContent
[] = {
5880 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
5881 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
5882 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
5883 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
5884 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
5885 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
5886 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5887 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5888 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
5889 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5890 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5891 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
5892 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
5893 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
5894 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
5895 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
5896 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
5897 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
5898 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
5899 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5900 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5901 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
5902 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
5903 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
5904 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
5905 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
5906 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
5907 0x00,0x00,0x00,0x00,0x00,0x00 };
5909 static void test_decodePKCSContentInfo(DWORD dwEncoding
)
5914 CRYPT_CONTENT_INFO
*info
;
5916 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
,
5917 emptyPKCSContentInfo
, sizeof(emptyPKCSContentInfo
),
5918 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5919 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5922 info
= (CRYPT_CONTENT_INFO
*)buf
;
5924 ok(!strcmp(info
->pszObjId
, "1.2.3"), "Expected 1.2.3, got %s\n",
5926 ok(info
->Content
.cbData
== 0, "Expected no data, got %d\n",
5927 info
->Content
.cbData
);
5930 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
,
5931 emptyPKCSContentInfoExtraBytes
, sizeof(emptyPKCSContentInfoExtraBytes
),
5932 0, NULL
, NULL
, &size
);
5933 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5934 SetLastError(0xdeadbeef);
5935 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
,
5936 bogusPKCSContentInfo
, sizeof(bogusPKCSContentInfo
),
5937 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5938 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5939 * I doubt an app depends on that.
5941 ok((!ret
&& (GetLastError() == CRYPT_E_ASN1_EOD
||
5942 GetLastError() == CRYPT_E_ASN1_CORRUPT
)) || broken(ret
),
5943 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5945 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
,
5946 intPKCSContentInfo
, sizeof(intPKCSContentInfo
),
5947 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5948 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5951 info
= (CRYPT_CONTENT_INFO
*)buf
;
5953 ok(!strcmp(info
->pszObjId
, "1.2.3"), "Expected 1.2.3, got %s\n",
5955 ok(info
->Content
.cbData
== ints
[0].encoded
[1] + 2,
5956 "Unexpected size %d\n", info
->Content
.cbData
);
5957 ok(!memcmp(info
->Content
.pbData
, ints
[0].encoded
,
5958 info
->Content
.cbData
), "Unexpected value\n");
5961 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
,
5962 indefiniteSignedPKCSContent
, sizeof(indefiniteSignedPKCSContent
),
5963 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5964 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5967 info
= (CRYPT_CONTENT_INFO
*)buf
;
5969 ok(!strcmp(info
->pszObjId
, szOID_RSA_signedData
),
5970 "Expected %s, got %s\n", szOID_RSA_signedData
, info
->pszObjId
);
5971 ok(info
->Content
.cbData
== 392, "Expected 392, got %d\n",
5972 info
->Content
.cbData
);
5977 static const BYTE emptyPKCSAttr
[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
5979 static const BYTE bogusPKCSAttr
[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
5981 static const BYTE intPKCSAttr
[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
5984 static void test_encodePKCSAttribute(DWORD dwEncoding
)
5986 CRYPT_ATTRIBUTE attr
= { 0 };
5990 CRYPT_ATTR_BLOB blob
;
5991 char oid
[] = "1.2.3";
5995 /* Crashes on win9x */
5996 SetLastError(0xdeadbeef);
5997 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
, NULL
,
5998 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5999 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
6000 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
6002 SetLastError(0xdeadbeef);
6003 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
, &attr
,
6004 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6005 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
6006 GetLastError() == OSS_LIMITED
/* Win9x */),
6007 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
6008 attr
.pszObjId
= oid
;
6009 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
, &attr
,
6010 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6011 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6014 ok(size
== sizeof(emptyPKCSAttr
), "Unexpected size %d\n", size
);
6015 ok(!memcmp(buf
, emptyPKCSAttr
, size
), "Unexpected value\n");
6018 blob
.cbData
= sizeof(bogusDER
);
6019 blob
.pbData
= bogusDER
;
6021 attr
.rgValue
= &blob
;
6022 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
, &attr
,
6023 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6024 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6027 ok(size
== sizeof(bogusPKCSAttr
), "Unexpected size %d\n", size
);
6028 ok(!memcmp(buf
, bogusPKCSAttr
, size
), "Unexpected value\n");
6031 blob
.pbData
= (BYTE
*)ints
[0].encoded
;
6032 blob
.cbData
= ints
[0].encoded
[1] + 2;
6033 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
, &attr
,
6034 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6037 ok(size
== sizeof(intPKCSAttr
), "Unexpected size %d\n", size
);
6038 ok(!memcmp(buf
, intPKCSAttr
, size
), "Unexpected value\n");
6043 static void test_decodePKCSAttribute(DWORD dwEncoding
)
6048 CRYPT_ATTRIBUTE
*attr
;
6050 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
,
6051 emptyPKCSAttr
, sizeof(emptyPKCSAttr
),
6052 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6053 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6056 attr
= (CRYPT_ATTRIBUTE
*)buf
;
6058 ok(!strcmp(attr
->pszObjId
, "1.2.3"), "Expected 1.2.3, got %s\n",
6060 ok(attr
->cValue
== 0, "Expected no value, got %d\n", attr
->cValue
);
6063 SetLastError(0xdeadbeef);
6064 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
,
6065 bogusPKCSAttr
, sizeof(bogusPKCSAttr
),
6066 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6067 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
6068 * I doubt an app depends on that.
6070 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_EOD
||
6071 GetLastError() == CRYPT_E_ASN1_CORRUPT
||
6072 GetLastError() == OSS_MORE_INPUT
/* Win9x */),
6073 "Expected CRYPT_E_ASN1_EOD, CRYPT_E_ASN1_CORRUPT, or OSS_MORE_INPUT, got %x\n",
6075 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
,
6076 intPKCSAttr
, sizeof(intPKCSAttr
),
6077 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6078 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6081 attr
= (CRYPT_ATTRIBUTE
*)buf
;
6083 ok(!strcmp(attr
->pszObjId
, "1.2.3"), "Expected 1.2.3, got %s\n",
6085 ok(attr
->cValue
== 1, "Expected 1 value, got %d\n", attr
->cValue
);
6086 ok(attr
->rgValue
[0].cbData
== ints
[0].encoded
[1] + 2,
6087 "Unexpected size %d\n", attr
->rgValue
[0].cbData
);
6088 ok(!memcmp(attr
->rgValue
[0].pbData
, ints
[0].encoded
,
6089 attr
->rgValue
[0].cbData
), "Unexpected value\n");
6094 static const BYTE emptyPKCSAttributes
[] = { 0x31,0x00 };
6095 static const BYTE singlePKCSAttributes
[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
6096 0x2a,0x03,0x31,0x00 };
6097 static const BYTE doublePKCSAttributes
[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
6098 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
6100 static void test_encodePKCSAttributes(DWORD dwEncoding
)
6102 CRYPT_ATTRIBUTES attributes
= { 0 };
6103 CRYPT_ATTRIBUTE attr
[2] = { { 0 } };
6104 CRYPT_ATTR_BLOB blob
;
6108 char oid1
[] = "1.2.3", oid2
[] = "1.5.6";
6110 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
, &attributes
,
6111 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6112 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6115 ok(size
== sizeof(emptyPKCSAttributes
), "Unexpected size %d\n", size
);
6116 ok(!memcmp(buf
, emptyPKCSAttributes
, size
), "Unexpected value\n");
6119 attributes
.cAttr
= 1;
6120 attributes
.rgAttr
= attr
;
6121 SetLastError(0xdeadbeef);
6122 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
, &attributes
,
6123 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6124 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
6125 GetLastError() == OSS_LIMITED
/* Win9x */),
6126 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6127 attr
[0].pszObjId
= oid1
;
6128 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
, &attributes
,
6129 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6132 ok(size
== sizeof(singlePKCSAttributes
), "Unexpected size %d\n", size
);
6133 ok(!memcmp(buf
, singlePKCSAttributes
, size
), "Unexpected value\n");
6136 attr
[1].pszObjId
= oid2
;
6138 attr
[1].rgValue
= &blob
;
6139 blob
.pbData
= (BYTE
*)ints
[0].encoded
;
6140 blob
.cbData
= ints
[0].encoded
[1] + 2;
6141 attributes
.cAttr
= 2;
6142 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
, &attributes
,
6143 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6144 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6147 ok(size
== sizeof(doublePKCSAttributes
), "Unexpected size %d\n", size
);
6148 ok(!memcmp(buf
, doublePKCSAttributes
, size
), "Unexpected value\n");
6153 static void test_decodePKCSAttributes(DWORD dwEncoding
)
6158 CRYPT_ATTRIBUTES
*attributes
;
6160 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
,
6161 emptyPKCSAttributes
, sizeof(emptyPKCSAttributes
),
6162 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6163 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6166 attributes
= (CRYPT_ATTRIBUTES
*)buf
;
6167 ok(attributes
->cAttr
== 0, "Expected no attributes, got %d\n",
6171 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
,
6172 singlePKCSAttributes
, sizeof(singlePKCSAttributes
),
6173 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6174 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6177 attributes
= (CRYPT_ATTRIBUTES
*)buf
;
6178 ok(attributes
->cAttr
== 1, "Expected 1 attribute, got %d\n",
6180 ok(!strcmp(attributes
->rgAttr
[0].pszObjId
, "1.2.3"),
6181 "Expected 1.2.3, got %s\n", attributes
->rgAttr
[0].pszObjId
);
6182 ok(attributes
->rgAttr
[0].cValue
== 0,
6183 "Expected no attributes, got %d\n", attributes
->rgAttr
[0].cValue
);
6186 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
,
6187 doublePKCSAttributes
, sizeof(doublePKCSAttributes
),
6188 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6189 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6192 attributes
= (CRYPT_ATTRIBUTES
*)buf
;
6193 ok(attributes
->cAttr
== 2, "Expected 2 attributes, got %d\n",
6195 ok(!strcmp(attributes
->rgAttr
[0].pszObjId
, "1.2.3"),
6196 "Expected 1.2.3, got %s\n", attributes
->rgAttr
[0].pszObjId
);
6197 ok(attributes
->rgAttr
[0].cValue
== 0,
6198 "Expected no attributes, got %d\n", attributes
->rgAttr
[0].cValue
);
6199 ok(!strcmp(attributes
->rgAttr
[1].pszObjId
, "1.5.6"),
6200 "Expected 1.5.6, got %s\n", attributes
->rgAttr
[1].pszObjId
);
6201 ok(attributes
->rgAttr
[1].cValue
== 1,
6202 "Expected 1 attribute, got %d\n", attributes
->rgAttr
[1].cValue
);
6203 ok(attributes
->rgAttr
[1].rgValue
[0].cbData
== ints
[0].encoded
[1] + 2,
6204 "Unexpected size %d\n", attributes
->rgAttr
[1].rgValue
[0].cbData
);
6205 ok(!memcmp(attributes
->rgAttr
[1].rgValue
[0].pbData
, ints
[0].encoded
,
6206 attributes
->rgAttr
[1].rgValue
[0].cbData
), "Unexpected value\n");
6211 static const BYTE singleCapability
[] = {
6212 0x30,0x06,0x30,0x04,0x06,0x02,0x2d,0x06 };
6213 static const BYTE twoCapabilities
[] = {
6214 0x30,0x0c,0x30,0x04,0x06,0x02,0x2d,0x06,0x30,0x04,0x06,0x02,0x2a,0x03 };
6215 static const BYTE singleCapabilitywithNULL
[] = {
6216 0x30,0x08,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
6218 static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding
)
6220 static char oid1
[] = "1.5.6", oid2
[] = "1.2.3";
6224 CRYPT_SMIME_CAPABILITY capability
[2];
6225 CRYPT_SMIME_CAPABILITIES capabilities
;
6227 /* An empty capabilities is allowed */
6228 capabilities
.cCapability
= 0;
6229 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6230 &capabilities
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6231 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6234 ok(size
== sizeof(emptySequence
), "unexpected size %d\n", size
);
6235 ok(!memcmp(buf
, emptySequence
, size
), "unexpected value\n");
6238 /* A non-empty capabilities with an empty capability (lacking an OID) is
6241 capability
[0].pszObjId
= NULL
;
6242 capability
[0].Parameters
.cbData
= 0;
6243 capabilities
.cCapability
= 1;
6244 capabilities
.rgCapability
= capability
;
6245 SetLastError(0xdeadbeef);
6246 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6247 &capabilities
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6248 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
6249 GetLastError() == OSS_LIMITED
/* Win9x */),
6250 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6251 capability
[0].pszObjId
= oid1
;
6252 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6253 &capabilities
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6254 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6257 ok(size
== sizeof(singleCapability
), "unexpected size %d\n", size
);
6258 ok(!memcmp(buf
, singleCapability
, size
), "unexpected value\n");
6261 capability
[1].pszObjId
= oid2
;
6262 capability
[1].Parameters
.cbData
= 0;
6263 capabilities
.cCapability
= 2;
6264 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6265 &capabilities
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6266 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6269 ok(size
== sizeof(twoCapabilities
), "unexpected size %d\n", size
);
6270 ok(!memcmp(buf
, twoCapabilities
, size
), "unexpected value\n");
6275 static void compareSMimeCapabilities(LPCSTR header
,
6276 const CRYPT_SMIME_CAPABILITIES
*expected
, const CRYPT_SMIME_CAPABILITIES
*got
)
6280 ok(got
->cCapability
== expected
->cCapability
,
6281 "%s: expected %d capabilities, got %d\n", header
, expected
->cCapability
,
6283 for (i
= 0; i
< expected
->cCapability
; i
++)
6285 ok(!strcmp(expected
->rgCapability
[i
].pszObjId
,
6286 got
->rgCapability
[i
].pszObjId
), "%s[%d]: expected %s, got %s\n",
6287 header
, i
, expected
->rgCapability
[i
].pszObjId
,
6288 got
->rgCapability
[i
].pszObjId
);
6289 ok(expected
->rgCapability
[i
].Parameters
.cbData
==
6290 got
->rgCapability
[i
].Parameters
.cbData
,
6291 "%s[%d]: expected %d bytes, got %d\n", header
, i
,
6292 expected
->rgCapability
[i
].Parameters
.cbData
,
6293 got
->rgCapability
[i
].Parameters
.cbData
);
6294 if (expected
->rgCapability
[i
].Parameters
.cbData
)
6295 ok(!memcmp(expected
->rgCapability
[i
].Parameters
.pbData
,
6296 got
->rgCapability
[i
].Parameters
.pbData
,
6297 expected
->rgCapability
[i
].Parameters
.cbData
),
6298 "%s[%d]: unexpected value\n", header
, i
);
6302 static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding
)
6304 static char oid1
[] = "1.5.6", oid2
[] = "1.2.3";
6307 CRYPT_SMIME_CAPABILITY capability
[2];
6308 CRYPT_SMIME_CAPABILITIES capabilities
, *ptr
;
6310 SetLastError(0xdeadbeef);
6311 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6312 emptySequence
, sizeof(emptySequence
),
6313 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &ptr
, &size
);
6314 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6317 capabilities
.cCapability
= 0;
6318 compareSMimeCapabilities("empty capabilities", &capabilities
, ptr
);
6321 SetLastError(0xdeadbeef);
6322 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6323 singleCapability
, sizeof(singleCapability
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
6325 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6328 capability
[0].pszObjId
= oid1
;
6329 capability
[0].Parameters
.cbData
= 0;
6330 capabilities
.cCapability
= 1;
6331 capabilities
.rgCapability
= capability
;
6332 compareSMimeCapabilities("single capability", &capabilities
, ptr
);
6335 SetLastError(0xdeadbeef);
6336 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6337 singleCapabilitywithNULL
, sizeof(singleCapabilitywithNULL
),
6338 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &ptr
, &size
);
6339 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6342 BYTE NULLparam
[] = {0x05, 0x00};
6343 capability
[0].pszObjId
= oid1
;
6344 capability
[0].Parameters
.cbData
= 2;
6345 capability
[0].Parameters
.pbData
= NULLparam
;
6346 capabilities
.cCapability
= 1;
6347 capabilities
.rgCapability
= capability
;
6348 compareSMimeCapabilities("single capability with NULL", &capabilities
,
6352 SetLastError(0xdeadbeef);
6353 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6354 twoCapabilities
, sizeof(twoCapabilities
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
6356 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6359 capability
[0].Parameters
.cbData
= 0;
6360 capability
[1].pszObjId
= oid2
;
6361 capability
[1].Parameters
.cbData
= 0;
6362 capabilities
.cCapability
= 2;
6363 compareSMimeCapabilities("two capabilities", &capabilities
, ptr
);
6368 static BYTE encodedCommonNameNoNull
[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
6369 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
6371 static const BYTE minimalPKCSSigner
[] = {
6372 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6373 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6374 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6375 static const BYTE PKCSSignerWithSerial
[] = {
6376 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6377 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6378 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
6380 static const BYTE PKCSSignerWithHashAlgo
[] = {
6381 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6382 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6383 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
6385 static const BYTE PKCSSignerWithHashAndEncryptionAlgo
[] = {
6386 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6387 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6388 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6389 0x06,0x05,0x00,0x04,0x00 };
6390 static const BYTE PKCSSignerWithHash
[] = {
6391 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6392 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6393 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6394 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
6395 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6396 static const BYTE PKCSSignerWithAuthAttr
[] = {
6397 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6398 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6399 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
6400 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
6401 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
6402 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
6403 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6405 static void test_encodePKCSSignerInfo(DWORD dwEncoding
)
6407 static char oid1
[] = "1.2.3", oid2
[] = "1.5.6";
6411 CMSG_SIGNER_INFO info
= { 0 };
6412 char oid_common_name
[] = szOID_COMMON_NAME
;
6413 CRYPT_ATTR_BLOB commonName
= { sizeof(encodedCommonName
),
6414 (LPBYTE
)encodedCommonName
};
6415 CRYPT_ATTRIBUTE attr
= { oid_common_name
, 1, &commonName
};
6417 SetLastError(0xdeadbeef);
6418 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6419 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6420 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
6422 skip("no PKCS7_SIGNER_INFO encode support\n");
6425 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
6426 GetLastError() == OSS_LIMITED
/* Win9x */),
6427 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6428 /* To be encoded, a signer must have an issuer at least, and the encoding
6429 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
6430 * see decoding tests.)
6432 info
.Issuer
.cbData
= sizeof(encodedCommonNameNoNull
);
6433 info
.Issuer
.pbData
= encodedCommonNameNoNull
;
6434 SetLastError(0xdeadbeef);
6435 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6436 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6437 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6438 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6439 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6442 ok(ret
|| broken(GetLastError() == OSS_LIMITED
/* Win9x */),
6443 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6446 ok(size
== sizeof(minimalPKCSSigner
), "Unexpected size %d\n", size
);
6447 if (size
== sizeof(minimalPKCSSigner
))
6448 ok(!memcmp(buf
, minimalPKCSSigner
, size
), "Unexpected value\n");
6450 ok(0, "Unexpected value\n");
6454 info
.SerialNumber
.cbData
= sizeof(serialNum
);
6455 info
.SerialNumber
.pbData
= (BYTE
*)serialNum
;
6456 SetLastError(0xdeadbeef);
6457 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6458 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6459 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6460 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6461 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6464 ok(ret
|| broken(GetLastError() == OSS_LIMITED
/* Win9x */),
6465 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6468 ok(size
== sizeof(PKCSSignerWithSerial
), "Unexpected size %d\n",
6470 if (size
== sizeof(PKCSSignerWithSerial
))
6471 ok(!memcmp(buf
, PKCSSignerWithSerial
, size
),
6472 "Unexpected value\n");
6474 ok(0, "Unexpected value\n");
6478 info
.HashAlgorithm
.pszObjId
= oid1
;
6479 SetLastError(0xdeadbeef);
6480 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6481 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6482 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6483 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6484 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6487 ok(ret
|| broken(GetLastError() == OSS_LIMITED
/* Win9x */),
6488 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6491 ok(size
== sizeof(PKCSSignerWithHashAlgo
), "Unexpected size %d\n",
6493 if (size
== sizeof(PKCSSignerWithHashAlgo
))
6494 ok(!memcmp(buf
, PKCSSignerWithHashAlgo
, size
),
6495 "Unexpected value\n");
6497 ok(0, "Unexpected value\n");
6501 info
.HashEncryptionAlgorithm
.pszObjId
= oid2
;
6502 SetLastError(0xdeadbeef);
6503 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6504 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6505 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6506 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6507 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6510 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6513 ok(size
== sizeof(PKCSSignerWithHashAndEncryptionAlgo
),
6514 "Unexpected size %d\n", size
);
6515 if (size
== sizeof(PKCSSignerWithHashAndEncryptionAlgo
))
6516 ok(!memcmp(buf
, PKCSSignerWithHashAndEncryptionAlgo
, size
),
6517 "Unexpected value\n");
6519 ok(0, "Unexpected value\n");
6523 info
.EncryptedHash
.cbData
= sizeof(hash
);
6524 info
.EncryptedHash
.pbData
= (BYTE
*)hash
;
6525 SetLastError(0xdeadbeef);
6526 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6527 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6528 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6529 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6530 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6533 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6536 ok(size
== sizeof(PKCSSignerWithHash
), "Unexpected size %d\n",
6538 if (size
== sizeof(PKCSSignerWithHash
))
6539 ok(!memcmp(buf
, PKCSSignerWithHash
, size
),
6540 "Unexpected value\n");
6542 ok(0, "Unexpected value\n");
6546 info
.AuthAttrs
.cAttr
= 1;
6547 info
.AuthAttrs
.rgAttr
= &attr
;
6548 SetLastError(0xdeadbeef);
6549 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6550 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6551 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6552 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6553 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6556 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6559 ok(size
== sizeof(PKCSSignerWithAuthAttr
), "Unexpected size %d\n",
6561 if (size
== sizeof(PKCSSignerWithAuthAttr
))
6562 ok(!memcmp(buf
, PKCSSignerWithAuthAttr
, size
),
6563 "Unexpected value\n");
6565 ok(0, "Unexpected value\n");
6571 static void test_decodePKCSSignerInfo(DWORD dwEncoding
)
6576 CMSG_SIGNER_INFO
*info
;
6578 /* A PKCS signer can't be decoded without a serial number. */
6579 SetLastError(0xdeadbeef);
6580 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
6581 minimalPKCSSigner
, sizeof(minimalPKCSSigner
),
6582 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6583 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
6584 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
6585 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %x\n",
6587 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
6588 PKCSSignerWithSerial
, sizeof(PKCSSignerWithSerial
),
6589 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6590 ok(ret
|| broken(GetLastError() == OSS_DATA_ERROR
),
6591 "CryptDecodeObjectEx failed: %x\n", GetLastError());
6594 info
= (CMSG_SIGNER_INFO
*)buf
;
6595 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6597 ok(info
->Issuer
.cbData
== sizeof(encodedCommonNameNoNull
),
6598 "Unexpected size %d\n", info
->Issuer
.cbData
);
6599 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonNameNoNull
,
6600 info
->Issuer
.cbData
), "Unexpected value\n");
6601 ok(info
->SerialNumber
.cbData
== sizeof(serialNum
),
6602 "Unexpected size %d\n", info
->SerialNumber
.cbData
);
6603 ok(!memcmp(info
->SerialNumber
.pbData
, serialNum
, sizeof(serialNum
)),
6604 "Unexpected value\n");
6607 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
6608 PKCSSignerWithHashAlgo
, sizeof(PKCSSignerWithHashAlgo
),
6609 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6612 info
= (CMSG_SIGNER_INFO
*)buf
;
6613 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6615 ok(info
->Issuer
.cbData
== sizeof(encodedCommonNameNoNull
),
6616 "Unexpected size %d\n", info
->Issuer
.cbData
);
6617 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonNameNoNull
,
6618 info
->Issuer
.cbData
), "Unexpected value\n");
6619 ok(info
->SerialNumber
.cbData
== sizeof(serialNum
),
6620 "Unexpected size %d\n", info
->SerialNumber
.cbData
);
6621 ok(!memcmp(info
->SerialNumber
.pbData
, serialNum
, sizeof(serialNum
)),
6622 "Unexpected value\n");
6623 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, "1.2.3"),
6624 "Expected 1.2.3, got %s\n", info
->HashAlgorithm
.pszObjId
);
6627 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
6628 PKCSSignerWithHashAndEncryptionAlgo
,
6629 sizeof(PKCSSignerWithHashAndEncryptionAlgo
), CRYPT_DECODE_ALLOC_FLAG
,
6633 info
= (CMSG_SIGNER_INFO
*)buf
;
6634 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6636 ok(info
->Issuer
.cbData
== sizeof(encodedCommonNameNoNull
),
6637 "Unexpected size %d\n", info
->Issuer
.cbData
);
6638 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonNameNoNull
,
6639 info
->Issuer
.cbData
), "Unexpected value\n");
6640 ok(info
->SerialNumber
.cbData
== sizeof(serialNum
),
6641 "Unexpected size %d\n", info
->SerialNumber
.cbData
);
6642 ok(!memcmp(info
->SerialNumber
.pbData
, serialNum
, sizeof(serialNum
)),
6643 "Unexpected value\n");
6644 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, "1.2.3"),
6645 "Expected 1.2.3, got %s\n", info
->HashAlgorithm
.pszObjId
);
6646 ok(!strcmp(info
->HashEncryptionAlgorithm
.pszObjId
, "1.5.6"),
6647 "Expected 1.5.6, got %s\n", info
->HashEncryptionAlgorithm
.pszObjId
);
6650 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
6651 PKCSSignerWithHash
, sizeof(PKCSSignerWithHash
),
6652 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6655 info
= (CMSG_SIGNER_INFO
*)buf
;
6656 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6658 ok(info
->Issuer
.cbData
== sizeof(encodedCommonNameNoNull
),
6659 "Unexpected size %d\n", info
->Issuer
.cbData
);
6660 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonNameNoNull
,
6661 info
->Issuer
.cbData
), "Unexpected value\n");
6662 ok(info
->SerialNumber
.cbData
== sizeof(serialNum
),
6663 "Unexpected size %d\n", info
->SerialNumber
.cbData
);
6664 ok(!memcmp(info
->SerialNumber
.pbData
, serialNum
, sizeof(serialNum
)),
6665 "Unexpected value\n");
6666 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, "1.2.3"),
6667 "Expected 1.2.3, got %s\n", info
->HashAlgorithm
.pszObjId
);
6668 ok(!strcmp(info
->HashEncryptionAlgorithm
.pszObjId
, "1.5.6"),
6669 "Expected 1.5.6, got %s\n", info
->HashEncryptionAlgorithm
.pszObjId
);
6670 ok(info
->EncryptedHash
.cbData
== sizeof(hash
), "Unexpected size %d\n",
6671 info
->EncryptedHash
.cbData
);
6672 ok(!memcmp(info
->EncryptedHash
.pbData
, hash
, sizeof(hash
)),
6673 "Unexpected value\n");
6676 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
6677 PKCSSignerWithAuthAttr
, sizeof(PKCSSignerWithAuthAttr
),
6678 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6681 info
= (CMSG_SIGNER_INFO
*)buf
;
6682 ok(info
->AuthAttrs
.cAttr
== 1, "Expected 1 attribute, got %d\n",
6683 info
->AuthAttrs
.cAttr
);
6684 ok(!strcmp(info
->AuthAttrs
.rgAttr
[0].pszObjId
, szOID_COMMON_NAME
),
6685 "Expected %s, got %s\n", szOID_COMMON_NAME
,
6686 info
->AuthAttrs
.rgAttr
[0].pszObjId
);
6687 ok(info
->AuthAttrs
.rgAttr
[0].cValue
== 1, "Expected 1 value, got %d\n",
6688 info
->AuthAttrs
.rgAttr
[0].cValue
);
6689 ok(info
->AuthAttrs
.rgAttr
[0].rgValue
[0].cbData
==
6690 sizeof(encodedCommonName
), "Unexpected size %d\n",
6691 info
->AuthAttrs
.rgAttr
[0].rgValue
[0].cbData
);
6692 ok(!memcmp(info
->AuthAttrs
.rgAttr
[0].rgValue
[0].pbData
,
6693 encodedCommonName
, sizeof(encodedCommonName
)), "Unexpected value\n");
6698 static const BYTE CMSSignerWithKeyId
[] = {
6699 0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,
6700 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6702 static void test_encodeCMSSignerInfo(DWORD dwEncoding
)
6707 CMSG_CMS_SIGNER_INFO info
= { 0 };
6708 static char oid1
[] = "1.2.3", oid2
[] = "1.5.6";
6710 SetLastError(0xdeadbeef);
6711 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6712 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6713 ok(!ret
, "Expected failure, got %d\n", ret
);
6714 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
6716 skip("no CMS_SIGNER_INFO encode support\n");
6719 ok(GetLastError() == E_INVALIDARG
,
6720 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6721 info
.SignerId
.dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
6722 SetLastError(0xdeadbeef);
6723 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6724 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6725 ok(!ret
, "Expected failure, got %d\n", ret
);
6726 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
6728 skip("no CMS_SIGNER_INFO encode support\n");
6731 ok(GetLastError() == E_INVALIDARG
,
6732 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6733 /* To be encoded, a signer must have a valid cert ID, where a valid ID may
6734 * be a key id or a issuer serial number with at least the issuer set, and
6735 * the encoding must include PKCS_7_ASN_ENCODING.
6736 * (That isn't enough to be decoded, see decoding tests.)
6738 U(info
.SignerId
).IssuerSerialNumber
.Issuer
.cbData
=
6739 sizeof(encodedCommonNameNoNull
);
6740 U(info
.SignerId
).IssuerSerialNumber
.Issuer
.pbData
= encodedCommonNameNoNull
;
6741 SetLastError(0xdeadbeef);
6742 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6743 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6744 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6745 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6746 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6749 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6752 ok(size
== sizeof(minimalPKCSSigner
), "Unexpected size %d\n", size
);
6753 ok(!memcmp(buf
, minimalPKCSSigner
, size
), "Unexpected value\n");
6757 U(info
.SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
= sizeof(serialNum
);
6758 U(info
.SignerId
).IssuerSerialNumber
.SerialNumber
.pbData
= (BYTE
*)serialNum
;
6759 SetLastError(0xdeadbeef);
6760 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6761 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6762 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6763 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6764 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6767 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6770 ok(size
== sizeof(PKCSSignerWithSerial
), "Unexpected size %d\n",
6772 ok(!memcmp(buf
, PKCSSignerWithSerial
, size
), "Unexpected value\n");
6776 info
.SignerId
.dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
6777 U(info
.SignerId
).KeyId
.cbData
= sizeof(serialNum
);
6778 U(info
.SignerId
).KeyId
.pbData
= (BYTE
*)serialNum
;
6779 SetLastError(0xdeadbeef);
6780 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6781 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6782 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6783 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6784 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6787 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6790 ok(size
== sizeof(CMSSignerWithKeyId
), "Unexpected size %d\n",
6792 ok(!memcmp(buf
, CMSSignerWithKeyId
, size
), "Unexpected value\n");
6796 /* While a CERT_ID can have a hash type, that's not allowed in CMS, where
6797 * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed
6798 * (see RFC 3852, section 5.3.)
6800 info
.SignerId
.dwIdChoice
= CERT_ID_SHA1_HASH
;
6801 U(info
.SignerId
).HashId
.cbData
= sizeof(hash
);
6802 U(info
.SignerId
).HashId
.pbData
= (BYTE
*)hash
;
6803 SetLastError(0xdeadbeef);
6804 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6805 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6806 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6807 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6808 /* Now with a hash algo */
6809 info
.SignerId
.dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
6810 U(info
.SignerId
).IssuerSerialNumber
.Issuer
.cbData
=
6811 sizeof(encodedCommonNameNoNull
);
6812 U(info
.SignerId
).IssuerSerialNumber
.Issuer
.pbData
= encodedCommonNameNoNull
;
6813 info
.HashAlgorithm
.pszObjId
= oid1
;
6814 SetLastError(0xdeadbeef);
6815 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6816 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6817 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6818 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6819 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6822 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6825 ok(size
== sizeof(PKCSSignerWithHashAlgo
), "Unexpected size %d\n",
6827 ok(!memcmp(buf
, PKCSSignerWithHashAlgo
, size
),
6828 "Unexpected value\n");
6832 info
.HashEncryptionAlgorithm
.pszObjId
= oid2
;
6833 SetLastError(0xdeadbeef);
6834 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6835 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6836 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6837 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6838 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6841 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6844 ok(size
== sizeof(PKCSSignerWithHashAndEncryptionAlgo
),
6845 "Unexpected size %d\n", size
);
6846 ok(!memcmp(buf
, PKCSSignerWithHashAndEncryptionAlgo
, size
),
6847 "Unexpected value\n");
6851 info
.EncryptedHash
.cbData
= sizeof(hash
);
6852 info
.EncryptedHash
.pbData
= (BYTE
*)hash
;
6853 SetLastError(0xdeadbeef);
6854 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6855 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6856 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6857 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6858 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6861 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6864 ok(size
== sizeof(PKCSSignerWithHash
), "Unexpected size %d\n",
6866 ok(!memcmp(buf
, PKCSSignerWithHash
, size
), "Unexpected value\n");
6872 static void test_decodeCMSSignerInfo(DWORD dwEncoding
)
6877 CMSG_CMS_SIGNER_INFO
*info
;
6878 static char oid1
[] = "1.2.3", oid2
[] = "1.5.6";
6880 /* A CMS signer can't be decoded without a serial number. */
6881 SetLastError(0xdeadbeef);
6882 ret
= pCryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
6883 minimalPKCSSigner
, sizeof(minimalPKCSSigner
),
6884 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6885 ok(!ret
, "expected failure\n");
6886 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
6888 skip("no CMS_SIGNER_INFO decode support\n");
6891 ok(GetLastError() == CRYPT_E_ASN1_CORRUPT
,
6892 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
6893 ret
= pCryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
6894 PKCSSignerWithSerial
, sizeof(PKCSSignerWithSerial
),
6895 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6896 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6899 info
= (CMSG_CMS_SIGNER_INFO
*)buf
;
6900 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6902 ok(info
->SignerId
.dwIdChoice
== CERT_ID_ISSUER_SERIAL_NUMBER
,
6903 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6904 info
->SignerId
.dwIdChoice
);
6905 ok(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
==
6906 sizeof(encodedCommonNameNoNull
), "Unexpected size %d\n",
6907 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
);
6908 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.pbData
,
6909 encodedCommonNameNoNull
,
6910 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
),
6911 "Unexpected value\n");
6912 ok(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
==
6913 sizeof(serialNum
), "Unexpected size %d\n",
6914 U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
);
6915 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.pbData
,
6916 serialNum
, sizeof(serialNum
)), "Unexpected value\n");
6919 ret
= pCryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
6920 PKCSSignerWithHashAlgo
, sizeof(PKCSSignerWithHashAlgo
),
6921 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6922 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6925 info
= (CMSG_CMS_SIGNER_INFO
*)buf
;
6926 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6928 ok(info
->SignerId
.dwIdChoice
== CERT_ID_ISSUER_SERIAL_NUMBER
,
6929 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6930 info
->SignerId
.dwIdChoice
);
6931 ok(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
==
6932 sizeof(encodedCommonNameNoNull
), "Unexpected size %d\n",
6933 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
);
6934 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.pbData
,
6935 encodedCommonNameNoNull
,
6936 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
),
6937 "Unexpected value\n");
6938 ok(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
==
6939 sizeof(serialNum
), "Unexpected size %d\n",
6940 U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
);
6941 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.pbData
,
6942 serialNum
, sizeof(serialNum
)), "Unexpected value\n");
6943 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, oid1
),
6944 "Expected %s, got %s\n", oid1
, info
->HashAlgorithm
.pszObjId
);
6947 ret
= pCryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
6948 PKCSSignerWithHashAndEncryptionAlgo
,
6949 sizeof(PKCSSignerWithHashAndEncryptionAlgo
), CRYPT_DECODE_ALLOC_FLAG
,
6951 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6954 info
= (CMSG_CMS_SIGNER_INFO
*)buf
;
6955 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6957 ok(info
->SignerId
.dwIdChoice
== CERT_ID_ISSUER_SERIAL_NUMBER
,
6958 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6959 info
->SignerId
.dwIdChoice
);
6960 ok(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
==
6961 sizeof(encodedCommonNameNoNull
), "Unexpected size %d\n",
6962 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
);
6963 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.pbData
,
6964 encodedCommonNameNoNull
,
6965 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
),
6966 "Unexpected value\n");
6967 ok(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
==
6968 sizeof(serialNum
), "Unexpected size %d\n",
6969 U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
);
6970 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.pbData
,
6971 serialNum
, sizeof(serialNum
)), "Unexpected value\n");
6972 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, oid1
),
6973 "Expected %s, got %s\n", oid1
, info
->HashAlgorithm
.pszObjId
);
6974 ok(!strcmp(info
->HashEncryptionAlgorithm
.pszObjId
, oid2
),
6975 "Expected %s, got %s\n", oid2
, info
->HashEncryptionAlgorithm
.pszObjId
);
6978 ret
= pCryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
6979 PKCSSignerWithHash
, sizeof(PKCSSignerWithHash
),
6980 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6981 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6984 info
= (CMSG_CMS_SIGNER_INFO
*)buf
;
6985 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6987 ok(info
->SignerId
.dwIdChoice
== CERT_ID_ISSUER_SERIAL_NUMBER
,
6988 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6989 info
->SignerId
.dwIdChoice
);
6990 ok(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
==
6991 sizeof(encodedCommonNameNoNull
), "Unexpected size %d\n",
6992 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
);
6993 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.pbData
,
6994 encodedCommonNameNoNull
,
6995 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
),
6996 "Unexpected value\n");
6997 ok(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
==
6998 sizeof(serialNum
), "Unexpected size %d\n",
6999 U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
);
7000 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.pbData
,
7001 serialNum
, sizeof(serialNum
)), "Unexpected value\n");
7002 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, oid1
),
7003 "Expected %s, got %s\n", oid1
, info
->HashAlgorithm
.pszObjId
);
7004 ok(!strcmp(info
->HashEncryptionAlgorithm
.pszObjId
, oid2
),
7005 "Expected %s, got %s\n", oid2
, info
->HashEncryptionAlgorithm
.pszObjId
);
7006 ok(info
->EncryptedHash
.cbData
== sizeof(hash
), "Unexpected size %d\n",
7007 info
->EncryptedHash
.cbData
);
7008 ok(!memcmp(info
->EncryptedHash
.pbData
, hash
, sizeof(hash
)),
7009 "Unexpected value\n");
7012 ret
= pCryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
7013 CMSSignerWithKeyId
, sizeof(CMSSignerWithKeyId
),
7014 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7015 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
7018 info
= (CMSG_CMS_SIGNER_INFO
*)buf
;
7019 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
7021 ok(info
->SignerId
.dwIdChoice
== CERT_ID_KEY_IDENTIFIER
,
7022 "Expected CERT_ID_KEY_IDENTIFIER, got %d\n",
7023 info
->SignerId
.dwIdChoice
);
7024 ok(U(info
->SignerId
).KeyId
.cbData
== sizeof(serialNum
),
7025 "Unexpected size %d\n", U(info
->SignerId
).KeyId
.cbData
);
7026 ok(!memcmp(U(info
->SignerId
).KeyId
.pbData
, serialNum
, sizeof(serialNum
)),
7027 "Unexpected value\n");
7032 static BYTE emptyDNSPermittedConstraints
[] = {
7033 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
7034 static BYTE emptyDNSExcludedConstraints
[] = {
7035 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
7036 static BYTE DNSExcludedConstraints
[] = {
7037 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
7038 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7039 static BYTE permittedAndExcludedConstraints
[] = {
7040 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7041 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
7042 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7043 static BYTE permittedAndExcludedWithMinConstraints
[] = {
7044 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7045 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
7046 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7047 static BYTE permittedAndExcludedWithMinMaxConstraints
[] = {
7048 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7049 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
7050 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7052 static void test_encodeNameConstraints(DWORD dwEncoding
)
7055 CERT_NAME_CONSTRAINTS_INFO constraints
= { 0 };
7056 CERT_GENERAL_SUBTREE permitted
= { { 0 } };
7057 CERT_GENERAL_SUBTREE excluded
= { { 0 } };
7061 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
7062 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7063 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7065 skip("no X509_NAME_CONSTRAINTS encode support\n");
7068 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7071 ok(size
== sizeof(emptySequence
), "Unexpected size\n");
7072 ok(!memcmp(buf
, emptySequence
, size
), "Unexpected value\n");
7075 constraints
.cPermittedSubtree
= 1;
7076 constraints
.rgPermittedSubtree
= &permitted
;
7077 SetLastError(0xdeadbeef);
7078 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
7079 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7080 ok(!ret
&& GetLastError() == E_INVALIDARG
,
7081 "Expected E_INVALIDARG, got %08x\n", GetLastError());
7082 permitted
.Base
.dwAltNameChoice
= CERT_ALT_NAME_DNS_NAME
;
7083 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
7084 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7085 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7088 ok(size
== sizeof(emptyDNSPermittedConstraints
), "Unexpected size\n");
7089 ok(!memcmp(buf
, emptyDNSPermittedConstraints
, size
),
7090 "Unexpected value\n");
7093 constraints
.cPermittedSubtree
= 0;
7094 constraints
.cExcludedSubtree
= 1;
7095 constraints
.rgExcludedSubtree
= &excluded
;
7096 excluded
.Base
.dwAltNameChoice
= CERT_ALT_NAME_DNS_NAME
;
7097 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
7098 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7099 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7102 ok(size
== sizeof(emptyDNSExcludedConstraints
), "Unexpected size\n");
7103 ok(!memcmp(buf
, emptyDNSExcludedConstraints
, size
),
7104 "Unexpected value\n");
7107 U(excluded
.Base
).pwszURL
= (LPWSTR
)url
;
7108 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
7109 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7110 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7113 ok(size
== sizeof(DNSExcludedConstraints
), "Unexpected size\n");
7114 ok(!memcmp(buf
, DNSExcludedConstraints
, size
),
7115 "Unexpected value\n");
7118 permitted
.Base
.dwAltNameChoice
= CERT_ALT_NAME_IP_ADDRESS
;
7119 U(permitted
.Base
).IPAddress
.cbData
= sizeof(encodedIPAddr
);
7120 U(permitted
.Base
).IPAddress
.pbData
= (LPBYTE
)encodedIPAddr
;
7121 constraints
.cPermittedSubtree
= 1;
7122 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
7123 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7124 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7127 ok(size
== sizeof(permittedAndExcludedConstraints
),
7128 "Unexpected size\n");
7129 ok(!memcmp(buf
, permittedAndExcludedConstraints
, size
),
7130 "Unexpected value\n");
7133 permitted
.dwMinimum
= 5;
7134 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
7135 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7136 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7139 ok(size
== sizeof(permittedAndExcludedWithMinConstraints
),
7140 "Unexpected size\n");
7141 ok(!memcmp(buf
, permittedAndExcludedWithMinConstraints
, size
),
7142 "Unexpected value\n");
7145 permitted
.fMaximum
= TRUE
;
7146 permitted
.dwMaximum
= 3;
7147 SetLastError(0xdeadbeef);
7148 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
7149 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7150 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7153 ok(size
== sizeof(permittedAndExcludedWithMinMaxConstraints
),
7154 "Unexpected size\n");
7155 ok(!memcmp(buf
, permittedAndExcludedWithMinMaxConstraints
, size
),
7156 "Unexpected value\n");
7161 struct EncodedNameConstraints
7163 CRYPT_DATA_BLOB encoded
;
7164 CERT_NAME_CONSTRAINTS_INFO constraints
;
7167 static CERT_GENERAL_SUBTREE emptyDNSSubtree
= {
7168 { CERT_ALT_NAME_DNS_NAME
, { 0 } }, 0 };
7169 static CERT_GENERAL_SUBTREE DNSSubtree
= {
7170 { CERT_ALT_NAME_DNS_NAME
, { 0 } }, 0 };
7171 static CERT_GENERAL_SUBTREE IPAddressSubtree
= {
7172 { CERT_ALT_NAME_IP_ADDRESS
, { 0 } }, 0 };
7173 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree
= {
7174 { CERT_ALT_NAME_IP_ADDRESS
, { 0 } }, 5, 0 };
7175 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree
= {
7176 { CERT_ALT_NAME_IP_ADDRESS
, { 0 } }, 5, TRUE
, 3 };
7178 struct EncodedNameConstraints encodedNameConstraints
[] = {
7179 { { sizeof(emptySequence
), (LPBYTE
)emptySequence
}, { 0 } },
7180 { { sizeof(emptyDNSPermittedConstraints
), emptyDNSPermittedConstraints
},
7181 { 1, &emptyDNSSubtree
, 0, NULL
} },
7182 { { sizeof(emptyDNSExcludedConstraints
), emptyDNSExcludedConstraints
},
7183 { 0, NULL
, 1, &emptyDNSSubtree
} },
7184 { { sizeof(DNSExcludedConstraints
), DNSExcludedConstraints
},
7185 { 0, NULL
, 1, &DNSSubtree
} },
7186 { { sizeof(permittedAndExcludedConstraints
), permittedAndExcludedConstraints
},
7187 { 1, &IPAddressSubtree
, 1, &DNSSubtree
} },
7188 { { sizeof(permittedAndExcludedWithMinConstraints
),
7189 permittedAndExcludedWithMinConstraints
},
7190 { 1, &IPAddressWithMinSubtree
, 1, &DNSSubtree
} },
7191 { { sizeof(permittedAndExcludedWithMinMaxConstraints
),
7192 permittedAndExcludedWithMinMaxConstraints
},
7193 { 1, &IPAddressWithMinMaxSubtree
, 1, &DNSSubtree
} },
7196 static void test_decodeNameConstraints(DWORD dwEncoding
)
7200 CERT_NAME_CONSTRAINTS_INFO
*constraints
;
7202 U(DNSSubtree
.Base
).pwszURL
= (LPWSTR
)url
;
7203 U(IPAddressSubtree
.Base
).IPAddress
.cbData
= sizeof(encodedIPAddr
);
7204 U(IPAddressSubtree
.Base
).IPAddress
.pbData
= (LPBYTE
)encodedIPAddr
;
7205 U(IPAddressWithMinSubtree
.Base
).IPAddress
.cbData
= sizeof(encodedIPAddr
);
7206 U(IPAddressWithMinSubtree
.Base
).IPAddress
.pbData
= (LPBYTE
)encodedIPAddr
;
7207 U(IPAddressWithMinMaxSubtree
.Base
).IPAddress
.cbData
= sizeof(encodedIPAddr
);
7208 U(IPAddressWithMinMaxSubtree
.Base
).IPAddress
.pbData
= (LPBYTE
)encodedIPAddr
;
7210 i
< sizeof(encodedNameConstraints
) / sizeof(encodedNameConstraints
[0]);
7215 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
,
7216 encodedNameConstraints
[i
].encoded
.pbData
,
7217 encodedNameConstraints
[i
].encoded
.cbData
,
7218 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &constraints
, &size
);
7219 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7221 skip("no X509_NAME_CONSTRAINTS decode support\n");
7224 ok(ret
, "%d: CryptDecodeObjectEx failed: %08x\n", i
, GetLastError());
7229 if (constraints
->cPermittedSubtree
!=
7230 encodedNameConstraints
[i
].constraints
.cPermittedSubtree
)
7231 fprintf(stderr
, "%d: expected %d permitted, got %d\n", i
,
7232 encodedNameConstraints
[i
].constraints
.cPermittedSubtree
,
7233 constraints
->cPermittedSubtree
);
7234 if (constraints
->cPermittedSubtree
==
7235 encodedNameConstraints
[i
].constraints
.cPermittedSubtree
)
7237 for (j
= 0; j
< constraints
->cPermittedSubtree
; j
++)
7239 compareAltNameEntry(&constraints
->rgPermittedSubtree
[j
].Base
,
7240 &encodedNameConstraints
[i
].constraints
.rgPermittedSubtree
[j
].Base
);
7243 if (constraints
->cExcludedSubtree
!=
7244 encodedNameConstraints
[i
].constraints
.cExcludedSubtree
)
7245 fprintf(stderr
, "%d: expected %d excluded, got %d\n", i
,
7246 encodedNameConstraints
[i
].constraints
.cExcludedSubtree
,
7247 constraints
->cExcludedSubtree
);
7248 if (constraints
->cExcludedSubtree
==
7249 encodedNameConstraints
[i
].constraints
.cExcludedSubtree
)
7251 for (j
= 0; j
< constraints
->cExcludedSubtree
; j
++)
7253 compareAltNameEntry(&constraints
->rgExcludedSubtree
[j
].Base
,
7254 &encodedNameConstraints
[i
].constraints
.rgExcludedSubtree
[j
].Base
);
7257 LocalFree(constraints
);
7262 static WCHAR noticeText
[] = { 'T','h','i','s',' ','i','s',' ','a',' ',
7263 'n','o','t','i','c','e',0 };
7264 static const BYTE noticeWithDisplayText
[] = {
7265 0x30,0x22,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,0x00,
7266 0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,0x74,
7267 0x00,0x69,0x00,0x63,0x00,0x65
7269 static char org
[] = "Wine";
7270 static int noticeNumbers
[] = { 2,3 };
7271 static BYTE noticeWithReference
[] = {
7272 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7273 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7274 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7275 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7278 static void test_encodePolicyQualifierUserNotice(DWORD dwEncoding
)
7283 CERT_POLICY_QUALIFIER_USER_NOTICE notice
;
7284 CERT_POLICY_QUALIFIER_NOTICE_REFERENCE reference
;
7286 memset(¬ice
, 0, sizeof(notice
));
7287 ret
= pCryptEncodeObjectEx(dwEncoding
,
7288 X509_PKIX_POLICY_QUALIFIER_USERNOTICE
, ¬ice
, CRYPT_ENCODE_ALLOC_FLAG
,
7290 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7292 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE encode support\n");
7295 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7298 ok(sizeof(emptySequence
) == size
, "unexpected size %d\n", size
);
7299 ok(!memcmp(buf
, emptySequence
, size
), "unexpected value\n");
7302 notice
.pszDisplayText
= noticeText
;
7303 ret
= pCryptEncodeObjectEx(dwEncoding
,
7304 X509_PKIX_POLICY_QUALIFIER_USERNOTICE
, ¬ice
, CRYPT_ENCODE_ALLOC_FLAG
,
7306 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7309 ok(sizeof(noticeWithDisplayText
) == size
, "unexpected size %d\n", size
);
7310 ok(!memcmp(buf
, noticeWithDisplayText
, size
), "unexpected value\n");
7313 reference
.pszOrganization
= org
;
7314 reference
.cNoticeNumbers
= 2;
7315 reference
.rgNoticeNumbers
= noticeNumbers
;
7316 notice
.pNoticeReference
= &reference
;
7317 ret
= pCryptEncodeObjectEx(dwEncoding
,
7318 X509_PKIX_POLICY_QUALIFIER_USERNOTICE
, ¬ice
, CRYPT_ENCODE_ALLOC_FLAG
,
7320 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7323 ok(sizeof(noticeWithReference
) == size
, "unexpected size %d\n", size
);
7324 ok(!memcmp(buf
, noticeWithReference
, size
), "unexpected value\n");
7329 static void test_decodePolicyQualifierUserNotice(DWORD dwEncoding
)
7332 CERT_POLICY_QUALIFIER_USER_NOTICE
*notice
;
7335 ret
= pCryptDecodeObjectEx(dwEncoding
,
7336 X509_PKIX_POLICY_QUALIFIER_USERNOTICE
,
7337 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
7339 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7341 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE decode support\n");
7344 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7347 ok(notice
->pszDisplayText
== NULL
, "unexpected display text\n");
7348 ok(notice
->pNoticeReference
== NULL
, "unexpected notice reference\n");
7351 ret
= pCryptDecodeObjectEx(dwEncoding
,
7352 X509_PKIX_POLICY_QUALIFIER_USERNOTICE
,
7353 noticeWithDisplayText
, sizeof(noticeWithDisplayText
),
7354 CRYPT_DECODE_ALLOC_FLAG
, NULL
, ¬ice
, &size
);
7355 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7358 ok(!lstrcmpW(notice
->pszDisplayText
, noticeText
),
7359 "unexpected display text\n");
7360 ok(notice
->pNoticeReference
== NULL
, "unexpected notice reference\n");
7363 ret
= pCryptDecodeObjectEx(dwEncoding
,
7364 X509_PKIX_POLICY_QUALIFIER_USERNOTICE
,
7365 noticeWithReference
, sizeof(noticeWithReference
),
7366 CRYPT_DECODE_ALLOC_FLAG
, NULL
, ¬ice
, &size
);
7367 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7370 ok(!lstrcmpW(notice
->pszDisplayText
, noticeText
),
7371 "unexpected display text\n");
7372 ok(notice
->pNoticeReference
!= NULL
, "expected a notice reference\n");
7373 if (notice
->pNoticeReference
)
7375 ok(!strcmp(notice
->pNoticeReference
->pszOrganization
, org
),
7376 "unexpected organization %s\n",
7377 notice
->pNoticeReference
->pszOrganization
);
7378 ok(notice
->pNoticeReference
->cNoticeNumbers
== 2,
7379 "expected 2 notice numbers, got %d\n",
7380 notice
->pNoticeReference
->cNoticeNumbers
);
7381 ok(notice
->pNoticeReference
->rgNoticeNumbers
[0] == noticeNumbers
[0],
7382 "unexpected notice number %d\n",
7383 notice
->pNoticeReference
->rgNoticeNumbers
[0]);
7384 ok(notice
->pNoticeReference
->rgNoticeNumbers
[1] == noticeNumbers
[1],
7385 "unexpected notice number %d\n",
7386 notice
->pNoticeReference
->rgNoticeNumbers
[1]);
7392 static char oid_any_policy
[] = "2.5.29.32.0";
7393 static const BYTE policiesWithAnyPolicy
[] = {
7394 0x30,0x08,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00
7396 static char oid1
[] = "1.2.3";
7397 static char oid_user_notice
[] = "1.3.6.1.5.5.7.2.2";
7398 static const BYTE twoPolicies
[] = {
7399 0x30,0x50,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00,0x30,0x46,0x06,0x02,0x2a,
7400 0x03,0x30,0x40,0x30,0x3e,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x02,
7401 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7402 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7403 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7404 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7407 static void test_encodeCertPolicies(DWORD dwEncoding
)
7410 CERT_POLICIES_INFO info
;
7411 CERT_POLICY_INFO policy
[2];
7412 CERT_POLICY_QUALIFIER_INFO qualifier
;
7416 memset(&info
, 0, sizeof(info
));
7417 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_POLICIES
, &info
,
7418 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7419 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7422 ok(sizeof(emptySequence
) == size
, "unexpected size %d\n", size
);
7423 ok(!memcmp(buf
, emptySequence
, size
), "unexpected value\n");
7426 memset(policy
, 0, sizeof(policy
));
7427 info
.cPolicyInfo
= 1;
7428 info
.rgPolicyInfo
= policy
;
7429 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_POLICIES
, &info
,
7430 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7431 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
7432 GetLastError() == OSS_LIMITED
/* Win9x/NT4 */),
7433 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
7434 policy
[0].pszPolicyIdentifier
= oid_any_policy
;
7435 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_POLICIES
, &info
,
7436 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7437 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7440 ok(sizeof(policiesWithAnyPolicy
) == size
, "unexpected size %d\n", size
);
7441 ok(!memcmp(buf
, policiesWithAnyPolicy
, size
), "unexpected value\n");
7444 policy
[1].pszPolicyIdentifier
= oid1
;
7445 memset(&qualifier
, 0, sizeof(qualifier
));
7446 qualifier
.pszPolicyQualifierId
= oid_user_notice
;
7447 qualifier
.Qualifier
.cbData
= sizeof(noticeWithReference
);
7448 qualifier
.Qualifier
.pbData
= noticeWithReference
;
7449 policy
[1].cPolicyQualifier
= 1;
7450 policy
[1].rgPolicyQualifier
= &qualifier
;
7451 info
.cPolicyInfo
= 2;
7452 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_POLICIES
, &info
,
7453 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7454 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7457 ok(sizeof(twoPolicies
) == size
, "unexpected size %d\n", size
);
7458 ok(!memcmp(buf
, twoPolicies
, size
), "unexpected value\n");
7463 static void test_decodeCertPolicies(DWORD dwEncoding
)
7466 CERT_POLICIES_INFO
*info
;
7469 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_POLICIES
,
7470 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
7472 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7475 ok(info
->cPolicyInfo
== 0, "unexpected policy info %d\n",
7479 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_POLICIES
,
7480 policiesWithAnyPolicy
, sizeof(policiesWithAnyPolicy
),
7481 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
);
7482 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7485 ok(info
->cPolicyInfo
== 1, "unexpected policy info %d\n",
7487 ok(!strcmp(info
->rgPolicyInfo
[0].pszPolicyIdentifier
, oid_any_policy
),
7488 "unexpected policy id %s\n",
7489 info
->rgPolicyInfo
[0].pszPolicyIdentifier
);
7490 ok(info
->rgPolicyInfo
[0].cPolicyQualifier
== 0,
7491 "unexpected policy qualifier count %d\n",
7492 info
->rgPolicyInfo
[0].cPolicyQualifier
);
7495 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_POLICIES
,
7496 twoPolicies
, sizeof(twoPolicies
),
7497 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
);
7498 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7501 ok(info
->cPolicyInfo
== 2, "unexpected policy info %d\n",
7503 ok(!strcmp(info
->rgPolicyInfo
[0].pszPolicyIdentifier
, oid_any_policy
),
7504 "unexpected policy id %s\n",
7505 info
->rgPolicyInfo
[0].pszPolicyIdentifier
);
7506 ok(info
->rgPolicyInfo
[0].cPolicyQualifier
== 0,
7507 "unexpected policy qualifier count %d\n",
7508 info
->rgPolicyInfo
[0].cPolicyQualifier
);
7509 ok(!strcmp(info
->rgPolicyInfo
[1].pszPolicyIdentifier
, oid1
),
7510 "unexpected policy id %s\n",
7511 info
->rgPolicyInfo
[1].pszPolicyIdentifier
);
7512 ok(info
->rgPolicyInfo
[1].cPolicyQualifier
== 1,
7513 "unexpected policy qualifier count %d\n",
7514 info
->rgPolicyInfo
[1].cPolicyQualifier
);
7516 info
->rgPolicyInfo
[1].rgPolicyQualifier
[0].pszPolicyQualifierId
,
7517 oid_user_notice
), "unexpected policy qualifier id %s\n",
7518 info
->rgPolicyInfo
[1].rgPolicyQualifier
[0].pszPolicyQualifierId
);
7519 ok(info
->rgPolicyInfo
[1].rgPolicyQualifier
[0].Qualifier
.cbData
==
7520 sizeof(noticeWithReference
), "unexpected qualifier size %d\n",
7521 info
->rgPolicyInfo
[1].rgPolicyQualifier
[0].Qualifier
.cbData
);
7523 info
->rgPolicyInfo
[1].rgPolicyQualifier
[0].Qualifier
.pbData
,
7524 noticeWithReference
, sizeof(noticeWithReference
)),
7525 "unexpected qualifier value\n");
7530 static const BYTE policyMappingWithOneMapping
[] = {
7531 0x30,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04 };
7532 static const BYTE policyMappingWithTwoMappings
[] = {
7533 0x30,0x14,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04,0x30,0x08,0x06,
7534 0x02,0x2b,0x04,0x06,0x02,0x55,0x06 };
7535 static const LPCSTR mappingOids
[] = { X509_POLICY_MAPPINGS
,
7536 szOID_POLICY_MAPPINGS
, szOID_LEGACY_POLICY_MAPPINGS
};
7538 static void test_encodeCertPolicyMappings(DWORD dwEncoding
)
7540 static char oid2
[] = "2.3.4";
7541 static char oid3
[] = "1.3.4";
7542 static char oid4
[] = "2.5.6";
7544 CERT_POLICY_MAPPINGS_INFO info
= { 0 };
7545 CERT_POLICY_MAPPING mapping
[2];
7549 /* Each of the mapping OIDs is equivalent, so check with all of them */
7550 for (i
= 0; i
< sizeof(mappingOids
) / sizeof(mappingOids
[0]); i
++)
7552 memset(&info
, 0, sizeof(info
));
7553 ret
= pCryptEncodeObjectEx(dwEncoding
, mappingOids
[i
], &info
,
7554 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7555 ok(ret
|| broken(GetLastError() == ERROR_FILE_NOT_FOUND
),
7556 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7557 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7559 win_skip("no policy mappings support\n");
7564 ok(size
== sizeof(emptySequence
), "unexpected size %d\n", size
);
7565 ok(!memcmp(buf
, emptySequence
, sizeof(emptySequence
)),
7566 "unexpected value\n");
7569 mapping
[0].pszIssuerDomainPolicy
= NULL
;
7570 mapping
[0].pszSubjectDomainPolicy
= NULL
;
7571 info
.cPolicyMapping
= 1;
7572 info
.rgPolicyMapping
= mapping
;
7573 SetLastError(0xdeadbeef);
7574 ret
= pCryptEncodeObjectEx(dwEncoding
, mappingOids
[i
], &info
,
7575 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7576 ok(!ret
&& GetLastError() == E_INVALIDARG
,
7577 "expected E_INVALIDARG, got %08x\n", GetLastError());
7578 mapping
[0].pszIssuerDomainPolicy
= oid1
;
7579 mapping
[0].pszSubjectDomainPolicy
= oid2
;
7580 ret
= pCryptEncodeObjectEx(dwEncoding
, mappingOids
[i
], &info
,
7581 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7582 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7585 ok(size
== sizeof(policyMappingWithOneMapping
),
7586 "unexpected size %d\n", size
);
7587 ok(!memcmp(buf
, policyMappingWithOneMapping
, size
),
7588 "unexpected value\n");
7591 mapping
[1].pszIssuerDomainPolicy
= oid3
;
7592 mapping
[1].pszSubjectDomainPolicy
= oid4
;
7593 info
.cPolicyMapping
= 2;
7594 ret
= pCryptEncodeObjectEx(dwEncoding
, mappingOids
[i
], &info
,
7595 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7596 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7599 ok(size
== sizeof(policyMappingWithTwoMappings
),
7600 "unexpected size %d\n", size
);
7601 ok(!memcmp(buf
, policyMappingWithTwoMappings
, size
),
7602 "unexpected value\n");
7608 static void test_decodeCertPolicyMappings(DWORD dwEncoding
)
7611 CERT_POLICY_MAPPINGS_INFO
*info
;
7614 /* Each of the mapping OIDs is equivalent, so check with all of them */
7615 for (i
= 0; i
< sizeof(mappingOids
) / sizeof(mappingOids
[0]); i
++)
7617 ret
= pCryptDecodeObjectEx(dwEncoding
, mappingOids
[i
],
7618 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
7620 ok(ret
|| broken(GetLastError() == ERROR_FILE_NOT_FOUND
),
7621 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7622 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7624 win_skip("no policy mappings support\n");
7629 ok(info
->cPolicyMapping
== 0,
7630 "expected 0 policy mappings, got %d\n", info
->cPolicyMapping
);
7633 ret
= pCryptDecodeObjectEx(dwEncoding
, mappingOids
[i
],
7634 policyMappingWithOneMapping
, sizeof(policyMappingWithOneMapping
),
7635 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
);
7636 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7639 ok(info
->cPolicyMapping
== 1,
7640 "expected 1 policy mappings, got %d\n", info
->cPolicyMapping
);
7641 ok(!strcmp(info
->rgPolicyMapping
[0].pszIssuerDomainPolicy
, "1.2.3"),
7642 "unexpected issuer policy %s\n",
7643 info
->rgPolicyMapping
[0].pszIssuerDomainPolicy
);
7644 ok(!strcmp(info
->rgPolicyMapping
[0].pszSubjectDomainPolicy
,
7645 "2.3.4"), "unexpected subject policy %s\n",
7646 info
->rgPolicyMapping
[0].pszSubjectDomainPolicy
);
7649 ret
= pCryptDecodeObjectEx(dwEncoding
, mappingOids
[i
],
7650 policyMappingWithTwoMappings
, sizeof(policyMappingWithTwoMappings
),
7651 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
);
7652 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7655 ok(info
->cPolicyMapping
== 2,
7656 "expected 2 policy mappings, got %d\n", info
->cPolicyMapping
);
7657 ok(!strcmp(info
->rgPolicyMapping
[0].pszIssuerDomainPolicy
, "1.2.3"),
7658 "unexpected issuer policy %s\n",
7659 info
->rgPolicyMapping
[0].pszIssuerDomainPolicy
);
7660 ok(!strcmp(info
->rgPolicyMapping
[0].pszSubjectDomainPolicy
,
7661 "2.3.4"), "unexpected subject policy %s\n",
7662 info
->rgPolicyMapping
[0].pszSubjectDomainPolicy
);
7663 ok(!strcmp(info
->rgPolicyMapping
[1].pszIssuerDomainPolicy
, "1.3.4"),
7664 "unexpected issuer policy %s\n",
7665 info
->rgPolicyMapping
[1].pszIssuerDomainPolicy
);
7666 ok(!strcmp(info
->rgPolicyMapping
[1].pszSubjectDomainPolicy
,
7667 "2.5.6"), "unexpected subject policy %s\n",
7668 info
->rgPolicyMapping
[1].pszSubjectDomainPolicy
);
7674 static const BYTE policyConstraintsWithRequireExplicit
[] = {
7675 0x30,0x03,0x80,0x01,0x00 };
7676 static const BYTE policyConstraintsWithInhibitMapping
[] = {
7677 0x30,0x03,0x81,0x01,0x01 };
7678 static const BYTE policyConstraintsWithBoth
[] = {
7679 0x30,0x06,0x80,0x01,0x01,0x81,0x01,0x01 };
7681 static void test_encodeCertPolicyConstraints(DWORD dwEncoding
)
7683 CERT_POLICY_CONSTRAINTS_INFO info
= { 0 };
7688 /* Even though RFC 5280 explicitly states CAs must not issue empty
7689 * policy constraints (section 4.2.1.11), the API doesn't prevent it.
7691 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_POLICY_CONSTRAINTS
, &info
,
7692 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7693 ok(ret
|| broken(GetLastError() == ERROR_FILE_NOT_FOUND
),
7694 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7695 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7697 win_skip("no policy constraints support\n");
7702 ok(size
== sizeof(emptySequence
), "unexpected size %d\n", size
);
7703 ok(!memcmp(buf
, emptySequence
, sizeof(emptySequence
)),
7704 "unexpected value\n");
7707 /* If fRequireExplicitPolicy is set but dwRequireExplicitPolicySkipCerts
7708 * is not, then a skip of 0 is encoded.
7710 info
.fRequireExplicitPolicy
= TRUE
;
7711 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_POLICY_CONSTRAINTS
, &info
,
7712 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7713 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7716 ok(size
== sizeof(policyConstraintsWithRequireExplicit
),
7717 "unexpected size %d\n", size
);
7718 ok(!memcmp(buf
, policyConstraintsWithRequireExplicit
,
7719 sizeof(policyConstraintsWithRequireExplicit
)), "unexpected value\n");
7722 /* With inhibit policy mapping */
7723 info
.fRequireExplicitPolicy
= FALSE
;
7724 info
.dwRequireExplicitPolicySkipCerts
= 0;
7725 info
.fInhibitPolicyMapping
= TRUE
;
7726 info
.dwInhibitPolicyMappingSkipCerts
= 1;
7727 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_POLICY_CONSTRAINTS
, &info
,
7728 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7729 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7732 ok(size
== sizeof(policyConstraintsWithInhibitMapping
),
7733 "unexpected size %d\n", size
);
7734 ok(!memcmp(buf
, policyConstraintsWithInhibitMapping
,
7735 sizeof(policyConstraintsWithInhibitMapping
)), "unexpected value\n");
7739 info
.fRequireExplicitPolicy
= TRUE
;
7740 info
.dwRequireExplicitPolicySkipCerts
= 1;
7741 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_POLICY_CONSTRAINTS
, &info
,
7742 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7743 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7746 ok(size
== sizeof(policyConstraintsWithBoth
), "unexpected size %d\n",
7748 ok(!memcmp(buf
, policyConstraintsWithBoth
,
7749 sizeof(policyConstraintsWithBoth
)), "unexpected value\n");
7754 static void test_decodeCertPolicyConstraints(DWORD dwEncoding
)
7756 CERT_POLICY_CONSTRAINTS_INFO
*info
;
7760 /* Again, even though CAs must not issue such constraints, they can be
7763 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_POLICY_CONSTRAINTS
,
7764 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
7766 ok(ret
|| broken(GetLastError() == ERROR_FILE_NOT_FOUND
),
7767 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7768 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7770 win_skip("no policy mappings support\n");
7775 ok(!info
->fRequireExplicitPolicy
,
7776 "expected require explicit = FALSE\n");
7777 ok(!info
->fInhibitPolicyMapping
,
7778 "expected implicit mapping = FALSE\n");
7781 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_POLICY_CONSTRAINTS
,
7782 policyConstraintsWithRequireExplicit
,
7783 sizeof(policyConstraintsWithRequireExplicit
), CRYPT_DECODE_ALLOC_FLAG
,
7784 NULL
, &info
, &size
);
7785 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7788 ok(info
->fRequireExplicitPolicy
,
7789 "expected require explicit = TRUE\n");
7790 ok(info
->dwRequireExplicitPolicySkipCerts
== 0, "expected 0, got %d\n",
7791 info
->dwRequireExplicitPolicySkipCerts
);
7792 ok(!info
->fInhibitPolicyMapping
,
7793 "expected implicit mapping = FALSE\n");
7796 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_POLICY_CONSTRAINTS
,
7797 policyConstraintsWithInhibitMapping
,
7798 sizeof(policyConstraintsWithInhibitMapping
), CRYPT_DECODE_ALLOC_FLAG
,
7799 NULL
, &info
, &size
);
7800 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7803 ok(!info
->fRequireExplicitPolicy
,
7804 "expected require explicit = FALSE\n");
7805 ok(info
->fInhibitPolicyMapping
,
7806 "expected implicit mapping = TRUE\n");
7807 ok(info
->dwInhibitPolicyMappingSkipCerts
== 1, "expected 1, got %d\n",
7808 info
->dwInhibitPolicyMappingSkipCerts
);
7811 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_POLICY_CONSTRAINTS
,
7812 policyConstraintsWithBoth
, sizeof(policyConstraintsWithBoth
),
7813 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
);
7814 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7817 ok(info
->fRequireExplicitPolicy
,
7818 "expected require explicit = TRUE\n");
7819 ok(info
->dwRequireExplicitPolicySkipCerts
== 1, "expected 1, got %d\n",
7820 info
->dwRequireExplicitPolicySkipCerts
);
7821 ok(info
->fInhibitPolicyMapping
,
7822 "expected implicit mapping = TRUE\n");
7823 ok(info
->dwInhibitPolicyMappingSkipCerts
== 1, "expected 1, got %d\n",
7824 info
->dwInhibitPolicyMappingSkipCerts
);
7829 /* Free *pInfo with HeapFree */
7830 static void testExportPublicKey(HCRYPTPROV csp
, PCERT_PUBLIC_KEY_INFO
*pInfo
)
7837 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
7839 ret
= CryptExportPublicKeyInfoEx(0, 0, 0, NULL
, 0, NULL
, NULL
, &size
);
7840 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
7841 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7842 ret
= CryptExportPublicKeyInfoEx(0, AT_SIGNATURE
, 0, NULL
, 0, NULL
, NULL
,
7844 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
7845 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7846 ret
= CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING
, NULL
, 0, NULL
,
7848 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
7849 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7850 ret
= CryptExportPublicKeyInfoEx(0, AT_SIGNATURE
, X509_ASN_ENCODING
, NULL
,
7851 0, NULL
, NULL
, &size
);
7852 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
7853 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7854 /* Test with no key */
7855 ret
= CryptExportPublicKeyInfoEx(csp
, AT_SIGNATURE
, X509_ASN_ENCODING
, NULL
,
7856 0, NULL
, NULL
, &size
);
7857 ok(!ret
&& GetLastError() == NTE_NO_KEY
, "Expected NTE_NO_KEY, got %08x\n",
7859 ret
= CryptGenKey(csp
, AT_SIGNATURE
, 0, &key
);
7860 ok(ret
, "CryptGenKey failed: %08x\n", GetLastError());
7863 ret
= CryptExportPublicKeyInfoEx(csp
, AT_SIGNATURE
, X509_ASN_ENCODING
,
7864 NULL
, 0, NULL
, NULL
, &size
);
7865 ok(ret
, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
7866 *pInfo
= HeapAlloc(GetProcessHeap(), 0, size
);
7869 ret
= CryptExportPublicKeyInfoEx(csp
, AT_SIGNATURE
,
7870 X509_ASN_ENCODING
, NULL
, 0, NULL
, *pInfo
, &size
);
7871 ok(ret
, "CryptExportPublicKeyInfoEx failed: %08x\n",
7875 /* By default (we passed NULL as the OID) the OID is
7878 ok(!strcmp((*pInfo
)->Algorithm
.pszObjId
, szOID_RSA_RSA
),
7879 "Expected %s, got %s\n", szOID_RSA_RSA
,
7880 (*pInfo
)->Algorithm
.pszObjId
);
7884 CryptDestroyKey(key
);
7887 static const BYTE expiredCert
[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
7888 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
7889 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
7890 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7891 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7892 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7893 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
7894 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
7895 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7896 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7897 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7898 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
7899 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
7900 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
7901 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
7902 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
7903 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
7904 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
7905 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
7906 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
7907 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
7908 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
7909 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
7910 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
7911 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
7913 static void testImportPublicKey(HCRYPTPROV csp
, PCERT_PUBLIC_KEY_INFO info
)
7917 PCCERT_CONTEXT context
;
7922 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
7923 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
7924 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
7925 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7928 ret
= CryptImportPublicKeyInfoEx(0, 0, info
, 0, 0, NULL
, &key
);
7929 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
7930 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7931 ret
= CryptImportPublicKeyInfoEx(csp
, 0, info
, 0, 0, NULL
, &key
);
7932 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
7933 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7934 ret
= CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING
, info
, 0, 0, NULL
,
7936 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
7937 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7939 /* Export key with standard algorithm (CALG_RSA_KEYX) */
7940 ret
= CryptImportPublicKeyInfoEx(csp
, X509_ASN_ENCODING
, info
, 0, 0, NULL
,
7942 ok(ret
, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7944 dwSize
= sizeof(ai
);
7945 CryptGetKeyParam(key
, KP_ALGID
, (LPVOID
)&ai
, &dwSize
, 0);
7946 ok(ret
, "CryptGetKeyParam failed: %08x\n", GetLastError());
7949 ok(dwSize
== sizeof(ai
), "CryptGetKeyParam returned size %d\n",dwSize
);
7950 ok(ai
== CALG_RSA_KEYX
, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai
);
7953 CryptDestroyKey(key
);
7955 /* Repeat with forced algorithm */
7956 ret
= CryptImportPublicKeyInfoEx(csp
, X509_ASN_ENCODING
, info
, CALG_RSA_SIGN
, 0, NULL
,
7958 ok(ret
, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7960 dwSize
= sizeof(ai
);
7961 CryptGetKeyParam(key
, KP_ALGID
, (LPVOID
)&ai
, &dwSize
, 0);
7962 ok(ret
, "CryptGetKeyParam failed: %08x\n", GetLastError());
7965 ok(dwSize
== sizeof(ai
), "CryptGetKeyParam returned size %d\n",dwSize
);
7966 ok(ai
== CALG_RSA_SIGN
, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai
);
7969 CryptDestroyKey(key
);
7971 /* Test importing a public key from a certificate context */
7972 context
= CertCreateCertificateContext(X509_ASN_ENCODING
, expiredCert
,
7973 sizeof(expiredCert
));
7974 ok(context
!= NULL
, "CertCreateCertificateContext failed: %08x\n",
7978 ok(!strcmp(szOID_RSA_RSA
,
7979 context
->pCertInfo
->SubjectPublicKeyInfo
.Algorithm
.pszObjId
),
7980 "Expected %s, got %s\n", szOID_RSA_RSA
,
7981 context
->pCertInfo
->SubjectPublicKeyInfo
.Algorithm
.pszObjId
);
7982 ret
= CryptImportPublicKeyInfoEx(csp
, X509_ASN_ENCODING
,
7983 &context
->pCertInfo
->SubjectPublicKeyInfo
, 0, 0, NULL
, &key
);
7984 ok(ret
, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7985 CryptDestroyKey(key
);
7986 CertFreeCertificateContext(context
);
7990 static const char cspName
[] = "WineCryptTemp";
7992 static void testPortPublicKeyInfo(void)
7996 PCERT_PUBLIC_KEY_INFO info
= NULL
;
7998 /* Just in case a previous run failed, delete this thing */
7999 CryptAcquireContextA(&csp
, cspName
, MS_DEF_PROV
, PROV_RSA_FULL
,
8000 CRYPT_DELETEKEYSET
);
8001 ret
= CryptAcquireContextA(&csp
, cspName
, MS_DEF_PROV
, PROV_RSA_FULL
,
8004 testExportPublicKey(csp
, &info
);
8005 testImportPublicKey(csp
, info
);
8007 HeapFree(GetProcessHeap(), 0, info
);
8008 CryptReleaseContext(csp
, 0);
8009 ret
= CryptAcquireContextA(&csp
, cspName
, MS_DEF_PROV
, PROV_RSA_FULL
,
8010 CRYPT_DELETEKEYSET
);
8015 static const DWORD encodings
[] = { X509_ASN_ENCODING
, PKCS_7_ASN_ENCODING
,
8016 X509_ASN_ENCODING
| PKCS_7_ASN_ENCODING
};
8020 hCrypt32
= GetModuleHandleA("crypt32.dll");
8021 pCryptDecodeObjectEx
= (void*)GetProcAddress(hCrypt32
, "CryptDecodeObjectEx");
8022 pCryptEncodeObjectEx
= (void*)GetProcAddress(hCrypt32
, "CryptEncodeObjectEx");
8023 if (!pCryptDecodeObjectEx
|| !pCryptEncodeObjectEx
)
8025 win_skip("CryptDecodeObjectEx() is not available\n");
8029 for (i
= 0; i
< sizeof(encodings
) / sizeof(encodings
[0]); i
++)
8031 test_encodeInt(encodings
[i
]);
8032 test_decodeInt(encodings
[i
]);
8033 test_encodeEnumerated(encodings
[i
]);
8034 test_decodeEnumerated(encodings
[i
]);
8035 test_encodeFiletime(encodings
[i
]);
8036 test_decodeFiletime(encodings
[i
]);
8037 test_encodeName(encodings
[i
]);
8038 test_decodeName(encodings
[i
]);
8039 test_encodeUnicodeName(encodings
[i
]);
8040 test_decodeUnicodeName(encodings
[i
]);
8041 test_encodeNameValue(encodings
[i
]);
8042 test_decodeNameValue(encodings
[i
]);
8043 test_encodeUnicodeNameValue(encodings
[i
]);
8044 test_decodeUnicodeNameValue(encodings
[i
]);
8045 test_encodeAltName(encodings
[i
]);
8046 test_decodeAltName(encodings
[i
]);
8047 test_encodeOctets(encodings
[i
]);
8048 test_decodeOctets(encodings
[i
]);
8049 test_encodeBits(encodings
[i
]);
8050 test_decodeBits(encodings
[i
]);
8051 test_encodeBasicConstraints(encodings
[i
]);
8052 test_decodeBasicConstraints(encodings
[i
]);
8053 test_encodeRsaPublicKey(encodings
[i
]);
8054 test_decodeRsaPublicKey(encodings
[i
]);
8055 test_encodeSequenceOfAny(encodings
[i
]);
8056 test_decodeSequenceOfAny(encodings
[i
]);
8057 test_encodeExtensions(encodings
[i
]);
8058 test_decodeExtensions(encodings
[i
]);
8059 test_encodePublicKeyInfo(encodings
[i
]);
8060 test_decodePublicKeyInfo(encodings
[i
]);
8061 test_encodeCertToBeSigned(encodings
[i
]);
8062 test_decodeCertToBeSigned(encodings
[i
]);
8063 test_encodeCert(encodings
[i
]);
8064 test_decodeCert(encodings
[i
]);
8065 test_encodeCRLDistPoints(encodings
[i
]);
8066 test_decodeCRLDistPoints(encodings
[i
]);
8067 test_encodeCRLIssuingDistPoint(encodings
[i
]);
8068 test_decodeCRLIssuingDistPoint(encodings
[i
]);
8069 test_encodeCRLToBeSigned(encodings
[i
]);
8070 test_decodeCRLToBeSigned(encodings
[i
]);
8071 test_encodeEnhancedKeyUsage(encodings
[i
]);
8072 test_decodeEnhancedKeyUsage(encodings
[i
]);
8073 test_encodeAuthorityKeyId(encodings
[i
]);
8074 test_decodeAuthorityKeyId(encodings
[i
]);
8075 test_encodeAuthorityKeyId2(encodings
[i
]);
8076 test_decodeAuthorityKeyId2(encodings
[i
]);
8077 test_encodeAuthorityInfoAccess(encodings
[i
]);
8078 test_decodeAuthorityInfoAccess(encodings
[i
]);
8079 test_encodeCTL(encodings
[i
]);
8080 test_decodeCTL(encodings
[i
]);
8081 test_encodePKCSContentInfo(encodings
[i
]);
8082 test_decodePKCSContentInfo(encodings
[i
]);
8083 test_encodePKCSAttribute(encodings
[i
]);
8084 test_decodePKCSAttribute(encodings
[i
]);
8085 test_encodePKCSAttributes(encodings
[i
]);
8086 test_decodePKCSAttributes(encodings
[i
]);
8087 test_encodePKCSSMimeCapabilities(encodings
[i
]);
8088 test_decodePKCSSMimeCapabilities(encodings
[i
]);
8089 test_encodePKCSSignerInfo(encodings
[i
]);
8090 test_decodePKCSSignerInfo(encodings
[i
]);
8091 test_encodeCMSSignerInfo(encodings
[i
]);
8092 test_decodeCMSSignerInfo(encodings
[i
]);
8093 test_encodeNameConstraints(encodings
[i
]);
8094 test_decodeNameConstraints(encodings
[i
]);
8095 test_encodePolicyQualifierUserNotice(encodings
[i
]);
8096 test_decodePolicyQualifierUserNotice(encodings
[i
]);
8097 test_encodeCertPolicies(encodings
[i
]);
8098 test_decodeCertPolicies(encodings
[i
]);
8099 test_encodeCertPolicyMappings(encodings
[i
]);
8100 test_decodeCertPolicyMappings(encodings
[i
]);
8101 test_encodeCertPolicyConstraints(encodings
[i
]);
8102 test_decodeCertPolicyConstraints(encodings
[i
]);
8104 testPortPublicKeyInfo();