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
, (BYTE
*)&buf
, &bufSize
);
234 ok((!ret
&& GetLastError() == CRYPT_E_ASN1_LARGE
) ||
235 broken(ret
) /* Win9x */,
236 "Expected CRYPT_E_ASN1_LARGE, got %d\n", GetLastError());
237 /* check with a DER-encoded string */
238 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_INTEGER
, testStr
, testStr
[1] + 2,
239 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
240 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_BADTAG
||
241 GetLastError() == OSS_PDU_MISMATCH
/* Win9x */ ),
242 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %08x\n",
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
, (BYTE
*)&buf
, &bufSize
);
256 ok(ret
, "CryptDecodeObjectEx failed: %d\n", GetLastError());
257 ok(bufSize
== sizeof(int), "Wrong size %d\n", bufSize
);
258 ok(buf
!= NULL
, "Expected allocated buffer\n");
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
, (BYTE
*)&buf
, &bufSize
);
276 ok(ret
, "CryptDecodeObjectEx failed: %d\n", GetLastError());
277 ok(bufSize
>= sizeof(CRYPT_INTEGER_BLOB
), "Wrong size %d\n", bufSize
);
278 ok(buf
!= NULL
, "Expected allocated buffer\n");
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
, (BYTE
*)&buf
, &bufSize
);
301 ok(ret
, "CryptDecodeObjectEx failed: %d\n", GetLastError());
302 ok(bufSize
>= sizeof(CRYPT_INTEGER_BLOB
), "Wrong size %d\n", bufSize
);
303 ok(buf
!= NULL
, "Expected allocated buffer\n");
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
, (BYTE
*)&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
, (BYTE
*)&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, (BYTE *)&buf, &bufSize);
342 ok(!ret && GetLastError() == CRYPT_E_ASN1_LARGE,
343 "Expected CRYPT_E_ASN1_LARGE, got %08x\n", GetLastError());
345 /* This will try to decode the buffer and overflow it, check that it's
350 /* a large buffer isn't guaranteed to crash, it depends on memory allocation order */
351 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_MULTI_BYTE_INTEGER
, bigBogus
,
352 0x01ffffff, CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
353 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
354 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
358 static const BYTE bin18
[] = {0x0a,0x01,0x01};
359 static const BYTE bin19
[] = {0x0a,0x05,0x00,0xff,0xff,0xff,0x80};
361 /* These are always encoded unsigned, and aren't constrained to be any
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
, (BYTE
*)&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
,
422 (BYTE
*)&val
, &bufSize
);
423 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
424 ok(bufSize
== sizeof(int),
425 "Got unexpected size %d for enumerated\n", bufSize
);
426 ok(val
== enums
[j
].val
, "Unexpected value %d, expected %d\n",
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
, (BYTE
*)&buf
, &bufSize
);
450 /* years other than 1950-2050 are not allowed for encodings other than
451 * X509_CHOICE_OF_TIME.
453 if (structType
== X509_CHOICE_OF_TIME
||
454 (time
->sysTime
.wYear
>= 1950 && time
->sysTime
.wYear
<= 2050))
456 ok(ret
, "CryptEncodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
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
, (BYTE
*)&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
, (BYTE
*)&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
, (BYTE
*)&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
, (BYTE
*)&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
, (BYTE
*)&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 = (BYTE *)commonName;
813 rdn.rgRDNAttr = attrs;
814 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
815 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&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
, (BYTE
*)&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
, (BYTE
*)&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
, (BYTE
*)&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
= (PCERT_RDN_ATTR
)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
, (BYTE
*)&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
, (BYTE
*)&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
, (BYTE
*)&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
, (BYTE
*)&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
, (BYTE
*)&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
, (BYTE
*)&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 ok(got
->dwValueType
== expected
->dwValueType
,
997 "Expected string type %d, got %d\n", expected
->dwValueType
,
999 ok(got
->Value
.cbData
== expected
->Value
.cbData
,
1000 "String type %d: unexpected data size, got %d, expected %d\n",
1001 expected
->dwValueType
, got
->Value
.cbData
, expected
->Value
.cbData
);
1002 if (got
->Value
.cbData
&& got
->Value
.pbData
)
1003 ok(!memcmp(got
->Value
.pbData
, expected
->Value
.pbData
,
1004 min(got
->Value
.cbData
, expected
->Value
.cbData
)),
1005 "String type %d: unexpected value\n", expected
->dwValueType
);
1008 static void compareRDNAttrs(const CERT_RDN_ATTR
*expected
,
1009 const CERT_RDN_ATTR
*got
)
1011 if (expected
->pszObjId
&& strlen(expected
->pszObjId
))
1013 ok(got
->pszObjId
!= NULL
, "Expected OID %s, got NULL\n",
1014 expected
->pszObjId
);
1017 ok(!strcmp(got
->pszObjId
, expected
->pszObjId
),
1018 "Got unexpected OID %s, expected %s\n", got
->pszObjId
,
1019 expected
->pszObjId
);
1022 compareNameValues((const CERT_NAME_VALUE
*)&expected
->dwValueType
,
1023 (const CERT_NAME_VALUE
*)&got
->dwValueType
);
1026 static void compareRDNs(const CERT_RDN
*expected
, const CERT_RDN
*got
)
1028 ok(got
->cRDNAttr
== expected
->cRDNAttr
,
1029 "Expected %d RDN attrs, got %d\n", expected
->cRDNAttr
, got
->cRDNAttr
);
1034 for (i
= 0; i
< got
->cRDNAttr
; i
++)
1035 compareRDNAttrs(&expected
->rgRDNAttr
[i
], &got
->rgRDNAttr
[i
]);
1039 static void compareNames(const CERT_NAME_INFO
*expected
,
1040 const CERT_NAME_INFO
*got
)
1042 ok(got
->cRDN
== expected
->cRDN
, "Expected %d RDNs, got %d\n",
1043 expected
->cRDN
, got
->cRDN
);
1048 for (i
= 0; i
< got
->cRDN
; i
++)
1049 compareRDNs(&expected
->rgRDN
[i
], &got
->rgRDN
[i
]);
1053 static const BYTE emptyIndefiniteSequence
[] = { 0x30,0x80,0x00,0x00 };
1054 static const BYTE twoRDNsExtraBytes
[] = {
1055 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
1056 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1057 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0,0,0,0,0,0};
1059 static void test_decodeName(DWORD dwEncoding
)
1065 CERT_NAME_INFO info
= { 1, &rdn
};
1067 /* test empty name */
1069 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME
, emptySequence
,
1070 emptySequence
[1] + 2,
1071 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1072 (BYTE
*)&buf
, &bufSize
);
1073 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1074 /* Interestingly, in Windows, if cRDN is 0, rgRGN may not be NULL. My
1075 * decoder works the same way, so only test the count.
1079 ok(bufSize
== sizeof(CERT_NAME_INFO
), "Wrong bufSize %d\n", bufSize
);
1080 ok(((CERT_NAME_INFO
*)buf
)->cRDN
== 0,
1081 "Expected 0 RDNs in empty info, got %d\n",
1082 ((CERT_NAME_INFO
*)buf
)->cRDN
);
1085 /* test empty name with indefinite-length encoding */
1086 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME
, emptyIndefiniteSequence
,
1087 sizeof(emptyIndefiniteSequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1088 (BYTE
*)&buf
, &bufSize
);
1089 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1092 ok(bufSize
== sizeof(CERT_NAME_INFO
), "Wrong bufSize %d\n", bufSize
);
1093 ok(((CERT_NAME_INFO
*)buf
)->cRDN
== 0,
1094 "Expected 0 RDNs in empty info, got %d\n",
1095 ((CERT_NAME_INFO
*)buf
)->cRDN
);
1098 /* test empty RDN */
1100 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME
, emptyRDNs
,
1102 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1103 (BYTE
*)&buf
, &bufSize
);
1104 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1107 CERT_NAME_INFO
*info
= (CERT_NAME_INFO
*)buf
;
1109 ok(bufSize
== sizeof(CERT_NAME_INFO
) + sizeof(CERT_RDN
) &&
1110 info
->cRDN
== 1 && info
->rgRDN
&& info
->rgRDN
[0].cRDNAttr
== 0,
1111 "Got unexpected value for empty RDN\n");
1114 /* test two RDN attrs */
1116 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME
, twoRDNs
,
1118 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1119 (BYTE
*)&buf
, &bufSize
);
1120 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1123 static CHAR oid_sur_name
[] = szOID_SUR_NAME
,
1124 oid_common_name
[] = szOID_COMMON_NAME
;
1126 CERT_RDN_ATTR attrs
[] = {
1127 { oid_sur_name
, CERT_RDN_PRINTABLE_STRING
, { sizeof(surName
),
1128 (BYTE
*)surName
} },
1129 { oid_common_name
, CERT_RDN_PRINTABLE_STRING
, { sizeof(commonName
),
1130 (BYTE
*)commonName
} },
1133 rdn
.cRDNAttr
= sizeof(attrs
) / sizeof(attrs
[0]);
1134 rdn
.rgRDNAttr
= attrs
;
1135 compareNames(&info
, (CERT_NAME_INFO
*)buf
);
1138 /* test that two RDN attrs with extra bytes succeeds */
1140 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME
, twoRDNsExtraBytes
,
1141 sizeof(twoRDNsExtraBytes
), 0, NULL
, NULL
, &bufSize
);
1142 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1143 /* And, a slightly more complicated name */
1146 ret
= pCryptDecodeObjectEx(X509_ASN_ENCODING
, X509_NAME
, encodedRDNAttrs
,
1147 sizeof(encodedRDNAttrs
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1148 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1151 rdn
.cRDNAttr
= sizeof(decodedRdnAttrs
) / sizeof(decodedRdnAttrs
[0]);
1152 rdn
.rgRDNAttr
= (PCERT_RDN_ATTR
)decodedRdnAttrs
;
1153 compareNames(&info
, (CERT_NAME_INFO
*)buf
);
1158 static void test_decodeUnicodeName(DWORD dwEncoding
)
1164 CERT_NAME_INFO info
= { 1, &rdn
};
1166 /* test empty name */
1168 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, emptySequence
,
1169 emptySequence
[1] + 2,
1170 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1171 (BYTE
*)&buf
, &bufSize
);
1172 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1175 ok(bufSize
== sizeof(CERT_NAME_INFO
),
1176 "Got wrong bufSize %d\n", bufSize
);
1177 ok(((CERT_NAME_INFO
*)buf
)->cRDN
== 0,
1178 "Expected 0 RDNs in empty info, got %d\n",
1179 ((CERT_NAME_INFO
*)buf
)->cRDN
);
1182 /* test empty RDN */
1184 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, emptyRDNs
,
1186 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1187 (BYTE
*)&buf
, &bufSize
);
1188 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1191 CERT_NAME_INFO
*info
= (CERT_NAME_INFO
*)buf
;
1193 ok(bufSize
== sizeof(CERT_NAME_INFO
) + sizeof(CERT_RDN
) &&
1194 info
->cRDN
== 1 && info
->rgRDN
&& info
->rgRDN
[0].cRDNAttr
== 0,
1195 "Got unexpected value for empty RDN\n");
1198 /* test two RDN attrs */
1200 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, twoRDNsNoNull
,
1201 sizeof(twoRDNsNoNull
),
1202 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1203 (BYTE
*)&buf
, &bufSize
);
1204 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1207 static CHAR oid_sur_name
[] = szOID_SUR_NAME
,
1208 oid_common_name
[] = szOID_COMMON_NAME
;
1210 CERT_RDN_ATTR attrs
[] = {
1211 { oid_sur_name
, CERT_RDN_PRINTABLE_STRING
,
1212 { lstrlenW(surNameW
) * sizeof(WCHAR
), (BYTE
*)surNameW
} },
1213 { oid_common_name
, CERT_RDN_PRINTABLE_STRING
,
1214 { lstrlenW(commonNameW
) * sizeof(WCHAR
), (BYTE
*)commonNameW
} },
1217 rdn
.cRDNAttr
= sizeof(attrs
) / sizeof(attrs
[0]);
1218 rdn
.rgRDNAttr
= attrs
;
1219 compareNames(&info
, (CERT_NAME_INFO
*)buf
);
1224 struct EncodedNameValue
1226 CERT_NAME_VALUE value
;
1227 const BYTE
*encoded
;
1231 static const char bogusIA5
[] = "\x80";
1232 static const char bogusPrintable
[] = "~";
1233 static const char bogusNumeric
[] = "A";
1234 static const BYTE bin42
[] = { 0x16,0x02,0x80,0x00 };
1235 static const BYTE bin43
[] = { 0x13,0x02,0x7e,0x00 };
1236 static const BYTE bin44
[] = { 0x12,0x02,0x41,0x00 };
1237 static BYTE octetCommonNameValue
[] = {
1238 0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1239 static BYTE numericCommonNameValue
[] = {
1240 0x12,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1241 static BYTE printableCommonNameValue
[] = {
1242 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1243 static BYTE t61CommonNameValue
[] = {
1244 0x14,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1245 static BYTE videotexCommonNameValue
[] = {
1246 0x15,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1247 static BYTE ia5CommonNameValue
[] = {
1248 0x16,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1249 static BYTE graphicCommonNameValue
[] = {
1250 0x19,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1251 static BYTE visibleCommonNameValue
[] = {
1252 0x1a,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1253 static BYTE generalCommonNameValue
[] = {
1254 0x1b,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1255 static BYTE bmpCommonNameValue
[] = {
1256 0x1e,0x14,0x00,0x4a,0x00,0x75,0x00,0x61,0x00,0x6e,0x00,0x20,0x00,0x4c,0x00,
1257 0x61,0x00,0x6e,0x00,0x67,0x00,0x00 };
1258 static BYTE utf8CommonNameValue
[] = {
1259 0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1261 static struct EncodedNameValue nameValues
[] = {
1262 { { CERT_RDN_OCTET_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1263 octetCommonNameValue
, sizeof(octetCommonNameValue
) },
1264 { { CERT_RDN_NUMERIC_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1265 numericCommonNameValue
, sizeof(numericCommonNameValue
) },
1266 { { CERT_RDN_PRINTABLE_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1267 printableCommonNameValue
, sizeof(printableCommonNameValue
) },
1268 { { CERT_RDN_T61_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1269 t61CommonNameValue
, sizeof(t61CommonNameValue
) },
1270 { { CERT_RDN_VIDEOTEX_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1271 videotexCommonNameValue
, sizeof(videotexCommonNameValue
) },
1272 { { CERT_RDN_IA5_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1273 ia5CommonNameValue
, sizeof(ia5CommonNameValue
) },
1274 { { CERT_RDN_GRAPHIC_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1275 graphicCommonNameValue
, sizeof(graphicCommonNameValue
) },
1276 { { CERT_RDN_VISIBLE_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1277 visibleCommonNameValue
, sizeof(visibleCommonNameValue
) },
1278 { { CERT_RDN_GENERAL_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1279 generalCommonNameValue
, sizeof(generalCommonNameValue
) },
1280 { { CERT_RDN_BMP_STRING
, { sizeof(commonNameW
), (BYTE
*)commonNameW
} },
1281 bmpCommonNameValue
, sizeof(bmpCommonNameValue
) },
1282 { { CERT_RDN_UTF8_STRING
, { sizeof(commonNameW
), (BYTE
*)commonNameW
} },
1283 utf8CommonNameValue
, sizeof(utf8CommonNameValue
) },
1284 /* The following tests succeed under Windows, but really should fail,
1285 * they contain characters that are illegal for the encoding. I'm
1286 * including them to justify my lazy encoding.
1288 { { CERT_RDN_IA5_STRING
, { sizeof(bogusIA5
), (BYTE
*)bogusIA5
} }, bin42
,
1290 { { CERT_RDN_PRINTABLE_STRING
, { sizeof(bogusPrintable
),
1291 (BYTE
*)bogusPrintable
} }, bin43
, sizeof(bin43
) },
1292 { { CERT_RDN_NUMERIC_STRING
, { sizeof(bogusNumeric
), (BYTE
*)bogusNumeric
} },
1293 bin44
, sizeof(bin44
) },
1296 static void test_encodeNameValue(DWORD dwEncoding
)
1301 CERT_NAME_VALUE value
= { 0, { 0, NULL
} };
1303 value
.dwValueType
= CERT_RDN_ENCODED_BLOB
;
1304 value
.Value
.pbData
= printableCommonNameValue
;
1305 value
.Value
.cbData
= sizeof(printableCommonNameValue
);
1306 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_VALUE
, &value
,
1307 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1308 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1311 ok(size
== sizeof(printableCommonNameValue
), "Unexpected size %d\n",
1313 ok(!memcmp(buf
, printableCommonNameValue
, size
),
1314 "Unexpected encoding\n");
1317 for (i
= 0; i
< sizeof(nameValues
) / sizeof(nameValues
[0]); i
++)
1319 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_VALUE
,
1320 &nameValues
[i
].value
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
1322 ok(ret
|| broken(GetLastError() == OSS_PDU_MISMATCH
) /* NT4/Win9x */,
1323 "Type %d: CryptEncodeObjectEx failed: %08x\n",
1324 nameValues
[i
].value
.dwValueType
, GetLastError());
1327 ok(size
== nameValues
[i
].encodedSize
,
1328 "Expected size %d, got %d\n", nameValues
[i
].encodedSize
, size
);
1329 ok(!memcmp(buf
, nameValues
[i
].encoded
, size
),
1330 "Got unexpected encoding\n");
1336 static void test_decodeNameValue(DWORD dwEncoding
)
1343 for (i
= 0; i
< sizeof(nameValues
) / sizeof(nameValues
[0]); i
++)
1345 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME_VALUE
,
1346 nameValues
[i
].encoded
, nameValues
[i
].encoded
[1] + 2,
1347 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1348 (BYTE
*)&buf
, &bufSize
);
1349 ok(ret
, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
1350 nameValues
[i
].value
.dwValueType
, GetLastError());
1353 compareNameValues(&nameValues
[i
].value
,
1354 (const CERT_NAME_VALUE
*)buf
);
1360 static const BYTE emptyURL
[] = { 0x30, 0x02, 0x86, 0x00 };
1361 static const BYTE emptyURLExtraBytes
[] = { 0x30, 0x02, 0x86, 0x00, 0, 0, 0 };
1362 static const WCHAR url
[] = { 'h','t','t','p',':','/','/','w','i','n','e',
1363 'h','q','.','o','r','g',0 };
1364 static const BYTE encodedURL
[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74,
1365 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e,
1367 static const WCHAR nihongoURL
[] = { 'h','t','t','p',':','/','/',0x226f,
1369 static const WCHAR dnsName
[] = { 'w','i','n','e','h','q','.','o','r','g',0 };
1370 static const BYTE encodedDnsName
[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69,
1371 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
1372 static const BYTE localhost
[] = { 127, 0, 0, 1 };
1373 static const BYTE encodedIPAddr
[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00,
1375 static const unsigned char encodedCommonName
[] = {
1376 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0};
1377 static const BYTE encodedOidName
[] = { 0x30,0x04,0x88,0x02,0x2a,0x03 };
1378 static const BYTE encodedDirectoryName
[] = {
1379 0x30,0x19,0xa4,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1380 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1382 static void test_encodeAltName(DWORD dwEncoding
)
1384 CERT_ALT_NAME_INFO info
= { 0 };
1385 CERT_ALT_NAME_ENTRY entry
= { 0 };
1389 char oid
[] = "1.2.3";
1391 /* Test with empty info */
1392 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1393 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1396 ok(size
== sizeof(emptySequence
), "Wrong size %d\n", size
);
1397 ok(!memcmp(buf
, emptySequence
, size
), "Unexpected value\n");
1400 /* Test with an empty entry */
1402 info
.rgAltEntry
= &entry
;
1403 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1404 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1405 ok(!ret
&& GetLastError() == E_INVALIDARG
,
1406 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1407 /* Test with an empty pointer */
1408 entry
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
1409 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1410 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1413 ok(size
== sizeof(emptyURL
), "Wrong size %d\n", size
);
1414 ok(!memcmp(buf
, emptyURL
, size
), "Unexpected value\n");
1417 /* Test with a real URL */
1418 U(entry
).pwszURL
= (LPWSTR
)url
;
1419 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1420 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1423 ok(size
== sizeof(encodedURL
), "Wrong size %d\n", size
);
1424 ok(!memcmp(buf
, encodedURL
, size
), "Unexpected value\n");
1427 /* Now with the URL containing an invalid IA5 char */
1428 U(entry
).pwszURL
= (LPWSTR
)nihongoURL
;
1429 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1430 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1431 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_IA5_STRING
,
1432 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
1433 /* The first invalid character is at index 7 */
1434 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size
) == 7,
1435 "Expected invalid char at index 7, got %d\n",
1436 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size
));
1437 /* Now with the URL missing a scheme */
1438 U(entry
).pwszURL
= (LPWSTR
)dnsName
;
1439 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1440 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1441 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1444 /* This succeeds, but it shouldn't, so don't worry about conforming */
1447 /* Now with a DNS name */
1448 entry
.dwAltNameChoice
= CERT_ALT_NAME_DNS_NAME
;
1449 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1450 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1451 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1454 ok(size
== sizeof(encodedDnsName
), "Wrong size %d\n", size
);
1455 ok(!memcmp(buf
, encodedDnsName
, size
), "Unexpected value\n");
1458 /* Test with an IP address */
1459 entry
.dwAltNameChoice
= CERT_ALT_NAME_IP_ADDRESS
;
1460 U(entry
).IPAddress
.cbData
= sizeof(localhost
);
1461 U(entry
).IPAddress
.pbData
= (LPBYTE
)localhost
;
1462 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1463 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1466 ok(size
== sizeof(encodedIPAddr
), "Wrong size %d\n", size
);
1467 ok(!memcmp(buf
, encodedIPAddr
, size
), "Unexpected value\n");
1471 entry
.dwAltNameChoice
= CERT_ALT_NAME_REGISTERED_ID
;
1472 U(entry
).pszRegisteredID
= oid
;
1473 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1474 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1477 ok(size
== sizeof(encodedOidName
), "Wrong size %d\n", size
);
1478 ok(!memcmp(buf
, encodedOidName
, size
), "Unexpected value\n");
1481 /* Test with directory name */
1482 entry
.dwAltNameChoice
= CERT_ALT_NAME_DIRECTORY_NAME
;
1483 U(entry
).DirectoryName
.cbData
= sizeof(encodedCommonName
);
1484 U(entry
).DirectoryName
.pbData
= (LPBYTE
)encodedCommonName
;
1485 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1486 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1489 ok(size
== sizeof(encodedDirectoryName
), "Wrong size %d\n", size
);
1490 ok(!memcmp(buf
, encodedDirectoryName
, size
), "Unexpected value\n");
1495 static void test_decodeAltName(DWORD dwEncoding
)
1497 static const BYTE unimplementedType
[] = { 0x30, 0x06, 0x85, 0x04, 0x7f,
1499 static const BYTE bogusType
[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00,
1504 CERT_ALT_NAME_INFO
*info
;
1506 /* Test some bogus ones first */
1507 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1508 unimplementedType
, sizeof(unimplementedType
), CRYPT_DECODE_ALLOC_FLAG
,
1509 NULL
, (BYTE
*)&buf
, &bufSize
);
1510 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_BADTAG
||
1511 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
1512 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
1514 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1515 bogusType
, sizeof(bogusType
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
1517 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
1518 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
1519 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
1521 /* Now expected cases */
1522 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, emptySequence
,
1523 emptySequence
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
1525 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1528 info
= (CERT_ALT_NAME_INFO
*)buf
;
1530 ok(info
->cAltEntry
== 0, "Expected 0 entries, got %d\n",
1534 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, emptyURL
,
1535 emptyURL
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
1537 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1540 info
= (CERT_ALT_NAME_INFO
*)buf
;
1542 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1544 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_URL
,
1545 "Expected CERT_ALT_NAME_URL, got %d\n",
1546 info
->rgAltEntry
[0].dwAltNameChoice
);
1547 ok(U(info
->rgAltEntry
[0]).pwszURL
== NULL
|| !*U(info
->rgAltEntry
[0]).pwszURL
,
1548 "Expected empty URL\n");
1551 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1552 emptyURLExtraBytes
, sizeof(emptyURLExtraBytes
), 0, NULL
, NULL
, &bufSize
);
1553 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1554 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, encodedURL
,
1555 encodedURL
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
1557 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1560 info
= (CERT_ALT_NAME_INFO
*)buf
;
1562 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1564 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_URL
,
1565 "Expected CERT_ALT_NAME_URL, got %d\n",
1566 info
->rgAltEntry
[0].dwAltNameChoice
);
1567 ok(!lstrcmpW(U(info
->rgAltEntry
[0]).pwszURL
, url
), "Unexpected URL\n");
1570 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, encodedDnsName
,
1571 encodedDnsName
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
1573 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1576 info
= (CERT_ALT_NAME_INFO
*)buf
;
1578 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1580 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_DNS_NAME
,
1581 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1582 info
->rgAltEntry
[0].dwAltNameChoice
);
1583 ok(!lstrcmpW(U(info
->rgAltEntry
[0]).pwszDNSName
, dnsName
),
1584 "Unexpected DNS name\n");
1587 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, encodedIPAddr
,
1588 encodedIPAddr
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
1590 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1593 info
= (CERT_ALT_NAME_INFO
*)buf
;
1595 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1597 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_IP_ADDRESS
,
1598 "Expected CERT_ALT_NAME_IP_ADDRESS, got %d\n",
1599 info
->rgAltEntry
[0].dwAltNameChoice
);
1600 ok(U(info
->rgAltEntry
[0]).IPAddress
.cbData
== sizeof(localhost
),
1601 "Unexpected IP address length %d\n",
1602 U(info
->rgAltEntry
[0]).IPAddress
.cbData
);
1603 ok(!memcmp(U(info
->rgAltEntry
[0]).IPAddress
.pbData
, localhost
,
1604 sizeof(localhost
)), "Unexpected IP address value\n");
1607 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, encodedOidName
,
1608 sizeof(encodedOidName
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
1610 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1613 info
= (CERT_ALT_NAME_INFO
*)buf
;
1615 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1617 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_REGISTERED_ID
,
1618 "Expected CERT_ALT_NAME_REGISTERED_ID, got %d\n",
1619 info
->rgAltEntry
[0].dwAltNameChoice
);
1620 ok(!strcmp(U(info
->rgAltEntry
[0]).pszRegisteredID
, "1.2.3"),
1621 "Expected OID 1.2.3, got %s\n", U(info
->rgAltEntry
[0]).pszRegisteredID
);
1624 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1625 encodedDirectoryName
, sizeof(encodedDirectoryName
),
1626 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&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_DIRECTORY_NAME
,
1635 "Expected CERT_ALT_NAME_DIRECTORY_NAME, got %d\n",
1636 info
->rgAltEntry
[0].dwAltNameChoice
);
1637 ok(U(info
->rgAltEntry
[0]).DirectoryName
.cbData
==
1638 sizeof(encodedCommonName
), "Unexpected directory name length %d\n",
1639 U(info
->rgAltEntry
[0]).DirectoryName
.cbData
);
1640 ok(!memcmp(U(info
->rgAltEntry
[0]).DirectoryName
.pbData
,
1641 encodedCommonName
, sizeof(encodedCommonName
)),
1642 "Unexpected directory name value\n");
1647 struct UnicodeExpectedError
1655 static const WCHAR oneW
[] = { '1',0 };
1656 static const WCHAR aW
[] = { 'a',0 };
1657 static const WCHAR quoteW
[] = { '"', 0 };
1659 static struct UnicodeExpectedError unicodeErrors
[] = {
1660 { CERT_RDN_ANY_TYPE
, oneW
, 0, CRYPT_E_NOT_CHAR_STRING
},
1661 { CERT_RDN_ENCODED_BLOB
, oneW
, 0, CRYPT_E_NOT_CHAR_STRING
},
1662 { CERT_RDN_OCTET_STRING
, oneW
, 0, CRYPT_E_NOT_CHAR_STRING
},
1663 { CERT_RDN_NUMERIC_STRING
, aW
, 0, CRYPT_E_INVALID_NUMERIC_STRING
},
1664 { CERT_RDN_PRINTABLE_STRING
, quoteW
, 0, CRYPT_E_INVALID_PRINTABLE_STRING
},
1665 { CERT_RDN_IA5_STRING
, nihongoURL
, 7, CRYPT_E_INVALID_IA5_STRING
},
1668 struct UnicodeExpectedResult
1672 CRYPT_DATA_BLOB encoded
;
1675 static BYTE oneNumeric
[] = { 0x12, 0x01, 0x31 };
1676 static BYTE onePrintable
[] = { 0x13, 0x01, 0x31 };
1677 static BYTE oneTeletex
[] = { 0x14, 0x01, 0x31 };
1678 static BYTE oneVideotex
[] = { 0x15, 0x01, 0x31 };
1679 static BYTE oneIA5
[] = { 0x16, 0x01, 0x31 };
1680 static BYTE oneGraphic
[] = { 0x19, 0x01, 0x31 };
1681 static BYTE oneVisible
[] = { 0x1a, 0x01, 0x31 };
1682 static BYTE oneUniversal
[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 };
1683 static BYTE oneGeneral
[] = { 0x1b, 0x01, 0x31 };
1684 static BYTE oneBMP
[] = { 0x1e, 0x02, 0x00, 0x31 };
1685 static BYTE oneUTF8
[] = { 0x0c, 0x01, 0x31 };
1686 static BYTE nihongoT61
[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,
1688 static BYTE nihongoGeneral
[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1690 static BYTE nihongoBMP
[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,
1691 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
1692 static BYTE nihongoUTF8
[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1693 0xe2,0x89,0xaf,0xe5,0x9d,0x9b };
1695 static struct UnicodeExpectedResult unicodeResults
[] = {
1696 { CERT_RDN_NUMERIC_STRING
, oneW
, { sizeof(oneNumeric
), oneNumeric
} },
1697 { CERT_RDN_PRINTABLE_STRING
, oneW
, { sizeof(onePrintable
), onePrintable
} },
1698 { CERT_RDN_TELETEX_STRING
, oneW
, { sizeof(oneTeletex
), oneTeletex
} },
1699 { CERT_RDN_VIDEOTEX_STRING
, oneW
, { sizeof(oneVideotex
), oneVideotex
} },
1700 { CERT_RDN_IA5_STRING
, oneW
, { sizeof(oneIA5
), oneIA5
} },
1701 { CERT_RDN_GRAPHIC_STRING
, oneW
, { sizeof(oneGraphic
), oneGraphic
} },
1702 { CERT_RDN_VISIBLE_STRING
, oneW
, { sizeof(oneVisible
), oneVisible
} },
1703 { CERT_RDN_UNIVERSAL_STRING
, oneW
, { sizeof(oneUniversal
), oneUniversal
} },
1704 { CERT_RDN_GENERAL_STRING
, oneW
, { sizeof(oneGeneral
), oneGeneral
} },
1705 { CERT_RDN_BMP_STRING
, oneW
, { sizeof(oneBMP
), oneBMP
} },
1706 { CERT_RDN_UTF8_STRING
, oneW
, { sizeof(oneUTF8
), oneUTF8
} },
1707 { CERT_RDN_BMP_STRING
, nihongoURL
, { sizeof(nihongoBMP
), nihongoBMP
} },
1708 { CERT_RDN_UTF8_STRING
, nihongoURL
, { sizeof(nihongoUTF8
), nihongoUTF8
} },
1711 static struct UnicodeExpectedResult unicodeWeirdness
[] = {
1712 { CERT_RDN_TELETEX_STRING
, nihongoURL
, { sizeof(nihongoT61
), nihongoT61
} },
1713 { CERT_RDN_GENERAL_STRING
, nihongoURL
, { sizeof(nihongoGeneral
), nihongoGeneral
} },
1716 static void test_encodeUnicodeNameValue(DWORD dwEncoding
)
1721 CERT_NAME_VALUE value
;
1725 /* Crashes on win9x */
1726 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, NULL
,
1727 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1728 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
1729 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1731 /* Have to have a string of some sort */
1732 value
.dwValueType
= 0; /* aka CERT_RDN_ANY_TYPE */
1733 value
.Value
.pbData
= NULL
;
1734 value
.Value
.cbData
= 0;
1735 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1736 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1737 ok(!ret
&& GetLastError() == CRYPT_E_NOT_CHAR_STRING
,
1738 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1739 value
.dwValueType
= CERT_RDN_ENCODED_BLOB
;
1740 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1741 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1742 ok(!ret
&& GetLastError() == CRYPT_E_NOT_CHAR_STRING
,
1743 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1744 value
.dwValueType
= CERT_RDN_ANY_TYPE
;
1745 value
.Value
.pbData
= (LPBYTE
)oneW
;
1746 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1747 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1748 ok(!ret
&& GetLastError() == CRYPT_E_NOT_CHAR_STRING
,
1749 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1750 value
.Value
.cbData
= sizeof(oneW
);
1751 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1752 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1753 ok(!ret
&& GetLastError() == CRYPT_E_NOT_CHAR_STRING
,
1754 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1755 /* An encoded string with specified length isn't good enough either */
1756 value
.dwValueType
= CERT_RDN_ENCODED_BLOB
;
1757 value
.Value
.pbData
= oneUniversal
;
1758 value
.Value
.cbData
= sizeof(oneUniversal
);
1759 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1760 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1761 ok(!ret
&& GetLastError() == CRYPT_E_NOT_CHAR_STRING
,
1762 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1763 /* More failure checking */
1764 value
.Value
.cbData
= 0;
1765 for (i
= 0; i
< sizeof(unicodeErrors
) / sizeof(unicodeErrors
[0]); i
++)
1767 value
.Value
.pbData
= (LPBYTE
)unicodeErrors
[i
].str
;
1768 value
.dwValueType
= unicodeErrors
[i
].valueType
;
1769 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1770 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1771 ok(!ret
&& GetLastError() == unicodeErrors
[i
].error
,
1772 "Value type %d: expected %08x, got %08x\n", value
.dwValueType
,
1773 unicodeErrors
[i
].error
, GetLastError());
1774 ok(size
== unicodeErrors
[i
].errorIndex
,
1775 "Expected error index %d, got %d\n", unicodeErrors
[i
].errorIndex
,
1778 /* cbData can be zero if the string is NULL-terminated */
1779 value
.Value
.cbData
= 0;
1780 for (i
= 0; i
< sizeof(unicodeResults
) / sizeof(unicodeResults
[0]); i
++)
1782 value
.Value
.pbData
= (LPBYTE
)unicodeResults
[i
].str
;
1783 value
.dwValueType
= unicodeResults
[i
].valueType
;
1784 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1785 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1786 ok(ret
|| broken(GetLastError() == OSS_PDU_MISMATCH
/* Win9x */),
1787 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1790 ok(size
== unicodeResults
[i
].encoded
.cbData
,
1791 "Value type %d: expected size %d, got %d\n",
1792 value
.dwValueType
, unicodeResults
[i
].encoded
.cbData
, size
);
1793 ok(!memcmp(unicodeResults
[i
].encoded
.pbData
, buf
, size
),
1794 "Value type %d: unexpected value\n", value
.dwValueType
);
1798 /* These "encode," but they do so by truncating each unicode character
1799 * rather than properly encoding it. Kept separate from the proper results,
1800 * because the encoded forms won't decode to their original strings.
1802 for (i
= 0; i
< sizeof(unicodeWeirdness
) / sizeof(unicodeWeirdness
[0]); i
++)
1804 value
.Value
.pbData
= (LPBYTE
)unicodeWeirdness
[i
].str
;
1805 value
.dwValueType
= unicodeWeirdness
[i
].valueType
;
1806 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1807 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1808 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1811 ok(size
== unicodeWeirdness
[i
].encoded
.cbData
,
1812 "Value type %d: expected size %d, got %d\n",
1813 value
.dwValueType
, unicodeWeirdness
[i
].encoded
.cbData
, size
);
1814 ok(!memcmp(unicodeWeirdness
[i
].encoded
.pbData
, buf
, size
),
1815 "Value type %d: unexpected value\n", value
.dwValueType
);
1821 static inline int strncmpW( const WCHAR
*str1
, const WCHAR
*str2
, int n
)
1823 if (n
<= 0) return 0;
1824 while ((--n
> 0) && *str1
&& (*str1
== *str2
)) { str1
++; str2
++; }
1825 return *str1
- *str2
;
1828 static void test_decodeUnicodeNameValue(DWORD dwEncoding
)
1832 for (i
= 0; i
< sizeof(unicodeResults
) / sizeof(unicodeResults
[0]); i
++)
1838 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
,
1839 unicodeResults
[i
].encoded
.pbData
, unicodeResults
[i
].encoded
.cbData
,
1840 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
1841 ok(ret
|| broken(GetLastError() == CRYPT_E_NOT_CHAR_STRING
/* Win9x */),
1842 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1845 PCERT_NAME_VALUE value
= (PCERT_NAME_VALUE
)buf
;
1847 ok(value
->dwValueType
== unicodeResults
[i
].valueType
,
1848 "Expected value type %d, got %d\n", unicodeResults
[i
].valueType
,
1849 value
->dwValueType
);
1850 ok(!strncmpW((LPWSTR
)value
->Value
.pbData
, unicodeResults
[i
].str
,
1851 value
->Value
.cbData
/ sizeof(WCHAR
)),
1852 "Unexpected decoded value for index %d (value type %d)\n", i
,
1853 unicodeResults
[i
].valueType
);
1859 struct encodedOctets
1862 const BYTE
*encoded
;
1865 static const unsigned char bin46
[] = { 'h','i',0 };
1866 static const unsigned char bin47
[] = { 0x04,0x02,'h','i',0 };
1867 static const unsigned char bin48
[] = {
1868 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1869 static const unsigned char bin49
[] = {
1870 0x04,0x0f,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1871 static const unsigned char bin50
[] = { 0 };
1872 static const unsigned char bin51
[] = { 0x04,0x00,0 };
1874 static const struct encodedOctets octets
[] = {
1880 static void test_encodeOctets(DWORD dwEncoding
)
1882 CRYPT_DATA_BLOB blob
;
1885 for (i
= 0; i
< sizeof(octets
) / sizeof(octets
[0]); i
++)
1891 blob
.cbData
= strlen((const char*)octets
[i
].val
);
1892 blob
.pbData
= (BYTE
*)octets
[i
].val
;
1893 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_OCTET_STRING
, &blob
,
1894 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
1895 ok(ret
, "CryptEncodeObjectEx failed: %d\n", GetLastError());
1899 "Got unexpected type %d for octet string (expected 4)\n", buf
[0]);
1900 ok(buf
[1] == octets
[i
].encoded
[1], "Got length %d, expected %d\n",
1901 buf
[1], octets
[i
].encoded
[1]);
1902 ok(!memcmp(buf
+ 1, octets
[i
].encoded
+ 1,
1903 octets
[i
].encoded
[1] + 1), "Got unexpected value\n");
1909 static void test_decodeOctets(DWORD dwEncoding
)
1913 for (i
= 0; i
< sizeof(octets
) / sizeof(octets
[0]); i
++)
1919 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_OCTET_STRING
,
1920 (BYTE
*)octets
[i
].encoded
, octets
[i
].encoded
[1] + 2,
1921 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
1922 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1923 ok(bufSize
>= sizeof(CRYPT_DATA_BLOB
) + octets
[i
].encoded
[1],
1924 "Expected size >= %d, got %d\n",
1925 (int)sizeof(CRYPT_DATA_BLOB
) + octets
[i
].encoded
[1], bufSize
);
1926 ok(buf
!= NULL
, "Expected allocated buffer\n");
1929 CRYPT_DATA_BLOB
*blob
= (CRYPT_DATA_BLOB
*)buf
;
1932 ok(!memcmp(blob
->pbData
, octets
[i
].val
, blob
->cbData
),
1933 "Unexpected value\n");
1939 static const BYTE bytesToEncode
[] = { 0xff, 0xff };
1944 const BYTE
*encoded
;
1946 const BYTE
*decoded
;
1949 static const unsigned char bin52
[] = { 0x03,0x03,0x00,0xff,0xff };
1950 static const unsigned char bin53
[] = { 0xff,0xff };
1951 static const unsigned char bin54
[] = { 0x03,0x03,0x01,0xff,0xfe };
1952 static const unsigned char bin55
[] = { 0xff,0xfe };
1953 static const unsigned char bin56
[] = { 0x03,0x02,0x01,0xfe };
1954 static const unsigned char bin57
[] = { 0xfe };
1955 static const unsigned char bin58
[] = { 0x03,0x01,0x00 };
1957 static const struct encodedBits bits
[] = {
1958 /* normal test cases */
1959 { 0, bin52
, 2, bin53
},
1960 { 1, bin54
, 2, bin55
},
1961 /* strange test case, showing cUnusedBits >= 8 is allowed */
1962 { 9, bin56
, 1, bin57
},
1963 /* even stranger test case, showing cUnusedBits > cbData * 8 is allowed */
1964 { 17, bin58
, 0, NULL
},
1967 static void test_encodeBits(DWORD dwEncoding
)
1971 for (i
= 0; i
< sizeof(bits
) / sizeof(bits
[0]); i
++)
1973 CRYPT_BIT_BLOB blob
;
1978 blob
.cbData
= sizeof(bytesToEncode
);
1979 blob
.pbData
= (BYTE
*)bytesToEncode
;
1980 blob
.cUnusedBits
= bits
[i
].cUnusedBits
;
1981 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_BITS
, &blob
,
1982 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
1983 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1986 ok(bufSize
== bits
[i
].encoded
[1] + 2,
1987 "Got unexpected size %d, expected %d\n", bufSize
,
1988 bits
[i
].encoded
[1] + 2);
1989 ok(!memcmp(buf
, bits
[i
].encoded
, bits
[i
].encoded
[1] + 2),
1990 "Unexpected value\n");
1996 static void test_decodeBits(DWORD dwEncoding
)
1998 static const BYTE ber
[] = "\x03\x02\x01\xff";
1999 static const BYTE berDecoded
= 0xfe;
2006 for (i
= 0; i
< sizeof(bits
) / sizeof(bits
[0]); i
++)
2008 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BITS
, bits
[i
].encoded
,
2009 bits
[i
].encoded
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
2011 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2014 CRYPT_BIT_BLOB
*blob
;
2016 ok(bufSize
>= sizeof(CRYPT_BIT_BLOB
) + bits
[i
].cbDecoded
,
2017 "Got unexpected size %d\n", bufSize
);
2018 blob
= (CRYPT_BIT_BLOB
*)buf
;
2019 ok(blob
->cbData
== bits
[i
].cbDecoded
,
2020 "Got unexpected length %d, expected %d\n", blob
->cbData
,
2022 if (blob
->cbData
&& bits
[i
].cbDecoded
)
2023 ok(!memcmp(blob
->pbData
, bits
[i
].decoded
, bits
[i
].cbDecoded
),
2024 "Unexpected value\n");
2028 /* special case: check that something that's valid in BER but not in DER
2029 * decodes successfully
2031 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BITS
, ber
, ber
[1] + 2,
2032 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2033 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2036 CRYPT_BIT_BLOB
*blob
;
2038 ok(bufSize
>= sizeof(CRYPT_BIT_BLOB
) + sizeof(berDecoded
),
2039 "Got unexpected size %d\n", bufSize
);
2040 blob
= (CRYPT_BIT_BLOB
*)buf
;
2041 ok(blob
->cbData
== sizeof(berDecoded
),
2042 "Got unexpected length %d\n", blob
->cbData
);
2044 ok(*blob
->pbData
== berDecoded
, "Unexpected value\n");
2051 CERT_BASIC_CONSTRAINTS2_INFO info
;
2052 const BYTE
*encoded
;
2055 static const unsigned char bin59
[] = { 0x30,0x00 };
2056 static const unsigned char bin60
[] = { 0x30,0x03,0x01,0x01,0xff };
2057 static const unsigned char bin61
[] = { 0x30,0x03,0x02,0x01,0x00 };
2058 static const unsigned char bin62
[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2059 static const struct Constraints2 constraints2
[] = {
2060 /* empty constraints */
2061 { { FALSE
, FALSE
, 0}, bin59
},
2063 { { TRUE
, FALSE
, 0}, bin60
},
2064 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well,
2065 * but that's not the case
2067 { { FALSE
, TRUE
, 0}, bin61
},
2068 /* can be a CA and has path length constraints set */
2069 { { TRUE
, TRUE
, 1}, bin62
},
2072 static const BYTE emptyConstraint
[] = { 0x30, 0x03, 0x03, 0x01, 0x00 };
2073 static const BYTE encodedDomainName
[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11,
2074 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
2075 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
2076 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2077 static const BYTE constraintWithDomainName
[] = { 0x30, 0x32, 0x03, 0x01, 0x00,
2078 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
2079 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30,
2080 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
2081 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2083 static void test_encodeBasicConstraints(DWORD dwEncoding
)
2085 DWORD i
, bufSize
= 0;
2086 CERT_BASIC_CONSTRAINTS_INFO info
= { { 0 } };
2087 CERT_NAME_BLOB nameBlob
= { sizeof(encodedDomainName
),
2088 (LPBYTE
)encodedDomainName
};
2092 /* First test with the simpler info2 */
2093 for (i
= 0; i
< sizeof(constraints2
) / sizeof(constraints2
[0]); i
++)
2095 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS2
,
2096 &constraints2
[i
].info
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
2098 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2101 ok(bufSize
== constraints2
[i
].encoded
[1] + 2,
2102 "Expected %d bytes, got %d\n", constraints2
[i
].encoded
[1] + 2,
2104 ok(!memcmp(buf
, constraints2
[i
].encoded
,
2105 constraints2
[i
].encoded
[1] + 2), "Unexpected value\n");
2109 /* Now test with more complex basic constraints */
2110 info
.SubjectType
.cbData
= 0;
2111 info
.fPathLenConstraint
= FALSE
;
2112 info
.cSubtreesConstraint
= 0;
2113 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS
, &info
,
2114 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2115 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
2116 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2119 ok(bufSize
== sizeof(emptyConstraint
), "Wrong size %d\n", bufSize
);
2120 ok(!memcmp(buf
, emptyConstraint
, sizeof(emptyConstraint
)),
2121 "Unexpected value\n");
2124 /* None of the certs I examined had any subtree constraint, but I test one
2125 * anyway just in case.
2127 info
.cSubtreesConstraint
= 1;
2128 info
.rgSubtreesConstraint
= &nameBlob
;
2129 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS
, &info
,
2130 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2131 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
2132 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2135 ok(bufSize
== sizeof(constraintWithDomainName
), "Wrong size %d\n", bufSize
);
2136 ok(!memcmp(buf
, constraintWithDomainName
,
2137 sizeof(constraintWithDomainName
)), "Unexpected value\n");
2140 /* FIXME: test encoding with subject type. */
2143 static const unsigned char bin63
[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 };
2145 static void test_decodeBasicConstraints(DWORD dwEncoding
)
2147 static const BYTE inverted
[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01,
2149 static const struct Constraints2 badBool
= { { TRUE
, TRUE
, 1 }, bin63
};
2155 /* First test with simpler info2 */
2156 for (i
= 0; i
< sizeof(constraints2
) / sizeof(constraints2
[0]); i
++)
2158 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS2
,
2159 constraints2
[i
].encoded
, constraints2
[i
].encoded
[1] + 2,
2160 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2161 ok(ret
, "CryptDecodeObjectEx failed for item %d: %08x\n", i
,
2165 CERT_BASIC_CONSTRAINTS2_INFO
*info
=
2166 (CERT_BASIC_CONSTRAINTS2_INFO
*)buf
;
2168 ok(!memcmp(info
, &constraints2
[i
].info
, sizeof(*info
)),
2169 "Unexpected value for item %d\n", i
);
2173 /* Check with the order of encoded elements inverted */
2175 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS2
,
2176 inverted
, inverted
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
2178 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
2179 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
2180 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2182 ok(!buf
, "Expected buf to be set to NULL\n");
2183 /* Check with a non-DER bool */
2184 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS2
,
2185 badBool
.encoded
, badBool
.encoded
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
2186 (BYTE
*)&buf
, &bufSize
);
2187 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2190 CERT_BASIC_CONSTRAINTS2_INFO
*info
=
2191 (CERT_BASIC_CONSTRAINTS2_INFO
*)buf
;
2193 ok(!memcmp(info
, &badBool
.info
, sizeof(*info
)), "Unexpected value\n");
2196 /* Check with a non-basic constraints value */
2197 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS2
,
2198 (LPBYTE
)encodedCommonName
, encodedCommonName
[1] + 2,
2199 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2200 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
2201 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
2202 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2204 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */
2205 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS
,
2206 emptyConstraint
, sizeof(emptyConstraint
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
2207 (BYTE
*)&buf
, &bufSize
);
2208 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2211 CERT_BASIC_CONSTRAINTS_INFO
*info
= (CERT_BASIC_CONSTRAINTS_INFO
*)buf
;
2213 ok(info
->SubjectType
.cbData
== 0, "Expected no subject type\n");
2214 ok(!info
->fPathLenConstraint
, "Expected no path length constraint\n");
2215 ok(info
->cSubtreesConstraint
== 0, "Expected no subtree constraints\n");
2218 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS
,
2219 constraintWithDomainName
, sizeof(constraintWithDomainName
),
2220 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2221 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2224 CERT_BASIC_CONSTRAINTS_INFO
*info
= (CERT_BASIC_CONSTRAINTS_INFO
*)buf
;
2226 ok(info
->SubjectType
.cbData
== 0, "Expected no subject type\n");
2227 ok(!info
->fPathLenConstraint
, "Expected no path length constraint\n");
2228 ok(info
->cSubtreesConstraint
== 1, "Expected a subtree constraint\n");
2229 if (info
->cSubtreesConstraint
&& info
->rgSubtreesConstraint
)
2231 ok(info
->rgSubtreesConstraint
[0].cbData
==
2232 sizeof(encodedDomainName
), "Wrong size %d\n",
2233 info
->rgSubtreesConstraint
[0].cbData
);
2234 ok(!memcmp(info
->rgSubtreesConstraint
[0].pbData
, encodedDomainName
,
2235 sizeof(encodedDomainName
)), "Unexpected value\n");
2241 /* These are terrible public keys of course, I'm just testing encoding */
2242 static const BYTE modulus1
[] = { 0,0,0,1,1,1,1,1 };
2243 static const BYTE modulus2
[] = { 1,1,1,1,1,0,0,0 };
2244 static const BYTE modulus3
[] = { 0x80,1,1,1,1,0,0,0 };
2245 static const BYTE modulus4
[] = { 1,1,1,1,1,0,0,0x80 };
2246 static const BYTE mod1_encoded
[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 };
2247 static const BYTE mod2_encoded
[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2248 static const BYTE mod3_encoded
[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 };
2249 static const BYTE mod4_encoded
[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2251 struct EncodedRSAPubKey
2253 const BYTE
*modulus
;
2255 const BYTE
*encoded
;
2256 size_t decodedModulusLen
;
2259 struct EncodedRSAPubKey rsaPubKeys
[] = {
2260 { modulus1
, sizeof(modulus1
), mod1_encoded
, sizeof(modulus1
) },
2261 { modulus2
, sizeof(modulus2
), mod2_encoded
, 5 },
2262 { modulus3
, sizeof(modulus3
), mod3_encoded
, 5 },
2263 { modulus4
, sizeof(modulus4
), mod4_encoded
, 8 },
2266 static void test_encodeRsaPublicKey(DWORD dwEncoding
)
2268 BYTE toEncode
[sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) + sizeof(modulus1
)];
2269 BLOBHEADER
*hdr
= (BLOBHEADER
*)toEncode
;
2270 RSAPUBKEY
*rsaPubKey
= (RSAPUBKEY
*)(toEncode
+ sizeof(BLOBHEADER
));
2273 DWORD bufSize
= 0, i
;
2275 /* Try with a bogus blob type */
2277 hdr
->bVersion
= CUR_BLOB_VERSION
;
2279 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
2280 rsaPubKey
->magic
= 0x31415352;
2281 rsaPubKey
->bitlen
= sizeof(modulus1
) * 8;
2282 rsaPubKey
->pubexp
= 65537;
2283 memcpy(toEncode
+ sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
), modulus1
,
2286 ret
= pCryptEncodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2287 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
2289 ok(!ret
&& GetLastError() == E_INVALIDARG
,
2290 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2291 /* Now with a bogus reserved field */
2292 hdr
->bType
= PUBLICKEYBLOB
;
2294 ret
= pCryptEncodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2295 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
2299 ok(bufSize
== rsaPubKeys
[0].encoded
[1] + 2,
2300 "Expected size %d, got %d\n", rsaPubKeys
[0].encoded
[1] + 2, bufSize
);
2301 ok(!memcmp(buf
, rsaPubKeys
[0].encoded
, bufSize
), "Unexpected value\n");
2304 /* Now with a bogus blob version */
2307 ret
= pCryptEncodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2308 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
2312 ok(bufSize
== rsaPubKeys
[0].encoded
[1] + 2,
2313 "Expected size %d, got %d\n", rsaPubKeys
[0].encoded
[1] + 2, bufSize
);
2314 ok(!memcmp(buf
, rsaPubKeys
[0].encoded
, bufSize
), "Unexpected value\n");
2317 /* And with a bogus alg ID */
2318 hdr
->bVersion
= CUR_BLOB_VERSION
;
2319 hdr
->aiKeyAlg
= CALG_DES
;
2320 ret
= pCryptEncodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2321 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
2325 ok(bufSize
== rsaPubKeys
[0].encoded
[1] + 2,
2326 "Expected size %d, got %d\n", rsaPubKeys
[0].encoded
[1] + 2, bufSize
);
2327 ok(!memcmp(buf
, rsaPubKeys
[0].encoded
, bufSize
), "Unexpected value\n");
2330 /* Check a couple of RSA-related OIDs */
2331 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
2332 ret
= pCryptEncodeObjectEx(dwEncoding
, szOID_RSA_RSA
,
2333 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2334 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
2335 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2336 ret
= pCryptEncodeObjectEx(dwEncoding
, szOID_RSA_SHA1RSA
,
2337 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2338 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
2339 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2340 /* Finally, all valid */
2341 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
2342 for (i
= 0; i
< sizeof(rsaPubKeys
) / sizeof(rsaPubKeys
[0]); i
++)
2344 memcpy(toEncode
+ sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
),
2345 rsaPubKeys
[i
].modulus
, rsaPubKeys
[i
].modulusLen
);
2346 ret
= pCryptEncodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2347 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2348 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2351 ok(bufSize
== rsaPubKeys
[i
].encoded
[1] + 2,
2352 "Expected size %d, got %d\n", rsaPubKeys
[i
].encoded
[1] + 2,
2354 ok(!memcmp(buf
, rsaPubKeys
[i
].encoded
, bufSize
),
2355 "Unexpected value\n");
2361 static void test_decodeRsaPublicKey(DWORD dwEncoding
)
2368 /* Try with a bad length */
2369 ret
= pCryptDecodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2370 rsaPubKeys
[0].encoded
, rsaPubKeys
[0].encoded
[1],
2371 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2372 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_EOD
||
2373 GetLastError() == OSS_MORE_INPUT
/* Win9x/NT4 */),
2374 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n",
2376 /* Try with a couple of RSA-related OIDs */
2377 ret
= pCryptDecodeObjectEx(dwEncoding
, szOID_RSA_RSA
,
2378 rsaPubKeys
[0].encoded
, rsaPubKeys
[0].encoded
[1] + 2,
2379 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2380 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
2381 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2382 ret
= pCryptDecodeObjectEx(dwEncoding
, szOID_RSA_SHA1RSA
,
2383 rsaPubKeys
[0].encoded
, rsaPubKeys
[0].encoded
[1] + 2,
2384 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2385 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
2386 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2387 /* Now try success cases */
2388 for (i
= 0; i
< sizeof(rsaPubKeys
) / sizeof(rsaPubKeys
[0]); i
++)
2391 ret
= pCryptDecodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2392 rsaPubKeys
[i
].encoded
, rsaPubKeys
[i
].encoded
[1] + 2,
2393 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2394 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2397 BLOBHEADER
*hdr
= (BLOBHEADER
*)buf
;
2398 RSAPUBKEY
*rsaPubKey
= (RSAPUBKEY
*)(buf
+ sizeof(BLOBHEADER
));
2400 ok(bufSize
>= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
2401 rsaPubKeys
[i
].decodedModulusLen
,
2402 "Wrong size %d\n", bufSize
);
2403 ok(hdr
->bType
== PUBLICKEYBLOB
,
2404 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB
,
2406 ok(hdr
->bVersion
== CUR_BLOB_VERSION
,
2407 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
2408 CUR_BLOB_VERSION
, hdr
->bVersion
);
2409 ok(hdr
->reserved
== 0, "Expected reserved 0, got %d\n",
2411 ok(hdr
->aiKeyAlg
== CALG_RSA_KEYX
,
2412 "Expected CALG_RSA_KEYX, got %08x\n", hdr
->aiKeyAlg
);
2413 ok(rsaPubKey
->magic
== 0x31415352,
2414 "Expected magic RSA1, got %08x\n", rsaPubKey
->magic
);
2415 ok(rsaPubKey
->bitlen
== rsaPubKeys
[i
].decodedModulusLen
* 8,
2416 "Wrong bit len %d\n", rsaPubKey
->bitlen
);
2417 ok(rsaPubKey
->pubexp
== 65537, "Expected pubexp 65537, got %d\n",
2419 ok(!memcmp(buf
+ sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
),
2420 rsaPubKeys
[i
].modulus
, rsaPubKeys
[i
].decodedModulusLen
),
2421 "Unexpected modulus\n");
2427 static const BYTE intSequence
[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01,
2428 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02,
2429 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2431 static const BYTE mixedSequence
[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
2432 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f,
2433 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02,
2434 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2436 static void test_encodeSequenceOfAny(DWORD dwEncoding
)
2438 CRYPT_DER_BLOB blobs
[sizeof(ints
) / sizeof(ints
[0])];
2439 CRYPT_SEQUENCE_OF_ANY seq
;
2445 /* Encode a homogeneous sequence */
2446 for (i
= 0; i
< sizeof(ints
) / sizeof(ints
[0]); i
++)
2448 blobs
[i
].cbData
= ints
[i
].encoded
[1] + 2;
2449 blobs
[i
].pbData
= (BYTE
*)ints
[i
].encoded
;
2451 seq
.cValue
= sizeof(ints
) / sizeof(ints
[0]);
2452 seq
.rgValue
= blobs
;
2454 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_SEQUENCE_OF_ANY
, &seq
,
2455 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2456 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2459 ok(bufSize
== sizeof(intSequence
), "Wrong size %d\n", bufSize
);
2460 ok(!memcmp(buf
, intSequence
, intSequence
[1] + 2), "Unexpected value\n");
2463 /* Change the type of the first element in the sequence, and give it
2466 blobs
[0].cbData
= times
[0].encodedTime
[1] + 2;
2467 blobs
[0].pbData
= (BYTE
*)times
[0].encodedTime
;
2468 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_SEQUENCE_OF_ANY
, &seq
,
2469 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2470 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2473 ok(bufSize
== sizeof(mixedSequence
), "Wrong size %d\n", bufSize
);
2474 ok(!memcmp(buf
, mixedSequence
, mixedSequence
[1] + 2),
2475 "Unexpected value\n");
2480 static void test_decodeSequenceOfAny(DWORD dwEncoding
)
2486 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_SEQUENCE_OF_ANY
, intSequence
,
2487 intSequence
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2488 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2491 CRYPT_SEQUENCE_OF_ANY
*seq
= (CRYPT_SEQUENCE_OF_ANY
*)buf
;
2494 ok(seq
->cValue
== sizeof(ints
) / sizeof(ints
[0]),
2495 "Wrong elements %d\n", seq
->cValue
);
2496 for (i
= 0; i
< min(seq
->cValue
, sizeof(ints
) / sizeof(ints
[0])); i
++)
2498 ok(seq
->rgValue
[i
].cbData
== ints
[i
].encoded
[1] + 2,
2499 "Expected %d bytes, got %d\n", ints
[i
].encoded
[1] + 2,
2500 seq
->rgValue
[i
].cbData
);
2501 ok(!memcmp(seq
->rgValue
[i
].pbData
, ints
[i
].encoded
,
2502 ints
[i
].encoded
[1] + 2), "Unexpected value\n");
2506 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_SEQUENCE_OF_ANY
, mixedSequence
,
2507 mixedSequence
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
2509 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2512 CRYPT_SEQUENCE_OF_ANY
*seq
= (CRYPT_SEQUENCE_OF_ANY
*)buf
;
2514 ok(seq
->cValue
== sizeof(ints
) / sizeof(ints
[0]),
2515 "Wrong elements %d\n", seq
->cValue
);
2516 /* Just check the first element since it's all that changed */
2517 ok(seq
->rgValue
[0].cbData
== times
[0].encodedTime
[1] + 2,
2518 "Expected %d bytes, got %d\n", times
[0].encodedTime
[1] + 2,
2519 seq
->rgValue
[0].cbData
);
2520 ok(!memcmp(seq
->rgValue
[0].pbData
, times
[0].encodedTime
,
2521 times
[0].encodedTime
[1] + 2), "Unexpected value\n");
2526 struct encodedExtensions
2528 CERT_EXTENSIONS exts
;
2529 const BYTE
*encoded
;
2532 static BYTE crit_ext_data
[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2533 static BYTE noncrit_ext_data
[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2534 static CHAR oid_basic_constraints2
[] = szOID_BASIC_CONSTRAINTS2
;
2535 static CERT_EXTENSION criticalExt
=
2536 { oid_basic_constraints2
, TRUE
, { 8, crit_ext_data
} };
2537 static CERT_EXTENSION nonCriticalExt
=
2538 { oid_basic_constraints2
, FALSE
, { 8, noncrit_ext_data
} };
2539 static CHAR oid_short
[] = "1.1";
2540 static CERT_EXTENSION extWithShortOid
=
2541 { oid_short
, FALSE
, { 0, NULL
} };
2543 static const BYTE ext0
[] = { 0x30,0x00 };
2544 static const BYTE ext1
[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2545 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2546 static const BYTE ext2
[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2547 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2548 static const BYTE ext3
[] = { 0x30,0x07,0x30,0x05,0x06,0x01,0x29,0x04,0x00 };
2550 static const struct encodedExtensions exts
[] = {
2551 { { 0, NULL
}, ext0
},
2552 { { 1, &criticalExt
}, ext1
},
2553 { { 1, &nonCriticalExt
}, ext2
},
2554 { { 1, &extWithShortOid
}, ext3
}
2557 static void test_encodeExtensions(DWORD dwEncoding
)
2561 for (i
= 0; i
< sizeof(exts
) / sizeof(exts
[i
]); i
++)
2567 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_EXTENSIONS
, &exts
[i
].exts
,
2568 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2569 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2572 ok(bufSize
== exts
[i
].encoded
[1] + 2,
2573 "Expected %d bytes, got %d\n", exts
[i
].encoded
[1] + 2, bufSize
);
2574 ok(!memcmp(buf
, exts
[i
].encoded
, exts
[i
].encoded
[1] + 2),
2575 "Unexpected value\n");
2581 static void test_decodeExtensions(DWORD dwEncoding
)
2585 for (i
= 0; i
< sizeof(exts
) / sizeof(exts
[i
]); i
++)
2591 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_EXTENSIONS
,
2592 exts
[i
].encoded
, exts
[i
].encoded
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
,
2593 NULL
, (BYTE
*)&buf
, &bufSize
);
2594 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2597 CERT_EXTENSIONS
*ext
= (CERT_EXTENSIONS
*)buf
;
2600 ok(ext
->cExtension
== exts
[i
].exts
.cExtension
,
2601 "Expected %d extensions, see %d\n", exts
[i
].exts
.cExtension
,
2603 for (j
= 0; j
< min(ext
->cExtension
, exts
[i
].exts
.cExtension
); j
++)
2605 ok(!strcmp(ext
->rgExtension
[j
].pszObjId
,
2606 exts
[i
].exts
.rgExtension
[j
].pszObjId
),
2607 "Expected OID %s, got %s\n",
2608 exts
[i
].exts
.rgExtension
[j
].pszObjId
,
2609 ext
->rgExtension
[j
].pszObjId
);
2610 ok(!memcmp(ext
->rgExtension
[j
].Value
.pbData
,
2611 exts
[i
].exts
.rgExtension
[j
].Value
.pbData
,
2612 exts
[i
].exts
.rgExtension
[j
].Value
.cbData
),
2613 "Unexpected value\n");
2620 /* MS encodes public key info with a NULL if the algorithm identifier's
2621 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2622 * it encodes them by omitting the algorithm parameters. This latter approach
2623 * seems more correct, so accept either form.
2625 struct encodedPublicKey
2627 CERT_PUBLIC_KEY_INFO info
;
2628 const BYTE
*encoded
;
2629 const BYTE
*encodedNoNull
;
2630 CERT_PUBLIC_KEY_INFO decoded
;
2633 static const BYTE aKey
[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2635 static const BYTE params
[] = { 0x02, 0x01, 0x01 };
2637 static const unsigned char bin64
[] = {
2638 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2639 static const unsigned char bin65
[] = {
2640 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2641 static const unsigned char bin66
[] = {
2642 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2643 static const unsigned char bin67
[] = {
2644 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2645 static const unsigned char bin68
[] = {
2646 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01,
2647 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2648 static const unsigned char bin69
[] = {
2649 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2650 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2651 static const unsigned char bin70
[] = {
2652 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2653 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2655 static const unsigned char bin71
[] = {
2656 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2657 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2659 static unsigned char bin72
[] = { 0x05,0x00};
2661 static CHAR oid_bogus
[] = "1.2.3",
2662 oid_rsa
[] = szOID_RSA
;
2664 static const struct encodedPublicKey pubKeys
[] = {
2665 /* with a bogus OID */
2666 { { { oid_bogus
, { 0, NULL
} }, { 0, NULL
, 0 } },
2668 { { oid_bogus
, { 2, bin72
} }, { 0, NULL
, 0 } } },
2669 /* some normal keys */
2670 { { { oid_rsa
, { 0, NULL
} }, { 0, NULL
, 0} },
2672 { { oid_rsa
, { 2, bin72
} }, { 0, NULL
, 0 } } },
2673 { { { oid_rsa
, { 0, NULL
} }, { sizeof(aKey
), (BYTE
*)aKey
, 0} },
2675 { { oid_rsa
, { 2, bin72
} }, { sizeof(aKey
), (BYTE
*)aKey
, 0} } },
2676 /* with add'l parameters--note they must be DER-encoded */
2677 { { { oid_rsa
, { sizeof(params
), (BYTE
*)params
} }, { sizeof(aKey
),
2678 (BYTE
*)aKey
, 0 } },
2680 { { oid_rsa
, { sizeof(params
), (BYTE
*)params
} }, { sizeof(aKey
),
2681 (BYTE
*)aKey
, 0 } } },
2684 static void test_encodePublicKeyInfo(DWORD dwEncoding
)
2688 for (i
= 0; i
< sizeof(pubKeys
) / sizeof(pubKeys
[0]); i
++)
2694 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_PUBLIC_KEY_INFO
,
2695 &pubKeys
[i
].info
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
2697 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
2698 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2701 ok(bufSize
== pubKeys
[i
].encoded
[1] + 2 ||
2702 bufSize
== pubKeys
[i
].encodedNoNull
[1] + 2,
2703 "Expected %d or %d bytes, got %d\n", pubKeys
[i
].encoded
[1] + 2,
2704 pubKeys
[i
].encodedNoNull
[1] + 2, bufSize
);
2705 if (bufSize
== pubKeys
[i
].encoded
[1] + 2)
2706 ok(!memcmp(buf
, pubKeys
[i
].encoded
, pubKeys
[i
].encoded
[1] + 2),
2707 "Unexpected value\n");
2708 else if (bufSize
== pubKeys
[i
].encodedNoNull
[1] + 2)
2709 ok(!memcmp(buf
, pubKeys
[i
].encodedNoNull
,
2710 pubKeys
[i
].encodedNoNull
[1] + 2), "Unexpected value\n");
2716 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO
*expected
,
2717 const CERT_PUBLIC_KEY_INFO
*got
)
2719 ok(!strcmp(expected
->Algorithm
.pszObjId
, got
->Algorithm
.pszObjId
),
2720 "Expected OID %s, got %s\n", expected
->Algorithm
.pszObjId
,
2721 got
->Algorithm
.pszObjId
);
2722 ok(expected
->Algorithm
.Parameters
.cbData
==
2723 got
->Algorithm
.Parameters
.cbData
,
2724 "Expected parameters of %d bytes, got %d\n",
2725 expected
->Algorithm
.Parameters
.cbData
, got
->Algorithm
.Parameters
.cbData
);
2726 if (expected
->Algorithm
.Parameters
.cbData
)
2727 ok(!memcmp(expected
->Algorithm
.Parameters
.pbData
,
2728 got
->Algorithm
.Parameters
.pbData
, got
->Algorithm
.Parameters
.cbData
),
2729 "Unexpected algorithm parameters\n");
2730 ok(expected
->PublicKey
.cbData
== got
->PublicKey
.cbData
,
2731 "Expected public key of %d bytes, got %d\n",
2732 expected
->PublicKey
.cbData
, got
->PublicKey
.cbData
);
2733 if (expected
->PublicKey
.cbData
)
2734 ok(!memcmp(expected
->PublicKey
.pbData
, got
->PublicKey
.pbData
,
2735 got
->PublicKey
.cbData
), "Unexpected public key value\n");
2738 static void test_decodePublicKeyInfo(DWORD dwEncoding
)
2740 static const BYTE bogusPubKeyInfo
[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
2741 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
2742 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
2743 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2749 for (i
= 0; i
< sizeof(pubKeys
) / sizeof(pubKeys
[0]); i
++)
2751 /* The NULL form decodes to the decoded member */
2752 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_PUBLIC_KEY_INFO
,
2753 pubKeys
[i
].encoded
, pubKeys
[i
].encoded
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
,
2754 NULL
, (BYTE
*)&buf
, &bufSize
);
2755 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2758 comparePublicKeyInfo(&pubKeys
[i
].decoded
,
2759 (CERT_PUBLIC_KEY_INFO
*)buf
);
2762 /* The non-NULL form decodes to the original */
2763 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_PUBLIC_KEY_INFO
,
2764 pubKeys
[i
].encodedNoNull
, pubKeys
[i
].encodedNoNull
[1] + 2,
2765 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
2766 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2769 comparePublicKeyInfo(&pubKeys
[i
].info
, (CERT_PUBLIC_KEY_INFO
*)buf
);
2773 /* Test with bogus (not valid DER) parameters */
2774 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_PUBLIC_KEY_INFO
,
2775 bogusPubKeyInfo
, bogusPubKeyInfo
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
,
2776 NULL
, (BYTE
*)&buf
, &bufSize
);
2777 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
2778 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
2779 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2783 static const BYTE v1Cert
[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
2784 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2785 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
2786 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
2787 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2788 static const BYTE v2Cert
[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02,
2789 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2790 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2791 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2792 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2793 static const BYTE v3Cert
[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2794 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2795 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2796 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2797 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2798 static const BYTE v1CertWithConstraints
[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
2799 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2800 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2801 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2802 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2803 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2804 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2805 static const BYTE v1CertWithSerial
[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
2806 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2807 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2808 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2809 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2810 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2811 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2812 static const BYTE bigCert
[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2813 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
2814 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
2815 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
2816 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
2817 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
2818 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
2819 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
2820 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
2821 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2822 static const BYTE v1CertWithPubKey
[] = {
2823 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2824 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2825 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2826 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2827 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2828 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2829 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2830 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2831 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
2832 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
2834 static const BYTE v1CertWithPubKeyNoNull
[] = {
2835 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2836 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2837 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2838 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2839 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2840 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2841 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2842 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2843 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
2844 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2845 static const BYTE v1CertWithSubjectKeyId
[] = {
2846 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2847 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2848 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2849 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2850 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2851 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2852 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
2853 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2854 0x4c,0x61,0x6e,0x67,0x00 };
2856 static const BYTE serialNum
[] = { 0x01 };
2858 static void test_encodeCertToBeSigned(DWORD dwEncoding
)
2863 CERT_INFO info
= { 0 };
2864 static char oid_rsa_rsa
[] = szOID_RSA_RSA
;
2865 static char oid_subject_key_identifier
[] = szOID_SUBJECT_KEY_IDENTIFIER
;
2870 /* Test with NULL pvStructInfo (crashes on win9x) */
2871 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, NULL
,
2872 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
2873 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
2874 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2876 /* Test with a V1 cert */
2877 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
2878 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
2879 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
2880 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2883 ok(size
== v1Cert
[1] + 2, "Expected size %d, got %d\n",
2884 v1Cert
[1] + 2, size
);
2885 ok(!memcmp(buf
, v1Cert
, size
), "Got unexpected value\n");
2889 info
.dwVersion
= CERT_V2
;
2890 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
2891 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
2892 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
2893 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2896 ok(size
== sizeof(v2Cert
), "Wrong size %d\n", size
);
2897 ok(!memcmp(buf
, v2Cert
, size
), "Got unexpected value\n");
2901 info
.dwVersion
= CERT_V3
;
2902 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
2903 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
2904 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
2905 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2908 ok(size
== sizeof(v3Cert
), "Wrong size %d\n", size
);
2909 ok(!memcmp(buf
, v3Cert
, size
), "Got unexpected value\n");
2912 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
2913 * API doesn't prevent it)
2915 info
.dwVersion
= CERT_V1
;
2916 info
.cExtension
= 1;
2917 info
.rgExtension
= &criticalExt
;
2918 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
2919 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
2920 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
2921 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2924 ok(size
== sizeof(v1CertWithConstraints
), "Wrong size %d\n", size
);
2925 ok(!memcmp(buf
, v1CertWithConstraints
, size
), "Got unexpected value\n");
2928 /* test v1 cert with a serial number */
2929 info
.SerialNumber
.cbData
= sizeof(serialNum
);
2930 info
.SerialNumber
.pbData
= (BYTE
*)serialNum
;
2931 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
2932 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
2935 ok(size
== sizeof(v1CertWithSerial
), "Wrong size %d\n", size
);
2936 ok(!memcmp(buf
, v1CertWithSerial
, size
), "Got unexpected value\n");
2939 /* Test v1 cert with an issuer name, a subject name, and a serial number */
2940 info
.Issuer
.cbData
= sizeof(encodedCommonName
);
2941 info
.Issuer
.pbData
= (BYTE
*)encodedCommonName
;
2942 info
.Subject
.cbData
= sizeof(encodedCommonName
);
2943 info
.Subject
.pbData
= (BYTE
*)encodedCommonName
;
2944 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
2945 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
2948 ok(size
== sizeof(bigCert
), "Wrong size %d\n", size
);
2949 ok(!memcmp(buf
, bigCert
, size
), "Got unexpected value\n");
2952 /* Add a public key */
2953 info
.SubjectPublicKeyInfo
.Algorithm
.pszObjId
= oid_rsa_rsa
;
2954 info
.SubjectPublicKeyInfo
.PublicKey
.cbData
= sizeof(aKey
);
2955 info
.SubjectPublicKeyInfo
.PublicKey
.pbData
= (LPBYTE
)aKey
;
2956 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
2957 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
2960 ok(size
== sizeof(v1CertWithPubKey
) ||
2961 size
== sizeof(v1CertWithPubKeyNoNull
), "Wrong size %d\n", size
);
2962 if (size
== sizeof(v1CertWithPubKey
))
2963 ok(!memcmp(buf
, v1CertWithPubKey
, size
), "Got unexpected value\n");
2964 else if (size
== sizeof(v1CertWithPubKeyNoNull
))
2965 ok(!memcmp(buf
, v1CertWithPubKeyNoNull
, size
),
2966 "Got unexpected value\n");
2969 /* Remove the public key, and add a subject key identifier extension */
2970 info
.SubjectPublicKeyInfo
.Algorithm
.pszObjId
= NULL
;
2971 info
.SubjectPublicKeyInfo
.PublicKey
.cbData
= 0;
2972 info
.SubjectPublicKeyInfo
.PublicKey
.pbData
= NULL
;
2973 ext
.pszObjId
= oid_subject_key_identifier
;
2974 ext
.fCritical
= FALSE
;
2975 ext
.Value
.cbData
= sizeof(octetCommonNameValue
);
2976 ext
.Value
.pbData
= (BYTE
*)octetCommonNameValue
;
2977 info
.cExtension
= 1;
2978 info
.rgExtension
= &ext
;
2979 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
2980 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
2983 ok(size
== sizeof(v1CertWithSubjectKeyId
), "Wrong size %d\n", size
);
2984 ok(!memcmp(buf
, v1CertWithSubjectKeyId
, size
), "Unexpected value\n");
2989 static void test_decodeCertToBeSigned(DWORD dwEncoding
)
2991 static const BYTE
*corruptCerts
[] = { v1Cert
, v2Cert
, v3Cert
,
2992 v1CertWithConstraints
, v1CertWithSerial
};
2997 /* Test with NULL pbEncoded */
2998 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, NULL
, 0,
2999 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3000 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_EOD
||
3001 GetLastError() == OSS_BAD_ARG
/* Win9x */),
3002 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
3005 /* Crashes on win9x */
3006 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, NULL
, 1,
3007 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3008 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
3009 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3011 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT, because at a
3012 * minimum a cert must have a non-zero serial number, an issuer, and a
3015 for (i
= 0; i
< sizeof(corruptCerts
) / sizeof(corruptCerts
[0]); i
++)
3017 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
,
3018 corruptCerts
[i
], corruptCerts
[i
][1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3019 (BYTE
*)&buf
, &size
);
3020 ok(!ret
, "Expected failure\n");
3022 /* Now check with serial number, subject and issuer specified */
3023 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, bigCert
,
3024 sizeof(bigCert
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3025 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3028 CERT_INFO
*info
= (CERT_INFO
*)buf
;
3030 ok(size
>= sizeof(CERT_INFO
), "Wrong size %d\n", size
);
3031 ok(info
->SerialNumber
.cbData
== 1,
3032 "Expected serial number size 1, got %d\n", info
->SerialNumber
.cbData
);
3033 ok(*info
->SerialNumber
.pbData
== *serialNum
,
3034 "Expected serial number %d, got %d\n", *serialNum
,
3035 *info
->SerialNumber
.pbData
);
3036 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
3037 "Wrong size %d\n", info
->Issuer
.cbData
);
3038 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
3039 "Unexpected issuer\n");
3040 ok(info
->Subject
.cbData
== sizeof(encodedCommonName
),
3041 "Wrong size %d\n", info
->Subject
.cbData
);
3042 ok(!memcmp(info
->Subject
.pbData
, encodedCommonName
,
3043 info
->Subject
.cbData
), "Unexpected subject\n");
3046 /* Check again with pub key specified */
3047 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
,
3048 v1CertWithPubKey
, sizeof(v1CertWithPubKey
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3049 (BYTE
*)&buf
, &size
);
3050 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3053 CERT_INFO
*info
= (CERT_INFO
*)buf
;
3055 ok(size
>= sizeof(CERT_INFO
), "Wrong size %d\n", size
);
3056 ok(info
->SerialNumber
.cbData
== 1,
3057 "Expected serial number size 1, got %d\n", info
->SerialNumber
.cbData
);
3058 ok(*info
->SerialNumber
.pbData
== *serialNum
,
3059 "Expected serial number %d, got %d\n", *serialNum
,
3060 *info
->SerialNumber
.pbData
);
3061 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
3062 "Wrong size %d\n", info
->Issuer
.cbData
);
3063 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
3064 "Unexpected issuer\n");
3065 ok(info
->Subject
.cbData
== sizeof(encodedCommonName
),
3066 "Wrong size %d\n", info
->Subject
.cbData
);
3067 ok(!memcmp(info
->Subject
.pbData
, encodedCommonName
,
3068 info
->Subject
.cbData
), "Unexpected subject\n");
3069 ok(!strcmp(info
->SubjectPublicKeyInfo
.Algorithm
.pszObjId
,
3070 szOID_RSA_RSA
), "Expected szOID_RSA_RSA, got %s\n",
3071 info
->SubjectPublicKeyInfo
.Algorithm
.pszObjId
);
3072 ok(info
->SubjectPublicKeyInfo
.PublicKey
.cbData
== sizeof(aKey
),
3073 "Wrong size %d\n", info
->SubjectPublicKeyInfo
.PublicKey
.cbData
);
3074 ok(!memcmp(info
->SubjectPublicKeyInfo
.PublicKey
.pbData
, aKey
,
3075 sizeof(aKey
)), "Unexpected public key\n");
3080 static const BYTE hash
[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
3083 static const BYTE signedBigCert
[] = {
3084 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
3085 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
3086 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
3087 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3088 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
3089 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
3090 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
3091 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
3092 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
3093 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3094 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
3095 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
3097 static void test_encodeCert(DWORD dwEncoding
)
3099 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
3100 * also that bigCert is a NULL-terminated string, so don't count its
3101 * last byte (otherwise the signed cert won't decode.)
3103 CERT_SIGNED_CONTENT_INFO info
= { { sizeof(bigCert
), (BYTE
*)bigCert
},
3104 { NULL
, { 0, NULL
} }, { sizeof(hash
), (BYTE
*)hash
, 0 } };
3109 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT
, &info
,
3110 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &bufSize
);
3111 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3114 ok(bufSize
== sizeof(signedBigCert
), "Wrong size %d\n", bufSize
);
3115 ok(!memcmp(buf
, signedBigCert
, bufSize
), "Unexpected cert\n");
3120 static void test_decodeCert(DWORD dwEncoding
)
3126 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT
, signedBigCert
,
3127 sizeof(signedBigCert
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3128 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3131 CERT_SIGNED_CONTENT_INFO
*info
= (CERT_SIGNED_CONTENT_INFO
*)buf
;
3133 ok(info
->ToBeSigned
.cbData
== sizeof(bigCert
),
3134 "Wrong cert size %d\n", info
->ToBeSigned
.cbData
);
3135 ok(!memcmp(info
->ToBeSigned
.pbData
, bigCert
, info
->ToBeSigned
.cbData
),
3136 "Unexpected cert\n");
3137 ok(info
->Signature
.cbData
== sizeof(hash
),
3138 "Wrong signature size %d\n", info
->Signature
.cbData
);
3139 ok(!memcmp(info
->Signature
.pbData
, hash
, info
->Signature
.cbData
),
3140 "Unexpected signature\n");
3143 /* A signed cert decodes as a CERT_INFO too */
3144 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, signedBigCert
,
3145 sizeof(signedBigCert
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3146 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3149 CERT_INFO
*info
= (CERT_INFO
*)buf
;
3151 ok(size
>= sizeof(CERT_INFO
), "Wrong size %d\n", size
);
3152 ok(info
->SerialNumber
.cbData
== 1,
3153 "Expected serial number size 1, got %d\n", info
->SerialNumber
.cbData
);
3154 ok(*info
->SerialNumber
.pbData
== *serialNum
,
3155 "Expected serial number %d, got %d\n", *serialNum
,
3156 *info
->SerialNumber
.pbData
);
3157 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
3158 "Wrong size %d\n", info
->Issuer
.cbData
);
3159 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
3160 "Unexpected issuer\n");
3161 ok(info
->Subject
.cbData
== sizeof(encodedCommonName
),
3162 "Wrong size %d\n", info
->Subject
.cbData
);
3163 ok(!memcmp(info
->Subject
.pbData
, encodedCommonName
,
3164 info
->Subject
.cbData
), "Unexpected subject\n");
3169 static const BYTE emptyDistPoint
[] = { 0x30, 0x02, 0x30, 0x00 };
3170 static const BYTE distPointWithUrl
[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3171 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3172 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3173 static const BYTE distPointWithReason
[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3175 static const BYTE distPointWithIssuer
[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3176 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3177 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3178 static const BYTE distPointWithUrlAndIssuer
[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3179 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3180 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3181 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3182 0x2e, 0x6f, 0x72, 0x67 };
3183 static const BYTE crlReason
= CRL_REASON_KEY_COMPROMISE
|
3184 CRL_REASON_AFFILIATION_CHANGED
;
3186 static void test_encodeCRLDistPoints(DWORD dwEncoding
)
3188 CRL_DIST_POINTS_INFO info
= { 0 };
3189 CRL_DIST_POINT point
= { { 0 } };
3190 CERT_ALT_NAME_ENTRY entry
= { 0 };
3195 /* Test with an empty info */
3196 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3197 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3198 ok(!ret
&& GetLastError() == E_INVALIDARG
,
3199 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3200 /* Test with one empty dist point */
3201 info
.cDistPoint
= 1;
3202 info
.rgDistPoint
= &point
;
3203 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3204 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3205 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3208 ok(size
== sizeof(emptyDistPoint
), "Wrong size %d\n", size
);
3209 ok(!memcmp(buf
, emptyDistPoint
, size
), "Unexpected value\n");
3212 /* A dist point with an invalid name */
3213 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3214 entry
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
3215 U(entry
).pwszURL
= (LPWSTR
)nihongoURL
;
3216 U(point
.DistPointName
).FullName
.cAltEntry
= 1;
3217 U(point
.DistPointName
).FullName
.rgAltEntry
= &entry
;
3218 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3219 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3220 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_IA5_STRING
,
3221 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
3222 /* The first invalid character is at index 7 */
3223 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size
) == 7,
3224 "Expected invalid char at index 7, got %d\n",
3225 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size
));
3226 /* A dist point with (just) a valid name */
3227 U(entry
).pwszURL
= (LPWSTR
)url
;
3228 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3229 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3230 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3233 ok(size
== sizeof(distPointWithUrl
), "Wrong size %d\n", size
);
3234 ok(!memcmp(buf
, distPointWithUrl
, size
), "Unexpected value\n");
3237 /* A dist point with (just) reason flags */
3238 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
3239 point
.ReasonFlags
.cbData
= sizeof(crlReason
);
3240 point
.ReasonFlags
.pbData
= (LPBYTE
)&crlReason
;
3241 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3242 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3243 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3246 ok(size
== sizeof(distPointWithReason
), "Wrong size %d\n", size
);
3247 ok(!memcmp(buf
, distPointWithReason
, size
), "Unexpected value\n");
3250 /* A dist point with just an issuer */
3251 point
.ReasonFlags
.cbData
= 0;
3252 point
.CRLIssuer
.cAltEntry
= 1;
3253 point
.CRLIssuer
.rgAltEntry
= &entry
;
3254 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3255 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3256 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3259 ok(size
== sizeof(distPointWithIssuer
), "Wrong size %d\n", size
);
3260 ok(!memcmp(buf
, distPointWithIssuer
, size
), "Unexpected value\n");
3263 /* A dist point with both a name and an issuer */
3264 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3265 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3266 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3267 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3270 ok(size
== sizeof(distPointWithUrlAndIssuer
),
3271 "Wrong size %d\n", size
);
3272 ok(!memcmp(buf
, distPointWithUrlAndIssuer
, size
), "Unexpected value\n");
3277 static void test_decodeCRLDistPoints(DWORD dwEncoding
)
3282 PCRL_DIST_POINTS_INFO info
;
3283 PCRL_DIST_POINT point
;
3284 PCERT_ALT_NAME_ENTRY entry
;
3286 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
,
3287 emptyDistPoint
, emptyDistPoint
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3288 (BYTE
*)&buf
, &size
);
3289 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3292 info
= (PCRL_DIST_POINTS_INFO
)buf
;
3293 ok(size
>= sizeof(CRL_DIST_POINTS_INFO
) + sizeof(CRL_DIST_POINT
),
3294 "Wrong size %d\n", size
);
3295 ok(info
->cDistPoint
== 1, "Expected 1 dist points, got %d\n",
3297 point
= info
->rgDistPoint
;
3298 ok(point
->DistPointName
.dwDistPointNameChoice
== CRL_DIST_POINT_NO_NAME
,
3299 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3300 point
->DistPointName
.dwDistPointNameChoice
);
3301 ok(point
->ReasonFlags
.cbData
== 0, "Expected no reason\n");
3302 ok(point
->CRLIssuer
.cAltEntry
== 0, "Expected no issuer\n");
3305 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
,
3306 distPointWithUrl
, distPointWithUrl
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3307 (BYTE
*)&buf
, &size
);
3308 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3311 info
= (PCRL_DIST_POINTS_INFO
)buf
;
3312 ok(size
>= sizeof(CRL_DIST_POINTS_INFO
) + sizeof(CRL_DIST_POINT
),
3313 "Wrong size %d\n", size
);
3314 ok(info
->cDistPoint
== 1, "Expected 1 dist points, got %d\n",
3316 point
= info
->rgDistPoint
;
3317 ok(point
->DistPointName
.dwDistPointNameChoice
==
3318 CRL_DIST_POINT_FULL_NAME
,
3319 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3320 point
->DistPointName
.dwDistPointNameChoice
);
3321 ok(U(point
->DistPointName
).FullName
.cAltEntry
== 1,
3322 "Expected 1 name entry, got %d\n",
3323 U(point
->DistPointName
).FullName
.cAltEntry
);
3324 entry
= U(point
->DistPointName
).FullName
.rgAltEntry
;
3325 ok(entry
->dwAltNameChoice
== CERT_ALT_NAME_URL
,
3326 "Expected CERT_ALT_NAME_URL, got %d\n", entry
->dwAltNameChoice
);
3327 ok(!lstrcmpW(U(*entry
).pwszURL
, url
), "Unexpected name\n");
3328 ok(point
->ReasonFlags
.cbData
== 0, "Expected no reason\n");
3329 ok(point
->CRLIssuer
.cAltEntry
== 0, "Expected no issuer\n");
3332 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
,
3333 distPointWithReason
, distPointWithReason
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
,
3334 NULL
, (BYTE
*)&buf
, &size
);
3335 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3338 info
= (PCRL_DIST_POINTS_INFO
)buf
;
3339 ok(size
>= sizeof(CRL_DIST_POINTS_INFO
) + sizeof(CRL_DIST_POINT
),
3340 "Wrong size %d\n", size
);
3341 ok(info
->cDistPoint
== 1, "Expected 1 dist points, got %d\n",
3343 point
= info
->rgDistPoint
;
3344 ok(point
->DistPointName
.dwDistPointNameChoice
==
3345 CRL_DIST_POINT_NO_NAME
,
3346 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3347 point
->DistPointName
.dwDistPointNameChoice
);
3348 ok(point
->ReasonFlags
.cbData
== sizeof(crlReason
),
3349 "Expected reason length\n");
3350 ok(!memcmp(point
->ReasonFlags
.pbData
, &crlReason
, sizeof(crlReason
)),
3351 "Unexpected reason\n");
3352 ok(point
->CRLIssuer
.cAltEntry
== 0, "Expected no issuer\n");
3355 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
,
3356 distPointWithUrlAndIssuer
, distPointWithUrlAndIssuer
[1] + 2,
3357 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3358 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3361 info
= (PCRL_DIST_POINTS_INFO
)buf
;
3362 ok(size
>= sizeof(CRL_DIST_POINTS_INFO
) + sizeof(CRL_DIST_POINT
),
3363 "Wrong size %d\n", size
);
3364 ok(info
->cDistPoint
== 1, "Expected 1 dist points, got %d\n",
3366 point
= info
->rgDistPoint
;
3367 ok(point
->DistPointName
.dwDistPointNameChoice
==
3368 CRL_DIST_POINT_FULL_NAME
,
3369 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3370 point
->DistPointName
.dwDistPointNameChoice
);
3371 ok(U(point
->DistPointName
).FullName
.cAltEntry
== 1,
3372 "Expected 1 name entry, got %d\n",
3373 U(point
->DistPointName
).FullName
.cAltEntry
);
3374 entry
= U(point
->DistPointName
).FullName
.rgAltEntry
;
3375 ok(entry
->dwAltNameChoice
== CERT_ALT_NAME_URL
,
3376 "Expected CERT_ALT_NAME_URL, got %d\n", entry
->dwAltNameChoice
);
3377 ok(!lstrcmpW(U(*entry
).pwszURL
, url
), "Unexpected name\n");
3378 ok(point
->ReasonFlags
.cbData
== 0, "Expected no reason\n");
3379 ok(point
->CRLIssuer
.cAltEntry
== 1,
3380 "Expected 1 issuer entry, got %d\n", point
->CRLIssuer
.cAltEntry
);
3381 entry
= point
->CRLIssuer
.rgAltEntry
;
3382 ok(entry
->dwAltNameChoice
== CERT_ALT_NAME_URL
,
3383 "Expected CERT_ALT_NAME_URL, got %d\n", entry
->dwAltNameChoice
);
3384 ok(!lstrcmpW(U(*entry
).pwszURL
, url
), "Unexpected name\n");
3389 static const BYTE badFlagsIDP
[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3390 static const BYTE emptyNameIDP
[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3391 static const BYTE urlIDP
[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3392 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3395 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding
)
3400 CRL_ISSUING_DIST_POINT point
= { { 0 } };
3401 CERT_ALT_NAME_ENTRY entry
;
3403 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, NULL
,
3404 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3405 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
3407 skip("no X509_ISSUING_DIST_POINT encode support\n");
3410 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
3411 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3412 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, &point
,
3413 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3414 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3417 ok(size
== sizeof(emptySequence
), "Unexpected size %d\n", size
);
3418 ok(!memcmp(buf
, emptySequence
, size
), "Unexpected value\n");
3421 /* nonsensical flags */
3422 point
.fOnlyContainsUserCerts
= TRUE
;
3423 point
.fOnlyContainsCACerts
= TRUE
;
3424 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, &point
,
3425 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3426 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3429 ok(size
== sizeof(badFlagsIDP
), "Unexpected size %d\n", size
);
3430 ok(!memcmp(buf
, badFlagsIDP
, size
), "Unexpected value\n");
3433 /* unimplemented name type */
3434 point
.fOnlyContainsCACerts
= point
.fOnlyContainsUserCerts
= FALSE
;
3435 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_ISSUER_RDN_NAME
;
3436 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, &point
,
3437 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3438 ok(!ret
&& GetLastError() == E_INVALIDARG
,
3439 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3441 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3442 U(point
.DistPointName
).FullName
.cAltEntry
= 0;
3443 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, &point
,
3444 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3445 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3448 ok(size
== sizeof(emptyNameIDP
), "Unexpected size %d\n", size
);
3449 ok(!memcmp(buf
, emptyNameIDP
, size
), "Unexpected value\n");
3452 /* name with URL entry */
3453 entry
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
3454 U(entry
).pwszURL
= (LPWSTR
)url
;
3455 U(point
.DistPointName
).FullName
.cAltEntry
= 1;
3456 U(point
.DistPointName
).FullName
.rgAltEntry
= &entry
;
3457 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, &point
,
3458 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3459 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3462 ok(size
== sizeof(urlIDP
), "Unexpected size %d\n", size
);
3463 ok(!memcmp(buf
, urlIDP
, size
), "Unexpected value\n");
3468 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY
*expected
,
3469 const CERT_ALT_NAME_ENTRY
*got
)
3471 ok(expected
->dwAltNameChoice
== got
->dwAltNameChoice
,
3472 "Expected name choice %d, got %d\n", expected
->dwAltNameChoice
,
3473 got
->dwAltNameChoice
);
3474 if (expected
->dwAltNameChoice
== got
->dwAltNameChoice
)
3476 switch (got
->dwAltNameChoice
)
3478 case CERT_ALT_NAME_RFC822_NAME
:
3479 case CERT_ALT_NAME_DNS_NAME
:
3480 case CERT_ALT_NAME_EDI_PARTY_NAME
:
3481 case CERT_ALT_NAME_URL
:
3482 case CERT_ALT_NAME_REGISTERED_ID
:
3483 ok((!U(*expected
).pwszURL
&& !U(*got
).pwszURL
) ||
3484 (!U(*expected
).pwszURL
&& !lstrlenW(U(*got
).pwszURL
)) ||
3485 (!U(*got
).pwszURL
&& !lstrlenW(U(*expected
).pwszURL
)) ||
3486 !lstrcmpW(U(*expected
).pwszURL
, U(*got
).pwszURL
),
3487 "Unexpected name\n");
3489 case CERT_ALT_NAME_X400_ADDRESS
:
3490 case CERT_ALT_NAME_DIRECTORY_NAME
:
3491 case CERT_ALT_NAME_IP_ADDRESS
:
3492 ok(U(*got
).IPAddress
.cbData
== U(*expected
).IPAddress
.cbData
,
3493 "Unexpected IP address length %d\n", U(*got
).IPAddress
.cbData
);
3494 ok(!memcmp(U(*got
).IPAddress
.pbData
, U(*got
).IPAddress
.pbData
,
3495 U(*got
).IPAddress
.cbData
), "Unexpected value\n");
3501 static void compareAltNameInfo(const CERT_ALT_NAME_INFO
*expected
,
3502 const CERT_ALT_NAME_INFO
*got
)
3506 ok(expected
->cAltEntry
== got
->cAltEntry
, "Expected %d entries, got %d\n",
3507 expected
->cAltEntry
, got
->cAltEntry
);
3508 for (i
= 0; i
< min(expected
->cAltEntry
, got
->cAltEntry
); i
++)
3509 compareAltNameEntry(&expected
->rgAltEntry
[i
], &got
->rgAltEntry
[i
]);
3512 static void compareDistPointName(const CRL_DIST_POINT_NAME
*expected
,
3513 const CRL_DIST_POINT_NAME
*got
)
3515 ok(got
->dwDistPointNameChoice
== expected
->dwDistPointNameChoice
,
3516 "Unexpected name choice %d\n", got
->dwDistPointNameChoice
);
3517 if (got
->dwDistPointNameChoice
== CRL_DIST_POINT_FULL_NAME
)
3518 compareAltNameInfo(&(U(*expected
).FullName
), &(U(*got
).FullName
));
3521 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT
*expected
,
3522 const CRL_ISSUING_DIST_POINT
*got
)
3524 compareDistPointName(&expected
->DistPointName
, &got
->DistPointName
);
3525 ok(got
->fOnlyContainsUserCerts
== expected
->fOnlyContainsUserCerts
,
3526 "Unexpected fOnlyContainsUserCerts\n");
3527 ok(got
->fOnlyContainsCACerts
== expected
->fOnlyContainsCACerts
,
3528 "Unexpected fOnlyContainsCACerts\n");
3529 ok(got
->OnlySomeReasonFlags
.cbData
== expected
->OnlySomeReasonFlags
.cbData
,
3530 "Unexpected reason flags\n");
3531 ok(got
->fIndirectCRL
== expected
->fIndirectCRL
,
3532 "Unexpected fIndirectCRL\n");
3535 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding
)
3540 CRL_ISSUING_DIST_POINT point
= { { 0 } };
3542 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
,
3543 emptySequence
, emptySequence
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3544 (BYTE
*)&buf
, &size
);
3545 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
3547 skip("no X509_ISSUING_DIST_POINT decode support\n");
3550 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3553 compareCRLIssuingDistPoints(&point
, (PCRL_ISSUING_DIST_POINT
)buf
);
3556 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
,
3557 badFlagsIDP
, badFlagsIDP
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3558 (BYTE
*)&buf
, &size
);
3559 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3562 point
.fOnlyContainsUserCerts
= point
.fOnlyContainsCACerts
= TRUE
;
3563 compareCRLIssuingDistPoints(&point
, (PCRL_ISSUING_DIST_POINT
)buf
);
3566 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
,
3567 emptyNameIDP
, emptyNameIDP
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3568 (BYTE
*)&buf
, &size
);
3569 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3572 point
.fOnlyContainsCACerts
= point
.fOnlyContainsUserCerts
= FALSE
;
3573 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3574 U(point
.DistPointName
).FullName
.cAltEntry
= 0;
3575 compareCRLIssuingDistPoints(&point
, (PCRL_ISSUING_DIST_POINT
)buf
);
3578 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
,
3579 urlIDP
, urlIDP
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3580 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3583 CERT_ALT_NAME_ENTRY entry
;
3585 entry
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
3586 U(entry
).pwszURL
= (LPWSTR
)url
;
3587 U(point
.DistPointName
).FullName
.cAltEntry
= 1;
3588 U(point
.DistPointName
).FullName
.rgAltEntry
= &entry
;
3589 compareCRLIssuingDistPoints(&point
, (PCRL_ISSUING_DIST_POINT
)buf
);
3594 static const BYTE v1CRL
[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3595 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3597 static const BYTE v2CRL
[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3598 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3599 0x30, 0x30, 0x30, 0x30, 0x5a };
3600 static const BYTE v1CRLWithIssuer
[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3601 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3602 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3603 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3605 static const BYTE v1CRLWithIssuerAndEmptyEntry
[] = { 0x30, 0x43, 0x30, 0x02,
3606 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3607 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3608 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3609 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3610 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3611 static const BYTE v1CRLWithIssuerAndEntry
[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3612 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3613 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3614 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3615 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3616 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3617 static const BYTE v1CRLWithEntryExt
[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3618 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3619 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3620 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3621 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3622 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3623 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3624 static const BYTE v1CRLWithExt
[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3625 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3626 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3627 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
3628 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3629 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
3630 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3631 static const BYTE v2CRLWithExt
[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
3632 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
3633 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
3634 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
3635 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
3636 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
3637 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3638 static const BYTE v2CRLWithIssuingDistPoint
[] = { 0x30,0x5c,0x02,0x01,0x01,
3639 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
3640 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
3641 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
3642 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3643 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
3644 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3646 static void test_encodeCRLToBeSigned(DWORD dwEncoding
)
3650 static CHAR oid_issuing_dist_point
[] = szOID_ISSUING_DIST_POINT
;
3652 CRL_INFO info
= { 0 };
3653 CRL_ENTRY entry
= { { 0 }, { 0 }, 0, 0 };
3656 /* Test with a V1 CRL */
3657 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3658 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3659 ok(ret
|| broken(GetLastError() == OSS_DATA_ERROR
/* Win9x */),
3660 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3663 ok(size
== sizeof(v1CRL
), "Wrong size %d\n", size
);
3664 ok(!memcmp(buf
, v1CRL
, size
), "Got unexpected value\n");
3668 info
.dwVersion
= CRL_V2
;
3669 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3670 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3671 ok(ret
|| broken(GetLastError() == OSS_DATA_ERROR
/* Win9x */),
3672 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3675 ok(size
== v2CRL
[1] + 2, "Expected size %d, got %d\n",
3676 v2CRL
[1] + 2, size
);
3677 ok(!memcmp(buf
, v2CRL
, size
), "Got unexpected value\n");
3680 /* v1 CRL with a name */
3681 info
.dwVersion
= CRL_V1
;
3682 info
.Issuer
.cbData
= sizeof(encodedCommonName
);
3683 info
.Issuer
.pbData
= (BYTE
*)encodedCommonName
;
3684 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3685 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3686 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3689 ok(size
== sizeof(v1CRLWithIssuer
), "Wrong size %d\n", size
);
3690 ok(!memcmp(buf
, v1CRLWithIssuer
, size
), "Got unexpected value\n");
3695 /* v1 CRL with a name and a NULL entry pointer (crashes on win9x) */
3697 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3698 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3699 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
3700 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3702 /* now set an empty entry */
3704 info
.rgCRLEntry
= &entry
;
3705 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3706 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3709 ok(size
== sizeof(v1CRLWithIssuerAndEmptyEntry
),
3710 "Wrong size %d\n", size
);
3711 ok(!memcmp(buf
, v1CRLWithIssuerAndEmptyEntry
, size
),
3712 "Got unexpected value\n");
3715 /* an entry with a serial number */
3716 entry
.SerialNumber
.cbData
= sizeof(serialNum
);
3717 entry
.SerialNumber
.pbData
= (BYTE
*)serialNum
;
3718 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3719 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3722 ok(size
== sizeof(v1CRLWithIssuerAndEntry
),
3723 "Wrong size %d\n", size
);
3724 ok(!memcmp(buf
, v1CRLWithIssuerAndEntry
, size
),
3725 "Got unexpected value\n");
3728 /* an entry with an extension */
3729 entry
.cExtension
= 1;
3730 entry
.rgExtension
= &criticalExt
;
3731 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3732 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3733 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3736 ok(size
== sizeof(v1CRLWithEntryExt
), "Wrong size %d\n", size
);
3737 ok(!memcmp(buf
, v1CRLWithEntryExt
, size
), "Got unexpected value\n");
3740 /* a CRL with an extension */
3741 entry
.cExtension
= 0;
3742 info
.cExtension
= 1;
3743 info
.rgExtension
= &criticalExt
;
3744 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3745 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3746 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3749 ok(size
== sizeof(v1CRLWithExt
), "Wrong size %d\n", size
);
3750 ok(!memcmp(buf
, v1CRLWithExt
, size
), "Got unexpected value\n");
3753 /* a v2 CRL with an extension, this time non-critical */
3754 info
.dwVersion
= CRL_V2
;
3755 info
.rgExtension
= &nonCriticalExt
;
3756 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3757 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3758 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3761 ok(size
== sizeof(v2CRLWithExt
), "Wrong size %d\n", size
);
3762 ok(!memcmp(buf
, v2CRLWithExt
, size
), "Got unexpected value\n");
3765 /* a v2 CRL with an issuing dist point extension */
3766 ext
.pszObjId
= oid_issuing_dist_point
;
3767 ext
.fCritical
= TRUE
;
3768 ext
.Value
.cbData
= sizeof(urlIDP
);
3769 ext
.Value
.pbData
= (LPBYTE
)urlIDP
;
3770 entry
.rgExtension
= &ext
;
3771 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
3772 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
3773 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3776 ok(size
== sizeof(v2CRLWithIssuingDistPoint
), "Wrong size %d\n", size
);
3777 ok(!memcmp(buf
, v2CRLWithIssuingDistPoint
, size
), "Unexpected value\n");
3782 static const BYTE verisignCRL
[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
3783 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
3784 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
3785 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
3786 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
3787 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
3788 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
3789 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
3790 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
3791 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
3792 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
3793 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
3794 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
3795 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
3796 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
3797 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
3798 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
3799 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
3800 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
3801 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
3802 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
3803 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
3804 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
3805 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
3806 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
3807 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
3808 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
3809 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
3810 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
3811 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
3812 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
3813 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
3814 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
3815 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
3817 static const BYTE verisignCRLWithLotsOfEntries
[] = {
3818 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
3819 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
3820 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
3821 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
3822 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
3823 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
3824 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
3825 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
3826 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
3827 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
3828 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
3829 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
3830 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
3831 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
3832 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
3833 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
3834 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3835 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
3836 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
3837 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3838 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
3839 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
3840 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
3841 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
3842 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
3843 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
3844 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
3845 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
3846 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
3847 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
3848 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3849 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
3850 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
3851 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3852 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
3853 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
3854 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
3855 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
3856 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
3857 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
3858 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
3859 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
3860 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
3861 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
3862 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
3863 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
3864 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
3865 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
3866 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
3867 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
3868 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
3869 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
3870 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
3871 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
3872 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3873 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
3874 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
3875 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
3876 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
3877 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
3878 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
3879 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
3880 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
3881 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
3882 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
3883 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
3884 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
3885 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
3886 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
3887 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
3888 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
3889 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
3890 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
3891 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
3892 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
3893 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
3894 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
3895 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
3896 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
3897 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
3898 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
3899 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
3900 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3901 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
3902 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
3903 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
3904 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
3905 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
3906 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
3907 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
3908 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
3909 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
3910 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
3911 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
3912 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
3913 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
3914 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
3915 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
3916 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
3917 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
3918 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
3919 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
3920 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
3921 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
3922 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
3923 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
3924 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
3925 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
3926 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
3927 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
3928 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3929 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
3930 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
3931 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
3932 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
3933 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
3934 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
3935 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
3936 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
3937 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
3938 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
3939 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
3940 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
3941 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
3942 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3943 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
3944 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
3945 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
3946 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
3947 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
3948 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
3949 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
3950 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
3951 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
3952 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
3953 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
3954 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
3955 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
3956 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
3957 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
3958 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
3959 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
3960 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
3961 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
3962 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
3963 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
3964 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
3965 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
3966 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
3967 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
3968 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
3969 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
3970 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
3971 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
3972 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
3973 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
3974 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
3975 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
3976 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
3977 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
3978 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
3979 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
3980 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
3981 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
3982 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
3983 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
3984 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
3985 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
3986 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
3987 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
3988 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
3989 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
3990 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
3991 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
3992 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
3993 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
3994 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
3995 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
3996 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
3997 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
3998 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
3999 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
4000 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
4001 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
4002 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
4003 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
4004 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
4005 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
4006 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
4007 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
4008 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
4009 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
4010 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
4011 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
4012 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
4013 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
4014 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
4015 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
4016 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
4017 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
4018 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
4019 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
4020 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
4021 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
4022 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
4023 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
4024 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
4025 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
4026 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
4027 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
4028 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
4029 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
4030 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
4031 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
4032 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
4033 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
4034 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
4035 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
4036 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
4037 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
4038 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
4039 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
4040 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
4041 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
4042 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
4043 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
4044 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
4045 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
4046 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
4047 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
4048 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
4049 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
4050 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
4051 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
4052 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
4053 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
4054 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
4055 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
4056 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
4057 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
4058 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
4059 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
4060 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
4061 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
4062 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
4063 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
4064 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
4065 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
4066 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
4067 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
4068 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
4069 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
4070 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
4071 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
4072 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
4073 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
4074 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
4075 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
4076 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
4077 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
4078 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
4079 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
4080 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
4081 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
4082 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
4083 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
4084 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
4085 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
4086 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
4087 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
4088 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
4089 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
4090 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
4091 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
4092 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
4093 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
4094 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
4095 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
4096 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
4097 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
4098 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
4099 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
4100 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
4101 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
4102 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
4103 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
4104 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
4105 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
4106 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
4107 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
4108 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
4109 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
4110 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
4111 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
4112 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
4113 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
4114 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
4115 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
4116 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
4117 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
4118 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
4119 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
4120 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
4121 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4122 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4123 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4124 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4125 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4126 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4127 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4128 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4129 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4130 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4131 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4132 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4133 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4134 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4135 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4136 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4137 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4138 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4139 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4140 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4141 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4142 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4143 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4144 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4145 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4146 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4147 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4148 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4149 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4150 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4151 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4152 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4153 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4154 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4155 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4156 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4157 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4158 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4159 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4160 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4161 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4162 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4163 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4164 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4165 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4166 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4167 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4168 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4169 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4170 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4171 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4172 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4173 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4174 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4175 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4176 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4177 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4178 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4179 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4180 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4181 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4182 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4183 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4184 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4185 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4186 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4187 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4188 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4189 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4190 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4191 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4192 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4193 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4194 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4195 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4196 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4197 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4198 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4199 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4200 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4201 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4202 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4203 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4204 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4205 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4206 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4207 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4208 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4209 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4210 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4211 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4212 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4213 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4214 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4215 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4216 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4217 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4218 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4219 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4220 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4221 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4222 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4223 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4224 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4225 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4226 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4227 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4228 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4229 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4230 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4231 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4232 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4233 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4234 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4235 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4236 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4237 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4238 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4239 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4240 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4241 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4242 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4243 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4244 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4245 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4246 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4247 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4248 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4249 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4250 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4251 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4252 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4253 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4254 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4255 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4256 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4257 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4258 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4259 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4260 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4261 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4262 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4263 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4264 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4265 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4266 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4267 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4268 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4269 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4270 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4271 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4272 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4273 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4274 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4275 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4276 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4277 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4278 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4279 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4280 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4281 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4282 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4283 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4284 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4285 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4286 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4287 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4288 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4289 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4290 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4291 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4292 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4293 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4294 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4295 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4296 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4297 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4298 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4299 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4300 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4301 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4302 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4303 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4304 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4305 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4306 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4307 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4308 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4309 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4310 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4311 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4312 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4313 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4314 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4315 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4316 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4317 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4318 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4319 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4320 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4321 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4322 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4323 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4324 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4325 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4327 static void test_decodeCRLToBeSigned(DWORD dwEncoding
)
4329 static const BYTE
*corruptCRLs
[] = { v1CRL
, v2CRL
};
4334 for (i
= 0; i
< sizeof(corruptCRLs
) / sizeof(corruptCRLs
[0]); i
++)
4336 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4337 corruptCRLs
[i
], corruptCRLs
[i
][1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4338 (BYTE
*)&buf
, &size
);
4339 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
4340 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
4341 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4344 /* at a minimum, a CRL must contain an issuer: */
4345 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4346 v1CRLWithIssuer
, v1CRLWithIssuer
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4347 (BYTE
*)&buf
, &size
);
4348 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4351 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4353 ok(size
>= sizeof(CRL_INFO
), "Wrong size %d\n", size
);
4354 ok(info
->cCRLEntry
== 0, "Expected 0 CRL entries, got %d\n",
4356 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
4357 "Wrong issuer size %d\n", info
->Issuer
.cbData
);
4358 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
4359 "Unexpected issuer\n");
4362 /* check decoding with an empty CRL entry */
4363 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4364 v1CRLWithIssuerAndEmptyEntry
, v1CRLWithIssuerAndEmptyEntry
[1] + 2,
4365 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4366 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
4367 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
4368 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4370 /* with a real CRL entry */
4371 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4372 v1CRLWithIssuerAndEntry
, v1CRLWithIssuerAndEntry
[1] + 2,
4373 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4374 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4377 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4380 ok(size
>= sizeof(CRL_INFO
), "Wrong size %d\n", size
);
4381 ok(info
->cCRLEntry
== 1, "Expected 1 CRL entries, got %d\n",
4383 ok(info
->rgCRLEntry
!= NULL
, "Expected a valid CRL entry array\n");
4384 entry
= info
->rgCRLEntry
;
4385 ok(entry
->SerialNumber
.cbData
== 1,
4386 "Expected serial number size 1, got %d\n",
4387 entry
->SerialNumber
.cbData
);
4388 ok(*entry
->SerialNumber
.pbData
== *serialNum
,
4389 "Expected serial number %d, got %d\n", *serialNum
,
4390 *entry
->SerialNumber
.pbData
);
4391 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
4392 "Wrong issuer size %d\n", info
->Issuer
.cbData
);
4393 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
4394 "Unexpected issuer\n");
4397 /* a real CRL from verisign that has extensions */
4398 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4399 verisignCRL
, sizeof(verisignCRL
), CRYPT_DECODE_ALLOC_FLAG
,
4400 NULL
, (BYTE
*)&buf
, &size
);
4401 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4404 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4407 ok(size
>= sizeof(CRL_INFO
), "Wrong size %d\n", size
);
4408 ok(info
->cCRLEntry
== 3, "Expected 3 CRL entries, got %d\n",
4410 ok(info
->rgCRLEntry
!= NULL
, "Expected a valid CRL entry array\n");
4411 entry
= info
->rgCRLEntry
;
4412 ok(info
->cExtension
== 2, "Expected 2 extensions, got %d\n",
4416 /* another real CRL from verisign that has lots of entries */
4417 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4418 verisignCRLWithLotsOfEntries
, sizeof(verisignCRLWithLotsOfEntries
),
4419 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4420 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4423 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4425 ok(size
>= sizeof(CRL_INFO
), "Got size %d\n", size
);
4426 ok(info
->cCRLEntry
== 209, "Expected 209 CRL entries, got %d\n",
4428 ok(info
->cExtension
== 0, "Expected 0 extensions, got %d\n",
4432 /* and finally, with an extension */
4433 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4434 v1CRLWithExt
, sizeof(v1CRLWithExt
), CRYPT_DECODE_ALLOC_FLAG
,
4435 NULL
, (BYTE
*)&buf
, &size
);
4436 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4439 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4442 ok(size
>= sizeof(CRL_INFO
), "Wrong size %d\n", size
);
4443 ok(info
->cCRLEntry
== 1, "Expected 1 CRL entries, got %d\n",
4445 ok(info
->rgCRLEntry
!= NULL
, "Expected a valid CRL entry array\n");
4446 entry
= info
->rgCRLEntry
;
4447 ok(entry
->SerialNumber
.cbData
== 1,
4448 "Expected serial number size 1, got %d\n",
4449 entry
->SerialNumber
.cbData
);
4450 ok(*entry
->SerialNumber
.pbData
== *serialNum
,
4451 "Expected serial number %d, got %d\n", *serialNum
,
4452 *entry
->SerialNumber
.pbData
);
4453 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
4454 "Wrong issuer size %d\n", info
->Issuer
.cbData
);
4455 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
4456 "Unexpected issuer\n");
4457 ok(info
->cExtension
== 1, "Expected 1 extensions, got %d\n",
4461 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4462 v2CRLWithExt
, sizeof(v2CRLWithExt
), CRYPT_DECODE_ALLOC_FLAG
,
4463 NULL
, (BYTE
*)&buf
, &size
);
4464 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4467 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4469 ok(info
->cExtension
== 1, "Expected 1 extensions, got %d\n",
4473 /* And again, with an issuing dist point */
4474 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4475 v2CRLWithIssuingDistPoint
, sizeof(v2CRLWithIssuingDistPoint
),
4476 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4477 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4480 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4482 ok(info
->cExtension
== 1, "Expected 1 extensions, got %d\n",
4488 static const LPCSTR keyUsages
[] = { szOID_PKIX_KP_CODE_SIGNING
,
4489 szOID_PKIX_KP_CLIENT_AUTH
, szOID_RSA_RSA
};
4490 static const BYTE encodedUsage
[] = {
4491 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4492 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4493 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4495 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding
)
4500 CERT_ENHKEY_USAGE usage
;
4502 /* Test with empty usage */
4503 usage
.cUsageIdentifier
= 0;
4504 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ENHANCED_KEY_USAGE
, &usage
,
4505 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4506 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4509 ok(size
== sizeof(emptySequence
), "Wrong size %d\n", size
);
4510 ok(!memcmp(buf
, emptySequence
, size
), "Got unexpected value\n");
4513 /* Test with a few usages */
4514 usage
.cUsageIdentifier
= sizeof(keyUsages
) / sizeof(keyUsages
[0]);
4515 usage
.rgpszUsageIdentifier
= (LPSTR
*)keyUsages
;
4516 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ENHANCED_KEY_USAGE
, &usage
,
4517 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4518 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4521 ok(size
== sizeof(encodedUsage
), "Wrong size %d\n", size
);
4522 ok(!memcmp(buf
, encodedUsage
, size
), "Got unexpected value\n");
4527 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding
)
4533 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ENHANCED_KEY_USAGE
,
4534 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4535 (BYTE
*)&buf
, &size
);
4536 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4539 CERT_ENHKEY_USAGE
*usage
= (CERT_ENHKEY_USAGE
*)buf
;
4541 ok(size
>= sizeof(CERT_ENHKEY_USAGE
),
4542 "Wrong size %d\n", size
);
4543 ok(usage
->cUsageIdentifier
== 0, "Expected 0 CRL entries, got %d\n",
4544 usage
->cUsageIdentifier
);
4547 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ENHANCED_KEY_USAGE
,
4548 encodedUsage
, sizeof(encodedUsage
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4549 (BYTE
*)&buf
, &size
);
4550 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4553 CERT_ENHKEY_USAGE
*usage
= (CERT_ENHKEY_USAGE
*)buf
;
4556 ok(size
>= sizeof(CERT_ENHKEY_USAGE
),
4557 "Wrong size %d\n", size
);
4558 ok(usage
->cUsageIdentifier
== sizeof(keyUsages
) / sizeof(keyUsages
[0]),
4559 "Wrong CRL entries count %d\n", usage
->cUsageIdentifier
);
4560 for (i
= 0; i
< usage
->cUsageIdentifier
; i
++)
4561 ok(!strcmp(usage
->rgpszUsageIdentifier
[i
], keyUsages
[i
]),
4562 "Expected OID %s, got %s\n", keyUsages
[i
],
4563 usage
->rgpszUsageIdentifier
[i
]);
4568 static BYTE keyId
[] = { 1,2,3,4 };
4569 static const BYTE authorityKeyIdWithId
[] = {
4570 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4571 static const BYTE authorityKeyIdWithIssuer
[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4572 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4573 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4574 static const BYTE authorityKeyIdWithSerial
[] = { 0x30,0x03,0x82,0x01,0x01 };
4576 static void test_encodeAuthorityKeyId(DWORD dwEncoding
)
4578 CERT_AUTHORITY_KEY_ID_INFO info
= { { 0 } };
4583 /* Test with empty id */
4584 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
, &info
,
4585 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4586 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4589 ok(size
== sizeof(emptySequence
), "Unexpected size %d\n", size
);
4590 ok(!memcmp(buf
, emptySequence
, size
), "Unexpected value\n");
4593 /* With just a key id */
4594 info
.KeyId
.cbData
= sizeof(keyId
);
4595 info
.KeyId
.pbData
= keyId
;
4596 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
, &info
,
4597 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4598 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4601 ok(size
== sizeof(authorityKeyIdWithId
), "Unexpected size %d\n", size
);
4602 ok(!memcmp(buf
, authorityKeyIdWithId
, size
), "Unexpected value\n");
4605 /* With just an issuer */
4606 info
.KeyId
.cbData
= 0;
4607 info
.CertIssuer
.cbData
= sizeof(encodedCommonName
);
4608 info
.CertIssuer
.pbData
= (BYTE
*)encodedCommonName
;
4609 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
, &info
,
4610 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4611 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4614 ok(size
== sizeof(authorityKeyIdWithIssuer
), "Unexpected size %d\n",
4616 ok(!memcmp(buf
, authorityKeyIdWithIssuer
, size
), "Unexpected value\n");
4619 /* With just a serial number */
4620 info
.CertIssuer
.cbData
= 0;
4621 info
.CertSerialNumber
.cbData
= sizeof(serialNum
);
4622 info
.CertSerialNumber
.pbData
= (BYTE
*)serialNum
;
4623 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
, &info
,
4624 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4625 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4628 ok(size
== sizeof(authorityKeyIdWithSerial
), "Unexpected size %d\n",
4630 ok(!memcmp(buf
, authorityKeyIdWithSerial
, size
), "Unexpected value\n");
4635 static void test_decodeAuthorityKeyId(DWORD dwEncoding
)
4641 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
,
4642 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4643 (BYTE
*)&buf
, &size
);
4644 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4647 CERT_AUTHORITY_KEY_ID_INFO
*info
= (CERT_AUTHORITY_KEY_ID_INFO
*)buf
;
4649 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID_INFO
), "Unexpected size %d\n",
4651 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
4652 ok(info
->CertIssuer
.cbData
== 0, "Expected no issuer name\n");
4653 ok(info
->CertSerialNumber
.cbData
== 0, "Expected no serial number\n");
4656 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
,
4657 authorityKeyIdWithId
, sizeof(authorityKeyIdWithId
),
4658 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4659 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4662 CERT_AUTHORITY_KEY_ID_INFO
*info
= (CERT_AUTHORITY_KEY_ID_INFO
*)buf
;
4664 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID_INFO
), "Unexpected size %d\n",
4666 ok(info
->KeyId
.cbData
== sizeof(keyId
), "Unexpected key id len\n");
4667 ok(!memcmp(info
->KeyId
.pbData
, keyId
, sizeof(keyId
)),
4668 "Unexpected key id\n");
4669 ok(info
->CertIssuer
.cbData
== 0, "Expected no issuer name\n");
4670 ok(info
->CertSerialNumber
.cbData
== 0, "Expected no serial number\n");
4673 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
,
4674 authorityKeyIdWithIssuer
, sizeof(authorityKeyIdWithIssuer
),
4675 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4676 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4679 CERT_AUTHORITY_KEY_ID_INFO
*info
= (CERT_AUTHORITY_KEY_ID_INFO
*)buf
;
4681 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID_INFO
), "Unexpected size %d\n",
4683 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
4684 ok(info
->CertIssuer
.cbData
== sizeof(encodedCommonName
),
4685 "Unexpected issuer len\n");
4686 ok(!memcmp(info
->CertIssuer
.pbData
, encodedCommonName
,
4687 sizeof(encodedCommonName
)), "Unexpected issuer\n");
4688 ok(info
->CertSerialNumber
.cbData
== 0, "Expected no serial number\n");
4691 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
,
4692 authorityKeyIdWithSerial
, sizeof(authorityKeyIdWithSerial
),
4693 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4694 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4697 CERT_AUTHORITY_KEY_ID_INFO
*info
= (CERT_AUTHORITY_KEY_ID_INFO
*)buf
;
4699 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID_INFO
), "Unexpected size %d\n",
4701 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
4702 ok(info
->CertIssuer
.cbData
== 0, "Expected no issuer name\n");
4703 ok(info
->CertSerialNumber
.cbData
== sizeof(serialNum
),
4704 "Unexpected serial number len\n");
4705 ok(!memcmp(info
->CertSerialNumber
.pbData
, serialNum
, sizeof(serialNum
)),
4706 "Unexpected serial number\n");
4711 static const BYTE authorityKeyIdWithIssuerUrl
[] = { 0x30,0x15,0xa1,0x13,0x86,
4712 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
4715 static void test_encodeAuthorityKeyId2(DWORD dwEncoding
)
4717 CERT_AUTHORITY_KEY_ID2_INFO info
= { { 0 } };
4718 CERT_ALT_NAME_ENTRY entry
= { 0 };
4723 /* Test with empty id */
4724 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
, &info
,
4725 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4726 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4729 ok(size
== sizeof(emptySequence
), "Unexpected size %d\n", size
);
4730 ok(!memcmp(buf
, emptySequence
, size
), "Unexpected value\n");
4733 /* With just a key id */
4734 info
.KeyId
.cbData
= sizeof(keyId
);
4735 info
.KeyId
.pbData
= keyId
;
4736 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
, &info
,
4737 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4738 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4741 ok(size
== sizeof(authorityKeyIdWithId
), "Unexpected size %d\n",
4743 ok(!memcmp(buf
, authorityKeyIdWithId
, size
), "Unexpected value\n");
4746 /* With a bogus issuer name */
4747 info
.KeyId
.cbData
= 0;
4748 info
.AuthorityCertIssuer
.cAltEntry
= 1;
4749 info
.AuthorityCertIssuer
.rgAltEntry
= &entry
;
4750 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
, &info
,
4751 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4752 ok(!ret
&& GetLastError() == E_INVALIDARG
,
4753 "Expected E_INVALIDARG, got %08x\n", GetLastError());
4754 /* With an issuer name */
4755 entry
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
4756 U(entry
).pwszURL
= (LPWSTR
)url
;
4757 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
, &info
,
4758 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4759 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4762 ok(size
== sizeof(authorityKeyIdWithIssuerUrl
), "Unexpected size %d\n",
4764 ok(!memcmp(buf
, authorityKeyIdWithIssuerUrl
, size
),
4765 "Unexpected value\n");
4768 /* With just a serial number */
4769 info
.AuthorityCertIssuer
.cAltEntry
= 0;
4770 info
.AuthorityCertSerialNumber
.cbData
= sizeof(serialNum
);
4771 info
.AuthorityCertSerialNumber
.pbData
= (BYTE
*)serialNum
;
4772 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
, &info
,
4773 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4774 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4777 ok(size
== sizeof(authorityKeyIdWithSerial
), "Unexpected size %d\n",
4779 ok(!memcmp(buf
, authorityKeyIdWithSerial
, size
), "Unexpected value\n");
4784 static void test_decodeAuthorityKeyId2(DWORD dwEncoding
)
4790 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
,
4791 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4792 (BYTE
*)&buf
, &size
);
4793 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4796 CERT_AUTHORITY_KEY_ID2_INFO
*info
= (CERT_AUTHORITY_KEY_ID2_INFO
*)buf
;
4798 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID2_INFO
), "Unexpected size %d\n",
4800 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
4801 ok(info
->AuthorityCertIssuer
.cAltEntry
== 0,
4802 "Expected no issuer name entries\n");
4803 ok(info
->AuthorityCertSerialNumber
.cbData
== 0,
4804 "Expected no serial number\n");
4807 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
,
4808 authorityKeyIdWithId
, sizeof(authorityKeyIdWithId
),
4809 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4810 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4813 CERT_AUTHORITY_KEY_ID2_INFO
*info
= (CERT_AUTHORITY_KEY_ID2_INFO
*)buf
;
4815 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID2_INFO
), "Unexpected size %d\n",
4817 ok(info
->KeyId
.cbData
== sizeof(keyId
), "Unexpected key id len\n");
4818 ok(!memcmp(info
->KeyId
.pbData
, keyId
, sizeof(keyId
)),
4819 "Unexpected key id\n");
4820 ok(info
->AuthorityCertIssuer
.cAltEntry
== 0,
4821 "Expected no issuer name entries\n");
4822 ok(info
->AuthorityCertSerialNumber
.cbData
== 0,
4823 "Expected no serial number\n");
4826 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
,
4827 authorityKeyIdWithIssuerUrl
, sizeof(authorityKeyIdWithIssuerUrl
),
4828 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4829 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4832 CERT_AUTHORITY_KEY_ID2_INFO
*info
= (CERT_AUTHORITY_KEY_ID2_INFO
*)buf
;
4834 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID2_INFO
), "Unexpected size %d\n",
4836 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
4837 ok(info
->AuthorityCertIssuer
.cAltEntry
== 1,
4838 "Expected 1 issuer entry, got %d\n",
4839 info
->AuthorityCertIssuer
.cAltEntry
);
4840 ok(info
->AuthorityCertIssuer
.rgAltEntry
[0].dwAltNameChoice
==
4841 CERT_ALT_NAME_URL
, "Expected CERT_ALT_NAME_URL, got %d\n",
4842 info
->AuthorityCertIssuer
.rgAltEntry
[0].dwAltNameChoice
);
4843 ok(!lstrcmpW(U(info
->AuthorityCertIssuer
.rgAltEntry
[0]).pwszURL
,
4844 url
), "Unexpected URL\n");
4845 ok(info
->AuthorityCertSerialNumber
.cbData
== 0,
4846 "Expected no serial number\n");
4849 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
,
4850 authorityKeyIdWithSerial
, sizeof(authorityKeyIdWithSerial
),
4851 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4852 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4855 CERT_AUTHORITY_KEY_ID2_INFO
*info
= (CERT_AUTHORITY_KEY_ID2_INFO
*)buf
;
4857 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID2_INFO
), "Unexpected size %d\n",
4859 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
4860 ok(info
->AuthorityCertIssuer
.cAltEntry
== 0,
4861 "Expected no issuer name entries\n");
4862 ok(info
->AuthorityCertSerialNumber
.cbData
== sizeof(serialNum
),
4863 "Unexpected serial number len\n");
4864 ok(!memcmp(info
->AuthorityCertSerialNumber
.pbData
, serialNum
,
4865 sizeof(serialNum
)), "Unexpected serial number\n");
4870 static const BYTE authorityInfoAccessWithUrl
[] = {
4871 0x30,0x19,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
4872 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
4873 static const BYTE authorityInfoAccessWithUrlAndIPAddr
[] = {
4874 0x30,0x29,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
4875 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x0e,0x06,
4876 0x02,0x2d,0x06,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
4878 static void test_encodeAuthorityInfoAccess(DWORD dwEncoding
)
4880 static char oid1
[] = "1.2.3";
4881 static char oid2
[] = "1.5.6";
4885 CERT_ACCESS_DESCRIPTION accessDescription
[2];
4886 CERT_AUTHORITY_INFO_ACCESS aia
;
4888 memset(accessDescription
, 0, sizeof(accessDescription
));
4890 aia
.rgAccDescr
= NULL
;
4891 /* Having no access descriptions is allowed */
4892 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
, &aia
,
4893 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4894 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4897 ok(size
== sizeof(emptySequence
), "unexpected size %d\n", size
);
4898 ok(!memcmp(buf
, emptySequence
, size
), "unexpected value\n");
4902 /* It can't have an empty access method */
4904 aia
.rgAccDescr
= accessDescription
;
4905 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
, &aia
,
4906 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4907 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
4908 GetLastError() == OSS_LIMITED
/* Win9x */),
4909 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
4910 /* It can't have an empty location */
4911 accessDescription
[0].pszAccessMethod
= oid1
;
4912 SetLastError(0xdeadbeef);
4913 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
, &aia
,
4914 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4915 ok(!ret
&& GetLastError() == E_INVALIDARG
,
4916 "expected E_INVALIDARG, got %08x\n", GetLastError());
4917 accessDescription
[0].AccessLocation
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
4918 U(accessDescription
[0].AccessLocation
).pwszURL
= (LPWSTR
)url
;
4919 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
, &aia
,
4920 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4921 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4924 ok(size
== sizeof(authorityInfoAccessWithUrl
), "unexpected size %d\n",
4926 ok(!memcmp(buf
, authorityInfoAccessWithUrl
, size
),
4927 "unexpected value\n");
4931 accessDescription
[1].pszAccessMethod
= oid2
;
4932 accessDescription
[1].AccessLocation
.dwAltNameChoice
=
4933 CERT_ALT_NAME_IP_ADDRESS
;
4934 U(accessDescription
[1].AccessLocation
).IPAddress
.cbData
=
4935 sizeof(encodedIPAddr
);
4936 U(accessDescription
[1].AccessLocation
).IPAddress
.pbData
=
4937 (LPBYTE
)encodedIPAddr
;
4939 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
, &aia
,
4940 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4941 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4944 ok(size
== sizeof(authorityInfoAccessWithUrlAndIPAddr
),
4945 "unexpected size %d\n", size
);
4946 ok(!memcmp(buf
, authorityInfoAccessWithUrlAndIPAddr
, size
),
4947 "unexpected value\n");
4953 static void compareAuthorityInfoAccess(LPCSTR header
,
4954 const CERT_AUTHORITY_INFO_ACCESS
*expected
,
4955 const CERT_AUTHORITY_INFO_ACCESS
*got
)
4959 ok(expected
->cAccDescr
== got
->cAccDescr
,
4960 "%s: expected %d access descriptions, got %d\n", header
,
4961 expected
->cAccDescr
, got
->cAccDescr
);
4962 for (i
= 0; i
< expected
->cAccDescr
; i
++)
4964 ok(!strcmp(expected
->rgAccDescr
[i
].pszAccessMethod
,
4965 got
->rgAccDescr
[i
].pszAccessMethod
), "%s[%d]: expected %s, got %s\n",
4966 header
, i
, expected
->rgAccDescr
[i
].pszAccessMethod
,
4967 got
->rgAccDescr
[i
].pszAccessMethod
);
4968 compareAltNameEntry(&expected
->rgAccDescr
[i
].AccessLocation
,
4969 &got
->rgAccDescr
[i
].AccessLocation
);
4973 static void test_decodeAuthorityInfoAccess(DWORD dwEncoding
)
4975 static char oid1
[] = "1.2.3";
4976 static char oid2
[] = "1.5.6";
4981 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
,
4982 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4983 (BYTE
*)&buf
, &size
);
4984 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4987 CERT_AUTHORITY_INFO_ACCESS aia
= { 0, NULL
};
4989 compareAuthorityInfoAccess("empty AIA", &aia
,
4990 (CERT_AUTHORITY_INFO_ACCESS
*)buf
);
4994 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
,
4995 authorityInfoAccessWithUrl
, sizeof(authorityInfoAccessWithUrl
),
4996 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
4997 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5000 CERT_ACCESS_DESCRIPTION accessDescription
;
5001 CERT_AUTHORITY_INFO_ACCESS aia
;
5003 accessDescription
.pszAccessMethod
= oid1
;
5004 accessDescription
.AccessLocation
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
5005 U(accessDescription
.AccessLocation
).pwszURL
= (LPWSTR
)url
;
5007 aia
.rgAccDescr
= &accessDescription
;
5008 compareAuthorityInfoAccess("AIA with URL", &aia
,
5009 (CERT_AUTHORITY_INFO_ACCESS
*)buf
);
5013 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
,
5014 authorityInfoAccessWithUrlAndIPAddr
,
5015 sizeof(authorityInfoAccessWithUrlAndIPAddr
), CRYPT_DECODE_ALLOC_FLAG
,
5016 NULL
, (BYTE
*)&buf
, &size
);
5017 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5020 CERT_ACCESS_DESCRIPTION accessDescription
[2];
5021 CERT_AUTHORITY_INFO_ACCESS aia
;
5023 accessDescription
[0].pszAccessMethod
= oid1
;
5024 accessDescription
[0].AccessLocation
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
5025 U(accessDescription
[0].AccessLocation
).pwszURL
= (LPWSTR
)url
;
5026 accessDescription
[1].pszAccessMethod
= oid2
;
5027 accessDescription
[1].AccessLocation
.dwAltNameChoice
=
5028 CERT_ALT_NAME_IP_ADDRESS
;
5029 U(accessDescription
[1].AccessLocation
).IPAddress
.cbData
=
5030 sizeof(encodedIPAddr
);
5031 U(accessDescription
[1].AccessLocation
).IPAddress
.pbData
=
5032 (LPBYTE
)encodedIPAddr
;
5034 aia
.rgAccDescr
= accessDescription
;
5035 compareAuthorityInfoAccess("AIA with URL and IP addr", &aia
,
5036 (CERT_AUTHORITY_INFO_ACCESS
*)buf
);
5042 static const BYTE emptyCTL
[] = {
5043 0x30,0x17,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5044 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5045 static const BYTE emptyCTLWithVersion1
[] = {
5046 0x30,0x1a,0x02,0x01,0x01,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5047 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5048 static const BYTE ctlWithUsageIdentifier
[] = {
5049 0x30,0x1b,0x30,0x04,0x06,0x02,0x2a,0x03,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
5050 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5051 static const BYTE ctlWithListIdentifier
[] = {
5052 0x30,0x1a,0x30,0x00,0x04,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5053 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5054 static const BYTE ctlWithSequenceNumber
[] = {
5055 0x30,0x1a,0x30,0x00,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5056 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5057 static const BYTE ctlWithThisUpdate
[] = {
5058 0x30,0x15,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5059 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5060 static const BYTE ctlWithThisAndNextUpdate
[] = {
5061 0x30,0x24,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5062 0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5063 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5064 static const BYTE ctlWithAlgId
[] = {
5065 0x30,0x1b,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5066 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5067 static const BYTE ctlWithBogusEntry
[] = {
5068 0x30,0x29,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5069 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x10,0x30,0x0e,0x04,
5070 0x01,0x01,0x31,0x09,0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,0x01 };
5071 static const BYTE ctlWithOneEntry
[] = {
5072 0x30,0x2a,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5073 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x11,0x30,0x0f,0x04,
5074 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00 };
5075 static const BYTE ctlWithTwoEntries
[] = {
5076 0x30,0x41,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5077 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x28,0x30,0x0f,0x04,
5078 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00,0x30,
5079 0x15,0x04,0x01,0x01,0x31,0x10,0x30,0x0e,0x06,0x02,0x2d,0x06,0x31,0x08,0x30,
5080 0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5082 static void test_encodeCTL(DWORD dwEncoding
)
5084 static char oid1
[] = "1.2.3";
5085 static char oid2
[] = "1.5.6";
5091 SYSTEMTIME thisUpdate
= { 2005, 6, 1, 6, 16, 10, 0, 0 };
5092 CTL_ENTRY ctlEntry
[2];
5093 CRYPT_ATTRIBUTE attr1
, attr2
;
5094 CRYPT_ATTR_BLOB value1
, value2
;
5096 memset(&info
, 0, sizeof(info
));
5097 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5098 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5099 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5102 ok(size
== sizeof(emptyCTL
), "unexpected size %d\n", size
);
5103 ok(!memcmp(buf
, emptyCTL
, size
), "unexpected value\n");
5108 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5109 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5110 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5113 ok(size
== sizeof(emptyCTLWithVersion1
), "unexpected size %d\n", size
);
5114 ok(!memcmp(buf
, emptyCTLWithVersion1
, size
), "unexpected value\n");
5119 info
.SubjectUsage
.cUsageIdentifier
= 1;
5120 info
.SubjectUsage
.rgpszUsageIdentifier
= &pOid1
;
5121 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5122 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5123 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5126 ok(size
== sizeof(ctlWithUsageIdentifier
), "unexpected size %d\n",
5128 ok(!memcmp(buf
, ctlWithUsageIdentifier
, size
), "unexpected value\n");
5132 info
.SubjectUsage
.cUsageIdentifier
= 0;
5133 info
.ListIdentifier
.cbData
= sizeof(serialNum
);
5134 info
.ListIdentifier
.pbData
= (LPBYTE
)serialNum
;
5135 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5136 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5137 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5140 ok(size
== sizeof(ctlWithListIdentifier
), "unexpected size %d\n", size
);
5141 ok(!memcmp(buf
, ctlWithListIdentifier
, size
), "unexpected value\n");
5145 info
.ListIdentifier
.cbData
= 0;
5146 info
.SequenceNumber
.cbData
= sizeof(serialNum
);
5147 info
.SequenceNumber
.pbData
= (LPBYTE
)serialNum
;
5148 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5149 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5150 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5153 ok(size
== sizeof(ctlWithSequenceNumber
), "unexpected size %d\n",
5155 ok(!memcmp(buf
, ctlWithSequenceNumber
, size
), "unexpected value\n");
5159 info
.SequenceNumber
.cbData
= 0;
5160 SystemTimeToFileTime(&thisUpdate
, &info
.ThisUpdate
);
5161 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5162 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5163 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5166 ok(size
== sizeof(ctlWithThisUpdate
), "unexpected size %d\n", size
);
5167 ok(!memcmp(buf
, ctlWithThisUpdate
, size
), "unexpected value\n");
5171 SystemTimeToFileTime(&thisUpdate
, &info
.NextUpdate
);
5172 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5173 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5174 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5177 ok(size
== sizeof(ctlWithThisAndNextUpdate
), "unexpected size %d\n",
5179 ok(!memcmp(buf
, ctlWithThisAndNextUpdate
, size
), "unexpected value\n");
5183 info
.ThisUpdate
.dwLowDateTime
= info
.ThisUpdate
.dwHighDateTime
= 0;
5184 info
.NextUpdate
.dwLowDateTime
= info
.NextUpdate
.dwHighDateTime
= 0;
5185 info
.SubjectAlgorithm
.pszObjId
= oid2
;
5186 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5187 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5188 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5191 ok(size
== sizeof(ctlWithAlgId
), "unexpected size %d\n", size
);
5192 ok(!memcmp(buf
, ctlWithAlgId
, size
), "unexpected value\n");
5196 /* The value is supposed to be asn.1 encoded, so this'll fail to decode
5197 * (see tests below) but it'll encode fine.
5199 info
.SubjectAlgorithm
.pszObjId
= NULL
;
5200 value1
.cbData
= sizeof(serialNum
);
5201 value1
.pbData
= (LPBYTE
)serialNum
;
5202 attr1
.pszObjId
= oid1
;
5204 attr1
.rgValue
= &value1
;
5205 ctlEntry
[0].SubjectIdentifier
.cbData
= sizeof(serialNum
);
5206 ctlEntry
[0].SubjectIdentifier
.pbData
= (LPBYTE
)serialNum
;
5207 ctlEntry
[0].cAttribute
= 1;
5208 ctlEntry
[0].rgAttribute
= &attr1
;
5210 info
.rgCTLEntry
= ctlEntry
;
5211 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5212 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5213 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5216 ok(size
== sizeof(ctlWithBogusEntry
), "unexpected size %d\n", size
);
5217 ok(!memcmp(buf
, ctlWithBogusEntry
, size
), "unexpected value\n");
5221 value1
.cbData
= sizeof(emptySequence
);
5222 value1
.pbData
= (LPBYTE
)emptySequence
;
5223 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5224 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5225 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5228 ok(size
== sizeof(ctlWithOneEntry
), "unexpected size %d\n", size
);
5229 ok(!memcmp(buf
, ctlWithOneEntry
, size
), "unexpected value\n");
5233 value2
.cbData
= sizeof(encodedIPAddr
);
5234 value2
.pbData
= (LPBYTE
)encodedIPAddr
;
5235 attr2
.pszObjId
= oid2
;
5237 attr2
.rgValue
= &value2
;
5238 ctlEntry
[1].SubjectIdentifier
.cbData
= sizeof(serialNum
);
5239 ctlEntry
[1].SubjectIdentifier
.pbData
= (LPBYTE
)serialNum
;
5240 ctlEntry
[1].cAttribute
= 1;
5241 ctlEntry
[1].rgAttribute
= &attr2
;
5243 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5244 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5245 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5248 ok(size
== sizeof(ctlWithTwoEntries
), "unexpected size %d\n", size
);
5249 ok(!memcmp(buf
, ctlWithTwoEntries
, size
), "unexpected value\n");
5255 static void compareCTLInfo(LPCSTR header
, const CTL_INFO
*expected
,
5256 const CTL_INFO
*got
)
5260 ok(expected
->dwVersion
== got
->dwVersion
,
5261 "%s: expected version %d, got %d\n", header
, expected
->dwVersion
,
5263 ok(expected
->SubjectUsage
.cUsageIdentifier
==
5264 got
->SubjectUsage
.cUsageIdentifier
,
5265 "%s: expected %d usage identifiers, got %d\n", header
,
5266 expected
->SubjectUsage
.cUsageIdentifier
,
5267 got
->SubjectUsage
.cUsageIdentifier
);
5268 for (i
= 0; i
< expected
->SubjectUsage
.cUsageIdentifier
; i
++)
5269 ok(!strcmp(expected
->SubjectUsage
.rgpszUsageIdentifier
[i
],
5270 got
->SubjectUsage
.rgpszUsageIdentifier
[i
]),
5271 "%s[%d]: expected %s, got %s\n", header
, i
,
5272 expected
->SubjectUsage
.rgpszUsageIdentifier
[i
],
5273 got
->SubjectUsage
.rgpszUsageIdentifier
[i
]);
5274 ok(expected
->ListIdentifier
.cbData
== got
->ListIdentifier
.cbData
,
5275 "%s: expected list identifier of %d bytes, got %d\n", header
,
5276 expected
->ListIdentifier
.cbData
, got
->ListIdentifier
.cbData
);
5277 if (expected
->ListIdentifier
.cbData
)
5278 ok(!memcmp(expected
->ListIdentifier
.pbData
, got
->ListIdentifier
.pbData
,
5279 expected
->ListIdentifier
.cbData
),
5280 "%s: unexpected list identifier value\n", header
);
5281 ok(expected
->SequenceNumber
.cbData
== got
->SequenceNumber
.cbData
,
5282 "%s: expected sequence number of %d bytes, got %d\n", header
,
5283 expected
->SequenceNumber
.cbData
, got
->SequenceNumber
.cbData
);
5284 if (expected
->SequenceNumber
.cbData
)
5285 ok(!memcmp(expected
->SequenceNumber
.pbData
, got
->SequenceNumber
.pbData
,
5286 expected
->SequenceNumber
.cbData
),
5287 "%s: unexpected sequence number value\n", header
);
5288 ok(!memcmp(&expected
->ThisUpdate
, &got
->ThisUpdate
, sizeof(FILETIME
)),
5289 "%s: expected this update = (%d, %d), got (%d, %d)\n", header
,
5290 expected
->ThisUpdate
.dwLowDateTime
, expected
->ThisUpdate
.dwHighDateTime
,
5291 got
->ThisUpdate
.dwLowDateTime
, got
->ThisUpdate
.dwHighDateTime
);
5292 ok(!memcmp(&expected
->NextUpdate
, &got
->NextUpdate
, sizeof(FILETIME
)),
5293 "%s: expected next update = (%d, %d), got (%d, %d)\n", header
,
5294 expected
->NextUpdate
.dwLowDateTime
, expected
->NextUpdate
.dwHighDateTime
,
5295 got
->NextUpdate
.dwLowDateTime
, got
->NextUpdate
.dwHighDateTime
);
5296 if (expected
->SubjectAlgorithm
.pszObjId
&&
5297 *expected
->SubjectAlgorithm
.pszObjId
&& !got
->SubjectAlgorithm
.pszObjId
)
5298 ok(0, "%s: expected subject algorithm %s, got NULL\n", header
,
5299 expected
->SubjectAlgorithm
.pszObjId
);
5300 if (expected
->SubjectAlgorithm
.pszObjId
&& got
->SubjectAlgorithm
.pszObjId
)
5301 ok(!strcmp(expected
->SubjectAlgorithm
.pszObjId
,
5302 got
->SubjectAlgorithm
.pszObjId
),
5303 "%s: expected subject algorithm %s, got %s\n", header
,
5304 expected
->SubjectAlgorithm
.pszObjId
, got
->SubjectAlgorithm
.pszObjId
);
5305 ok(expected
->SubjectAlgorithm
.Parameters
.cbData
==
5306 got
->SubjectAlgorithm
.Parameters
.cbData
,
5307 "%s: expected subject algorithm parameters of %d bytes, got %d\n", header
,
5308 expected
->SubjectAlgorithm
.Parameters
.cbData
,
5309 got
->SubjectAlgorithm
.Parameters
.cbData
);
5310 if (expected
->SubjectAlgorithm
.Parameters
.cbData
)
5311 ok(!memcmp(expected
->SubjectAlgorithm
.Parameters
.pbData
,
5312 got
->SubjectAlgorithm
.Parameters
.pbData
,
5313 expected
->SubjectAlgorithm
.Parameters
.cbData
),
5314 "%s: unexpected subject algorithm parameter value\n", header
);
5315 ok(expected
->cCTLEntry
== got
->cCTLEntry
,
5316 "%s: expected %d CTL entries, got %d\n", header
, expected
->cCTLEntry
,
5318 for (i
= 0; i
< expected
->cCTLEntry
; i
++)
5320 ok(expected
->rgCTLEntry
[i
].SubjectIdentifier
.cbData
==
5321 got
->rgCTLEntry
[i
].SubjectIdentifier
.cbData
,
5322 "%s[%d]: expected subject identifier of %d bytes, got %d\n",
5323 header
, i
, expected
->rgCTLEntry
[i
].SubjectIdentifier
.cbData
,
5324 got
->rgCTLEntry
[i
].SubjectIdentifier
.cbData
);
5325 if (expected
->rgCTLEntry
[i
].SubjectIdentifier
.cbData
)
5326 ok(!memcmp(expected
->rgCTLEntry
[i
].SubjectIdentifier
.pbData
,
5327 got
->rgCTLEntry
[i
].SubjectIdentifier
.pbData
,
5328 expected
->rgCTLEntry
[i
].SubjectIdentifier
.cbData
),
5329 "%s[%d]: unexpected subject identifier value\n",
5331 for (j
= 0; j
< expected
->rgCTLEntry
[i
].cAttribute
; j
++)
5333 ok(!strcmp(expected
->rgCTLEntry
[i
].rgAttribute
[j
].pszObjId
,
5334 got
->rgCTLEntry
[i
].rgAttribute
[j
].pszObjId
),
5335 "%s[%d][%d]: expected attribute OID %s, got %s\n", header
, i
, j
,
5336 expected
->rgCTLEntry
[i
].rgAttribute
[j
].pszObjId
,
5337 got
->rgCTLEntry
[i
].rgAttribute
[j
].pszObjId
);
5338 for (k
= 0; k
< expected
->rgCTLEntry
[i
].rgAttribute
[j
].cValue
; k
++)
5340 ok(expected
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].cbData
==
5341 got
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].cbData
,
5342 "%s[%d][%d][%d]: expected value of %d bytes, got %d\n",
5344 expected
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].cbData
,
5345 got
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].cbData
);
5346 if (expected
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].cbData
)
5348 expected
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].pbData
,
5349 got
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].pbData
,
5350 expected
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].cbData
),
5351 "%s[%d][%d][%d]: unexpected value\n",
5356 ok(expected
->cExtension
== got
->cExtension
,
5357 "%s: expected %d extensions, got %d\n", header
, expected
->cExtension
,
5359 for (i
= 0; i
< expected
->cExtension
; i
++)
5361 ok(!strcmp(expected
->rgExtension
[i
].pszObjId
,
5362 got
->rgExtension
[i
].pszObjId
), "%s[%d]: expected %s, got %s\n",
5363 header
, i
, expected
->rgExtension
[i
].pszObjId
,
5364 got
->rgExtension
[i
].pszObjId
);
5365 ok(expected
->rgExtension
[i
].fCritical
== got
->rgExtension
[i
].fCritical
,
5366 "%s[%d]: expected fCritical = %d, got %d\n", header
, i
,
5367 expected
->rgExtension
[i
].fCritical
, got
->rgExtension
[i
].fCritical
);
5368 ok(expected
->rgExtension
[i
].Value
.cbData
==
5369 got
->rgExtension
[i
].Value
.cbData
,
5370 "%s[%d]: expected extension value to have %d bytes, got %d\n",
5371 header
, i
, expected
->rgExtension
[i
].Value
.cbData
,
5372 got
->rgExtension
[i
].Value
.cbData
);
5373 if (expected
->rgExtension
[i
].Value
.cbData
)
5374 ok(!memcmp(expected
->rgExtension
[i
].Value
.pbData
,
5375 got
->rgExtension
[i
].Value
.pbData
,
5376 expected
->rgExtension
[i
].Value
.cbData
),
5377 "%s[%d]: unexpected extension value\n", header
, i
);
5381 static const BYTE signedCTL
[] = {
5382 0x30,0x81,0xc7,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
5383 0x81,0xb9,0x30,0x81,0xb6,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
5384 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x28,0x06,0x09,0x2a,0x86,
5385 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x1b,0x04,0x19,0x30,0x17,0x30,0x00,
5386 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5387 0x30,0x5a,0x30,0x02,0x06,0x00,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
5388 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
5389 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
5390 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5391 0x00,0x04,0x40,0xca,0xd8,0x32,0xd1,0xbd,0x97,0x61,0x54,0xd6,0x80,0xcf,0x0d,
5392 0xbd,0xa2,0x42,0xc7,0xca,0x37,0x91,0x7d,0x9d,0xac,0x8c,0xdf,0x05,0x8a,0x39,
5393 0xc6,0x07,0xc1,0x37,0xe6,0xb9,0xd1,0x0d,0x26,0xec,0xa5,0xb0,0x8a,0x51,0x26,
5394 0x2b,0x4f,0x73,0x44,0x86,0x83,0x5e,0x2b,0x6e,0xcc,0xf8,0x1b,0x85,0x53,0xe9,
5395 0x7a,0x80,0x8f,0x6b,0x42,0x19,0x93 };
5396 static const BYTE signedCTLWithCTLInnerContent
[] = {
5397 0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
5398 0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
5399 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
5400 0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
5401 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5402 0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
5403 0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
5404 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
5405 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
5406 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
5407 0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
5408 0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
5409 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
5410 0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5411 0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
5412 0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
5413 0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
5414 0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
5415 0x57,0x6c,0x0b,0x47,0xb8 };
5417 static void test_decodeCTL(DWORD dwEncoding
)
5419 static char oid1
[] = "1.2.3";
5420 static char oid2
[] = "1.5.6";
5421 static BYTE nullData
[] = { 5,0 };
5427 SYSTEMTIME thisUpdate
= { 2005, 6, 1, 6, 16, 10, 0, 0 };
5428 CTL_ENTRY ctlEntry
[2];
5429 CRYPT_ATTRIBUTE attr1
, attr2
;
5430 CRYPT_ATTR_BLOB value1
, value2
;
5432 memset(&info
, 0, sizeof(info
));
5433 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, emptyCTL
, sizeof(emptyCTL
),
5434 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5435 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5438 compareCTLInfo("empty CTL", &info
, (CTL_INFO
*)buf
);
5443 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, emptyCTLWithVersion1
,
5444 sizeof(emptyCTLWithVersion1
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
,
5446 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5449 compareCTLInfo("v1 CTL", &info
, (CTL_INFO
*)buf
);
5454 info
.SubjectUsage
.cUsageIdentifier
= 1;
5455 info
.SubjectUsage
.rgpszUsageIdentifier
= &pOid1
;
5456 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithUsageIdentifier
,
5457 sizeof(ctlWithUsageIdentifier
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5458 (BYTE
*)&buf
, &size
);
5459 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5462 compareCTLInfo("CTL with usage identifier", &info
, (CTL_INFO
*)buf
);
5466 info
.SubjectUsage
.cUsageIdentifier
= 0;
5467 info
.ListIdentifier
.cbData
= sizeof(serialNum
);
5468 info
.ListIdentifier
.pbData
= (LPBYTE
)serialNum
;
5469 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithListIdentifier
,
5470 sizeof(ctlWithListIdentifier
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5471 (BYTE
*)&buf
, &size
);
5472 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5475 compareCTLInfo("CTL with list identifier", &info
, (CTL_INFO
*)buf
);
5479 info
.ListIdentifier
.cbData
= 0;
5480 info
.SequenceNumber
.cbData
= sizeof(serialNum
);
5481 info
.SequenceNumber
.pbData
= (LPBYTE
)serialNum
;
5482 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithSequenceNumber
,
5483 sizeof(ctlWithSequenceNumber
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5484 (BYTE
*)&buf
, &size
);
5485 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5488 compareCTLInfo("CTL with sequence number", &info
, (CTL_INFO
*)buf
);
5492 info
.SequenceNumber
.cbData
= 0;
5493 SystemTimeToFileTime(&thisUpdate
, &info
.ThisUpdate
);
5494 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithThisUpdate
,
5495 sizeof(ctlWithThisUpdate
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5496 (BYTE
*)&buf
, &size
);
5497 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5500 compareCTLInfo("CTL with this update", &info
, (CTL_INFO
*)buf
);
5504 SystemTimeToFileTime(&thisUpdate
, &info
.NextUpdate
);
5505 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithThisAndNextUpdate
,
5506 sizeof(ctlWithThisAndNextUpdate
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5507 (BYTE
*)&buf
, &size
);
5508 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5511 compareCTLInfo("CTL with this and next update", &info
, (CTL_INFO
*)buf
);
5515 info
.ThisUpdate
.dwLowDateTime
= info
.ThisUpdate
.dwHighDateTime
= 0;
5516 info
.NextUpdate
.dwLowDateTime
= info
.NextUpdate
.dwHighDateTime
= 0;
5517 info
.SubjectAlgorithm
.pszObjId
= oid2
;
5518 info
.SubjectAlgorithm
.Parameters
.cbData
= sizeof(nullData
);
5519 info
.SubjectAlgorithm
.Parameters
.pbData
= nullData
;
5520 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithAlgId
,
5521 sizeof(ctlWithAlgId
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5522 (BYTE
*)&buf
, &size
);
5523 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5526 compareCTLInfo("CTL with algorithm identifier", &info
, (CTL_INFO
*)buf
);
5530 SetLastError(0xdeadbeef);
5531 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithBogusEntry
,
5532 sizeof(ctlWithBogusEntry
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5533 (BYTE
*)&buf
, &size
);
5534 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_EOD
|| CRYPT_E_ASN1_CORRUPT
),
5535 "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n",
5537 info
.SubjectAlgorithm
.Parameters
.cbData
= 0;
5538 info
.ThisUpdate
.dwLowDateTime
= info
.ThisUpdate
.dwHighDateTime
= 0;
5539 info
.NextUpdate
.dwLowDateTime
= info
.NextUpdate
.dwHighDateTime
= 0;
5540 info
.SubjectAlgorithm
.pszObjId
= oid2
;
5541 info
.SubjectAlgorithm
.pszObjId
= NULL
;
5542 value1
.cbData
= sizeof(emptySequence
);
5543 value1
.pbData
= (LPBYTE
)emptySequence
;
5544 attr1
.pszObjId
= oid1
;
5546 attr1
.rgValue
= &value1
;
5547 ctlEntry
[0].SubjectIdentifier
.cbData
= sizeof(serialNum
);
5548 ctlEntry
[0].SubjectIdentifier
.pbData
= (LPBYTE
)serialNum
;
5549 ctlEntry
[0].cAttribute
= 1;
5550 ctlEntry
[0].rgAttribute
= &attr1
;
5552 info
.rgCTLEntry
= ctlEntry
;
5553 SetLastError(0xdeadbeef);
5554 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithOneEntry
,
5555 sizeof(ctlWithOneEntry
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5556 (BYTE
*)&buf
, &size
);
5557 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5560 compareCTLInfo("CTL with one entry", &info
, (CTL_INFO
*)buf
);
5564 value2
.cbData
= sizeof(encodedIPAddr
);
5565 value2
.pbData
= (LPBYTE
)encodedIPAddr
;
5566 attr2
.pszObjId
= oid2
;
5568 attr2
.rgValue
= &value2
;
5569 ctlEntry
[1].SubjectIdentifier
.cbData
= sizeof(serialNum
);
5570 ctlEntry
[1].SubjectIdentifier
.pbData
= (LPBYTE
)serialNum
;
5571 ctlEntry
[1].cAttribute
= 1;
5572 ctlEntry
[1].rgAttribute
= &attr2
;
5574 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithTwoEntries
,
5575 sizeof(ctlWithTwoEntries
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5576 (BYTE
*)&buf
, &size
);
5577 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5580 compareCTLInfo("CTL with two entries", &info
, (CTL_INFO
*)buf
);
5584 /* A signed CTL isn't decodable, even if the inner content is a CTL */
5585 SetLastError(0xdeadbeef);
5586 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, signedCTL
,
5587 sizeof(signedCTL
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5588 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_BADTAG
||
5589 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
5590 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5592 SetLastError(0xdeadbeef);
5593 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
,
5594 signedCTLWithCTLInnerContent
, sizeof(signedCTLWithCTLInnerContent
),
5595 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5596 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_BADTAG
||
5597 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
5598 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5602 static const BYTE emptyPKCSContentInfo
[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
5603 static const BYTE emptyPKCSContentInfoExtraBytes
[] = { 0x30,0x04,0x06,0x02,0x2a,
5605 static const BYTE bogusPKCSContentInfo
[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
5607 static const BYTE intPKCSContentInfo
[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
5608 0x03,0x02,0x01,0x01 };
5609 static BYTE bogusDER
[] = { 1 };
5611 static void test_encodePKCSContentInfo(DWORD dwEncoding
)
5616 CRYPT_CONTENT_INFO info
= { 0 };
5617 char oid1
[] = "1.2.3";
5621 /* Crashes on win9x */
5622 SetLastError(0xdeadbeef);
5623 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
, NULL
,
5624 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5625 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
5626 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5628 SetLastError(0xdeadbeef);
5629 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
, &info
,
5630 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5631 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
5632 GetLastError() == OSS_LIMITED
/* Win9x */),
5633 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5634 info
.pszObjId
= oid1
;
5635 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
, &info
,
5636 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5637 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5640 ok(size
== sizeof(emptyPKCSContentInfo
), "Unexpected size %d\n", size
);
5641 ok(!memcmp(buf
, emptyPKCSContentInfo
, size
), "Unexpected value\n");
5644 info
.Content
.pbData
= bogusDER
;
5645 info
.Content
.cbData
= sizeof(bogusDER
);
5646 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
, &info
,
5647 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5648 ok(ret
, "CryptEncodeObjectEx failed; %x\n", GetLastError());
5651 ok(size
== sizeof(bogusPKCSContentInfo
), "Unexpected size %d\n", size
);
5652 ok(!memcmp(buf
, bogusPKCSContentInfo
, size
), "Unexpected value\n");
5655 info
.Content
.pbData
= (BYTE
*)ints
[0].encoded
;
5656 info
.Content
.cbData
= ints
[0].encoded
[1] + 2;
5657 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
, &info
,
5658 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5661 ok(size
== sizeof(intPKCSContentInfo
), "Unexpected size %d\n", size
);
5662 ok(!memcmp(buf
, intPKCSContentInfo
, size
), "Unexpected value\n");
5667 static const BYTE indefiniteSignedPKCSContent
[] = {
5668 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
5669 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
5670 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
5671 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
5672 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
5673 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
5674 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5675 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5676 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
5677 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5678 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5679 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
5680 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
5681 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
5682 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
5683 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
5684 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
5685 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
5686 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
5687 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5688 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5689 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
5690 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
5691 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
5692 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
5693 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
5694 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
5695 0x00,0x00,0x00,0x00,0x00,0x00 };
5697 static void test_decodePKCSContentInfo(DWORD dwEncoding
)
5702 CRYPT_CONTENT_INFO
*info
;
5704 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
,
5705 emptyPKCSContentInfo
, sizeof(emptyPKCSContentInfo
),
5706 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5707 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5710 info
= (CRYPT_CONTENT_INFO
*)buf
;
5712 ok(!strcmp(info
->pszObjId
, "1.2.3"), "Expected 1.2.3, got %s\n",
5714 ok(info
->Content
.cbData
== 0, "Expected no data, got %d\n",
5715 info
->Content
.cbData
);
5718 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
,
5719 emptyPKCSContentInfoExtraBytes
, sizeof(emptyPKCSContentInfoExtraBytes
),
5720 0, NULL
, NULL
, &size
);
5721 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5722 SetLastError(0xdeadbeef);
5723 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
,
5724 bogusPKCSContentInfo
, sizeof(bogusPKCSContentInfo
),
5725 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5726 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5727 * I doubt an app depends on that.
5729 ok((!ret
&& (GetLastError() == CRYPT_E_ASN1_EOD
||
5730 GetLastError() == CRYPT_E_ASN1_CORRUPT
)) || broken(ret
),
5731 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5733 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
,
5734 intPKCSContentInfo
, sizeof(intPKCSContentInfo
),
5735 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5736 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5739 info
= (CRYPT_CONTENT_INFO
*)buf
;
5741 ok(!strcmp(info
->pszObjId
, "1.2.3"), "Expected 1.2.3, got %s\n",
5743 ok(info
->Content
.cbData
== ints
[0].encoded
[1] + 2,
5744 "Unexpected size %d\n", info
->Content
.cbData
);
5745 ok(!memcmp(info
->Content
.pbData
, ints
[0].encoded
,
5746 info
->Content
.cbData
), "Unexpected value\n");
5749 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
,
5750 indefiniteSignedPKCSContent
, sizeof(indefiniteSignedPKCSContent
),
5751 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5752 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5755 info
= (CRYPT_CONTENT_INFO
*)buf
;
5757 ok(!strcmp(info
->pszObjId
, szOID_RSA_signedData
),
5758 "Expected %s, got %s\n", szOID_RSA_signedData
, info
->pszObjId
);
5759 ok(info
->Content
.cbData
== 392, "Expected 392, got %d\n",
5760 info
->Content
.cbData
);
5765 static const BYTE emptyPKCSAttr
[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
5767 static const BYTE bogusPKCSAttr
[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
5769 static const BYTE intPKCSAttr
[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
5772 static void test_encodePKCSAttribute(DWORD dwEncoding
)
5774 CRYPT_ATTRIBUTE attr
= { 0 };
5778 CRYPT_ATTR_BLOB blob
;
5779 char oid
[] = "1.2.3";
5783 /* Crashes on win9x */
5784 SetLastError(0xdeadbeef);
5785 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
, NULL
,
5786 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5787 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
5788 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5790 SetLastError(0xdeadbeef);
5791 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
, &attr
,
5792 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5793 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
5794 GetLastError() == OSS_LIMITED
/* Win9x */),
5795 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5796 attr
.pszObjId
= oid
;
5797 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
, &attr
,
5798 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5799 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5802 ok(size
== sizeof(emptyPKCSAttr
), "Unexpected size %d\n", size
);
5803 ok(!memcmp(buf
, emptyPKCSAttr
, size
), "Unexpected value\n");
5806 blob
.cbData
= sizeof(bogusDER
);
5807 blob
.pbData
= bogusDER
;
5809 attr
.rgValue
= &blob
;
5810 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
, &attr
,
5811 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5812 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5815 ok(size
== sizeof(bogusPKCSAttr
), "Unexpected size %d\n", size
);
5816 ok(!memcmp(buf
, bogusPKCSAttr
, size
), "Unexpected value\n");
5819 blob
.pbData
= (BYTE
*)ints
[0].encoded
;
5820 blob
.cbData
= ints
[0].encoded
[1] + 2;
5821 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
, &attr
,
5822 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5825 ok(size
== sizeof(intPKCSAttr
), "Unexpected size %d\n", size
);
5826 ok(!memcmp(buf
, intPKCSAttr
, size
), "Unexpected value\n");
5831 static void test_decodePKCSAttribute(DWORD dwEncoding
)
5836 CRYPT_ATTRIBUTE
*attr
;
5838 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
,
5839 emptyPKCSAttr
, sizeof(emptyPKCSAttr
),
5840 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5841 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5844 attr
= (CRYPT_ATTRIBUTE
*)buf
;
5846 ok(!strcmp(attr
->pszObjId
, "1.2.3"), "Expected 1.2.3, got %s\n",
5848 ok(attr
->cValue
== 0, "Expected no value, got %d\n", attr
->cValue
);
5851 SetLastError(0xdeadbeef);
5852 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
,
5853 bogusPKCSAttr
, sizeof(bogusPKCSAttr
),
5854 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5855 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5856 * I doubt an app depends on that.
5858 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_EOD
||
5859 GetLastError() == CRYPT_E_ASN1_CORRUPT
|| OSS_MORE_INPUT
/* Win9x */),
5860 "Expected CRYPT_E_ASN1_EOD, CRYPT_E_ASN1_CORRUPT, or OSS_MORE_INPUT, got %x\n",
5862 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
,
5863 intPKCSAttr
, sizeof(intPKCSAttr
),
5864 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5865 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5868 attr
= (CRYPT_ATTRIBUTE
*)buf
;
5870 ok(!strcmp(attr
->pszObjId
, "1.2.3"), "Expected 1.2.3, got %s\n",
5872 ok(attr
->cValue
== 1, "Expected 1 value, got %d\n", attr
->cValue
);
5873 ok(attr
->rgValue
[0].cbData
== ints
[0].encoded
[1] + 2,
5874 "Unexpected size %d\n", attr
->rgValue
[0].cbData
);
5875 ok(!memcmp(attr
->rgValue
[0].pbData
, ints
[0].encoded
,
5876 attr
->rgValue
[0].cbData
), "Unexpected value\n");
5881 static const BYTE emptyPKCSAttributes
[] = { 0x31,0x00 };
5882 static const BYTE singlePKCSAttributes
[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
5883 0x2a,0x03,0x31,0x00 };
5884 static const BYTE doublePKCSAttributes
[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
5885 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
5887 static void test_encodePKCSAttributes(DWORD dwEncoding
)
5889 CRYPT_ATTRIBUTES attributes
= { 0 };
5890 CRYPT_ATTRIBUTE attr
[2] = { { 0 } };
5891 CRYPT_ATTR_BLOB blob
;
5895 char oid1
[] = "1.2.3", oid2
[] = "1.5.6";
5897 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
, &attributes
,
5898 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5899 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5902 ok(size
== sizeof(emptyPKCSAttributes
), "Unexpected size %d\n", size
);
5903 ok(!memcmp(buf
, emptyPKCSAttributes
, size
), "Unexpected value\n");
5906 attributes
.cAttr
= 1;
5907 attributes
.rgAttr
= attr
;
5908 SetLastError(0xdeadbeef);
5909 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
, &attributes
,
5910 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5911 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
5912 GetLastError() == OSS_LIMITED
/* Win9x */),
5913 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
5914 attr
[0].pszObjId
= oid1
;
5915 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
, &attributes
,
5916 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5919 ok(size
== sizeof(singlePKCSAttributes
), "Unexpected size %d\n", size
);
5920 ok(!memcmp(buf
, singlePKCSAttributes
, size
), "Unexpected value\n");
5923 attr
[1].pszObjId
= oid2
;
5925 attr
[1].rgValue
= &blob
;
5926 blob
.pbData
= (BYTE
*)ints
[0].encoded
;
5927 blob
.cbData
= ints
[0].encoded
[1] + 2;
5928 attributes
.cAttr
= 2;
5929 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
, &attributes
,
5930 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5931 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5934 ok(size
== sizeof(doublePKCSAttributes
), "Unexpected size %d\n", size
);
5935 ok(!memcmp(buf
, doublePKCSAttributes
, size
), "Unexpected value\n");
5940 static void test_decodePKCSAttributes(DWORD dwEncoding
)
5945 CRYPT_ATTRIBUTES
*attributes
;
5947 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
,
5948 emptyPKCSAttributes
, sizeof(emptyPKCSAttributes
),
5949 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5950 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5953 attributes
= (CRYPT_ATTRIBUTES
*)buf
;
5954 ok(attributes
->cAttr
== 0, "Expected no attributes, got %d\n",
5958 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
,
5959 singlePKCSAttributes
, sizeof(singlePKCSAttributes
),
5960 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5961 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5964 attributes
= (CRYPT_ATTRIBUTES
*)buf
;
5965 ok(attributes
->cAttr
== 1, "Expected 1 attribute, got %d\n",
5967 ok(!strcmp(attributes
->rgAttr
[0].pszObjId
, "1.2.3"),
5968 "Expected 1.2.3, got %s\n", attributes
->rgAttr
[0].pszObjId
);
5969 ok(attributes
->rgAttr
[0].cValue
== 0,
5970 "Expected no attributes, got %d\n", attributes
->rgAttr
[0].cValue
);
5973 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
,
5974 doublePKCSAttributes
, sizeof(doublePKCSAttributes
),
5975 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
5976 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5979 attributes
= (CRYPT_ATTRIBUTES
*)buf
;
5980 ok(attributes
->cAttr
== 2, "Expected 2 attributes, got %d\n",
5982 ok(!strcmp(attributes
->rgAttr
[0].pszObjId
, "1.2.3"),
5983 "Expected 1.2.3, got %s\n", attributes
->rgAttr
[0].pszObjId
);
5984 ok(attributes
->rgAttr
[0].cValue
== 0,
5985 "Expected no attributes, got %d\n", attributes
->rgAttr
[0].cValue
);
5986 ok(!strcmp(attributes
->rgAttr
[1].pszObjId
, "1.5.6"),
5987 "Expected 1.5.6, got %s\n", attributes
->rgAttr
[1].pszObjId
);
5988 ok(attributes
->rgAttr
[1].cValue
== 1,
5989 "Expected 1 attribute, got %d\n", attributes
->rgAttr
[1].cValue
);
5990 ok(attributes
->rgAttr
[1].rgValue
[0].cbData
== ints
[0].encoded
[1] + 2,
5991 "Unexpected size %d\n", attributes
->rgAttr
[1].rgValue
[0].cbData
);
5992 ok(!memcmp(attributes
->rgAttr
[1].rgValue
[0].pbData
, ints
[0].encoded
,
5993 attributes
->rgAttr
[1].rgValue
[0].cbData
), "Unexpected value\n");
5998 static const BYTE singleCapability
[] = {
5999 0x30,0x06,0x30,0x04,0x06,0x02,0x2d,0x06 };
6000 static const BYTE twoCapabilities
[] = {
6001 0x30,0x0c,0x30,0x04,0x06,0x02,0x2d,0x06,0x30,0x04,0x06,0x02,0x2a,0x03 };
6002 static const BYTE singleCapabilitywithNULL
[] = {
6003 0x30,0x08,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
6005 static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding
)
6007 static char oid1
[] = "1.5.6", oid2
[] = "1.2.3";
6011 CRYPT_SMIME_CAPABILITY capability
[2];
6012 CRYPT_SMIME_CAPABILITIES capabilities
;
6014 /* An empty capabilities is allowed */
6015 capabilities
.cCapability
= 0;
6016 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6017 &capabilities
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6018 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6021 ok(size
== sizeof(emptySequence
), "unexpected size %d\n", size
);
6022 ok(!memcmp(buf
, emptySequence
, size
), "unexpected value\n");
6025 /* A non-empty capabilities with an empty capability (lacking an OID) is
6028 capability
[0].pszObjId
= NULL
;
6029 capability
[0].Parameters
.cbData
= 0;
6030 capabilities
.cCapability
= 1;
6031 capabilities
.rgCapability
= capability
;
6032 SetLastError(0xdeadbeef);
6033 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6034 &capabilities
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6035 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
6036 GetLastError() == OSS_LIMITED
/* Win9x */),
6037 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6038 capability
[0].pszObjId
= oid1
;
6039 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6040 &capabilities
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6041 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6044 ok(size
== sizeof(singleCapability
), "unexpected size %d\n", size
);
6045 ok(!memcmp(buf
, singleCapability
, size
), "unexpected value\n");
6048 capability
[1].pszObjId
= oid2
;
6049 capability
[1].Parameters
.cbData
= 0;
6050 capabilities
.cCapability
= 2;
6051 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6052 &capabilities
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6053 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6056 ok(size
== sizeof(twoCapabilities
), "unexpected size %d\n", size
);
6057 ok(!memcmp(buf
, twoCapabilities
, size
), "unexpected value\n");
6062 static void compareSMimeCapabilities(LPCSTR header
,
6063 const CRYPT_SMIME_CAPABILITIES
*expected
, const CRYPT_SMIME_CAPABILITIES
*got
)
6067 ok(got
->cCapability
== expected
->cCapability
,
6068 "%s: expected %d capabilities, got %d\n", header
, expected
->cCapability
,
6070 for (i
= 0; i
< expected
->cCapability
; i
++)
6072 ok(!strcmp(expected
->rgCapability
[i
].pszObjId
,
6073 got
->rgCapability
[i
].pszObjId
), "%s[%d]: expected %s, got %s\n",
6074 header
, i
, expected
->rgCapability
[i
].pszObjId
,
6075 got
->rgCapability
[i
].pszObjId
);
6076 ok(expected
->rgCapability
[i
].Parameters
.cbData
==
6077 got
->rgCapability
[i
].Parameters
.cbData
,
6078 "%s[%d]: expected %d bytes, got %d\n", header
, i
,
6079 expected
->rgCapability
[i
].Parameters
.cbData
,
6080 got
->rgCapability
[i
].Parameters
.cbData
);
6081 if (expected
->rgCapability
[i
].Parameters
.cbData
)
6082 ok(!memcmp(expected
->rgCapability
[i
].Parameters
.pbData
,
6083 got
->rgCapability
[i
].Parameters
.pbData
,
6084 expected
->rgCapability
[i
].Parameters
.cbData
),
6085 "%s[%d]: unexpected value\n", header
, i
);
6089 static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding
)
6091 static char oid1
[] = "1.5.6", oid2
[] = "1.2.3";
6094 CRYPT_SMIME_CAPABILITY capability
[2];
6095 CRYPT_SMIME_CAPABILITIES capabilities
, *ptr
;
6097 SetLastError(0xdeadbeef);
6098 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6099 emptySequence
, sizeof(emptySequence
),
6100 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&ptr
, &size
);
6101 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6104 capabilities
.cCapability
= 0;
6105 compareSMimeCapabilities("empty capabilities", &capabilities
, ptr
);
6108 SetLastError(0xdeadbeef);
6109 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6110 singleCapability
, sizeof(singleCapability
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
6111 (BYTE
*)&ptr
, &size
);
6112 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6115 capability
[0].pszObjId
= oid1
;
6116 capability
[0].Parameters
.cbData
= 0;
6117 capabilities
.cCapability
= 1;
6118 capabilities
.rgCapability
= capability
;
6119 compareSMimeCapabilities("single capability", &capabilities
, ptr
);
6122 SetLastError(0xdeadbeef);
6123 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6124 singleCapabilitywithNULL
, sizeof(singleCapabilitywithNULL
),
6125 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&ptr
, &size
);
6126 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6129 BYTE NULLparam
[] = {0x05, 0x00};
6130 capability
[0].pszObjId
= oid1
;
6131 capability
[0].Parameters
.cbData
= 2;
6132 capability
[0].Parameters
.pbData
= NULLparam
;
6133 capabilities
.cCapability
= 1;
6134 capabilities
.rgCapability
= capability
;
6135 compareSMimeCapabilities("single capability with NULL", &capabilities
,
6139 SetLastError(0xdeadbeef);
6140 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6141 twoCapabilities
, sizeof(twoCapabilities
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
6142 (BYTE
*)&ptr
, &size
);
6143 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6146 capability
[0].Parameters
.cbData
= 0;
6147 capability
[1].pszObjId
= oid2
;
6148 capability
[1].Parameters
.cbData
= 0;
6149 capabilities
.cCapability
= 2;
6150 compareSMimeCapabilities("two capabilities", &capabilities
, ptr
);
6155 static BYTE encodedCommonNameNoNull
[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
6156 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
6158 static const BYTE minimalPKCSSigner
[] = {
6159 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6160 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6161 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6162 static const BYTE PKCSSignerWithSerial
[] = {
6163 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6164 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6165 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
6167 static const BYTE PKCSSignerWithHashAlgo
[] = {
6168 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6169 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6170 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
6172 static const BYTE PKCSSignerWithHashAndEncryptionAlgo
[] = {
6173 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6174 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6175 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6176 0x06,0x05,0x00,0x04,0x00 };
6177 static const BYTE PKCSSignerWithHash
[] = {
6178 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6179 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6180 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6181 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
6182 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6183 static const BYTE PKCSSignerWithAuthAttr
[] = {
6184 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6185 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6186 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
6187 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
6188 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
6189 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
6190 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6192 static void test_encodePKCSSignerInfo(DWORD dwEncoding
)
6194 static char oid1
[] = "1.2.3", oid2
[] = "1.5.6";
6198 CMSG_SIGNER_INFO info
= { 0 };
6199 char oid_common_name
[] = szOID_COMMON_NAME
;
6200 CRYPT_ATTR_BLOB commonName
= { sizeof(encodedCommonName
),
6201 (LPBYTE
)encodedCommonName
};
6202 CRYPT_ATTRIBUTE attr
= { oid_common_name
, 1, &commonName
};
6204 SetLastError(0xdeadbeef);
6205 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6206 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6207 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
6209 skip("no PKCS7_SIGNER_INFO encode support\n");
6212 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
6213 GetLastError() == OSS_LIMITED
/* Win9x */),
6214 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6215 /* To be encoded, a signer must have an issuer at least, and the encoding
6216 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
6217 * see decoding tests.)
6219 info
.Issuer
.cbData
= sizeof(encodedCommonNameNoNull
);
6220 info
.Issuer
.pbData
= encodedCommonNameNoNull
;
6221 SetLastError(0xdeadbeef);
6222 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6223 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6224 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6225 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6226 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6229 ok(ret
|| broken(GetLastError() == OSS_LIMITED
/* Win9x */),
6230 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6233 ok(size
== sizeof(minimalPKCSSigner
), "Unexpected size %d\n", size
);
6234 if (size
== sizeof(minimalPKCSSigner
))
6235 ok(!memcmp(buf
, minimalPKCSSigner
, size
), "Unexpected value\n");
6237 ok(0, "Unexpected value\n");
6241 info
.SerialNumber
.cbData
= sizeof(serialNum
);
6242 info
.SerialNumber
.pbData
= (BYTE
*)serialNum
;
6243 SetLastError(0xdeadbeef);
6244 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6245 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6246 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6247 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6248 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6251 ok(ret
|| broken(GetLastError() == OSS_LIMITED
/* Win9x */),
6252 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6255 ok(size
== sizeof(PKCSSignerWithSerial
), "Unexpected size %d\n",
6257 if (size
== sizeof(PKCSSignerWithSerial
))
6258 ok(!memcmp(buf
, PKCSSignerWithSerial
, size
),
6259 "Unexpected value\n");
6261 ok(0, "Unexpected value\n");
6265 info
.HashAlgorithm
.pszObjId
= oid1
;
6266 SetLastError(0xdeadbeef);
6267 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6268 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6269 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6270 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6271 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6274 ok(ret
|| broken(GetLastError() == OSS_LIMITED
/* Win9x */),
6275 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6278 ok(size
== sizeof(PKCSSignerWithHashAlgo
), "Unexpected size %d\n",
6280 if (size
== sizeof(PKCSSignerWithHashAlgo
))
6281 ok(!memcmp(buf
, PKCSSignerWithHashAlgo
, size
),
6282 "Unexpected value\n");
6284 ok(0, "Unexpected value\n");
6288 info
.HashEncryptionAlgorithm
.pszObjId
= oid2
;
6289 SetLastError(0xdeadbeef);
6290 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6291 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6292 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6293 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6294 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6297 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6300 ok(size
== sizeof(PKCSSignerWithHashAndEncryptionAlgo
),
6301 "Unexpected size %d\n", size
);
6302 if (size
== sizeof(PKCSSignerWithHashAndEncryptionAlgo
))
6303 ok(!memcmp(buf
, PKCSSignerWithHashAndEncryptionAlgo
, size
),
6304 "Unexpected value\n");
6306 ok(0, "Unexpected value\n");
6310 info
.EncryptedHash
.cbData
= sizeof(hash
);
6311 info
.EncryptedHash
.pbData
= (BYTE
*)hash
;
6312 SetLastError(0xdeadbeef);
6313 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6314 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6315 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6316 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6317 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6320 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6323 ok(size
== sizeof(PKCSSignerWithHash
), "Unexpected size %d\n",
6325 if (size
== sizeof(PKCSSignerWithHash
))
6326 ok(!memcmp(buf
, PKCSSignerWithHash
, size
),
6327 "Unexpected value\n");
6329 ok(0, "Unexpected value\n");
6333 info
.AuthAttrs
.cAttr
= 1;
6334 info
.AuthAttrs
.rgAttr
= &attr
;
6335 SetLastError(0xdeadbeef);
6336 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6337 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6338 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6339 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6340 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6343 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6346 ok(size
== sizeof(PKCSSignerWithAuthAttr
), "Unexpected size %d\n",
6348 if (size
== sizeof(PKCSSignerWithAuthAttr
))
6349 ok(!memcmp(buf
, PKCSSignerWithAuthAttr
, size
),
6350 "Unexpected value\n");
6352 ok(0, "Unexpected value\n");
6358 static void test_decodePKCSSignerInfo(DWORD dwEncoding
)
6363 CMSG_SIGNER_INFO
*info
;
6365 /* A PKCS signer can't be decoded without a serial number. */
6366 SetLastError(0xdeadbeef);
6367 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
6368 minimalPKCSSigner
, sizeof(minimalPKCSSigner
),
6369 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6370 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
6371 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
6372 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %x\n",
6374 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
6375 PKCSSignerWithSerial
, sizeof(PKCSSignerWithSerial
),
6376 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6377 ok(ret
|| broken(GetLastError() == OSS_DATA_ERROR
),
6378 "CryptDecodeObjectEx failed: %x\n", GetLastError());
6381 info
= (CMSG_SIGNER_INFO
*)buf
;
6382 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6384 ok(info
->Issuer
.cbData
== sizeof(encodedCommonNameNoNull
),
6385 "Unexpected size %d\n", info
->Issuer
.cbData
);
6386 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonNameNoNull
,
6387 info
->Issuer
.cbData
), "Unexpected value\n");
6388 ok(info
->SerialNumber
.cbData
== sizeof(serialNum
),
6389 "Unexpected size %d\n", info
->SerialNumber
.cbData
);
6390 ok(!memcmp(info
->SerialNumber
.pbData
, serialNum
, sizeof(serialNum
)),
6391 "Unexpected value\n");
6394 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
6395 PKCSSignerWithHashAlgo
, sizeof(PKCSSignerWithHashAlgo
),
6396 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6399 info
= (CMSG_SIGNER_INFO
*)buf
;
6400 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6402 ok(info
->Issuer
.cbData
== sizeof(encodedCommonNameNoNull
),
6403 "Unexpected size %d\n", info
->Issuer
.cbData
);
6404 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonNameNoNull
,
6405 info
->Issuer
.cbData
), "Unexpected value\n");
6406 ok(info
->SerialNumber
.cbData
== sizeof(serialNum
),
6407 "Unexpected size %d\n", info
->SerialNumber
.cbData
);
6408 ok(!memcmp(info
->SerialNumber
.pbData
, serialNum
, sizeof(serialNum
)),
6409 "Unexpected value\n");
6410 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, "1.2.3"),
6411 "Expected 1.2.3, got %s\n", info
->HashAlgorithm
.pszObjId
);
6414 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
6415 PKCSSignerWithHashAndEncryptionAlgo
,
6416 sizeof(PKCSSignerWithHashAndEncryptionAlgo
), CRYPT_DECODE_ALLOC_FLAG
,
6417 NULL
, (BYTE
*)&buf
, &size
);
6420 info
= (CMSG_SIGNER_INFO
*)buf
;
6421 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6423 ok(info
->Issuer
.cbData
== sizeof(encodedCommonNameNoNull
),
6424 "Unexpected size %d\n", info
->Issuer
.cbData
);
6425 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonNameNoNull
,
6426 info
->Issuer
.cbData
), "Unexpected value\n");
6427 ok(info
->SerialNumber
.cbData
== sizeof(serialNum
),
6428 "Unexpected size %d\n", info
->SerialNumber
.cbData
);
6429 ok(!memcmp(info
->SerialNumber
.pbData
, serialNum
, sizeof(serialNum
)),
6430 "Unexpected value\n");
6431 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, "1.2.3"),
6432 "Expected 1.2.3, got %s\n", info
->HashAlgorithm
.pszObjId
);
6433 ok(!strcmp(info
->HashEncryptionAlgorithm
.pszObjId
, "1.5.6"),
6434 "Expected 1.5.6, got %s\n", info
->HashEncryptionAlgorithm
.pszObjId
);
6437 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
6438 PKCSSignerWithHash
, sizeof(PKCSSignerWithHash
),
6439 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6442 info
= (CMSG_SIGNER_INFO
*)buf
;
6443 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6445 ok(info
->Issuer
.cbData
== sizeof(encodedCommonNameNoNull
),
6446 "Unexpected size %d\n", info
->Issuer
.cbData
);
6447 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonNameNoNull
,
6448 info
->Issuer
.cbData
), "Unexpected value\n");
6449 ok(info
->SerialNumber
.cbData
== sizeof(serialNum
),
6450 "Unexpected size %d\n", info
->SerialNumber
.cbData
);
6451 ok(!memcmp(info
->SerialNumber
.pbData
, serialNum
, sizeof(serialNum
)),
6452 "Unexpected value\n");
6453 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, "1.2.3"),
6454 "Expected 1.2.3, got %s\n", info
->HashAlgorithm
.pszObjId
);
6455 ok(!strcmp(info
->HashEncryptionAlgorithm
.pszObjId
, "1.5.6"),
6456 "Expected 1.5.6, got %s\n", info
->HashEncryptionAlgorithm
.pszObjId
);
6457 ok(info
->EncryptedHash
.cbData
== sizeof(hash
), "Unexpected size %d\n",
6458 info
->EncryptedHash
.cbData
);
6459 ok(!memcmp(info
->EncryptedHash
.pbData
, hash
, sizeof(hash
)),
6460 "Unexpected value\n");
6463 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
6464 PKCSSignerWithAuthAttr
, sizeof(PKCSSignerWithAuthAttr
),
6465 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6468 info
= (CMSG_SIGNER_INFO
*)buf
;
6469 ok(info
->AuthAttrs
.cAttr
== 1, "Expected 1 attribute, got %d\n",
6470 info
->AuthAttrs
.cAttr
);
6471 ok(!strcmp(info
->AuthAttrs
.rgAttr
[0].pszObjId
, szOID_COMMON_NAME
),
6472 "Expected %s, got %s\n", szOID_COMMON_NAME
,
6473 info
->AuthAttrs
.rgAttr
[0].pszObjId
);
6474 ok(info
->AuthAttrs
.rgAttr
[0].cValue
== 1, "Expected 1 value, got %d\n",
6475 info
->AuthAttrs
.rgAttr
[0].cValue
);
6476 ok(info
->AuthAttrs
.rgAttr
[0].rgValue
[0].cbData
==
6477 sizeof(encodedCommonName
), "Unexpected size %d\n",
6478 info
->AuthAttrs
.rgAttr
[0].rgValue
[0].cbData
);
6479 ok(!memcmp(info
->AuthAttrs
.rgAttr
[0].rgValue
[0].pbData
,
6480 encodedCommonName
, sizeof(encodedCommonName
)), "Unexpected value\n");
6485 static const BYTE CMSSignerWithKeyId
[] = {
6486 0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,
6487 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6489 static void test_encodeCMSSignerInfo(DWORD dwEncoding
)
6494 CMSG_CMS_SIGNER_INFO info
= { 0 };
6495 static char oid1
[] = "1.2.3", oid2
[] = "1.5.6";
6497 SetLastError(0xdeadbeef);
6498 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6499 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6500 ok(!ret
, "Expected failure, got %d\n", ret
);
6501 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
6503 skip("no CMS_SIGNER_INFO encode support\n");
6506 ok(GetLastError() == E_INVALIDARG
,
6507 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6508 info
.SignerId
.dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
6509 SetLastError(0xdeadbeef);
6510 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6511 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6512 ok(!ret
, "Expected failure, got %d\n", ret
);
6513 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
6515 skip("no CMS_SIGNER_INFO encode support\n");
6518 ok(GetLastError() == E_INVALIDARG
,
6519 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6520 /* To be encoded, a signer must have a valid cert ID, where a valid ID may
6521 * be a key id or a issuer serial number with at least the issuer set, and
6522 * the encoding must include PKCS_7_ASN_ENCODING.
6523 * (That isn't enough to be decoded, see decoding tests.)
6525 U(info
.SignerId
).IssuerSerialNumber
.Issuer
.cbData
=
6526 sizeof(encodedCommonNameNoNull
);
6527 U(info
.SignerId
).IssuerSerialNumber
.Issuer
.pbData
= encodedCommonNameNoNull
;
6528 SetLastError(0xdeadbeef);
6529 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6530 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6531 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6532 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6533 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6536 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6539 ok(size
== sizeof(minimalPKCSSigner
), "Unexpected size %d\n", size
);
6540 ok(!memcmp(buf
, minimalPKCSSigner
, size
), "Unexpected value\n");
6544 U(info
.SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
= sizeof(serialNum
);
6545 U(info
.SignerId
).IssuerSerialNumber
.SerialNumber
.pbData
= (BYTE
*)serialNum
;
6546 SetLastError(0xdeadbeef);
6547 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6548 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6549 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6550 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6551 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6554 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6557 ok(size
== sizeof(PKCSSignerWithSerial
), "Unexpected size %d\n",
6559 ok(!memcmp(buf
, PKCSSignerWithSerial
, size
), "Unexpected value\n");
6563 info
.SignerId
.dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
6564 U(info
.SignerId
).KeyId
.cbData
= sizeof(serialNum
);
6565 U(info
.SignerId
).KeyId
.pbData
= (BYTE
*)serialNum
;
6566 SetLastError(0xdeadbeef);
6567 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6568 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6569 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6570 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6571 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6574 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6577 ok(size
== sizeof(CMSSignerWithKeyId
), "Unexpected size %d\n",
6579 ok(!memcmp(buf
, CMSSignerWithKeyId
, size
), "Unexpected value\n");
6583 /* While a CERT_ID can have a hash type, that's not allowed in CMS, where
6584 * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed
6585 * (see RFC 3852, section 5.3.)
6587 info
.SignerId
.dwIdChoice
= CERT_ID_SHA1_HASH
;
6588 U(info
.SignerId
).HashId
.cbData
= sizeof(hash
);
6589 U(info
.SignerId
).HashId
.pbData
= (BYTE
*)hash
;
6590 SetLastError(0xdeadbeef);
6591 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6592 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6593 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6594 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6595 /* Now with a hash algo */
6596 info
.SignerId
.dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
6597 U(info
.SignerId
).IssuerSerialNumber
.Issuer
.cbData
=
6598 sizeof(encodedCommonNameNoNull
);
6599 U(info
.SignerId
).IssuerSerialNumber
.Issuer
.pbData
= encodedCommonNameNoNull
;
6600 info
.HashAlgorithm
.pszObjId
= oid1
;
6601 SetLastError(0xdeadbeef);
6602 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6603 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6604 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6605 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6606 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6609 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6612 ok(size
== sizeof(PKCSSignerWithHashAlgo
), "Unexpected size %d\n",
6614 ok(!memcmp(buf
, PKCSSignerWithHashAlgo
, size
),
6615 "Unexpected value\n");
6619 info
.HashEncryptionAlgorithm
.pszObjId
= oid2
;
6620 SetLastError(0xdeadbeef);
6621 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6622 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6623 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6624 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6625 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6628 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6631 ok(size
== sizeof(PKCSSignerWithHashAndEncryptionAlgo
),
6632 "Unexpected size %d\n", size
);
6633 ok(!memcmp(buf
, PKCSSignerWithHashAndEncryptionAlgo
, size
),
6634 "Unexpected value\n");
6638 info
.EncryptedHash
.cbData
= sizeof(hash
);
6639 info
.EncryptedHash
.pbData
= (BYTE
*)hash
;
6640 SetLastError(0xdeadbeef);
6641 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6642 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6643 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6644 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6645 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6648 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6651 ok(size
== sizeof(PKCSSignerWithHash
), "Unexpected size %d\n",
6653 ok(!memcmp(buf
, PKCSSignerWithHash
, size
), "Unexpected value\n");
6659 static void test_decodeCMSSignerInfo(DWORD dwEncoding
)
6664 CMSG_CMS_SIGNER_INFO
*info
;
6665 static char oid1
[] = "1.2.3", oid2
[] = "1.5.6";
6667 /* A CMS signer can't be decoded without a serial number. */
6668 SetLastError(0xdeadbeef);
6669 ret
= pCryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
6670 minimalPKCSSigner
, sizeof(minimalPKCSSigner
),
6671 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6672 ok(!ret
, "expected failure\n");
6673 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
6675 skip("no CMS_SIGNER_INFO decode support\n");
6678 ok(GetLastError() == CRYPT_E_ASN1_CORRUPT
,
6679 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
6680 ret
= pCryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
6681 PKCSSignerWithSerial
, sizeof(PKCSSignerWithSerial
),
6682 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6683 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6686 info
= (CMSG_CMS_SIGNER_INFO
*)buf
;
6687 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6689 ok(info
->SignerId
.dwIdChoice
== CERT_ID_ISSUER_SERIAL_NUMBER
,
6690 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6691 info
->SignerId
.dwIdChoice
);
6692 ok(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
==
6693 sizeof(encodedCommonNameNoNull
), "Unexpected size %d\n",
6694 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
);
6695 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.pbData
,
6696 encodedCommonNameNoNull
,
6697 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
),
6698 "Unexpected value\n");
6699 ok(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
==
6700 sizeof(serialNum
), "Unexpected size %d\n",
6701 U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
);
6702 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.pbData
,
6703 serialNum
, sizeof(serialNum
)), "Unexpected value\n");
6706 ret
= pCryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
6707 PKCSSignerWithHashAlgo
, sizeof(PKCSSignerWithHashAlgo
),
6708 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6709 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6712 info
= (CMSG_CMS_SIGNER_INFO
*)buf
;
6713 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6715 ok(info
->SignerId
.dwIdChoice
== CERT_ID_ISSUER_SERIAL_NUMBER
,
6716 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6717 info
->SignerId
.dwIdChoice
);
6718 ok(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
==
6719 sizeof(encodedCommonNameNoNull
), "Unexpected size %d\n",
6720 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
);
6721 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.pbData
,
6722 encodedCommonNameNoNull
,
6723 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
),
6724 "Unexpected value\n");
6725 ok(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
==
6726 sizeof(serialNum
), "Unexpected size %d\n",
6727 U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
);
6728 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.pbData
,
6729 serialNum
, sizeof(serialNum
)), "Unexpected value\n");
6730 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, oid1
),
6731 "Expected %s, got %s\n", oid1
, info
->HashAlgorithm
.pszObjId
);
6734 ret
= pCryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
6735 PKCSSignerWithHashAndEncryptionAlgo
,
6736 sizeof(PKCSSignerWithHashAndEncryptionAlgo
), CRYPT_DECODE_ALLOC_FLAG
,
6737 NULL
, (BYTE
*)&buf
, &size
);
6738 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6741 info
= (CMSG_CMS_SIGNER_INFO
*)buf
;
6742 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6744 ok(info
->SignerId
.dwIdChoice
== CERT_ID_ISSUER_SERIAL_NUMBER
,
6745 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6746 info
->SignerId
.dwIdChoice
);
6747 ok(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
==
6748 sizeof(encodedCommonNameNoNull
), "Unexpected size %d\n",
6749 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
);
6750 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.pbData
,
6751 encodedCommonNameNoNull
,
6752 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
),
6753 "Unexpected value\n");
6754 ok(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
==
6755 sizeof(serialNum
), "Unexpected size %d\n",
6756 U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
);
6757 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.pbData
,
6758 serialNum
, sizeof(serialNum
)), "Unexpected value\n");
6759 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, oid1
),
6760 "Expected %s, got %s\n", oid1
, info
->HashAlgorithm
.pszObjId
);
6761 ok(!strcmp(info
->HashEncryptionAlgorithm
.pszObjId
, oid2
),
6762 "Expected %s, got %s\n", oid2
, info
->HashEncryptionAlgorithm
.pszObjId
);
6765 ret
= pCryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
6766 PKCSSignerWithHash
, sizeof(PKCSSignerWithHash
),
6767 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6768 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6771 info
= (CMSG_CMS_SIGNER_INFO
*)buf
;
6772 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6774 ok(info
->SignerId
.dwIdChoice
== CERT_ID_ISSUER_SERIAL_NUMBER
,
6775 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6776 info
->SignerId
.dwIdChoice
);
6777 ok(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
==
6778 sizeof(encodedCommonNameNoNull
), "Unexpected size %d\n",
6779 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
);
6780 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.pbData
,
6781 encodedCommonNameNoNull
,
6782 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
),
6783 "Unexpected value\n");
6784 ok(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
==
6785 sizeof(serialNum
), "Unexpected size %d\n",
6786 U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
);
6787 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.pbData
,
6788 serialNum
, sizeof(serialNum
)), "Unexpected value\n");
6789 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, oid1
),
6790 "Expected %s, got %s\n", oid1
, info
->HashAlgorithm
.pszObjId
);
6791 ok(!strcmp(info
->HashEncryptionAlgorithm
.pszObjId
, oid2
),
6792 "Expected %s, got %s\n", oid2
, info
->HashEncryptionAlgorithm
.pszObjId
);
6793 ok(info
->EncryptedHash
.cbData
== sizeof(hash
), "Unexpected size %d\n",
6794 info
->EncryptedHash
.cbData
);
6795 ok(!memcmp(info
->EncryptedHash
.pbData
, hash
, sizeof(hash
)),
6796 "Unexpected value\n");
6799 ret
= pCryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
6800 CMSSignerWithKeyId
, sizeof(CMSSignerWithKeyId
),
6801 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6802 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6805 info
= (CMSG_CMS_SIGNER_INFO
*)buf
;
6806 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6808 ok(info
->SignerId
.dwIdChoice
== CERT_ID_KEY_IDENTIFIER
,
6809 "Expected CERT_ID_KEY_IDENTIFIER, got %d\n",
6810 info
->SignerId
.dwIdChoice
);
6811 ok(U(info
->SignerId
).KeyId
.cbData
== sizeof(serialNum
),
6812 "Unexpected size %d\n", U(info
->SignerId
).KeyId
.cbData
);
6813 ok(!memcmp(U(info
->SignerId
).KeyId
.pbData
, serialNum
, sizeof(serialNum
)),
6814 "Unexpected value\n");
6819 static BYTE emptyDNSPermittedConstraints
[] = {
6820 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
6821 static BYTE emptyDNSExcludedConstraints
[] = {
6822 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
6823 static BYTE DNSExcludedConstraints
[] = {
6824 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
6825 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6826 static BYTE permittedAndExcludedConstraints
[] = {
6827 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6828 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
6829 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6830 static BYTE permittedAndExcludedWithMinConstraints
[] = {
6831 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6832 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
6833 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6834 static BYTE permittedAndExcludedWithMinMaxConstraints
[] = {
6835 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6836 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
6837 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6839 static void test_encodeNameConstraints(DWORD dwEncoding
)
6842 CERT_NAME_CONSTRAINTS_INFO constraints
= { 0 };
6843 CERT_GENERAL_SUBTREE permitted
= { { 0 } };
6844 CERT_GENERAL_SUBTREE excluded
= { { 0 } };
6848 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
6849 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6850 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
6852 skip("no X509_NAME_CONSTRAINTS encode support\n");
6855 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6858 ok(size
== sizeof(emptySequence
), "Unexpected size\n");
6859 ok(!memcmp(buf
, emptySequence
, size
), "Unexpected value\n");
6862 constraints
.cPermittedSubtree
= 1;
6863 constraints
.rgPermittedSubtree
= &permitted
;
6864 SetLastError(0xdeadbeef);
6865 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
6866 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6867 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6868 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6869 permitted
.Base
.dwAltNameChoice
= CERT_ALT_NAME_DNS_NAME
;
6870 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
6871 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6872 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6875 ok(size
== sizeof(emptyDNSPermittedConstraints
), "Unexpected size\n");
6876 ok(!memcmp(buf
, emptyDNSPermittedConstraints
, size
),
6877 "Unexpected value\n");
6880 constraints
.cPermittedSubtree
= 0;
6881 constraints
.cExcludedSubtree
= 1;
6882 constraints
.rgExcludedSubtree
= &excluded
;
6883 excluded
.Base
.dwAltNameChoice
= CERT_ALT_NAME_DNS_NAME
;
6884 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
6885 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6886 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6889 ok(size
== sizeof(emptyDNSExcludedConstraints
), "Unexpected size\n");
6890 ok(!memcmp(buf
, emptyDNSExcludedConstraints
, size
),
6891 "Unexpected value\n");
6894 U(excluded
.Base
).pwszURL
= (LPWSTR
)url
;
6895 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
6896 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6897 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6900 ok(size
== sizeof(DNSExcludedConstraints
), "Unexpected size\n");
6901 ok(!memcmp(buf
, DNSExcludedConstraints
, size
),
6902 "Unexpected value\n");
6905 permitted
.Base
.dwAltNameChoice
= CERT_ALT_NAME_IP_ADDRESS
;
6906 U(permitted
.Base
).IPAddress
.cbData
= sizeof(encodedIPAddr
);
6907 U(permitted
.Base
).IPAddress
.pbData
= (LPBYTE
)encodedIPAddr
;
6908 constraints
.cPermittedSubtree
= 1;
6909 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
6910 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6911 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6914 ok(size
== sizeof(permittedAndExcludedConstraints
),
6915 "Unexpected size\n");
6916 ok(!memcmp(buf
, permittedAndExcludedConstraints
, size
),
6917 "Unexpected value\n");
6920 permitted
.dwMinimum
= 5;
6921 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
6922 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6923 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6926 ok(size
== sizeof(permittedAndExcludedWithMinConstraints
),
6927 "Unexpected size\n");
6928 ok(!memcmp(buf
, permittedAndExcludedWithMinConstraints
, size
),
6929 "Unexpected value\n");
6932 permitted
.fMaximum
= TRUE
;
6933 permitted
.dwMaximum
= 3;
6934 SetLastError(0xdeadbeef);
6935 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
6936 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
6937 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6940 ok(size
== sizeof(permittedAndExcludedWithMinMaxConstraints
),
6941 "Unexpected size\n");
6942 ok(!memcmp(buf
, permittedAndExcludedWithMinMaxConstraints
, size
),
6943 "Unexpected value\n");
6948 struct EncodedNameConstraints
6950 CRYPT_DATA_BLOB encoded
;
6951 CERT_NAME_CONSTRAINTS_INFO constraints
;
6954 static CERT_GENERAL_SUBTREE emptyDNSSubtree
= {
6955 { CERT_ALT_NAME_DNS_NAME
, { 0 } }, 0 };
6956 static CERT_GENERAL_SUBTREE DNSSubtree
= {
6957 { CERT_ALT_NAME_DNS_NAME
, { 0 } }, 0 };
6958 static CERT_GENERAL_SUBTREE IPAddressSubtree
= {
6959 { CERT_ALT_NAME_IP_ADDRESS
, { 0 } }, 0 };
6960 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree
= {
6961 { CERT_ALT_NAME_IP_ADDRESS
, { 0 } }, 5, 0 };
6962 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree
= {
6963 { CERT_ALT_NAME_IP_ADDRESS
, { 0 } }, 5, TRUE
, 3 };
6965 struct EncodedNameConstraints encodedNameConstraints
[] = {
6966 { { sizeof(emptySequence
), (LPBYTE
)emptySequence
}, { 0 } },
6967 { { sizeof(emptyDNSPermittedConstraints
), emptyDNSPermittedConstraints
},
6968 { 1, &emptyDNSSubtree
, 0, NULL
} },
6969 { { sizeof(emptyDNSExcludedConstraints
), emptyDNSExcludedConstraints
},
6970 { 0, NULL
, 1, &emptyDNSSubtree
} },
6971 { { sizeof(DNSExcludedConstraints
), DNSExcludedConstraints
},
6972 { 0, NULL
, 1, &DNSSubtree
} },
6973 { { sizeof(permittedAndExcludedConstraints
), permittedAndExcludedConstraints
},
6974 { 1, &IPAddressSubtree
, 1, &DNSSubtree
} },
6975 { { sizeof(permittedAndExcludedWithMinConstraints
),
6976 permittedAndExcludedWithMinConstraints
},
6977 { 1, &IPAddressWithMinSubtree
, 1, &DNSSubtree
} },
6978 { { sizeof(permittedAndExcludedWithMinMaxConstraints
),
6979 permittedAndExcludedWithMinMaxConstraints
},
6980 { 1, &IPAddressWithMinMaxSubtree
, 1, &DNSSubtree
} },
6983 static void test_decodeNameConstraints(DWORD dwEncoding
)
6987 CERT_NAME_CONSTRAINTS_INFO
*constraints
;
6989 U(DNSSubtree
.Base
).pwszURL
= (LPWSTR
)url
;
6990 U(IPAddressSubtree
.Base
).IPAddress
.cbData
= sizeof(encodedIPAddr
);
6991 U(IPAddressSubtree
.Base
).IPAddress
.pbData
= (LPBYTE
)encodedIPAddr
;
6992 U(IPAddressWithMinSubtree
.Base
).IPAddress
.cbData
= sizeof(encodedIPAddr
);
6993 U(IPAddressWithMinSubtree
.Base
).IPAddress
.pbData
= (LPBYTE
)encodedIPAddr
;
6994 U(IPAddressWithMinMaxSubtree
.Base
).IPAddress
.cbData
= sizeof(encodedIPAddr
);
6995 U(IPAddressWithMinMaxSubtree
.Base
).IPAddress
.pbData
= (LPBYTE
)encodedIPAddr
;
6997 i
< sizeof(encodedNameConstraints
) / sizeof(encodedNameConstraints
[0]);
7002 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
,
7003 encodedNameConstraints
[i
].encoded
.pbData
,
7004 encodedNameConstraints
[i
].encoded
.cbData
,
7005 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &constraints
, &size
);
7006 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7008 skip("no X509_NAME_CONSTRAINTS decode support\n");
7011 ok(ret
, "%d: CryptDecodeObjectEx failed: %08x\n", i
, GetLastError());
7016 if (constraints
->cPermittedSubtree
!=
7017 encodedNameConstraints
[i
].constraints
.cPermittedSubtree
)
7018 fprintf(stderr
, "%d: expected %d permitted, got %d\n", i
,
7019 encodedNameConstraints
[i
].constraints
.cPermittedSubtree
,
7020 constraints
->cPermittedSubtree
);
7021 if (constraints
->cPermittedSubtree
==
7022 encodedNameConstraints
[i
].constraints
.cPermittedSubtree
)
7024 for (j
= 0; j
< constraints
->cPermittedSubtree
; j
++)
7026 compareAltNameEntry(&constraints
->rgPermittedSubtree
[j
].Base
,
7027 &encodedNameConstraints
[i
].constraints
.rgPermittedSubtree
[j
].Base
);
7030 if (constraints
->cExcludedSubtree
!=
7031 encodedNameConstraints
[i
].constraints
.cExcludedSubtree
)
7032 fprintf(stderr
, "%d: expected %d excluded, got %d\n", i
,
7033 encodedNameConstraints
[i
].constraints
.cExcludedSubtree
,
7034 constraints
->cExcludedSubtree
);
7035 if (constraints
->cExcludedSubtree
==
7036 encodedNameConstraints
[i
].constraints
.cExcludedSubtree
)
7038 for (j
= 0; j
< constraints
->cExcludedSubtree
; j
++)
7040 compareAltNameEntry(&constraints
->rgExcludedSubtree
[j
].Base
,
7041 &encodedNameConstraints
[i
].constraints
.rgExcludedSubtree
[j
].Base
);
7044 LocalFree(constraints
);
7049 static WCHAR noticeText
[] = { 'T','h','i','s',' ','i','s',' ','a',' ',
7050 'n','o','t','i','c','e',0 };
7051 static const BYTE noticeWithDisplayText
[] = {
7052 0x30,0x22,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,0x00,
7053 0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,0x74,
7054 0x00,0x69,0x00,0x63,0x00,0x65
7056 static char org
[] = "Wine";
7057 static int noticeNumbers
[] = { 2,3 };
7058 static BYTE noticeWithReference
[] = {
7059 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7060 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7061 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7062 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7065 static void test_encodePolicyQualifierUserNotice(DWORD dwEncoding
)
7070 CERT_POLICY_QUALIFIER_USER_NOTICE notice
;
7071 CERT_POLICY_QUALIFIER_NOTICE_REFERENCE reference
;
7073 memset(¬ice
, 0, sizeof(notice
));
7074 ret
= pCryptEncodeObjectEx(dwEncoding
,
7075 X509_PKIX_POLICY_QUALIFIER_USERNOTICE
, ¬ice
, CRYPT_ENCODE_ALLOC_FLAG
,
7077 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7079 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE encode support\n");
7082 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7085 ok(sizeof(emptySequence
) == size
, "unexpected size %d\n", size
);
7086 ok(!memcmp(buf
, emptySequence
, size
), "unexpected value\n");
7089 notice
.pszDisplayText
= noticeText
;
7090 ret
= pCryptEncodeObjectEx(dwEncoding
,
7091 X509_PKIX_POLICY_QUALIFIER_USERNOTICE
, ¬ice
, CRYPT_ENCODE_ALLOC_FLAG
,
7093 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7096 ok(sizeof(noticeWithDisplayText
) == size
, "unexpected size %d\n", size
);
7097 ok(!memcmp(buf
, noticeWithDisplayText
, size
), "unexpected value\n");
7100 reference
.pszOrganization
= org
;
7101 reference
.cNoticeNumbers
= 2;
7102 reference
.rgNoticeNumbers
= noticeNumbers
;
7103 notice
.pNoticeReference
= &reference
;
7104 ret
= pCryptEncodeObjectEx(dwEncoding
,
7105 X509_PKIX_POLICY_QUALIFIER_USERNOTICE
, ¬ice
, CRYPT_ENCODE_ALLOC_FLAG
,
7107 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7110 ok(sizeof(noticeWithReference
) == size
, "unexpected size %d\n", size
);
7111 ok(!memcmp(buf
, noticeWithReference
, size
), "unexpected value\n");
7116 static void test_decodePolicyQualifierUserNotice(DWORD dwEncoding
)
7119 CERT_POLICY_QUALIFIER_USER_NOTICE
*notice
;
7122 ret
= pCryptDecodeObjectEx(dwEncoding
,
7123 X509_PKIX_POLICY_QUALIFIER_USERNOTICE
,
7124 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
7126 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7128 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE decode support\n");
7131 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7134 ok(notice
->pszDisplayText
== NULL
, "unexpected display text\n");
7135 ok(notice
->pNoticeReference
== NULL
, "unexpected notice reference\n");
7138 ret
= pCryptDecodeObjectEx(dwEncoding
,
7139 X509_PKIX_POLICY_QUALIFIER_USERNOTICE
,
7140 noticeWithDisplayText
, sizeof(noticeWithDisplayText
),
7141 CRYPT_DECODE_ALLOC_FLAG
, NULL
, ¬ice
, &size
);
7142 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7145 ok(!lstrcmpW(notice
->pszDisplayText
, noticeText
),
7146 "unexpected display text\n");
7147 ok(notice
->pNoticeReference
== NULL
, "unexpected notice reference\n");
7150 ret
= pCryptDecodeObjectEx(dwEncoding
,
7151 X509_PKIX_POLICY_QUALIFIER_USERNOTICE
,
7152 noticeWithReference
, sizeof(noticeWithReference
),
7153 CRYPT_DECODE_ALLOC_FLAG
, NULL
, ¬ice
, &size
);
7154 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7157 ok(!lstrcmpW(notice
->pszDisplayText
, noticeText
),
7158 "unexpected display text\n");
7159 ok(notice
->pNoticeReference
!= NULL
, "expected a notice reference\n");
7160 if (notice
->pNoticeReference
)
7162 ok(!strcmp(notice
->pNoticeReference
->pszOrganization
, org
),
7163 "unexpected organization %s\n",
7164 notice
->pNoticeReference
->pszOrganization
);
7165 ok(notice
->pNoticeReference
->cNoticeNumbers
== 2,
7166 "expected 2 notice numbers, got %d\n",
7167 notice
->pNoticeReference
->cNoticeNumbers
);
7168 ok(notice
->pNoticeReference
->rgNoticeNumbers
[0] == noticeNumbers
[0],
7169 "unexpected notice number %d\n",
7170 notice
->pNoticeReference
->rgNoticeNumbers
[0]);
7171 ok(notice
->pNoticeReference
->rgNoticeNumbers
[1] == noticeNumbers
[1],
7172 "unexpected notice number %d\n",
7173 notice
->pNoticeReference
->rgNoticeNumbers
[1]);
7179 static char oid_any_policy
[] = "2.5.29.32.0";
7180 static const BYTE policiesWithAnyPolicy
[] = {
7181 0x30,0x08,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00
7183 static char oid1
[] = "1.2.3";
7184 static char oid_user_notice
[] = "1.3.6.1.5.5.7.2.2";
7185 static const BYTE twoPolicies
[] = {
7186 0x30,0x50,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00,0x30,0x46,0x06,0x02,0x2a,
7187 0x03,0x30,0x40,0x30,0x3e,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x02,
7188 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7189 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7190 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7191 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7194 static void test_encodeCertPolicies(DWORD dwEncoding
)
7197 CERT_POLICIES_INFO info
;
7198 CERT_POLICY_INFO policy
[2];
7199 CERT_POLICY_QUALIFIER_INFO qualifier
;
7203 memset(&info
, 0, sizeof(info
));
7204 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_POLICIES
, &info
,
7205 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7206 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7209 ok(sizeof(emptySequence
) == size
, "unexpected size %d\n", size
);
7210 ok(!memcmp(buf
, emptySequence
, size
), "unexpected value\n");
7213 memset(policy
, 0, sizeof(policy
));
7214 info
.cPolicyInfo
= 1;
7215 info
.rgPolicyInfo
= policy
;
7216 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_POLICIES
, &info
,
7217 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7218 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
7219 GetLastError() == OSS_LIMITED
/* Win9x/NT4 */),
7220 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
7221 policy
[0].pszPolicyIdentifier
= oid_any_policy
;
7222 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_POLICIES
, &info
,
7223 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7224 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7227 ok(sizeof(policiesWithAnyPolicy
) == size
, "unexpected size %d\n", size
);
7228 ok(!memcmp(buf
, policiesWithAnyPolicy
, size
), "unexpected value\n");
7231 policy
[1].pszPolicyIdentifier
= oid1
;
7232 memset(&qualifier
, 0, sizeof(qualifier
));
7233 qualifier
.pszPolicyQualifierId
= oid_user_notice
;
7234 qualifier
.Qualifier
.cbData
= sizeof(noticeWithReference
);
7235 qualifier
.Qualifier
.pbData
= noticeWithReference
;
7236 policy
[1].cPolicyQualifier
= 1;
7237 policy
[1].rgPolicyQualifier
= &qualifier
;
7238 info
.cPolicyInfo
= 2;
7239 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_POLICIES
, &info
,
7240 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7241 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7244 ok(sizeof(twoPolicies
) == size
, "unexpected size %d\n", size
);
7245 ok(!memcmp(buf
, twoPolicies
, size
), "unexpected value\n");
7250 static void test_decodeCertPolicies(DWORD dwEncoding
)
7253 CERT_POLICIES_INFO
*info
;
7256 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_POLICIES
,
7257 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
7259 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7262 ok(info
->cPolicyInfo
== 0, "unexpected policy info %d\n",
7266 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_POLICIES
,
7267 policiesWithAnyPolicy
, sizeof(policiesWithAnyPolicy
),
7268 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
);
7269 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7272 ok(info
->cPolicyInfo
== 1, "unexpected policy info %d\n",
7274 ok(!strcmp(info
->rgPolicyInfo
[0].pszPolicyIdentifier
, oid_any_policy
),
7275 "unexpected policy id %s\n",
7276 info
->rgPolicyInfo
[0].pszPolicyIdentifier
);
7277 ok(info
->rgPolicyInfo
[0].cPolicyQualifier
== 0,
7278 "unexpected policy qualifier count %d\n",
7279 info
->rgPolicyInfo
[0].cPolicyQualifier
);
7282 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_POLICIES
,
7283 twoPolicies
, sizeof(twoPolicies
),
7284 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
);
7285 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7288 ok(info
->cPolicyInfo
== 2, "unexpected policy info %d\n",
7290 ok(!strcmp(info
->rgPolicyInfo
[0].pszPolicyIdentifier
, oid_any_policy
),
7291 "unexpected policy id %s\n",
7292 info
->rgPolicyInfo
[0].pszPolicyIdentifier
);
7293 ok(info
->rgPolicyInfo
[0].cPolicyQualifier
== 0,
7294 "unexpected policy qualifier count %d\n",
7295 info
->rgPolicyInfo
[0].cPolicyQualifier
);
7296 ok(!strcmp(info
->rgPolicyInfo
[1].pszPolicyIdentifier
, oid1
),
7297 "unexpected policy id %s\n",
7298 info
->rgPolicyInfo
[1].pszPolicyIdentifier
);
7299 ok(info
->rgPolicyInfo
[1].cPolicyQualifier
== 1,
7300 "unexpected policy qualifier count %d\n",
7301 info
->rgPolicyInfo
[1].cPolicyQualifier
);
7303 info
->rgPolicyInfo
[1].rgPolicyQualifier
[0].pszPolicyQualifierId
,
7304 oid_user_notice
), "unexpected policy qualifier id %s\n",
7305 info
->rgPolicyInfo
[1].rgPolicyQualifier
[0].pszPolicyQualifierId
);
7306 ok(info
->rgPolicyInfo
[1].rgPolicyQualifier
[0].Qualifier
.cbData
==
7307 sizeof(noticeWithReference
), "unexpected qualifier size %d\n",
7308 info
->rgPolicyInfo
[1].rgPolicyQualifier
[0].Qualifier
.cbData
);
7310 info
->rgPolicyInfo
[1].rgPolicyQualifier
[0].Qualifier
.pbData
,
7311 noticeWithReference
, sizeof(noticeWithReference
)),
7312 "unexpected qualifier value\n");
7317 /* Free *pInfo with HeapFree */
7318 static void testExportPublicKey(HCRYPTPROV csp
, PCERT_PUBLIC_KEY_INFO
*pInfo
)
7325 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
7327 ret
= CryptExportPublicKeyInfoEx(0, 0, 0, NULL
, 0, NULL
, NULL
, &size
);
7328 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
7329 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7330 ret
= CryptExportPublicKeyInfoEx(0, AT_SIGNATURE
, 0, NULL
, 0, NULL
, NULL
,
7332 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
7333 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7334 ret
= CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING
, NULL
, 0, NULL
,
7336 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
7337 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7338 ret
= CryptExportPublicKeyInfoEx(0, AT_SIGNATURE
, X509_ASN_ENCODING
, NULL
,
7339 0, NULL
, NULL
, &size
);
7340 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
7341 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7342 /* Test with no key */
7343 ret
= CryptExportPublicKeyInfoEx(csp
, AT_SIGNATURE
, X509_ASN_ENCODING
, NULL
,
7344 0, NULL
, NULL
, &size
);
7345 ok(!ret
&& GetLastError() == NTE_NO_KEY
, "Expected NTE_NO_KEY, got %08x\n",
7347 ret
= CryptGenKey(csp
, AT_SIGNATURE
, 0, &key
);
7348 ok(ret
, "CryptGenKey failed: %08x\n", GetLastError());
7351 ret
= CryptExportPublicKeyInfoEx(csp
, AT_SIGNATURE
, X509_ASN_ENCODING
,
7352 NULL
, 0, NULL
, NULL
, &size
);
7353 ok(ret
, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
7354 *pInfo
= HeapAlloc(GetProcessHeap(), 0, size
);
7357 ret
= CryptExportPublicKeyInfoEx(csp
, AT_SIGNATURE
,
7358 X509_ASN_ENCODING
, NULL
, 0, NULL
, *pInfo
, &size
);
7359 ok(ret
, "CryptExportPublicKeyInfoEx failed: %08x\n",
7363 /* By default (we passed NULL as the OID) the OID is
7366 ok(!strcmp((*pInfo
)->Algorithm
.pszObjId
, szOID_RSA_RSA
),
7367 "Expected %s, got %s\n", szOID_RSA_RSA
,
7368 (*pInfo
)->Algorithm
.pszObjId
);
7372 CryptDestroyKey(key
);
7375 static const BYTE expiredCert
[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
7376 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
7377 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
7378 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7379 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7380 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7381 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
7382 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
7383 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7384 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7385 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7386 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
7387 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
7388 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
7389 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
7390 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
7391 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
7392 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
7393 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
7394 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
7395 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
7396 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
7397 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
7398 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
7399 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
7401 static void testImportPublicKey(HCRYPTPROV csp
, PCERT_PUBLIC_KEY_INFO info
)
7405 PCCERT_CONTEXT context
;
7410 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
7411 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
7412 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
7413 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7416 ret
= CryptImportPublicKeyInfoEx(0, 0, info
, 0, 0, NULL
, &key
);
7417 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
7418 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7419 ret
= CryptImportPublicKeyInfoEx(csp
, 0, info
, 0, 0, NULL
, &key
);
7420 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
7421 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7422 ret
= CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING
, info
, 0, 0, NULL
,
7424 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
7425 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7427 /* Export key with standard algorithm (CALG_RSA_KEYX) */
7428 ret
= CryptImportPublicKeyInfoEx(csp
, X509_ASN_ENCODING
, info
, 0, 0, NULL
,
7430 ok(ret
, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7432 dwSize
= sizeof(ai
);
7433 CryptGetKeyParam(key
, KP_ALGID
, (LPVOID
)&ai
, &dwSize
, 0);
7434 ok(ret
, "CryptGetKeyParam failed: %08x\n", GetLastError());
7437 ok(dwSize
== sizeof(ai
), "CryptGetKeyParam returned size %d\n",dwSize
);
7438 ok(ai
== CALG_RSA_KEYX
, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai
);
7441 CryptDestroyKey(key
);
7443 /* Repeat with forced algorithm */
7444 ret
= CryptImportPublicKeyInfoEx(csp
, X509_ASN_ENCODING
, info
, CALG_RSA_SIGN
, 0, NULL
,
7446 ok(ret
, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7448 dwSize
= sizeof(ai
);
7449 CryptGetKeyParam(key
, KP_ALGID
, (LPVOID
)&ai
, &dwSize
, 0);
7450 ok(ret
, "CryptGetKeyParam failed: %08x\n", GetLastError());
7453 ok(dwSize
== sizeof(ai
), "CryptGetKeyParam returned size %d\n",dwSize
);
7454 ok(ai
== CALG_RSA_SIGN
, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai
);
7457 CryptDestroyKey(key
);
7459 /* Test importing a public key from a certificate context */
7460 context
= CertCreateCertificateContext(X509_ASN_ENCODING
, expiredCert
,
7461 sizeof(expiredCert
));
7462 ok(context
!= NULL
, "CertCreateCertificateContext failed: %08x\n",
7466 ok(!strcmp(szOID_RSA_RSA
,
7467 context
->pCertInfo
->SubjectPublicKeyInfo
.Algorithm
.pszObjId
),
7468 "Expected %s, got %s\n", szOID_RSA_RSA
,
7469 context
->pCertInfo
->SubjectPublicKeyInfo
.Algorithm
.pszObjId
);
7470 ret
= CryptImportPublicKeyInfoEx(csp
, X509_ASN_ENCODING
,
7471 &context
->pCertInfo
->SubjectPublicKeyInfo
, 0, 0, NULL
, &key
);
7472 ok(ret
, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7473 CryptDestroyKey(key
);
7474 CertFreeCertificateContext(context
);
7478 static const char cspName
[] = "WineCryptTemp";
7480 static void testPortPublicKeyInfo(void)
7484 PCERT_PUBLIC_KEY_INFO info
= NULL
;
7486 /* Just in case a previous run failed, delete this thing */
7487 CryptAcquireContextA(&csp
, cspName
, MS_DEF_PROV
, PROV_RSA_FULL
,
7488 CRYPT_DELETEKEYSET
);
7489 ret
= CryptAcquireContextA(&csp
, cspName
, MS_DEF_PROV
, PROV_RSA_FULL
,
7492 testExportPublicKey(csp
, &info
);
7493 testImportPublicKey(csp
, info
);
7495 HeapFree(GetProcessHeap(), 0, info
);
7496 CryptReleaseContext(csp
, 0);
7497 ret
= CryptAcquireContextA(&csp
, cspName
, MS_DEF_PROV
, PROV_RSA_FULL
,
7498 CRYPT_DELETEKEYSET
);
7503 static const DWORD encodings
[] = { X509_ASN_ENCODING
, PKCS_7_ASN_ENCODING
,
7504 X509_ASN_ENCODING
| PKCS_7_ASN_ENCODING
};
7508 hCrypt32
= GetModuleHandleA("crypt32.dll");
7509 pCryptDecodeObjectEx
= (void*)GetProcAddress(hCrypt32
, "CryptDecodeObjectEx");
7510 pCryptEncodeObjectEx
= (void*)GetProcAddress(hCrypt32
, "CryptEncodeObjectEx");
7511 if (!pCryptDecodeObjectEx
|| !pCryptEncodeObjectEx
)
7513 skip("CryptDecodeObjectEx() is not available\n");
7517 for (i
= 0; i
< sizeof(encodings
) / sizeof(encodings
[0]); i
++)
7519 test_encodeInt(encodings
[i
]);
7520 test_decodeInt(encodings
[i
]);
7521 test_encodeEnumerated(encodings
[i
]);
7522 test_decodeEnumerated(encodings
[i
]);
7523 test_encodeFiletime(encodings
[i
]);
7524 test_decodeFiletime(encodings
[i
]);
7525 test_encodeName(encodings
[i
]);
7526 test_decodeName(encodings
[i
]);
7527 test_encodeUnicodeName(encodings
[i
]);
7528 test_decodeUnicodeName(encodings
[i
]);
7529 test_encodeNameValue(encodings
[i
]);
7530 test_decodeNameValue(encodings
[i
]);
7531 test_encodeUnicodeNameValue(encodings
[i
]);
7532 test_decodeUnicodeNameValue(encodings
[i
]);
7533 test_encodeAltName(encodings
[i
]);
7534 test_decodeAltName(encodings
[i
]);
7535 test_encodeOctets(encodings
[i
]);
7536 test_decodeOctets(encodings
[i
]);
7537 test_encodeBits(encodings
[i
]);
7538 test_decodeBits(encodings
[i
]);
7539 test_encodeBasicConstraints(encodings
[i
]);
7540 test_decodeBasicConstraints(encodings
[i
]);
7541 test_encodeRsaPublicKey(encodings
[i
]);
7542 test_decodeRsaPublicKey(encodings
[i
]);
7543 test_encodeSequenceOfAny(encodings
[i
]);
7544 test_decodeSequenceOfAny(encodings
[i
]);
7545 test_encodeExtensions(encodings
[i
]);
7546 test_decodeExtensions(encodings
[i
]);
7547 test_encodePublicKeyInfo(encodings
[i
]);
7548 test_decodePublicKeyInfo(encodings
[i
]);
7549 test_encodeCertToBeSigned(encodings
[i
]);
7550 test_decodeCertToBeSigned(encodings
[i
]);
7551 test_encodeCert(encodings
[i
]);
7552 test_decodeCert(encodings
[i
]);
7553 test_encodeCRLDistPoints(encodings
[i
]);
7554 test_decodeCRLDistPoints(encodings
[i
]);
7555 test_encodeCRLIssuingDistPoint(encodings
[i
]);
7556 test_decodeCRLIssuingDistPoint(encodings
[i
]);
7557 test_encodeCRLToBeSigned(encodings
[i
]);
7558 test_decodeCRLToBeSigned(encodings
[i
]);
7559 test_encodeEnhancedKeyUsage(encodings
[i
]);
7560 test_decodeEnhancedKeyUsage(encodings
[i
]);
7561 test_encodeAuthorityKeyId(encodings
[i
]);
7562 test_decodeAuthorityKeyId(encodings
[i
]);
7563 test_encodeAuthorityKeyId2(encodings
[i
]);
7564 test_decodeAuthorityKeyId2(encodings
[i
]);
7565 test_encodeAuthorityInfoAccess(encodings
[i
]);
7566 test_decodeAuthorityInfoAccess(encodings
[i
]);
7567 test_encodeCTL(encodings
[i
]);
7568 test_decodeCTL(encodings
[i
]);
7569 test_encodePKCSContentInfo(encodings
[i
]);
7570 test_decodePKCSContentInfo(encodings
[i
]);
7571 test_encodePKCSAttribute(encodings
[i
]);
7572 test_decodePKCSAttribute(encodings
[i
]);
7573 test_encodePKCSAttributes(encodings
[i
]);
7574 test_decodePKCSAttributes(encodings
[i
]);
7575 test_encodePKCSSMimeCapabilities(encodings
[i
]);
7576 test_decodePKCSSMimeCapabilities(encodings
[i
]);
7577 test_encodePKCSSignerInfo(encodings
[i
]);
7578 test_decodePKCSSignerInfo(encodings
[i
]);
7579 test_encodeCMSSignerInfo(encodings
[i
]);
7580 test_decodeCMSSignerInfo(encodings
[i
]);
7581 test_encodeNameConstraints(encodings
[i
]);
7582 test_decodeNameConstraints(encodings
[i
]);
7583 test_encodePolicyQualifierUserNotice(encodings
[i
]);
7584 test_decodePolicyQualifierUserNotice(encodings
[i
]);
7585 test_encodeCertPolicies(encodings
[i
]);
7586 test_decodeCertPolicies(encodings
[i
]);
7588 testPortPublicKeyInfo();