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
28 #include "wine/test.h"
31 static BOOL (WINAPI
*pCryptDecodeObjectEx
)(DWORD
,LPCSTR
,const BYTE
*,DWORD
,DWORD
,PCRYPT_DECODE_PARA
,void*,DWORD
*);
32 static BOOL (WINAPI
*pCryptEncodeObjectEx
)(DWORD
,LPCSTR
,const void*,DWORD
,PCRYPT_ENCODE_PARA
,void*,DWORD
*);
33 static DWORD (WINAPI
*pBCryptDestroyKey
)(BCRYPT_KEY_HANDLE
);
41 static const BYTE bin1
[] = {0x02,0x01,0x01};
42 static const BYTE bin2
[] = {0x02,0x01,0x7f};
43 static const BYTE bin3
[] = {0x02,0x02,0x00,0x80};
44 static const BYTE bin4
[] = {0x02,0x02,0x01,0x00};
45 static const BYTE bin5
[] = {0x02,0x01,0x80};
46 static const BYTE bin6
[] = {0x02,0x02,0xff,0x7f};
47 static const BYTE bin7
[] = {0x02,0x04,0xba,0xdd,0xf0,0x0d};
49 static const struct encodedInt ints
[] = {
66 static const BYTE bin8
[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
67 static const BYTE bin9
[] = {0x02,0x0a,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0};
68 static const BYTE bin10
[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
70 static const BYTE bin11
[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0xff,0};
71 static const BYTE bin12
[] = {0x02,0x09,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
72 static const BYTE bin13
[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0};
74 static const struct encodedBigInt bigInts
[] = {
75 { bin8
, bin9
, bin10
},
76 { bin11
, bin12
, bin13
},
79 static const BYTE bin14
[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
80 static const BYTE bin15
[] = {0x02,0x0a,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0};
81 static const BYTE bin16
[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0xff,0};
82 static const BYTE bin17
[] = {0x02,0x0c,0x00,0xff,0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
84 /* Decoded is the same as original, so don't bother storing a separate copy */
85 static const struct encodedBigInt bigUInts
[] = {
86 { bin14
, bin15
, NULL
},
87 { bin16
, bin17
, NULL
},
90 static void test_encodeInt(DWORD dwEncoding
)
95 CRYPT_INTEGER_BLOB blob
;
98 /* CryptEncodeObjectEx with NULL bufSize crashes..
99 ret = pCryptEncodeObjectEx(3, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
102 /* check bogus encoding */
103 ret
= pCryptEncodeObjectEx(0, X509_INTEGER
, &ints
[0].val
, 0, NULL
, NULL
,
105 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
106 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
109 /* check with NULL integer buffer. Windows XP incorrectly returns an
110 * NTSTATUS (crashes on win9x).
112 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_INTEGER
, NULL
, 0, NULL
, NULL
,
114 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
115 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
117 for (i
= 0; i
< ARRAY_SIZE(ints
); i
++)
119 /* encode as normal integer */
120 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_INTEGER
, &ints
[i
].val
, 0,
121 NULL
, NULL
, &bufSize
);
122 ok(ret
, "Expected success, got %d\n", GetLastError());
123 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_INTEGER
, &ints
[i
].val
,
124 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
125 ok(ret
, "CryptEncodeObjectEx failed: %d\n", GetLastError());
128 ok(buf
[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
130 ok(buf
[1] == ints
[i
].encoded
[1], "Got length %d, expected %d\n",
131 buf
[1], ints
[i
].encoded
[1]);
132 ok(!memcmp(buf
+ 1, ints
[i
].encoded
+ 1, ints
[i
].encoded
[1] + 1),
133 "Encoded value of 0x%08x didn't match expected\n", ints
[i
].val
);
136 /* encode as multibyte integer */
137 blob
.cbData
= sizeof(ints
[i
].val
);
138 blob
.pbData
= (BYTE
*)&ints
[i
].val
;
139 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_MULTI_BYTE_INTEGER
, &blob
,
140 0, NULL
, NULL
, &bufSize
);
141 ok(ret
, "Expected success, got %d\n", GetLastError());
142 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_MULTI_BYTE_INTEGER
, &blob
,
143 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
144 ok(ret
, "CryptEncodeObjectEx failed: %d\n", GetLastError());
147 ok(buf
[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
149 ok(buf
[1] == ints
[i
].encoded
[1], "Got length %d, expected %d\n",
150 buf
[1], ints
[i
].encoded
[1]);
151 ok(!memcmp(buf
+ 1, ints
[i
].encoded
+ 1, ints
[i
].encoded
[1] + 1),
152 "Encoded value of 0x%08x didn't match expected\n", ints
[i
].val
);
156 /* encode a couple bigger ints, just to show it's little-endian and leading
157 * sign bytes are dropped
159 for (i
= 0; i
< ARRAY_SIZE(bigInts
); i
++)
161 blob
.cbData
= strlen((const char*)bigInts
[i
].val
);
162 blob
.pbData
= (BYTE
*)bigInts
[i
].val
;
163 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_MULTI_BYTE_INTEGER
, &blob
,
164 0, NULL
, NULL
, &bufSize
);
165 ok(ret
, "Expected success, got %d\n", GetLastError());
166 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_MULTI_BYTE_INTEGER
, &blob
,
167 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
168 ok(ret
, "CryptEncodeObjectEx failed: %d\n", GetLastError());
171 ok(buf
[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
173 ok(buf
[1] == bigInts
[i
].encoded
[1], "Got length %d, expected %d\n",
174 buf
[1], bigInts
[i
].encoded
[1]);
175 ok(!memcmp(buf
+ 1, bigInts
[i
].encoded
+ 1,
176 bigInts
[i
].encoded
[1] + 1),
177 "Encoded value didn't match expected\n");
181 /* and, encode some uints */
182 for (i
= 0; i
< ARRAY_SIZE(bigUInts
); i
++)
184 blob
.cbData
= strlen((const char*)bigUInts
[i
].val
);
185 blob
.pbData
= (BYTE
*)bigUInts
[i
].val
;
186 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_MULTI_BYTE_UINT
, &blob
,
187 0, NULL
, NULL
, &bufSize
);
188 ok(ret
, "Expected success, got %d\n", GetLastError());
189 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_MULTI_BYTE_UINT
, &blob
,
190 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
191 ok(ret
, "CryptEncodeObjectEx failed: %d\n", GetLastError());
194 ok(buf
[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
196 ok(buf
[1] == bigUInts
[i
].encoded
[1], "Got length %d, expected %d\n",
197 buf
[1], bigUInts
[i
].encoded
[1]);
198 ok(!memcmp(buf
+ 1, bigUInts
[i
].encoded
+ 1,
199 bigUInts
[i
].encoded
[1] + 1),
200 "Encoded value didn't match expected\n");
206 static void test_decodeInt(DWORD dwEncoding
)
208 static const BYTE bigInt
[] = { 2, 5, 0xff, 0xfe, 0xff, 0xfe, 0xff };
209 static const BYTE testStr
[] = { 0x16, 4, 't', 'e', 's', 't' };
210 static const BYTE longForm
[] = { 2, 0x81, 0x01, 0x01 };
211 static const BYTE bigBogus
[] = { 0x02, 0x84, 0x01, 0xff, 0xff, 0xf9 };
212 static const BYTE extraBytes
[] = { 2, 1, 1, 0, 0, 0, 0 };
218 /* CryptDecodeObjectEx with NULL bufSize crashes..
219 ret = pCryptDecodeObjectEx(3, X509_INTEGER, &ints[0].encoded,
220 ints[0].encoded[1] + 2, 0, NULL, NULL, NULL);
222 /* check bogus encoding */
223 ret
= pCryptDecodeObjectEx(3, X509_INTEGER
, (BYTE
*)&ints
[0].encoded
,
224 ints
[0].encoded
[1] + 2, 0, NULL
, NULL
, &bufSize
);
225 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
226 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
227 /* check with NULL integer buffer */
228 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_INTEGER
, NULL
, 0, 0, NULL
, NULL
,
230 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_EOD
||
231 GetLastError() == OSS_BAD_ARG
/* Win9x */),
232 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
233 /* check with a valid, but too large, integer */
234 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_INTEGER
, bigInt
, bigInt
[1] + 2,
235 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
236 ok((!ret
&& GetLastError() == CRYPT_E_ASN1_LARGE
) ||
237 broken(ret
) /* Win9x */,
238 "Expected CRYPT_E_ASN1_LARGE, got %d\n", GetLastError());
239 /* check with a DER-encoded string */
240 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_INTEGER
, testStr
, testStr
[1] + 2,
241 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
242 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_BADTAG
||
243 GetLastError() == OSS_PDU_MISMATCH
/* Win9x */ ),
244 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %08x\n",
246 for (i
= 0; i
< ARRAY_SIZE(ints
); i
++)
248 /* When the output buffer is NULL, this always succeeds */
249 SetLastError(0xdeadbeef);
250 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_INTEGER
,
251 ints
[i
].encoded
, ints
[i
].encoded
[1] + 2, 0, NULL
, NULL
,
253 ok(ret
&& GetLastError() == NOERROR
,
254 "Expected success and NOERROR, got %d\n", GetLastError());
255 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_INTEGER
,
256 ints
[i
].encoded
, ints
[i
].encoded
[1] + 2,
257 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
258 ok(ret
, "CryptDecodeObjectEx failed: %d\n", GetLastError());
259 ok(bufSize
== sizeof(int), "Wrong size %d\n", bufSize
);
260 ok(buf
!= NULL
, "Expected allocated buffer\n");
263 ok(!memcmp(buf
, &ints
[i
].val
, bufSize
), "Expected %d, got %d\n",
264 ints
[i
].val
, *(int *)buf
);
268 for (i
= 0; i
< ARRAY_SIZE(bigInts
); i
++)
270 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_MULTI_BYTE_INTEGER
,
271 bigInts
[i
].encoded
, bigInts
[i
].encoded
[1] + 2, 0, NULL
, NULL
,
273 ok(ret
&& GetLastError() == NOERROR
,
274 "Expected success and NOERROR, got %d\n", GetLastError());
275 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_MULTI_BYTE_INTEGER
,
276 bigInts
[i
].encoded
, bigInts
[i
].encoded
[1] + 2,
277 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
278 ok(ret
, "CryptDecodeObjectEx failed: %d\n", GetLastError());
279 ok(bufSize
>= sizeof(CRYPT_INTEGER_BLOB
), "Wrong size %d\n", bufSize
);
280 ok(buf
!= NULL
, "Expected allocated buffer\n");
283 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)buf
;
285 ok(blob
->cbData
== strlen((const char*)bigInts
[i
].decoded
),
286 "Expected len %d, got %d\n", lstrlenA((const char*)bigInts
[i
].decoded
),
288 ok(!memcmp(blob
->pbData
, bigInts
[i
].decoded
, blob
->cbData
),
289 "Unexpected value\n");
293 for (i
= 0; i
< ARRAY_SIZE(bigUInts
); i
++)
295 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_MULTI_BYTE_UINT
,
296 bigUInts
[i
].encoded
, bigUInts
[i
].encoded
[1] + 2, 0, NULL
, NULL
,
298 ok(ret
&& GetLastError() == NOERROR
,
299 "Expected success and NOERROR, got %d\n", GetLastError());
300 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_MULTI_BYTE_UINT
,
301 bigUInts
[i
].encoded
, bigUInts
[i
].encoded
[1] + 2,
302 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
303 ok(ret
, "CryptDecodeObjectEx failed: %d\n", GetLastError());
304 ok(bufSize
>= sizeof(CRYPT_INTEGER_BLOB
), "Wrong size %d\n", bufSize
);
305 ok(buf
!= NULL
, "Expected allocated buffer\n");
308 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)buf
;
310 ok(blob
->cbData
== strlen((const char*)bigUInts
[i
].val
),
311 "Expected len %d, got %d\n", lstrlenA((const char*)bigUInts
[i
].val
),
313 ok(!memcmp(blob
->pbData
, bigUInts
[i
].val
, blob
->cbData
),
314 "Unexpected value\n");
318 /* Decode the value 1 with long-form length */
319 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_MULTI_BYTE_INTEGER
, longForm
,
320 sizeof(longForm
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
321 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
324 ok(*(int *)buf
== 1, "Expected 1, got %d\n", *(int *)buf
);
327 /* check with extra bytes at the end */
328 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_INTEGER
, extraBytes
,
329 sizeof(extraBytes
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
330 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
333 ok(*(int *)buf
== 1, "Expected 1, got %d\n", *(int *)buf
);
336 /* Try to decode some bogus large items */
337 /* The buffer size is smaller than the encoded length, so this should fail
338 * with CRYPT_E_ASN1_EOD if it's being decoded.
339 * Under XP it fails with CRYPT_E_ASN1_LARGE, which means there's a limit
340 * on the size decoded, but in ME it fails with CRYPT_E_ASN1_EOD or crashes.
341 * So this test unfortunately isn't useful.
342 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, tooBig,
343 0x7fffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
344 ok(!ret && GetLastError() == CRYPT_E_ASN1_LARGE,
345 "Expected CRYPT_E_ASN1_LARGE, got %08x\n", GetLastError());
347 /* This will try to decode the buffer and overflow it, check that it's
352 /* a large buffer isn't guaranteed to crash, it depends on memory allocation order */
353 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_MULTI_BYTE_INTEGER
, bigBogus
,
354 0x01ffffff, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
355 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
356 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
360 static const BYTE bin18
[] = {0x0a,0x01,0x01};
361 static const BYTE bin19
[] = {0x0a,0x05,0x00,0xff,0xff,0xff,0x80};
363 /* These are always encoded unsigned, and aren't constrained to be any
366 static const struct encodedInt enums
[] = {
371 /* X509_CRL_REASON_CODE is also an enumerated type, but it's #defined to
374 static const LPCSTR enumeratedTypes
[] = { X509_ENUMERATED
,
375 szOID_CRL_REASON_CODE
};
377 static void test_encodeEnumerated(DWORD dwEncoding
)
381 for (i
= 0; i
< ARRAY_SIZE(enumeratedTypes
); i
++)
383 for (j
= 0; j
< ARRAY_SIZE(enums
); j
++)
389 ret
= pCryptEncodeObjectEx(dwEncoding
, enumeratedTypes
[i
],
390 &enums
[j
].val
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
,
392 ok(ret
, "CryptEncodeObjectEx failed: %d\n", GetLastError());
396 "Got unexpected type %d for enumerated (expected 0xa)\n",
398 ok(buf
[1] == enums
[j
].encoded
[1],
399 "Got length %d, expected %d\n", buf
[1], enums
[j
].encoded
[1]);
400 ok(!memcmp(buf
+ 1, enums
[j
].encoded
+ 1,
401 enums
[j
].encoded
[1] + 1),
402 "Encoded value of 0x%08x didn't match expected\n",
410 static void test_decodeEnumerated(DWORD dwEncoding
)
414 for (i
= 0; i
< ARRAY_SIZE(enumeratedTypes
); i
++)
416 for (j
= 0; j
< ARRAY_SIZE(enums
); j
++)
419 DWORD bufSize
= sizeof(int);
422 ret
= pCryptDecodeObjectEx(dwEncoding
, enumeratedTypes
[i
],
423 enums
[j
].encoded
, enums
[j
].encoded
[1] + 2, 0, NULL
,
425 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
426 ok(bufSize
== sizeof(int),
427 "Got unexpected size %d for enumerated\n", bufSize
);
428 ok(val
== enums
[j
].val
, "Unexpected value %d, expected %d\n",
434 struct encodedFiletime
437 const BYTE
*encodedTime
;
440 static void testTimeEncoding(DWORD dwEncoding
, LPCSTR structType
,
441 const struct encodedFiletime
*time
)
448 ret
= SystemTimeToFileTime(&time
->sysTime
, &ft
);
449 ok(ret
, "SystemTimeToFileTime failed: %d\n", GetLastError());
450 ret
= pCryptEncodeObjectEx(dwEncoding
, structType
, &ft
,
451 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
452 /* years other than 1950-2050 are not allowed for encodings other than
453 * X509_CHOICE_OF_TIME.
455 if (structType
== X509_CHOICE_OF_TIME
||
456 (time
->sysTime
.wYear
>= 1950 && time
->sysTime
.wYear
<= 2050))
458 ok(ret
, "CryptEncodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
460 ok(buf
!= NULL
, "Expected an allocated buffer\n");
463 ok(buf
[0] == time
->encodedTime
[0],
464 "Expected type 0x%02x, got 0x%02x\n", time
->encodedTime
[0],
466 ok(buf
[1] == time
->encodedTime
[1], "Expected %d bytes, got %d\n",
467 time
->encodedTime
[1], bufSize
);
468 ok(!memcmp(time
->encodedTime
+ 2, buf
+ 2, time
->encodedTime
[1]),
469 "Got unexpected value for time encoding\n");
474 ok((!ret
&& GetLastError() == CRYPT_E_BAD_ENCODE
) ||
475 broken(GetLastError() == ERROR_SUCCESS
),
476 "Expected CRYPT_E_BAD_ENCODE, got 0x%08x\n", GetLastError());
479 static const char *printSystemTime(const SYSTEMTIME
*st
)
483 sprintf(buf
, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st
->wMonth
, st
->wDay
,
484 st
->wYear
, st
->wHour
, st
->wMinute
, st
->wSecond
, st
->wMilliseconds
);
488 static const char *printFileTime(const FILETIME
*ft
)
493 FileTimeToSystemTime(ft
, &st
);
494 sprintf(buf
, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st
.wMonth
, st
.wDay
,
495 st
.wYear
, st
.wHour
, st
.wMinute
, st
.wSecond
, st
.wMilliseconds
);
499 static void compareTime(const SYSTEMTIME
*expected
, const FILETIME
*got
)
503 FileTimeToSystemTime(got
, &st
);
504 ok((expected
->wYear
== st
.wYear
&&
505 expected
->wMonth
== st
.wMonth
&&
506 expected
->wDay
== st
.wDay
&&
507 expected
->wHour
== st
.wHour
&&
508 expected
->wMinute
== st
.wMinute
&&
509 expected
->wSecond
== st
.wSecond
&&
510 abs(expected
->wMilliseconds
- st
.wMilliseconds
) <= 1) ||
511 /* Some Windows systems only seem to be accurate in their time decoding to
512 * within about an hour.
514 broken(expected
->wYear
== st
.wYear
&&
515 expected
->wMonth
== st
.wMonth
&&
516 expected
->wDay
== st
.wDay
&&
517 abs(expected
->wHour
- st
.wHour
) <= 1),
518 "Got unexpected value for time decoding:\nexpected %s, got %s\n",
519 printSystemTime(expected
), printFileTime(got
));
522 static void testTimeDecoding(DWORD dwEncoding
, LPCSTR structType
,
523 const struct encodedFiletime
*time
)
526 DWORD size
= sizeof(ft
);
529 ret
= pCryptDecodeObjectEx(dwEncoding
, structType
, time
->encodedTime
,
530 time
->encodedTime
[1] + 2, 0, NULL
, &ft
, &size
);
531 /* years other than 1950-2050 are not allowed for encodings other than
532 * X509_CHOICE_OF_TIME.
534 if (structType
== X509_CHOICE_OF_TIME
||
535 (time
->sysTime
.wYear
>= 1950 && time
->sysTime
.wYear
<= 2050))
537 ok(ret
|| broken(GetLastError() == OSS_DATA_ERROR
),
538 "CryptDecodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
541 compareTime(&time
->sysTime
, &ft
);
544 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_BADTAG
||
545 GetLastError() == OSS_PDU_MISMATCH
/* Win9x */ ),
546 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %08x\n",
550 static const BYTE bin20
[] = {
551 0x17,0x0d,'0','5','0','6','0','6','1','6','1','0','0','0','Z'};
552 static const BYTE bin21
[] = {
553 0x18,0x0f,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
554 static const BYTE bin22
[] = {
555 0x18,0x0f,'2','1','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
557 static const struct encodedFiletime times
[] = {
558 { { 2005, 6, 1, 6, 16, 10, 0, 0 }, bin20
},
559 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin21
},
560 { { 2145, 6, 1, 6, 16, 10, 0, 0 }, bin22
},
563 static void test_encodeFiletime(DWORD dwEncoding
)
567 for (i
= 0; i
< ARRAY_SIZE(times
); i
++)
569 testTimeEncoding(dwEncoding
, X509_CHOICE_OF_TIME
, ×
[i
]);
570 testTimeEncoding(dwEncoding
, PKCS_UTC_TIME
, ×
[i
]);
571 testTimeEncoding(dwEncoding
, szOID_RSA_signingTime
, ×
[i
]);
575 static const BYTE bin23
[] = {
576 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','0','0','0','Z'};
577 static const BYTE bin24
[] = {
578 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','9','9','9','Z'};
579 static const BYTE bin25
[] = {
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 bin26
[] = {
582 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','0','0'};
583 static const BYTE bin27
[] = {
584 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','1','5'};
585 static const BYTE bin28
[] = {
586 0x18,0x0a,'2','1','4','5','0','6','0','6','1','6'};
587 static const BYTE bin29
[] = {
588 0x17,0x0a,'4','5','0','6','0','6','1','6','1','0'};
589 static const BYTE bin30
[] = {
590 0x17,0x0b,'4','5','0','6','0','6','1','6','1','0','Z'};
591 static const BYTE bin31
[] = {
592 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','+','0','1'};
593 static const BYTE bin32
[] = {
594 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','-','0','1'};
595 static const BYTE bin33
[] = {
596 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','+','0','1','0','0'};
597 static const BYTE bin34
[] = {
598 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','-','0','1','0','0'};
599 static const BYTE bin35
[] = {
600 0x17,0x08, '4','5','0','6','0','6','1','6'};
601 static const BYTE bin36
[] = {
602 0x18,0x0f, 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','Z'};
603 static const BYTE bin37
[] = {
604 0x18,0x04, '2','1','4','5'};
605 static const BYTE bin38
[] = {
606 0x18,0x08, '2','1','4','5','0','6','0','6'};
608 static void test_decodeFiletime(DWORD dwEncoding
)
610 static const struct encodedFiletime otherTimes
[] = {
611 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin23
},
612 { { 1945, 6, 1, 6, 16, 10, 0, 999 }, bin24
},
613 { { 1945, 6, 1, 6, 17, 10, 0, 0 }, bin25
},
614 { { 1945, 6, 1, 6, 15, 10, 0, 0 }, bin26
},
615 { { 1945, 6, 1, 6, 14, 55, 0, 0 }, bin27
},
616 { { 2145, 6, 1, 6, 16, 0, 0, 0 }, bin28
},
617 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin29
},
618 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin30
},
619 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin31
},
620 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin32
},
621 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin33
},
622 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin34
},
624 /* An oddball case that succeeds in Windows, but doesn't seem correct
625 { { 2145, 6, 1, 2, 11, 31, 0, 0 }, "\x18" "\x13" "21450606161000-9999" },
627 static const unsigned char *bogusTimes
[] = {
628 /* oddly, this succeeds on Windows, with year 2765
629 "\x18" "\x0f" "21r50606161000Z",
637 FILETIME ft1
= { 0 }, ft2
= { 0 };
640 /* Check bogus length with non-NULL buffer */
641 ret
= SystemTimeToFileTime(×
[0].sysTime
, &ft1
);
642 ok(ret
, "SystemTimeToFileTime failed: %d\n", GetLastError());
644 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CHOICE_OF_TIME
,
645 times
[0].encodedTime
, times
[0].encodedTime
[1] + 2, 0, NULL
, &ft2
, &size
);
646 ok(!ret
&& GetLastError() == ERROR_MORE_DATA
,
647 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
649 for (i
= 0; i
< ARRAY_SIZE(times
); i
++)
651 testTimeDecoding(dwEncoding
, X509_CHOICE_OF_TIME
, ×
[i
]);
652 testTimeDecoding(dwEncoding
, PKCS_UTC_TIME
, ×
[i
]);
653 testTimeDecoding(dwEncoding
, szOID_RSA_signingTime
, ×
[i
]);
655 for (i
= 0; i
< ARRAY_SIZE(otherTimes
); i
++)
657 testTimeDecoding(dwEncoding
, X509_CHOICE_OF_TIME
, &otherTimes
[i
]);
658 testTimeDecoding(dwEncoding
, PKCS_UTC_TIME
, &otherTimes
[i
]);
659 testTimeDecoding(dwEncoding
, szOID_RSA_signingTime
, &otherTimes
[i
]);
661 for (i
= 0; i
< ARRAY_SIZE(bogusTimes
); i
++)
664 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CHOICE_OF_TIME
,
665 bogusTimes
[i
], bogusTimes
[i
][1] + 2, 0, NULL
, &ft1
, &size
);
666 ok((!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
667 GetLastError() == OSS_DATA_ERROR
/* Win9x */)) ||
668 broken(ret
), /* Win9x and NT4 for bin38 */
669 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
674 static const char commonName
[] = "Juan Lang";
675 static const char surName
[] = "Lang";
677 static const BYTE emptySequence
[] = { 0x30, 0 };
678 static const BYTE emptyRDNs
[] = { 0x30, 0x02, 0x31, 0 };
679 static const BYTE twoRDNs
[] = {
680 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
681 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
682 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0};
683 static const BYTE encodedTwoRDNs
[] = {
684 0x30,0x2e,0x31,0x2c,0x30,0x2a,0x06,0x03,0x55,0x04,0x03,0x30,0x23,0x31,0x21,
685 0x30,0x0c,0x06,0x03,0x55,0x04,0x04,0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,
686 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
690 static const BYTE us
[] = { 0x55, 0x53 };
691 static const BYTE minnesota
[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x73, 0x6f,
693 static const BYTE minneapolis
[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x61, 0x70,
694 0x6f, 0x6c, 0x69, 0x73 };
695 static const BYTE codeweavers
[] = { 0x43, 0x6f, 0x64, 0x65, 0x57, 0x65, 0x61,
696 0x76, 0x65, 0x72, 0x73 };
697 static const BYTE wine
[] = { 0x57, 0x69, 0x6e, 0x65, 0x20, 0x44, 0x65, 0x76,
698 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74 };
699 static const BYTE localhostAttr
[] = { 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
701 static const BYTE aric
[] = { 0x61, 0x72, 0x69, 0x63, 0x40, 0x63, 0x6f, 0x64,
702 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d };
704 #define RDNA(arr) oid_ ## arr, CERT_RDN_PRINTABLE_STRING, { sizeof(arr), (LPBYTE)arr }
705 #define RDNIA5(arr) oid_ ## arr, CERT_RDN_IA5_STRING, { sizeof(arr), (LPBYTE)arr }
707 static CHAR oid_us
[] = "2.5.4.6",
708 oid_minnesota
[] = "2.5.4.8",
709 oid_minneapolis
[] = "2.5.4.7",
710 oid_codeweavers
[] = "2.5.4.10",
711 oid_wine
[] = "2.5.4.11",
712 oid_localhostAttr
[] = "2.5.4.3",
713 oid_aric
[] = "1.2.840.113549.1.9.1";
714 static CERT_RDN_ATTR rdnAttrs
[] = { { RDNA(us
) },
716 { RDNA(minneapolis
) },
717 { RDNA(codeweavers
) },
719 { RDNA(localhostAttr
) },
721 static CERT_RDN_ATTR decodedRdnAttrs
[] = { { RDNA(us
) },
722 { RDNA(localhostAttr
) },
724 { RDNA(minneapolis
) },
725 { RDNA(codeweavers
) },
732 static const BYTE encodedRDNAttrs
[] = {
733 0x30,0x81,0x96,0x31,0x81,0x93,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
734 0x53,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x68,
735 0x6f,0x73,0x74,0x30,0x10,0x06,0x03,0x55,0x04,0x08,0x13,0x09,0x4d,0x69,0x6e,0x6e,
736 0x65,0x73,0x6f,0x74,0x61,0x30,0x12,0x06,0x03,0x55,0x04,0x07,0x13,0x0b,0x4d,0x69,
737 0x6e,0x6e,0x65,0x61,0x70,0x6f,0x6c,0x69,0x73,0x30,0x12,0x06,0x03,0x55,0x04,0x0a,
738 0x13,0x0b,0x43,0x6f,0x64,0x65,0x57,0x65,0x61,0x76,0x65,0x72,0x73,0x30,0x17,0x06,
739 0x03,0x55,0x04,0x0b,0x13,0x10,0x57,0x69,0x6e,0x65,0x20,0x44,0x65,0x76,0x65,0x6c,
740 0x6f,0x70,0x6d,0x65,0x6e,0x74,0x30,0x21,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
741 0x01,0x09,0x01,0x16,0x14,0x61,0x72,0x69,0x63,0x40,0x63,0x6f,0x64,0x65,0x77,0x65,
742 0x61,0x76,0x65,0x72,0x73,0x2e,0x63,0x6f,0x6d
745 static void test_encodeName(DWORD dwEncoding
)
747 CERT_RDN_ATTR attrs
[2];
750 static CHAR oid_common_name
[] = szOID_COMMON_NAME
,
751 oid_sur_name
[] = szOID_SUR_NAME
;
758 /* Test with NULL pvStructInfo (crashes on win9x) */
759 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, NULL
,
760 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
761 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
762 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
764 /* Test with empty CERT_NAME_INFO */
767 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
768 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
769 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
772 ok(!memcmp(buf
, emptySequence
, sizeof(emptySequence
)),
773 "Got unexpected encoding for empty name\n");
778 /* Test with bogus CERT_RDN (crashes on win9x) */
780 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
781 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
782 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
783 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
785 /* Test with empty CERT_RDN */
787 rdn
.rgRDNAttr
= NULL
;
790 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
791 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
792 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
795 ok(!memcmp(buf
, emptyRDNs
, sizeof(emptyRDNs
)),
796 "Got unexpected encoding for empty RDN array\n");
801 /* Test with bogus attr array (crashes on win9x) */
803 rdn
.rgRDNAttr
= NULL
;
804 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
805 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
806 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
807 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
809 /* oddly, a bogus OID is accepted by Windows XP; not testing.
810 attrs[0].pszObjId = "bogus";
811 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
812 attrs[0].Value.cbData = sizeof(commonName);
813 attrs[0].Value.pbData = commonName;
815 rdn.rgRDNAttr = attrs;
816 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
817 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
818 ok(!ret, "Expected failure, got success\n");
820 /* Check with two CERT_RDN_ATTRs. Note DER encoding forces the order of
821 * the encoded attributes to be swapped.
823 attrs
[0].pszObjId
= oid_common_name
;
824 attrs
[0].dwValueType
= CERT_RDN_PRINTABLE_STRING
;
825 attrs
[0].Value
.cbData
= sizeof(commonName
);
826 attrs
[0].Value
.pbData
= (BYTE
*)commonName
;
827 attrs
[1].pszObjId
= oid_sur_name
;
828 attrs
[1].dwValueType
= CERT_RDN_PRINTABLE_STRING
;
829 attrs
[1].Value
.cbData
= sizeof(surName
);
830 attrs
[1].Value
.pbData
= (BYTE
*)surName
;
832 rdn
.rgRDNAttr
= attrs
;
833 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
834 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
835 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
838 ok(!memcmp(buf
, twoRDNs
, sizeof(twoRDNs
)),
839 "Got unexpected encoding for two RDN array\n");
842 /* A name can be "encoded" with previously encoded RDN attrs. */
843 attrs
[0].dwValueType
= CERT_RDN_ENCODED_BLOB
;
844 attrs
[0].Value
.pbData
= (LPBYTE
)twoRDNs
;
845 attrs
[0].Value
.cbData
= sizeof(twoRDNs
);
847 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
848 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
849 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
852 ok(size
== sizeof(encodedTwoRDNs
), "Unexpected size %d\n", size
);
853 ok(!memcmp(buf
, encodedTwoRDNs
, size
),
854 "Unexpected value for re-encoded two RDN array\n");
857 /* CERT_RDN_ANY_TYPE is too vague for X509_NAMEs, check the return */
859 attrs
[0].dwValueType
= CERT_RDN_ANY_TYPE
;
860 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME
, &info
,
861 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
862 ok(!ret
&& GetLastError() == E_INVALIDARG
,
863 "Expected E_INVALIDARG, got %08x\n", GetLastError());
864 /* Test a more complex name */
865 rdn
.cRDNAttr
= ARRAY_SIZE(rdnAttrs
);
866 rdn
.rgRDNAttr
= rdnAttrs
;
871 ret
= pCryptEncodeObjectEx(X509_ASN_ENCODING
, X509_NAME
, &info
,
872 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
873 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
876 ok(size
== sizeof(encodedRDNAttrs
), "Wrong size %d\n", size
);
877 ok(!memcmp(buf
, encodedRDNAttrs
, size
), "Unexpected value\n");
882 static WCHAR commonNameW
[] = { 'J','u','a','n',' ','L','a','n','g',0 };
883 static WCHAR surNameW
[] = { 'L','a','n','g',0 };
885 static const BYTE twoRDNsNoNull
[] = {
886 0x30,0x21,0x31,0x1f,0x30,0x0b,0x06,0x03,0x55,0x04,0x04,0x13,0x04,0x4c,0x61,
887 0x6e,0x67,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,
888 0x20,0x4c,0x61,0x6e,0x67 };
889 static const BYTE anyType
[] = {
890 0x30,0x2f,0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x1e,0x24,0x23,0x30,
891 0x21,0x31,0x0c,0x30,0x03,0x06,0x04,0x55,0x13,0x04,0x4c,0x05,0x6e,0x61,0x00,
892 0x67,0x11,0x30,0x03,0x06,0x04,0x55,0x13,0x03,0x4a,0x0a,0x61,0x75,0x20,0x6e,
893 0x61,0x4c,0x67,0x6e };
895 static void test_encodeUnicodeName(DWORD dwEncoding
)
897 CERT_RDN_ATTR attrs
[2];
900 static CHAR oid_common_name
[] = szOID_COMMON_NAME
,
901 oid_sur_name
[] = szOID_SUR_NAME
;
908 /* Test with NULL pvStructInfo (crashes on win9x) */
909 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, NULL
,
910 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
911 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
912 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
914 /* Test with empty CERT_NAME_INFO */
917 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, &info
,
918 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
919 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
922 ok(!memcmp(buf
, emptySequence
, sizeof(emptySequence
)),
923 "Got unexpected encoding for empty name\n");
926 /* Check with one CERT_RDN_ATTR, that has an invalid character for the
927 * encoding (the NULL).
929 attrs
[0].pszObjId
= oid_common_name
;
930 attrs
[0].dwValueType
= CERT_RDN_PRINTABLE_STRING
;
931 attrs
[0].Value
.cbData
= sizeof(commonNameW
);
932 attrs
[0].Value
.pbData
= (BYTE
*)commonNameW
;
934 rdn
.rgRDNAttr
= attrs
;
937 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, &info
,
938 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
939 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING
,
940 "Expected CRYPT_E_INVALID_PRINTABLE_STRING, got %08x\n", GetLastError());
941 ok(size
== 9, "Unexpected error index %08x\n", size
);
942 /* Check with two NULL-terminated CERT_RDN_ATTRs. Note DER encoding
943 * forces the order of the encoded attributes to be swapped.
945 attrs
[0].pszObjId
= oid_common_name
;
946 attrs
[0].dwValueType
= CERT_RDN_PRINTABLE_STRING
;
947 attrs
[0].Value
.cbData
= 0;
948 attrs
[0].Value
.pbData
= (BYTE
*)commonNameW
;
949 attrs
[1].pszObjId
= oid_sur_name
;
950 attrs
[1].dwValueType
= CERT_RDN_PRINTABLE_STRING
;
951 attrs
[1].Value
.cbData
= 0;
952 attrs
[1].Value
.pbData
= (BYTE
*)surNameW
;
954 rdn
.rgRDNAttr
= attrs
;
957 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, &info
,
958 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
959 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
962 ok(!memcmp(buf
, twoRDNsNoNull
, sizeof(twoRDNsNoNull
)),
963 "Got unexpected encoding for two RDN array\n");
966 /* A name can be "encoded" with previously encoded RDN attrs. */
967 attrs
[0].dwValueType
= CERT_RDN_ENCODED_BLOB
;
968 attrs
[0].Value
.pbData
= (LPBYTE
)twoRDNs
;
969 attrs
[0].Value
.cbData
= sizeof(twoRDNs
);
971 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, &info
,
972 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
973 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
976 ok(size
== sizeof(encodedTwoRDNs
), "Unexpected size %d\n", size
);
977 ok(!memcmp(buf
, encodedTwoRDNs
, size
),
978 "Unexpected value for re-encoded two RDN array\n");
981 /* Unicode names infer the type for CERT_RDN_ANY_TYPE */
983 attrs
[0].dwValueType
= CERT_RDN_ANY_TYPE
;
984 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, &info
,
985 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
986 todo_wine
ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
989 ok(size
== sizeof(anyType
), "Unexpected size %d\n", size
);
990 ok(!memcmp(buf
, anyType
, size
), "Unexpected value\n");
995 static void compareNameValues(const CERT_NAME_VALUE
*expected
,
996 const CERT_NAME_VALUE
*got
)
998 if (expected
->dwValueType
== CERT_RDN_UTF8_STRING
&&
999 got
->dwValueType
== CERT_RDN_ENCODED_BLOB
)
1001 win_skip("Can't handle CERT_RDN_UTF8_STRING\n");
1005 ok(got
->dwValueType
== expected
->dwValueType
,
1006 "Expected string type %d, got %d\n", expected
->dwValueType
,
1008 ok(got
->Value
.cbData
== expected
->Value
.cbData
||
1009 got
->Value
.cbData
== expected
->Value
.cbData
- sizeof(WCHAR
) /* Win8 */,
1010 "String type %d: unexpected data size, got %d, expected %d\n",
1011 expected
->dwValueType
, got
->Value
.cbData
, expected
->Value
.cbData
);
1012 if (got
->Value
.cbData
&& got
->Value
.pbData
)
1013 ok(!memcmp(got
->Value
.pbData
, expected
->Value
.pbData
,
1014 min(got
->Value
.cbData
, expected
->Value
.cbData
)),
1015 "String type %d: unexpected value\n", expected
->dwValueType
);
1018 static void compareRDNAttrs(const CERT_RDN_ATTR
*expected
,
1019 const CERT_RDN_ATTR
*got
)
1021 if (expected
->pszObjId
&& *expected
->pszObjId
)
1023 ok(got
->pszObjId
!= NULL
, "Expected OID %s, got NULL\n",
1024 expected
->pszObjId
);
1027 ok(!strcmp(got
->pszObjId
, expected
->pszObjId
),
1028 "Got unexpected OID %s, expected %s\n", got
->pszObjId
,
1029 expected
->pszObjId
);
1032 compareNameValues((const CERT_NAME_VALUE
*)&expected
->dwValueType
,
1033 (const CERT_NAME_VALUE
*)&got
->dwValueType
);
1036 static void compareRDNs(const CERT_RDN
*expected
, const CERT_RDN
*got
)
1038 ok(got
->cRDNAttr
== expected
->cRDNAttr
,
1039 "Expected %d RDN attrs, got %d\n", expected
->cRDNAttr
, got
->cRDNAttr
);
1044 for (i
= 0; i
< got
->cRDNAttr
; i
++)
1045 compareRDNAttrs(&expected
->rgRDNAttr
[i
], &got
->rgRDNAttr
[i
]);
1049 static void compareNames(const CERT_NAME_INFO
*expected
,
1050 const CERT_NAME_INFO
*got
)
1052 ok(got
->cRDN
== expected
->cRDN
, "Expected %d RDNs, got %d\n",
1053 expected
->cRDN
, got
->cRDN
);
1058 for (i
= 0; i
< got
->cRDN
; i
++)
1059 compareRDNs(&expected
->rgRDN
[i
], &got
->rgRDN
[i
]);
1063 static const BYTE emptyIndefiniteSequence
[] = { 0x30,0x80,0x00,0x00 };
1064 static const BYTE twoRDNsExtraBytes
[] = {
1065 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
1066 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1067 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0,0,0,0,0,0};
1069 static void test_decodeName(DWORD dwEncoding
)
1075 CERT_NAME_INFO info
= { 1, &rdn
};
1077 /* test empty name */
1079 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME
, emptySequence
,
1080 emptySequence
[1] + 2,
1081 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1083 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1084 /* Interestingly, in Windows, if cRDN is 0, rgRGN may not be NULL. My
1085 * decoder works the same way, so only test the count.
1089 ok(bufSize
== sizeof(CERT_NAME_INFO
), "Wrong bufSize %d\n", bufSize
);
1090 ok(((CERT_NAME_INFO
*)buf
)->cRDN
== 0,
1091 "Expected 0 RDNs in empty info, got %d\n",
1092 ((CERT_NAME_INFO
*)buf
)->cRDN
);
1095 /* test empty name with indefinite-length encoding */
1096 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME
, emptyIndefiniteSequence
,
1097 sizeof(emptyIndefiniteSequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1099 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1102 ok(bufSize
== sizeof(CERT_NAME_INFO
), "Wrong bufSize %d\n", bufSize
);
1103 ok(((CERT_NAME_INFO
*)buf
)->cRDN
== 0,
1104 "Expected 0 RDNs in empty info, got %d\n",
1105 ((CERT_NAME_INFO
*)buf
)->cRDN
);
1108 /* test empty RDN */
1110 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME
, emptyRDNs
,
1112 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1114 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1117 CERT_NAME_INFO
*info
= (CERT_NAME_INFO
*)buf
;
1119 ok(bufSize
== sizeof(CERT_NAME_INFO
) + sizeof(CERT_RDN
) &&
1120 info
->cRDN
== 1 && info
->rgRDN
&& info
->rgRDN
[0].cRDNAttr
== 0,
1121 "Got unexpected value for empty RDN\n");
1124 /* test two RDN attrs */
1126 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME
, twoRDNs
,
1128 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1130 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1133 static CHAR oid_sur_name
[] = szOID_SUR_NAME
,
1134 oid_common_name
[] = szOID_COMMON_NAME
;
1136 CERT_RDN_ATTR attrs
[] = {
1137 { oid_sur_name
, CERT_RDN_PRINTABLE_STRING
, { sizeof(surName
),
1138 (BYTE
*)surName
} },
1139 { oid_common_name
, CERT_RDN_PRINTABLE_STRING
, { sizeof(commonName
),
1140 (BYTE
*)commonName
} },
1143 rdn
.cRDNAttr
= ARRAY_SIZE(attrs
);
1144 rdn
.rgRDNAttr
= attrs
;
1145 compareNames(&info
, (CERT_NAME_INFO
*)buf
);
1148 /* test that two RDN attrs with extra bytes succeeds */
1150 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME
, twoRDNsExtraBytes
,
1151 sizeof(twoRDNsExtraBytes
), 0, NULL
, NULL
, &bufSize
);
1152 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1153 /* And, a slightly more complicated name */
1156 ret
= pCryptDecodeObjectEx(X509_ASN_ENCODING
, X509_NAME
, encodedRDNAttrs
,
1157 sizeof(encodedRDNAttrs
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1158 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1161 rdn
.cRDNAttr
= ARRAY_SIZE(decodedRdnAttrs
);
1162 rdn
.rgRDNAttr
= decodedRdnAttrs
;
1163 compareNames(&info
, (CERT_NAME_INFO
*)buf
);
1168 static void test_decodeUnicodeName(DWORD dwEncoding
)
1174 CERT_NAME_INFO info
= { 1, &rdn
};
1176 /* test empty name */
1178 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, emptySequence
,
1179 emptySequence
[1] + 2,
1180 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1182 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1185 ok(bufSize
== sizeof(CERT_NAME_INFO
),
1186 "Got wrong bufSize %d\n", bufSize
);
1187 ok(((CERT_NAME_INFO
*)buf
)->cRDN
== 0,
1188 "Expected 0 RDNs in empty info, got %d\n",
1189 ((CERT_NAME_INFO
*)buf
)->cRDN
);
1192 /* test empty RDN */
1194 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, emptyRDNs
,
1196 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1198 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1201 CERT_NAME_INFO
*info
= (CERT_NAME_INFO
*)buf
;
1203 ok(bufSize
== sizeof(CERT_NAME_INFO
) + sizeof(CERT_RDN
) &&
1204 info
->cRDN
== 1 && info
->rgRDN
&& info
->rgRDN
[0].cRDNAttr
== 0,
1205 "Got unexpected value for empty RDN\n");
1208 /* test two RDN attrs */
1210 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_UNICODE_NAME
, twoRDNsNoNull
,
1211 sizeof(twoRDNsNoNull
),
1212 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1214 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1217 static CHAR oid_sur_name
[] = szOID_SUR_NAME
,
1218 oid_common_name
[] = szOID_COMMON_NAME
;
1220 CERT_RDN_ATTR attrs
[] = {
1221 { oid_sur_name
, CERT_RDN_PRINTABLE_STRING
,
1222 { lstrlenW(surNameW
) * sizeof(WCHAR
), (BYTE
*)surNameW
} },
1223 { oid_common_name
, CERT_RDN_PRINTABLE_STRING
,
1224 { lstrlenW(commonNameW
) * sizeof(WCHAR
), (BYTE
*)commonNameW
} },
1227 rdn
.cRDNAttr
= ARRAY_SIZE(attrs
);
1228 rdn
.rgRDNAttr
= attrs
;
1229 compareNames(&info
, (CERT_NAME_INFO
*)buf
);
1234 struct EncodedNameValue
1236 CERT_NAME_VALUE value
;
1237 const BYTE
*encoded
;
1241 static const char bogusIA5
[] = "\x80";
1242 static const char bogusPrintable
[] = "~";
1243 static const char bogusNumeric
[] = "A";
1244 static const BYTE bin42
[] = { 0x16,0x02,0x80,0x00 };
1245 static const BYTE bin43
[] = { 0x13,0x02,0x7e,0x00 };
1246 static const BYTE bin44
[] = { 0x12,0x02,0x41,0x00 };
1247 static BYTE octetCommonNameValue
[] = {
1248 0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1249 static BYTE numericCommonNameValue
[] = {
1250 0x12,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1251 static BYTE printableCommonNameValue
[] = {
1252 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1253 static BYTE t61CommonNameValue
[] = {
1254 0x14,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1255 static BYTE videotexCommonNameValue
[] = {
1256 0x15,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1257 static BYTE ia5CommonNameValue
[] = {
1258 0x16,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1259 static BYTE graphicCommonNameValue
[] = {
1260 0x19,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1261 static BYTE visibleCommonNameValue
[] = {
1262 0x1a,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1263 static BYTE generalCommonNameValue
[] = {
1264 0x1b,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1265 static BYTE bmpCommonNameValue
[] = {
1266 0x1e,0x14,0x00,0x4a,0x00,0x75,0x00,0x61,0x00,0x6e,0x00,0x20,0x00,0x4c,0x00,
1267 0x61,0x00,0x6e,0x00,0x67,0x00,0x00 };
1268 static BYTE utf8CommonNameValue
[] = {
1269 0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1270 static char embedded_null
[] = "foo\0com";
1271 static BYTE ia5EmbeddedNull
[] = {
1272 0x16,0x07,0x66,0x6f,0x6f,0x00,0x63,0x6f,0x6d };
1274 static struct EncodedNameValue nameValues
[] = {
1275 { { CERT_RDN_OCTET_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1276 octetCommonNameValue
, sizeof(octetCommonNameValue
) },
1277 { { CERT_RDN_NUMERIC_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1278 numericCommonNameValue
, sizeof(numericCommonNameValue
) },
1279 { { CERT_RDN_PRINTABLE_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1280 printableCommonNameValue
, sizeof(printableCommonNameValue
) },
1281 { { CERT_RDN_T61_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1282 t61CommonNameValue
, sizeof(t61CommonNameValue
) },
1283 { { CERT_RDN_VIDEOTEX_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1284 videotexCommonNameValue
, sizeof(videotexCommonNameValue
) },
1285 { { CERT_RDN_IA5_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1286 ia5CommonNameValue
, sizeof(ia5CommonNameValue
) },
1287 { { CERT_RDN_GRAPHIC_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1288 graphicCommonNameValue
, sizeof(graphicCommonNameValue
) },
1289 { { CERT_RDN_VISIBLE_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1290 visibleCommonNameValue
, sizeof(visibleCommonNameValue
) },
1291 { { CERT_RDN_GENERAL_STRING
, { sizeof(commonName
), (BYTE
*)commonName
} },
1292 generalCommonNameValue
, sizeof(generalCommonNameValue
) },
1293 { { CERT_RDN_BMP_STRING
, { sizeof(commonNameW
), (BYTE
*)commonNameW
} },
1294 bmpCommonNameValue
, sizeof(bmpCommonNameValue
) },
1295 { { CERT_RDN_UTF8_STRING
, { sizeof(commonNameW
), (BYTE
*)commonNameW
} },
1296 utf8CommonNameValue
, sizeof(utf8CommonNameValue
) },
1297 /* The following tests succeed under Windows, but really should fail,
1298 * they contain characters that are illegal for the encoding. I'm
1299 * including them to justify my lazy encoding.
1301 { { CERT_RDN_IA5_STRING
, { sizeof(bogusIA5
), (BYTE
*)bogusIA5
} }, bin42
,
1303 { { CERT_RDN_PRINTABLE_STRING
, { sizeof(bogusPrintable
),
1304 (BYTE
*)bogusPrintable
} }, bin43
, sizeof(bin43
) },
1305 { { CERT_RDN_NUMERIC_STRING
, { sizeof(bogusNumeric
), (BYTE
*)bogusNumeric
} },
1306 bin44
, sizeof(bin44
) },
1308 /* This is kept separate, because the decoding doesn't return to the original
1311 static struct EncodedNameValue embeddedNullNameValue
= {
1312 { CERT_RDN_IA5_STRING
, { sizeof(embedded_null
) - 1, (BYTE
*)embedded_null
} },
1313 ia5EmbeddedNull
, sizeof(ia5EmbeddedNull
) };
1315 static void test_encodeNameValue(DWORD dwEncoding
)
1320 CERT_NAME_VALUE value
= { 0, { 0, NULL
} };
1322 value
.dwValueType
= CERT_RDN_ENCODED_BLOB
;
1323 value
.Value
.pbData
= printableCommonNameValue
;
1324 value
.Value
.cbData
= sizeof(printableCommonNameValue
);
1325 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_VALUE
, &value
,
1326 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1327 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1330 ok(size
== sizeof(printableCommonNameValue
), "Unexpected size %d\n",
1332 ok(!memcmp(buf
, printableCommonNameValue
, size
),
1333 "Unexpected encoding\n");
1336 for (i
= 0; i
< ARRAY_SIZE(nameValues
); i
++)
1338 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_VALUE
,
1339 &nameValues
[i
].value
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1340 ok(ret
|| broken(GetLastError() == OSS_PDU_MISMATCH
) /* NT4/Win9x */,
1341 "Type %d: CryptEncodeObjectEx failed: %08x\n",
1342 nameValues
[i
].value
.dwValueType
, GetLastError());
1345 ok(size
== nameValues
[i
].encodedSize
,
1346 "Expected size %d, got %d\n", nameValues
[i
].encodedSize
, size
);
1347 ok(!memcmp(buf
, nameValues
[i
].encoded
, size
),
1348 "Got unexpected encoding\n");
1352 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_VALUE
,
1353 &embeddedNullNameValue
.value
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1354 ok(ret
|| broken(GetLastError() == OSS_PDU_MISMATCH
) /* NT4/Win9x */,
1355 "Type %d: CryptEncodeObjectEx failed: %08x\n",
1356 embeddedNullNameValue
.value
.dwValueType
, GetLastError());
1359 ok(size
== embeddedNullNameValue
.encodedSize
,
1360 "Expected size %d, got %d\n", embeddedNullNameValue
.encodedSize
, size
);
1361 ok(!memcmp(buf
, embeddedNullNameValue
.encoded
, size
),
1362 "Got unexpected encoding\n");
1367 static void test_decodeNameValue(DWORD dwEncoding
)
1374 for (i
= 0; i
< ARRAY_SIZE(nameValues
); i
++)
1376 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME_VALUE
,
1377 nameValues
[i
].encoded
, nameValues
[i
].encoded
[1] + 2,
1378 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1380 ok(ret
, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
1381 nameValues
[i
].value
.dwValueType
, GetLastError());
1384 compareNameValues(&nameValues
[i
].value
,
1385 (const CERT_NAME_VALUE
*)buf
);
1389 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME_VALUE
,
1390 embeddedNullNameValue
.encoded
, embeddedNullNameValue
.encodedSize
,
1391 CRYPT_DECODE_ALLOC_FLAG
| CRYPT_DECODE_SHARE_OID_STRING_FLAG
, NULL
,
1393 /* Some Windows versions disallow name values with embedded NULLs, so
1394 * either success or failure is acceptable.
1398 CERT_NAME_VALUE rdnEncodedValue
= { CERT_RDN_ENCODED_BLOB
,
1399 { sizeof(ia5EmbeddedNull
), ia5EmbeddedNull
} };
1400 CERT_NAME_VALUE embeddedNullValue
= { CERT_RDN_IA5_STRING
,
1401 { sizeof(embedded_null
) - 1, (BYTE
*)embedded_null
} };
1402 const CERT_NAME_VALUE
*got
= (const CERT_NAME_VALUE
*)buf
,
1405 /* Some Windows versions decode name values with embedded NULLs,
1406 * others leave them encoded, even with the same version of crypt32.
1409 ok(got
->dwValueType
== CERT_RDN_ENCODED_BLOB
||
1410 got
->dwValueType
== CERT_RDN_IA5_STRING
,
1411 "Expected CERT_RDN_ENCODED_BLOB or CERT_RDN_IA5_STRING, got %d\n",
1413 if (got
->dwValueType
== CERT_RDN_ENCODED_BLOB
)
1414 expected
= &rdnEncodedValue
;
1415 else if (got
->dwValueType
== CERT_RDN_IA5_STRING
)
1416 expected
= &embeddedNullValue
;
1419 ok(got
->Value
.cbData
== expected
->Value
.cbData
,
1420 "String type %d: unexpected data size, got %d, expected %d\n",
1421 got
->dwValueType
, got
->Value
.cbData
, expected
->Value
.cbData
);
1422 if (got
->Value
.cbData
&& got
->Value
.pbData
)
1423 ok(!memcmp(got
->Value
.pbData
, expected
->Value
.pbData
,
1424 min(got
->Value
.cbData
, expected
->Value
.cbData
)),
1425 "String type %d: unexpected value\n", expected
->dwValueType
);
1431 static const BYTE emptyURL
[] = { 0x30, 0x02, 0x86, 0x00 };
1432 static const BYTE emptyURLExtraBytes
[] = { 0x30, 0x02, 0x86, 0x00, 0, 0, 0 };
1433 static const WCHAR url
[] = { 'h','t','t','p',':','/','/','w','i','n','e',
1434 'h','q','.','o','r','g',0 };
1435 static const BYTE encodedURL
[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74,
1436 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e,
1438 static const WCHAR nihongoURL
[] = { 'h','t','t','p',':','/','/',0x226f,
1440 static const WCHAR dnsName
[] = { 'w','i','n','e','h','q','.','o','r','g',0 };
1441 static const BYTE encodedDnsName
[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69,
1442 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
1443 static const BYTE localhost
[] = { 127, 0, 0, 1 };
1444 static const BYTE encodedIPAddr
[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00,
1446 static const unsigned char encodedCommonName
[] = {
1447 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0};
1448 static const BYTE encodedOidName
[] = { 0x30,0x04,0x88,0x02,0x2a,0x03 };
1449 static const BYTE encodedDirectoryName
[] = {
1450 0x30,0x19,0xa4,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1451 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1453 static void test_encodeAltName(DWORD dwEncoding
)
1455 CERT_ALT_NAME_INFO info
= { 0 };
1456 CERT_ALT_NAME_ENTRY entry
= { 0 };
1460 char oid
[] = "1.2.3";
1462 /* Test with empty info */
1463 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1464 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1467 ok(size
== sizeof(emptySequence
), "Wrong size %d\n", size
);
1468 ok(!memcmp(buf
, emptySequence
, size
), "Unexpected value\n");
1471 /* Test with an empty entry */
1473 info
.rgAltEntry
= &entry
;
1474 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1475 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1476 ok(!ret
&& GetLastError() == E_INVALIDARG
,
1477 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1478 /* Test with an empty pointer */
1479 entry
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
1480 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1481 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1484 ok(size
== sizeof(emptyURL
), "Wrong size %d\n", size
);
1485 ok(!memcmp(buf
, emptyURL
, size
), "Unexpected value\n");
1488 /* Test with a real URL */
1489 U(entry
).pwszURL
= (LPWSTR
)url
;
1490 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1491 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1494 ok(size
== sizeof(encodedURL
), "Wrong size %d\n", size
);
1495 ok(!memcmp(buf
, encodedURL
, size
), "Unexpected value\n");
1498 /* Now with the URL containing an invalid IA5 char */
1499 U(entry
).pwszURL
= (LPWSTR
)nihongoURL
;
1500 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1501 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1502 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_IA5_STRING
,
1503 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
1504 /* The first invalid character is at index 7 */
1505 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size
) == 7,
1506 "Expected invalid char at index 7, got %d\n",
1507 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size
));
1508 /* Now with the URL missing a scheme */
1509 U(entry
).pwszURL
= (LPWSTR
)dnsName
;
1510 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1511 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1512 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1515 /* This succeeds, but it shouldn't, so don't worry about conforming */
1518 /* Now with a DNS name */
1519 entry
.dwAltNameChoice
= CERT_ALT_NAME_DNS_NAME
;
1520 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1521 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1522 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1525 ok(size
== sizeof(encodedDnsName
), "Wrong size %d\n", size
);
1526 ok(!memcmp(buf
, encodedDnsName
, size
), "Unexpected value\n");
1529 /* Test with an IP address */
1530 entry
.dwAltNameChoice
= CERT_ALT_NAME_IP_ADDRESS
;
1531 U(entry
).IPAddress
.cbData
= sizeof(localhost
);
1532 U(entry
).IPAddress
.pbData
= (LPBYTE
)localhost
;
1533 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1534 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1537 ok(size
== sizeof(encodedIPAddr
), "Wrong size %d\n", size
);
1538 ok(!memcmp(buf
, encodedIPAddr
, size
), "Unexpected value\n");
1542 entry
.dwAltNameChoice
= CERT_ALT_NAME_REGISTERED_ID
;
1543 U(entry
).pszRegisteredID
= oid
;
1544 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1545 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1548 ok(size
== sizeof(encodedOidName
), "Wrong size %d\n", size
);
1549 ok(!memcmp(buf
, encodedOidName
, size
), "Unexpected value\n");
1552 /* Test with directory name */
1553 entry
.dwAltNameChoice
= CERT_ALT_NAME_DIRECTORY_NAME
;
1554 U(entry
).DirectoryName
.cbData
= sizeof(encodedCommonName
);
1555 U(entry
).DirectoryName
.pbData
= (LPBYTE
)encodedCommonName
;
1556 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, &info
,
1557 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1560 ok(size
== sizeof(encodedDirectoryName
), "Wrong size %d\n", size
);
1561 ok(!memcmp(buf
, encodedDirectoryName
, size
), "Unexpected value\n");
1566 static void test_decodeAltName(DWORD dwEncoding
)
1568 static const BYTE unimplementedType
[] = { 0x30, 0x06, 0x85, 0x04, 0x7f,
1570 static const BYTE bogusType
[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00,
1572 static const BYTE dns_embedded_null
[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f,
1573 0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 };
1574 static const BYTE dns_embedded_bell
[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f,
1575 0x6f,0x2e,0x63,0x6f,0x6d,0x07,0x62,0x61,0x64,0x64,0x69,0x65 };
1576 static const BYTE url_embedded_null
[] = { 0x30,0x10,0x86,0x0e,0x66,0x6f,
1577 0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 };
1581 CERT_ALT_NAME_INFO
*info
;
1583 /* Test some bogus ones first */
1584 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1585 unimplementedType
, sizeof(unimplementedType
), CRYPT_DECODE_ALLOC_FLAG
,
1586 NULL
, &buf
, &bufSize
);
1587 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_BADTAG
||
1588 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
1589 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
1591 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1592 bogusType
, sizeof(bogusType
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
,
1594 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
1595 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
1596 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
1598 /* Now expected cases */
1599 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, emptySequence
,
1600 emptySequence
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1601 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1604 info
= (CERT_ALT_NAME_INFO
*)buf
;
1606 ok(info
->cAltEntry
== 0, "Expected 0 entries, got %d\n",
1610 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, emptyURL
,
1611 emptyURL
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1612 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1615 info
= (CERT_ALT_NAME_INFO
*)buf
;
1617 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1619 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_URL
,
1620 "Expected CERT_ALT_NAME_URL, got %d\n",
1621 info
->rgAltEntry
[0].dwAltNameChoice
);
1622 ok(U(info
->rgAltEntry
[0]).pwszURL
== NULL
|| !*U(info
->rgAltEntry
[0]).pwszURL
,
1623 "Expected empty URL\n");
1626 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1627 emptyURLExtraBytes
, sizeof(emptyURLExtraBytes
), 0, NULL
, NULL
, &bufSize
);
1628 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1629 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, encodedURL
,
1630 encodedURL
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1631 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1634 info
= (CERT_ALT_NAME_INFO
*)buf
;
1636 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1638 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_URL
,
1639 "Expected CERT_ALT_NAME_URL, got %d\n",
1640 info
->rgAltEntry
[0].dwAltNameChoice
);
1641 ok(!lstrcmpW(U(info
->rgAltEntry
[0]).pwszURL
, url
), "Unexpected URL\n");
1644 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, encodedDnsName
,
1645 encodedDnsName
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1646 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1649 info
= (CERT_ALT_NAME_INFO
*)buf
;
1651 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1653 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_DNS_NAME
,
1654 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1655 info
->rgAltEntry
[0].dwAltNameChoice
);
1656 ok(!lstrcmpW(U(info
->rgAltEntry
[0]).pwszDNSName
, dnsName
),
1657 "Unexpected DNS name\n");
1660 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, encodedIPAddr
,
1661 encodedIPAddr
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1662 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1665 info
= (CERT_ALT_NAME_INFO
*)buf
;
1667 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1669 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_IP_ADDRESS
,
1670 "Expected CERT_ALT_NAME_IP_ADDRESS, got %d\n",
1671 info
->rgAltEntry
[0].dwAltNameChoice
);
1672 ok(U(info
->rgAltEntry
[0]).IPAddress
.cbData
== sizeof(localhost
),
1673 "Unexpected IP address length %d\n",
1674 U(info
->rgAltEntry
[0]).IPAddress
.cbData
);
1675 ok(!memcmp(U(info
->rgAltEntry
[0]).IPAddress
.pbData
, localhost
,
1676 sizeof(localhost
)), "Unexpected IP address value\n");
1679 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
, encodedOidName
,
1680 sizeof(encodedOidName
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1681 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1684 info
= (CERT_ALT_NAME_INFO
*)buf
;
1686 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1688 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_REGISTERED_ID
,
1689 "Expected CERT_ALT_NAME_REGISTERED_ID, got %d\n",
1690 info
->rgAltEntry
[0].dwAltNameChoice
);
1691 ok(!strcmp(U(info
->rgAltEntry
[0]).pszRegisteredID
, "1.2.3"),
1692 "Expected OID 1.2.3, got %s\n", U(info
->rgAltEntry
[0]).pszRegisteredID
);
1695 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1696 encodedDirectoryName
, sizeof(encodedDirectoryName
),
1697 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1698 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1701 info
= (CERT_ALT_NAME_INFO
*)buf
;
1703 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1705 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_DIRECTORY_NAME
,
1706 "Expected CERT_ALT_NAME_DIRECTORY_NAME, got %d\n",
1707 info
->rgAltEntry
[0].dwAltNameChoice
);
1708 ok(U(info
->rgAltEntry
[0]).DirectoryName
.cbData
==
1709 sizeof(encodedCommonName
), "Unexpected directory name length %d\n",
1710 U(info
->rgAltEntry
[0]).DirectoryName
.cbData
);
1711 ok(!memcmp(U(info
->rgAltEntry
[0]).DirectoryName
.pbData
,
1712 encodedCommonName
, sizeof(encodedCommonName
)),
1713 "Unexpected directory name value\n");
1716 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1717 dns_embedded_null
, sizeof(dns_embedded_null
), CRYPT_DECODE_ALLOC_FLAG
,
1718 NULL
, &buf
, &bufSize
);
1719 /* Fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned about the
1720 * particular failure, just that it doesn't decode.
1721 * It succeeds on (broken) Windows versions that haven't addressed
1722 * embedded NULLs in alternate names.
1724 ok(!ret
|| broken(ret
), "expected failure\n");
1725 /* An embedded bell character is allowed, however. */
1726 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1727 dns_embedded_bell
, sizeof(dns_embedded_bell
), CRYPT_DECODE_ALLOC_FLAG
,
1728 NULL
, &buf
, &bufSize
);
1729 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1732 info
= (CERT_ALT_NAME_INFO
*)buf
;
1734 ok(info
->cAltEntry
== 1, "Expected 1 entries, got %d\n",
1736 ok(info
->rgAltEntry
[0].dwAltNameChoice
== CERT_ALT_NAME_DNS_NAME
,
1737 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1738 info
->rgAltEntry
[0].dwAltNameChoice
);
1741 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ALTERNATE_NAME
,
1742 url_embedded_null
, sizeof(dns_embedded_null
), CRYPT_DECODE_ALLOC_FLAG
,
1743 NULL
, &buf
, &bufSize
);
1744 /* Again, fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned
1745 * about the particular failure, just that it doesn't decode.
1746 * It succeeds on (broken) Windows versions that haven't addressed
1747 * embedded NULLs in alternate names.
1749 ok(!ret
|| broken(ret
), "expected failure\n");
1752 struct UnicodeExpectedError
1760 static const WCHAR oneW
[] = { '1',0 };
1761 static const WCHAR aW
[] = { 'a',0 };
1762 static const WCHAR quoteW
[] = { '"', 0 };
1764 static struct UnicodeExpectedError unicodeErrors
[] = {
1765 { CERT_RDN_ANY_TYPE
, oneW
, 0, CRYPT_E_NOT_CHAR_STRING
},
1766 { CERT_RDN_ENCODED_BLOB
, oneW
, 0, CRYPT_E_NOT_CHAR_STRING
},
1767 { CERT_RDN_OCTET_STRING
, oneW
, 0, CRYPT_E_NOT_CHAR_STRING
},
1768 { CERT_RDN_NUMERIC_STRING
, aW
, 0, CRYPT_E_INVALID_NUMERIC_STRING
},
1769 { CERT_RDN_PRINTABLE_STRING
, quoteW
, 0, CRYPT_E_INVALID_PRINTABLE_STRING
},
1770 { CERT_RDN_IA5_STRING
, nihongoURL
, 7, CRYPT_E_INVALID_IA5_STRING
},
1773 struct UnicodeExpectedResult
1777 CRYPT_DATA_BLOB encoded
;
1780 static BYTE oneNumeric
[] = { 0x12, 0x01, 0x31 };
1781 static BYTE onePrintable
[] = { 0x13, 0x01, 0x31 };
1782 static BYTE oneTeletex
[] = { 0x14, 0x01, 0x31 };
1783 static BYTE oneVideotex
[] = { 0x15, 0x01, 0x31 };
1784 static BYTE oneIA5
[] = { 0x16, 0x01, 0x31 };
1785 static BYTE oneGraphic
[] = { 0x19, 0x01, 0x31 };
1786 static BYTE oneVisible
[] = { 0x1a, 0x01, 0x31 };
1787 static BYTE oneUniversal
[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 };
1788 static BYTE oneGeneral
[] = { 0x1b, 0x01, 0x31 };
1789 static BYTE oneBMP
[] = { 0x1e, 0x02, 0x00, 0x31 };
1790 static BYTE oneUTF8
[] = { 0x0c, 0x01, 0x31 };
1791 static BYTE nihongoT61
[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,
1793 static BYTE nihongoGeneral
[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1795 static BYTE nihongoBMP
[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,
1796 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
1797 static BYTE nihongoUTF8
[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1798 0xe2,0x89,0xaf,0xe5,0x9d,0x9b };
1800 static struct UnicodeExpectedResult unicodeResults
[] = {
1801 { CERT_RDN_NUMERIC_STRING
, oneW
, { sizeof(oneNumeric
), oneNumeric
} },
1802 { CERT_RDN_PRINTABLE_STRING
, oneW
, { sizeof(onePrintable
), onePrintable
} },
1803 { CERT_RDN_TELETEX_STRING
, oneW
, { sizeof(oneTeletex
), oneTeletex
} },
1804 { CERT_RDN_VIDEOTEX_STRING
, oneW
, { sizeof(oneVideotex
), oneVideotex
} },
1805 { CERT_RDN_IA5_STRING
, oneW
, { sizeof(oneIA5
), oneIA5
} },
1806 { CERT_RDN_GRAPHIC_STRING
, oneW
, { sizeof(oneGraphic
), oneGraphic
} },
1807 { CERT_RDN_VISIBLE_STRING
, oneW
, { sizeof(oneVisible
), oneVisible
} },
1808 { CERT_RDN_UNIVERSAL_STRING
, oneW
, { sizeof(oneUniversal
), oneUniversal
} },
1809 { CERT_RDN_GENERAL_STRING
, oneW
, { sizeof(oneGeneral
), oneGeneral
} },
1810 { CERT_RDN_BMP_STRING
, oneW
, { sizeof(oneBMP
), oneBMP
} },
1811 { CERT_RDN_UTF8_STRING
, oneW
, { sizeof(oneUTF8
), oneUTF8
} },
1812 { CERT_RDN_BMP_STRING
, nihongoURL
, { sizeof(nihongoBMP
), nihongoBMP
} },
1813 { CERT_RDN_UTF8_STRING
, nihongoURL
, { sizeof(nihongoUTF8
), nihongoUTF8
} },
1816 static struct UnicodeExpectedResult unicodeWeirdness
[] = {
1817 { CERT_RDN_TELETEX_STRING
, nihongoURL
, { sizeof(nihongoT61
), nihongoT61
} },
1818 { CERT_RDN_GENERAL_STRING
, nihongoURL
, { sizeof(nihongoGeneral
), nihongoGeneral
} },
1821 static void test_encodeUnicodeNameValue(DWORD dwEncoding
)
1826 CERT_NAME_VALUE value
;
1830 /* Crashes on win9x */
1831 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, NULL
,
1832 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1833 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
1834 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1836 /* Have to have a string of some sort */
1837 value
.dwValueType
= 0; /* aka CERT_RDN_ANY_TYPE */
1838 value
.Value
.pbData
= NULL
;
1839 value
.Value
.cbData
= 0;
1840 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1841 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1842 ok(!ret
&& GetLastError() == CRYPT_E_NOT_CHAR_STRING
,
1843 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1844 value
.dwValueType
= CERT_RDN_ENCODED_BLOB
;
1845 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1846 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1847 ok(!ret
&& GetLastError() == CRYPT_E_NOT_CHAR_STRING
,
1848 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1849 value
.dwValueType
= CERT_RDN_ANY_TYPE
;
1850 value
.Value
.pbData
= (LPBYTE
)oneW
;
1851 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1852 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1853 ok(!ret
&& GetLastError() == CRYPT_E_NOT_CHAR_STRING
,
1854 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1855 value
.Value
.cbData
= sizeof(oneW
);
1856 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1857 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1858 ok(!ret
&& GetLastError() == CRYPT_E_NOT_CHAR_STRING
,
1859 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1860 /* An encoded string with specified length isn't good enough either */
1861 value
.dwValueType
= CERT_RDN_ENCODED_BLOB
;
1862 value
.Value
.pbData
= oneUniversal
;
1863 value
.Value
.cbData
= sizeof(oneUniversal
);
1864 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1865 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1866 ok(!ret
&& GetLastError() == CRYPT_E_NOT_CHAR_STRING
,
1867 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1868 /* More failure checking */
1869 value
.Value
.cbData
= 0;
1870 for (i
= 0; i
< ARRAY_SIZE(unicodeErrors
); i
++)
1872 value
.Value
.pbData
= (LPBYTE
)unicodeErrors
[i
].str
;
1873 value
.dwValueType
= unicodeErrors
[i
].valueType
;
1874 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1875 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1876 ok(!ret
&& GetLastError() == unicodeErrors
[i
].error
,
1877 "Value type %d: expected %08x, got %08x\n", value
.dwValueType
,
1878 unicodeErrors
[i
].error
, GetLastError());
1879 ok(size
== unicodeErrors
[i
].errorIndex
,
1880 "Expected error index %d, got %d\n", unicodeErrors
[i
].errorIndex
,
1883 /* cbData can be zero if the string is NULL-terminated */
1884 value
.Value
.cbData
= 0;
1885 for (i
= 0; i
< ARRAY_SIZE(unicodeResults
); i
++)
1887 value
.Value
.pbData
= (LPBYTE
)unicodeResults
[i
].str
;
1888 value
.dwValueType
= unicodeResults
[i
].valueType
;
1889 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1890 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1891 ok(ret
|| broken(GetLastError() == OSS_PDU_MISMATCH
/* Win9x */),
1892 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1895 ok(size
== unicodeResults
[i
].encoded
.cbData
,
1896 "Value type %d: expected size %d, got %d\n",
1897 value
.dwValueType
, unicodeResults
[i
].encoded
.cbData
, size
);
1898 ok(!memcmp(unicodeResults
[i
].encoded
.pbData
, buf
, size
),
1899 "Value type %d: unexpected value\n", value
.dwValueType
);
1903 /* These "encode," but they do so by truncating each unicode character
1904 * rather than properly encoding it. Kept separate from the proper results,
1905 * because the encoded forms won't decode to their original strings.
1907 for (i
= 0; i
< ARRAY_SIZE(unicodeWeirdness
); i
++)
1909 value
.Value
.pbData
= (LPBYTE
)unicodeWeirdness
[i
].str
;
1910 value
.dwValueType
= unicodeWeirdness
[i
].valueType
;
1911 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
, &value
,
1912 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1913 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1916 ok(size
== unicodeWeirdness
[i
].encoded
.cbData
,
1917 "Value type %d: expected size %d, got %d\n",
1918 value
.dwValueType
, unicodeWeirdness
[i
].encoded
.cbData
, size
);
1919 ok(!memcmp(unicodeWeirdness
[i
].encoded
.pbData
, buf
, size
),
1920 "Value type %d: unexpected value\n", value
.dwValueType
);
1926 static void test_decodeUnicodeNameValue(DWORD dwEncoding
)
1930 for (i
= 0; i
< ARRAY_SIZE(unicodeResults
); i
++)
1936 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_UNICODE_NAME_VALUE
,
1937 unicodeResults
[i
].encoded
.pbData
, unicodeResults
[i
].encoded
.cbData
,
1938 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
1939 ok(ret
|| broken(GetLastError() == CRYPT_E_NOT_CHAR_STRING
/* Win9x */),
1940 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1943 PCERT_NAME_VALUE value
= (PCERT_NAME_VALUE
)buf
;
1945 ok(value
->dwValueType
== unicodeResults
[i
].valueType
,
1946 "Expected value type %d, got %d\n", unicodeResults
[i
].valueType
,
1947 value
->dwValueType
);
1948 ok(!wcsncmp((LPWSTR
)value
->Value
.pbData
, unicodeResults
[i
].str
,
1949 value
->Value
.cbData
/ sizeof(WCHAR
)),
1950 "Unexpected decoded value for index %d (value type %d)\n", i
,
1951 unicodeResults
[i
].valueType
);
1957 static const unsigned char decoded_hi_octet
[] = { 'h','i' };
1958 static const unsigned char encoded_hi_octet
[] = { ASN_OCTETSTRING
,2,'h','i' };
1959 static const unsigned char decoded_something_long_octet
[] = {
1960 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g' };
1961 static const unsigned char encoded_something_long_octet
[] = {
1962 ASN_OCTETSTRING
,15,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g' };
1963 static const unsigned char encoded_empty_octet
[] = { ASN_OCTETSTRING
,0 };
1965 static void test_encodeOctets(DWORD dwEncoding
)
1967 CRYPT_DATA_BLOB blob
;
1970 static const struct {
1971 const BYTE
*decoded
;
1973 const BYTE
*encoded
;
1977 decoded_hi_octet
, sizeof(decoded_hi_octet
),
1978 encoded_hi_octet
, sizeof(encoded_hi_octet
)
1980 decoded_something_long_octet
, sizeof(decoded_something_long_octet
),
1981 encoded_something_long_octet
, sizeof(encoded_something_long_octet
)
1983 encoded_empty_octet
, 0,
1984 encoded_empty_octet
, sizeof(encoded_empty_octet
)
1988 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
1994 blob
.cbData
= tests
[i
].decoded_size
;
1995 blob
.pbData
= (BYTE
*)tests
[i
].decoded
;
1996 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_OCTET_STRING
, &blob
,
1997 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
1998 ok(ret
, "CryptEncodeObjectEx failed: %d\n", GetLastError());
2001 ok(bufSize
== tests
[i
].encoded_size
, "[%u] buf size %u expected %u\n",
2002 i
, bufSize
, tests
[i
].encoded_size
);
2003 ok(buf
[0] == 4, "Got unexpected type %d for octet string (expected 4)\n", buf
[0]);
2004 ok(buf
[1] == tests
[i
].decoded_size
, "[%u] Got length %d, expected %d\n",
2005 i
, buf
[1], tests
[i
].decoded_size
);
2006 ok(!memcmp(buf
, tests
[i
].encoded
, tests
[i
].encoded_size
), "[%u] Got unexpected value\n", i
);
2012 static const unsigned char encoded_constructed_hi_octet
[] =
2013 { ASN_CONSTRUCTOR
|ASN_OCTETSTRING
,0x80, ASN_OCTETSTRING
,2,'h','i', 0,0 };
2014 static const unsigned char encoded_constructed_hi_octet2
[] =
2015 { ASN_CONSTRUCTOR
|ASN_OCTETSTRING
,4, ASN_OCTETSTRING
,2,'h','i', 1,2,3 };
2016 static const unsigned char encoded_constructed_hi_octet3
[] =
2017 { ASN_CONSTRUCTOR
|ASN_OCTETSTRING
,8, ASN_CONSTRUCTOR
|ASN_OCTETSTRING
,0x80, ASN_OCTETSTRING
,2,'h','i', 0,0, 0,0 };
2018 static const unsigned char encoded_constructed_hi_octet_invalid_end
[] =
2019 { ASN_CONSTRUCTOR
|ASN_OCTETSTRING
,0x80, ASN_OCTETSTRING
,2,'h','i', 0,1 };
2021 static void test_decodeOctets(DWORD dwEncoding
)
2025 static const struct {
2026 const BYTE
*encoded
;
2028 const BYTE
*decoded
;
2033 encoded_hi_octet
, sizeof(encoded_hi_octet
),
2034 decoded_hi_octet
, sizeof(decoded_hi_octet
)
2036 encoded_something_long_octet
, sizeof(encoded_something_long_octet
),
2037 decoded_something_long_octet
, sizeof(decoded_something_long_octet
)
2039 encoded_constructed_hi_octet
, sizeof(encoded_constructed_hi_octet
),
2040 decoded_hi_octet
, sizeof(decoded_hi_octet
)
2042 encoded_constructed_hi_octet2
, sizeof(encoded_constructed_hi_octet2
),
2043 decoded_hi_octet
, sizeof(decoded_hi_octet
)
2045 encoded_constructed_hi_octet3
, sizeof(encoded_constructed_hi_octet3
),
2046 decoded_hi_octet
, sizeof(decoded_hi_octet
)
2048 encoded_empty_octet
, sizeof(encoded_empty_octet
),
2049 encoded_empty_octet
, 0
2051 encoded_hi_octet
, sizeof(encoded_hi_octet
) - 1,
2052 NULL
, 0, CRYPT_E_ASN1_EOD
2054 encoded_constructed_hi_octet
, sizeof(encoded_constructed_hi_octet
) - 1,
2055 NULL
, 0, CRYPT_E_ASN1_EOD
2057 encoded_constructed_hi_octet_invalid_end
, sizeof(encoded_constructed_hi_octet_invalid_end
),
2058 NULL
, 0, CRYPT_E_ASN1_CORRUPT
2062 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
2068 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_OCTET_STRING
,
2069 tests
[i
].encoded
, tests
[i
].encoded_size
,
2070 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2073 ok(!ret
&& GetLastError() == tests
[i
].error
,
2074 "[%u] CryptDecodeObjectEx returned %x(%x)\n", i
, ret
, GetLastError());
2077 ok(ret
, "[%u] CryptDecodeObjectEx failed: %08x\n", i
, GetLastError());
2078 ok(bufSize
>= sizeof(CRYPT_DATA_BLOB
) + tests
[i
].decoded_size
,
2079 "[%u] Expected size >= %d, got %d\n", i
,
2080 (int)sizeof(CRYPT_DATA_BLOB
) + tests
[i
].decoded_size
, bufSize
);
2081 ok(buf
!= NULL
, "Expected allocated buffer\n");
2084 CRYPT_DATA_BLOB
*blob
= (CRYPT_DATA_BLOB
*)buf
;
2086 ok (blob
->cbData
== tests
[i
].decoded_size
, "[%u] cbData = %u\n", i
, blob
->cbData
);
2088 ok(!memcmp(blob
->pbData
, tests
[i
].decoded
, blob
->cbData
),
2089 "Unexpected value\n");
2095 static const BYTE bytesToEncode
[] = { 0xff, 0xff };
2100 const BYTE
*encoded
;
2102 const BYTE
*decoded
;
2105 static const unsigned char bin52
[] = { 0x03,0x03,0x00,0xff,0xff };
2106 static const unsigned char bin53
[] = { 0xff,0xff };
2107 static const unsigned char bin54
[] = { 0x03,0x03,0x01,0xff,0xfe };
2108 static const unsigned char bin55
[] = { 0xff,0xfe };
2109 static const unsigned char bin56
[] = { 0x03,0x02,0x01,0xfe };
2110 static const unsigned char bin57
[] = { 0xfe };
2112 static const struct encodedBits bits
[] = {
2113 /* normal test cases */
2114 { 0, bin52
, 2, bin53
},
2115 { 1, bin54
, 2, bin55
},
2116 /* strange test case, showing cUnusedBits >= 8 is allowed */
2117 { 9, bin56
, 1, bin57
},
2120 static void test_encodeBits(DWORD dwEncoding
)
2124 for (i
= 0; i
< ARRAY_SIZE(bits
); i
++)
2126 CRYPT_BIT_BLOB blob
;
2131 blob
.cbData
= sizeof(bytesToEncode
);
2132 blob
.pbData
= (BYTE
*)bytesToEncode
;
2133 blob
.cUnusedBits
= bits
[i
].cUnusedBits
;
2134 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_BITS
, &blob
,
2135 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2136 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2139 ok(bufSize
== bits
[i
].encoded
[1] + 2,
2140 "%d: Got unexpected size %d, expected %d\n", i
, bufSize
,
2141 bits
[i
].encoded
[1] + 2);
2142 ok(!memcmp(buf
, bits
[i
].encoded
, bits
[i
].encoded
[1] + 2),
2143 "%d: Unexpected value\n", i
);
2149 static void test_decodeBits(DWORD dwEncoding
)
2151 static const BYTE ber
[] = "\x03\x02\x01\xff";
2152 static const BYTE berDecoded
= 0xfe;
2159 for (i
= 0; i
< ARRAY_SIZE(bits
); i
++)
2161 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BITS
, bits
[i
].encoded
,
2162 bits
[i
].encoded
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
,
2164 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2167 CRYPT_BIT_BLOB
*blob
;
2169 ok(bufSize
>= sizeof(CRYPT_BIT_BLOB
) + bits
[i
].cbDecoded
,
2170 "Got unexpected size %d\n", bufSize
);
2171 blob
= (CRYPT_BIT_BLOB
*)buf
;
2172 ok(blob
->cbData
== bits
[i
].cbDecoded
,
2173 "Got unexpected length %d, expected %d\n", blob
->cbData
,
2175 if (blob
->cbData
&& bits
[i
].cbDecoded
)
2176 ok(!memcmp(blob
->pbData
, bits
[i
].decoded
, bits
[i
].cbDecoded
),
2177 "Unexpected value\n");
2181 /* special case: check that something that's valid in BER but not in DER
2182 * decodes successfully
2184 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BITS
, ber
, ber
[1] + 2,
2185 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2186 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2189 CRYPT_BIT_BLOB
*blob
;
2191 ok(bufSize
>= sizeof(CRYPT_BIT_BLOB
) + sizeof(berDecoded
),
2192 "Got unexpected size %d\n", bufSize
);
2193 blob
= (CRYPT_BIT_BLOB
*)buf
;
2194 ok(blob
->cbData
== sizeof(berDecoded
),
2195 "Got unexpected length %d\n", blob
->cbData
);
2197 ok(*blob
->pbData
== berDecoded
, "Unexpected value\n");
2204 CERT_BASIC_CONSTRAINTS2_INFO info
;
2205 const BYTE
*encoded
;
2208 static const unsigned char bin59
[] = { 0x30,0x00 };
2209 static const unsigned char bin60
[] = { 0x30,0x03,0x01,0x01,0xff };
2210 static const unsigned char bin61
[] = { 0x30,0x03,0x02,0x01,0x00 };
2211 static const unsigned char bin62
[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2212 static const struct Constraints2 constraints2
[] = {
2213 /* empty constraints */
2214 { { FALSE
, FALSE
, 0}, bin59
},
2216 { { TRUE
, FALSE
, 0}, bin60
},
2217 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well,
2218 * but that's not the case
2220 { { FALSE
, TRUE
, 0}, bin61
},
2221 /* can be a CA and has path length constraints set */
2222 { { TRUE
, TRUE
, 1}, bin62
},
2225 static const BYTE emptyConstraint
[] = { 0x30, 0x03, 0x03, 0x01, 0x00 };
2226 static const BYTE encodedDomainName
[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11,
2227 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
2228 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
2229 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2230 static const BYTE constraintWithDomainName
[] = { 0x30, 0x32, 0x03, 0x01, 0x00,
2231 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
2232 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30,
2233 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
2234 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2236 static void test_encodeBasicConstraints(DWORD dwEncoding
)
2238 DWORD i
, bufSize
= 0;
2239 CERT_BASIC_CONSTRAINTS_INFO info
= { { 0 } };
2240 CERT_NAME_BLOB nameBlob
= { sizeof(encodedDomainName
),
2241 (LPBYTE
)encodedDomainName
};
2245 /* First test with the simpler info2 */
2246 for (i
= 0; i
< ARRAY_SIZE(constraints2
); i
++)
2248 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS2
,
2249 &constraints2
[i
].info
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
,
2251 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2254 ok(bufSize
== constraints2
[i
].encoded
[1] + 2,
2255 "Expected %d bytes, got %d\n", constraints2
[i
].encoded
[1] + 2,
2257 ok(!memcmp(buf
, constraints2
[i
].encoded
,
2258 constraints2
[i
].encoded
[1] + 2), "Unexpected value\n");
2262 /* Now test with more complex basic constraints */
2263 info
.SubjectType
.cbData
= 0;
2264 info
.fPathLenConstraint
= FALSE
;
2265 info
.cSubtreesConstraint
= 0;
2266 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS
, &info
,
2267 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2268 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
2269 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2272 ok(bufSize
== sizeof(emptyConstraint
), "Wrong size %d\n", bufSize
);
2273 ok(!memcmp(buf
, emptyConstraint
, sizeof(emptyConstraint
)),
2274 "Unexpected value\n");
2277 /* None of the certs I examined had any subtree constraint, but I test one
2278 * anyway just in case.
2280 info
.cSubtreesConstraint
= 1;
2281 info
.rgSubtreesConstraint
= &nameBlob
;
2282 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS
, &info
,
2283 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2284 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
2285 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2288 ok(bufSize
== sizeof(constraintWithDomainName
), "Wrong size %d\n", bufSize
);
2289 ok(!memcmp(buf
, constraintWithDomainName
,
2290 sizeof(constraintWithDomainName
)), "Unexpected value\n");
2293 /* FIXME: test encoding with subject type. */
2296 static const unsigned char bin63
[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 };
2298 static void test_decodeBasicConstraints(DWORD dwEncoding
)
2300 static const BYTE inverted
[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01,
2302 static const struct Constraints2 badBool
= { { TRUE
, TRUE
, 1 }, bin63
};
2308 /* First test with simpler info2 */
2309 for (i
= 0; i
< ARRAY_SIZE(constraints2
); i
++)
2311 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS2
,
2312 constraints2
[i
].encoded
, constraints2
[i
].encoded
[1] + 2,
2313 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2314 ok(ret
, "CryptDecodeObjectEx failed for item %d: %08x\n", i
,
2318 CERT_BASIC_CONSTRAINTS2_INFO
*info
=
2319 (CERT_BASIC_CONSTRAINTS2_INFO
*)buf
;
2321 ok(!memcmp(info
, &constraints2
[i
].info
, sizeof(*info
)),
2322 "Unexpected value for item %d\n", i
);
2326 /* Check with the order of encoded elements inverted */
2328 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS2
,
2329 inverted
, inverted
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
,
2331 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
2332 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
2333 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2335 ok(!buf
, "Expected buf to be set to NULL\n");
2336 /* Check with a non-DER bool */
2337 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS2
,
2338 badBool
.encoded
, badBool
.encoded
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
2340 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2343 CERT_BASIC_CONSTRAINTS2_INFO
*info
=
2344 (CERT_BASIC_CONSTRAINTS2_INFO
*)buf
;
2346 ok(!memcmp(info
, &badBool
.info
, sizeof(*info
)), "Unexpected value\n");
2349 /* Check with a non-basic constraints value */
2350 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS2
,
2351 encodedCommonName
, encodedCommonName
[1] + 2,
2352 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2353 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
2354 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
2355 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2357 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */
2358 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS
,
2359 emptyConstraint
, sizeof(emptyConstraint
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
2361 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2364 CERT_BASIC_CONSTRAINTS_INFO
*info
= (CERT_BASIC_CONSTRAINTS_INFO
*)buf
;
2366 ok(info
->SubjectType
.cbData
== 0, "Expected no subject type\n");
2367 ok(!info
->fPathLenConstraint
, "Expected no path length constraint\n");
2368 ok(info
->cSubtreesConstraint
== 0, "Expected no subtree constraints\n");
2371 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_BASIC_CONSTRAINTS
,
2372 constraintWithDomainName
, sizeof(constraintWithDomainName
),
2373 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2374 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2377 CERT_BASIC_CONSTRAINTS_INFO
*info
= (CERT_BASIC_CONSTRAINTS_INFO
*)buf
;
2379 ok(info
->SubjectType
.cbData
== 0, "Expected no subject type\n");
2380 ok(!info
->fPathLenConstraint
, "Expected no path length constraint\n");
2381 ok(info
->cSubtreesConstraint
== 1, "Expected a subtree constraint\n");
2382 if (info
->cSubtreesConstraint
&& info
->rgSubtreesConstraint
)
2384 ok(info
->rgSubtreesConstraint
[0].cbData
==
2385 sizeof(encodedDomainName
), "Wrong size %d\n",
2386 info
->rgSubtreesConstraint
[0].cbData
);
2387 ok(!memcmp(info
->rgSubtreesConstraint
[0].pbData
, encodedDomainName
,
2388 sizeof(encodedDomainName
)), "Unexpected value\n");
2394 /* These are terrible public keys of course, I'm just testing encoding */
2395 static const BYTE modulus1
[] = { 0,0,0,1,1,1,1,1 };
2396 static const BYTE modulus2
[] = { 1,1,1,1,1,0,0,0 };
2397 static const BYTE modulus3
[] = { 0x80,1,1,1,1,0,0,0 };
2398 static const BYTE modulus4
[] = { 1,1,1,1,1,0,0,0x80 };
2399 static const BYTE mod1_encoded
[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 };
2400 static const BYTE mod2_encoded
[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2401 static const BYTE mod3_encoded
[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 };
2402 static const BYTE mod4_encoded
[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2404 struct EncodedRSAPubKey
2406 const BYTE
*modulus
;
2408 const BYTE
*encoded
;
2409 size_t decodedModulusLen
;
2412 static const struct EncodedRSAPubKey rsaPubKeys
[] = {
2413 { modulus1
, sizeof(modulus1
), mod1_encoded
, sizeof(modulus1
) },
2414 { modulus2
, sizeof(modulus2
), mod2_encoded
, 5 },
2415 { modulus3
, sizeof(modulus3
), mod3_encoded
, 5 },
2416 { modulus4
, sizeof(modulus4
), mod4_encoded
, 8 },
2419 static void test_encodeRsaPublicKey(DWORD dwEncoding
)
2421 BYTE toEncode
[sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) + sizeof(modulus1
)];
2422 BLOBHEADER
*hdr
= (BLOBHEADER
*)toEncode
;
2423 RSAPUBKEY
*rsaPubKey
= (RSAPUBKEY
*)(toEncode
+ sizeof(BLOBHEADER
));
2426 DWORD bufSize
= 0, i
;
2428 /* Try with a bogus blob type */
2430 hdr
->bVersion
= CUR_BLOB_VERSION
;
2432 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
2433 rsaPubKey
->magic
= 0x31415352;
2434 rsaPubKey
->bitlen
= sizeof(modulus1
) * 8;
2435 rsaPubKey
->pubexp
= 65537;
2436 memcpy(toEncode
+ sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
), modulus1
,
2439 ret
= pCryptEncodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2440 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2441 ok(!ret
&& GetLastError() == E_INVALIDARG
,
2442 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2443 /* Now with a bogus reserved field */
2444 hdr
->bType
= PUBLICKEYBLOB
;
2446 ret
= pCryptEncodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2447 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2450 ok(bufSize
== rsaPubKeys
[0].encoded
[1] + 2,
2451 "Expected size %d, got %d\n", rsaPubKeys
[0].encoded
[1] + 2, bufSize
);
2452 ok(!memcmp(buf
, rsaPubKeys
[0].encoded
, bufSize
), "Unexpected value\n");
2455 /* Now with a bogus blob version */
2458 ret
= pCryptEncodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2459 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2462 ok(bufSize
== rsaPubKeys
[0].encoded
[1] + 2,
2463 "Expected size %d, got %d\n", rsaPubKeys
[0].encoded
[1] + 2, bufSize
);
2464 ok(!memcmp(buf
, rsaPubKeys
[0].encoded
, bufSize
), "Unexpected value\n");
2467 /* And with a bogus alg ID */
2468 hdr
->bVersion
= CUR_BLOB_VERSION
;
2469 hdr
->aiKeyAlg
= CALG_DES
;
2470 ret
= pCryptEncodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2471 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2474 ok(bufSize
== rsaPubKeys
[0].encoded
[1] + 2,
2475 "Expected size %d, got %d\n", rsaPubKeys
[0].encoded
[1] + 2, bufSize
);
2476 ok(!memcmp(buf
, rsaPubKeys
[0].encoded
, bufSize
), "Unexpected value\n");
2479 /* Check a couple of RSA-related OIDs */
2480 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
2481 ret
= pCryptEncodeObjectEx(dwEncoding
, szOID_RSA_RSA
,
2482 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2483 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
2484 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2485 ret
= pCryptEncodeObjectEx(dwEncoding
, szOID_RSA_SHA1RSA
,
2486 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2487 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
2488 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2489 /* Finally, all valid */
2490 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
2491 for (i
= 0; i
< ARRAY_SIZE(rsaPubKeys
); i
++)
2493 memcpy(toEncode
+ sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
),
2494 rsaPubKeys
[i
].modulus
, rsaPubKeys
[i
].modulusLen
);
2495 ret
= pCryptEncodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2496 toEncode
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2497 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2500 ok(bufSize
== rsaPubKeys
[i
].encoded
[1] + 2,
2501 "Expected size %d, got %d\n", rsaPubKeys
[i
].encoded
[1] + 2,
2503 ok(!memcmp(buf
, rsaPubKeys
[i
].encoded
, bufSize
),
2504 "Unexpected value\n");
2510 static void test_decodeRsaPublicKey(DWORD dwEncoding
)
2517 /* Try with a bad length */
2518 ret
= pCryptDecodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2519 rsaPubKeys
[0].encoded
, rsaPubKeys
[0].encoded
[1],
2520 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2521 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_EOD
||
2522 GetLastError() == OSS_MORE_INPUT
/* Win9x/NT4 */),
2523 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n",
2525 /* Try with a couple of RSA-related OIDs */
2526 ret
= pCryptDecodeObjectEx(dwEncoding
, szOID_RSA_RSA
,
2527 rsaPubKeys
[0].encoded
, rsaPubKeys
[0].encoded
[1] + 2,
2528 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2529 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
2530 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2531 ret
= pCryptDecodeObjectEx(dwEncoding
, szOID_RSA_SHA1RSA
,
2532 rsaPubKeys
[0].encoded
, rsaPubKeys
[0].encoded
[1] + 2,
2533 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2534 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
2535 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2536 /* Now try success cases */
2537 for (i
= 0; i
< ARRAY_SIZE(rsaPubKeys
); i
++)
2540 ret
= pCryptDecodeObjectEx(dwEncoding
, RSA_CSP_PUBLICKEYBLOB
,
2541 rsaPubKeys
[i
].encoded
, rsaPubKeys
[i
].encoded
[1] + 2,
2542 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2543 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2546 BLOBHEADER
*hdr
= (BLOBHEADER
*)buf
;
2547 RSAPUBKEY
*rsaPubKey
= (RSAPUBKEY
*)(buf
+ sizeof(BLOBHEADER
));
2549 ok(bufSize
>= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
2550 rsaPubKeys
[i
].decodedModulusLen
,
2551 "Wrong size %d\n", bufSize
);
2552 ok(hdr
->bType
== PUBLICKEYBLOB
,
2553 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB
,
2555 ok(hdr
->bVersion
== CUR_BLOB_VERSION
,
2556 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
2557 CUR_BLOB_VERSION
, hdr
->bVersion
);
2558 ok(hdr
->reserved
== 0, "Expected reserved 0, got %d\n",
2560 ok(hdr
->aiKeyAlg
== CALG_RSA_KEYX
,
2561 "Expected CALG_RSA_KEYX, got %08x\n", hdr
->aiKeyAlg
);
2562 ok(rsaPubKey
->magic
== 0x31415352,
2563 "Expected magic RSA1, got %08x\n", rsaPubKey
->magic
);
2564 ok(rsaPubKey
->bitlen
== rsaPubKeys
[i
].decodedModulusLen
* 8,
2565 "Wrong bit len %d\n", rsaPubKey
->bitlen
);
2566 ok(rsaPubKey
->pubexp
== 65537, "Expected pubexp 65537, got %d\n",
2568 ok(!memcmp(buf
+ sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
),
2569 rsaPubKeys
[i
].modulus
, rsaPubKeys
[i
].decodedModulusLen
),
2570 "Unexpected modulus\n");
2576 static const BYTE intSequence
[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01,
2577 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02,
2578 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2580 static const BYTE mixedSequence
[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
2581 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f,
2582 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02,
2583 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2585 static void test_encodeSequenceOfAny(DWORD dwEncoding
)
2587 CRYPT_DER_BLOB blobs
[ARRAY_SIZE(ints
)];
2588 CRYPT_SEQUENCE_OF_ANY seq
;
2594 /* Encode a homogeneous sequence */
2595 for (i
= 0; i
< ARRAY_SIZE(ints
); i
++)
2597 blobs
[i
].cbData
= ints
[i
].encoded
[1] + 2;
2598 blobs
[i
].pbData
= (BYTE
*)ints
[i
].encoded
;
2600 seq
.cValue
= ARRAY_SIZE(ints
);
2601 seq
.rgValue
= blobs
;
2603 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_SEQUENCE_OF_ANY
, &seq
,
2604 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2605 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2608 ok(bufSize
== sizeof(intSequence
), "Wrong size %d\n", bufSize
);
2609 ok(!memcmp(buf
, intSequence
, intSequence
[1] + 2), "Unexpected value\n");
2612 /* Change the type of the first element in the sequence, and give it
2615 blobs
[0].cbData
= times
[0].encodedTime
[1] + 2;
2616 blobs
[0].pbData
= (BYTE
*)times
[0].encodedTime
;
2617 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_SEQUENCE_OF_ANY
, &seq
,
2618 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2619 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2622 ok(bufSize
== sizeof(mixedSequence
), "Wrong size %d\n", bufSize
);
2623 ok(!memcmp(buf
, mixedSequence
, mixedSequence
[1] + 2),
2624 "Unexpected value\n");
2629 static void test_decodeSequenceOfAny(DWORD dwEncoding
)
2635 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_SEQUENCE_OF_ANY
, intSequence
,
2636 intSequence
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2637 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2640 CRYPT_SEQUENCE_OF_ANY
*seq
= (CRYPT_SEQUENCE_OF_ANY
*)buf
;
2643 ok(seq
->cValue
== ARRAY_SIZE(ints
), "Wrong elements %d\n", seq
->cValue
);
2644 for (i
= 0; i
< min(seq
->cValue
, ARRAY_SIZE(ints
)); i
++)
2646 ok(seq
->rgValue
[i
].cbData
== ints
[i
].encoded
[1] + 2,
2647 "Expected %d bytes, got %d\n", ints
[i
].encoded
[1] + 2,
2648 seq
->rgValue
[i
].cbData
);
2649 ok(!memcmp(seq
->rgValue
[i
].pbData
, ints
[i
].encoded
,
2650 ints
[i
].encoded
[1] + 2), "Unexpected value\n");
2654 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_SEQUENCE_OF_ANY
, mixedSequence
,
2655 mixedSequence
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
,
2657 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2660 CRYPT_SEQUENCE_OF_ANY
*seq
= (CRYPT_SEQUENCE_OF_ANY
*)buf
;
2662 ok(seq
->cValue
== ARRAY_SIZE(ints
), "Wrong elements %d\n", seq
->cValue
);
2663 /* Just check the first element since it's all that changed */
2664 ok(seq
->rgValue
[0].cbData
== times
[0].encodedTime
[1] + 2,
2665 "Expected %d bytes, got %d\n", times
[0].encodedTime
[1] + 2,
2666 seq
->rgValue
[0].cbData
);
2667 ok(!memcmp(seq
->rgValue
[0].pbData
, times
[0].encodedTime
,
2668 times
[0].encodedTime
[1] + 2), "Unexpected value\n");
2673 struct encodedExtensions
2675 CERT_EXTENSIONS exts
;
2676 const BYTE
*encoded
;
2679 static BYTE crit_ext_data
[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2680 static BYTE noncrit_ext_data
[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2681 static CHAR oid_basic_constraints2
[] = szOID_BASIC_CONSTRAINTS2
;
2682 static CERT_EXTENSION criticalExt
=
2683 { oid_basic_constraints2
, TRUE
, { 8, crit_ext_data
} };
2684 static CERT_EXTENSION nonCriticalExt
=
2685 { oid_basic_constraints2
, FALSE
, { 8, noncrit_ext_data
} };
2686 static CHAR oid_short
[] = "1.1";
2687 static CERT_EXTENSION extWithShortOid
=
2688 { oid_short
, FALSE
, { 0, NULL
} };
2690 static const BYTE ext0
[] = { 0x30,0x00 };
2691 static const BYTE ext1
[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2692 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2693 static const BYTE ext2
[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2694 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2695 static const BYTE ext3
[] = { 0x30,0x07,0x30,0x05,0x06,0x01,0x29,0x04,0x00 };
2697 static const struct encodedExtensions exts
[] = {
2698 { { 0, NULL
}, ext0
},
2699 { { 1, &criticalExt
}, ext1
},
2700 { { 1, &nonCriticalExt
}, ext2
},
2701 { { 1, &extWithShortOid
}, ext3
}
2704 static void test_encodeExtensions(DWORD dwEncoding
)
2708 for (i
= 0; i
< ARRAY_SIZE(exts
); i
++)
2714 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_EXTENSIONS
, &exts
[i
].exts
,
2715 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2716 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2719 ok(bufSize
== exts
[i
].encoded
[1] + 2,
2720 "Expected %d bytes, got %d\n", exts
[i
].encoded
[1] + 2, bufSize
);
2721 ok(!memcmp(buf
, exts
[i
].encoded
, exts
[i
].encoded
[1] + 2),
2722 "Unexpected value\n");
2728 static void test_decodeExtensions(DWORD dwEncoding
)
2732 for (i
= 0; i
< ARRAY_SIZE(exts
); i
++)
2738 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_EXTENSIONS
,
2739 exts
[i
].encoded
, exts
[i
].encoded
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
,
2740 NULL
, &buf
, &bufSize
);
2741 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2744 CERT_EXTENSIONS
*ext
= (CERT_EXTENSIONS
*)buf
;
2747 ok(ext
->cExtension
== exts
[i
].exts
.cExtension
,
2748 "Expected %d extensions, see %d\n", exts
[i
].exts
.cExtension
,
2750 for (j
= 0; j
< min(ext
->cExtension
, exts
[i
].exts
.cExtension
); j
++)
2752 ok(!strcmp(ext
->rgExtension
[j
].pszObjId
,
2753 exts
[i
].exts
.rgExtension
[j
].pszObjId
),
2754 "Expected OID %s, got %s\n",
2755 exts
[i
].exts
.rgExtension
[j
].pszObjId
,
2756 ext
->rgExtension
[j
].pszObjId
);
2757 ok(!memcmp(ext
->rgExtension
[j
].Value
.pbData
,
2758 exts
[i
].exts
.rgExtension
[j
].Value
.pbData
,
2759 exts
[i
].exts
.rgExtension
[j
].Value
.cbData
),
2760 "Unexpected value\n");
2764 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_EXTENSIONS
,
2765 exts
[i
].encoded
, exts
[i
].encoded
[1] + 2, 0, NULL
, NULL
, &bufSize
);
2766 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2767 buf
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, bufSize
);
2770 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_EXTENSIONS
,
2771 exts
[i
].encoded
, exts
[i
].encoded
[1] + 2, 0, NULL
, buf
, &bufSize
);
2772 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2773 HeapFree(GetProcessHeap(), 0, buf
);
2778 /* MS encodes public key info with a NULL if the algorithm identifier's
2779 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2780 * it encodes them by omitting the algorithm parameters. It accepts either
2781 * form for decoding.
2783 struct encodedPublicKey
2785 CERT_PUBLIC_KEY_INFO info
;
2786 const BYTE
*encoded
;
2787 const BYTE
*encodedNoNull
;
2788 CERT_PUBLIC_KEY_INFO decoded
;
2791 static const BYTE aKey
[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2793 static const BYTE params
[] = { 0x02, 0x01, 0x01 };
2795 static const unsigned char bin64
[] = {
2796 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2797 static const unsigned char bin65
[] = {
2798 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2799 static const unsigned char bin66
[] = {
2800 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2801 static const unsigned char bin67
[] = {
2802 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2803 static const unsigned char bin68
[] = {
2804 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01,
2805 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2806 static const unsigned char bin69
[] = {
2807 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2808 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2809 static const unsigned char bin70
[] = {
2810 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2811 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2813 static const unsigned char bin71
[] = {
2814 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2815 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2817 static unsigned char bin72
[] = { 0x05,0x00};
2819 static CHAR oid_bogus
[] = "1.2.3",
2820 oid_rsa
[] = szOID_RSA
;
2822 static const struct encodedPublicKey pubKeys
[] = {
2823 /* with a bogus OID */
2824 { { { oid_bogus
, { 0, NULL
} }, { 0, NULL
, 0 } },
2826 { { oid_bogus
, { 2, bin72
} }, { 0, NULL
, 0 } } },
2827 /* some normal keys */
2828 { { { oid_rsa
, { 0, NULL
} }, { 0, NULL
, 0} },
2830 { { oid_rsa
, { 2, bin72
} }, { 0, NULL
, 0 } } },
2831 { { { oid_rsa
, { 0, NULL
} }, { sizeof(aKey
), (BYTE
*)aKey
, 0} },
2833 { { oid_rsa
, { 2, bin72
} }, { sizeof(aKey
), (BYTE
*)aKey
, 0} } },
2834 /* with add'l parameters--note they must be DER-encoded */
2835 { { { oid_rsa
, { sizeof(params
), (BYTE
*)params
} }, { sizeof(aKey
),
2836 (BYTE
*)aKey
, 0 } },
2838 { { oid_rsa
, { sizeof(params
), (BYTE
*)params
} }, { sizeof(aKey
),
2839 (BYTE
*)aKey
, 0 } } },
2842 static void test_encodePublicKeyInfo(DWORD dwEncoding
)
2846 for (i
= 0; i
< ARRAY_SIZE(pubKeys
); i
++)
2852 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_PUBLIC_KEY_INFO
,
2853 &pubKeys
[i
].info
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
,
2855 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
2856 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2859 ok(bufSize
== pubKeys
[i
].encoded
[1] + 2,
2860 "Expected %d bytes, got %d\n", pubKeys
[i
].encoded
[1] + 2, bufSize
);
2861 if (bufSize
== pubKeys
[i
].encoded
[1] + 2)
2862 ok(!memcmp(buf
, pubKeys
[i
].encoded
, pubKeys
[i
].encoded
[1] + 2),
2863 "Unexpected value\n");
2869 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO
*expected
,
2870 const CERT_PUBLIC_KEY_INFO
*got
)
2872 ok(!strcmp(expected
->Algorithm
.pszObjId
, got
->Algorithm
.pszObjId
),
2873 "Expected OID %s, got %s\n", expected
->Algorithm
.pszObjId
,
2874 got
->Algorithm
.pszObjId
);
2875 ok(expected
->Algorithm
.Parameters
.cbData
==
2876 got
->Algorithm
.Parameters
.cbData
,
2877 "Expected parameters of %d bytes, got %d\n",
2878 expected
->Algorithm
.Parameters
.cbData
, got
->Algorithm
.Parameters
.cbData
);
2879 if (expected
->Algorithm
.Parameters
.cbData
)
2880 ok(!memcmp(expected
->Algorithm
.Parameters
.pbData
,
2881 got
->Algorithm
.Parameters
.pbData
, got
->Algorithm
.Parameters
.cbData
),
2882 "Unexpected algorithm parameters\n");
2883 ok(expected
->PublicKey
.cbData
== got
->PublicKey
.cbData
,
2884 "Expected public key of %d bytes, got %d\n",
2885 expected
->PublicKey
.cbData
, got
->PublicKey
.cbData
);
2886 if (expected
->PublicKey
.cbData
)
2887 ok(!memcmp(expected
->PublicKey
.pbData
, got
->PublicKey
.pbData
,
2888 got
->PublicKey
.cbData
), "Unexpected public key value\n");
2891 static void test_decodePublicKeyInfo(DWORD dwEncoding
)
2893 static const BYTE bogusPubKeyInfo
[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
2894 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
2895 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
2896 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2902 for (i
= 0; i
< ARRAY_SIZE(pubKeys
); i
++)
2904 /* The NULL form decodes to the decoded member */
2905 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_PUBLIC_KEY_INFO
,
2906 pubKeys
[i
].encoded
, pubKeys
[i
].encoded
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
,
2907 NULL
, &buf
, &bufSize
);
2908 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2911 comparePublicKeyInfo(&pubKeys
[i
].decoded
,
2912 (CERT_PUBLIC_KEY_INFO
*)buf
);
2915 /* The non-NULL form decodes to the original */
2916 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_PUBLIC_KEY_INFO
,
2917 pubKeys
[i
].encodedNoNull
, pubKeys
[i
].encodedNoNull
[1] + 2,
2918 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
2919 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2922 comparePublicKeyInfo(&pubKeys
[i
].info
, (CERT_PUBLIC_KEY_INFO
*)buf
);
2926 /* Test with bogus (not valid DER) parameters */
2927 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_PUBLIC_KEY_INFO
,
2928 bogusPubKeyInfo
, bogusPubKeyInfo
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
,
2929 NULL
, &buf
, &bufSize
);
2930 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
2931 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
2932 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2936 static const BYTE v1Cert
[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
2937 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2938 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
2939 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
2940 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2941 static const BYTE v2Cert
[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02,
2942 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2943 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2944 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2945 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2946 static const BYTE v3Cert
[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2947 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2948 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2949 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2950 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2951 static const BYTE v4Cert
[] = {
2952 0x30,0x38,0xa0,0x03,0x02,0x01,0x03,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,
2953 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
2954 0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
2955 0x30,0x30,0x30,0x5a,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00 };
2956 static const BYTE v1CertWithConstraints
[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
2957 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2958 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2959 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2960 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2961 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2962 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2963 static const BYTE v1CertWithSerial
[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
2964 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2965 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2966 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2967 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2968 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2969 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2970 static const BYTE bigCert
[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2971 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
2972 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
2973 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
2974 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
2975 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
2976 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
2977 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
2978 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
2979 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2980 static const BYTE v1CertWithPubKey
[] = {
2981 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2982 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2983 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2984 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2985 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2986 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2987 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2988 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2989 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
2990 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
2992 static const BYTE v1CertWithPubKeyNoNull
[] = {
2993 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2994 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2995 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2996 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2997 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2998 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2999 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
3000 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
3001 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
3002 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3003 static const BYTE v1CertWithSubjectKeyId
[] = {
3004 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
3005 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
3006 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
3007 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3008 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
3009 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
3010 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
3011 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
3012 0x4c,0x61,0x6e,0x67,0x00 };
3013 static const BYTE v1CertWithIssuerUniqueId
[] = {
3014 0x30,0x38,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
3015 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
3016 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
3017 0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x81,0x02,0x00,0x01 };
3018 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueId
[] = {
3019 0x30,0x81,0x99,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
3020 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
3021 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
3022 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3023 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
3024 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
3025 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
3026 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
3027 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,
3028 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
3029 0x01,0x01,0xff,0x02,0x01,0x01 };
3030 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull
[] = {
3031 0x30,0x81,0x97,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
3032 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
3033 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
3034 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3035 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
3036 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
3037 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
3038 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
3039 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
3040 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
3041 0xff,0x02,0x01,0x01 };
3043 static const BYTE serialNum
[] = { 0x01 };
3045 static void test_encodeCertToBeSigned(DWORD dwEncoding
)
3050 CERT_INFO info
= { 0 };
3051 static char oid_rsa_rsa
[] = szOID_RSA_RSA
;
3052 static char oid_subject_key_identifier
[] = szOID_SUBJECT_KEY_IDENTIFIER
;
3057 /* Test with NULL pvStructInfo (crashes on win9x) */
3058 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, NULL
,
3059 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3060 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
3061 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3063 /* Test with a V1 cert */
3064 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3065 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3066 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
3067 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3070 ok(size
== v1Cert
[1] + 2, "Expected size %d, got %d\n",
3071 v1Cert
[1] + 2, size
);
3072 ok(!memcmp(buf
, v1Cert
, size
), "Got unexpected value\n");
3076 info
.dwVersion
= CERT_V2
;
3077 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3078 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3079 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
3080 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3083 ok(size
== sizeof(v2Cert
), "Wrong size %d\n", size
);
3084 ok(!memcmp(buf
, v2Cert
, size
), "Got unexpected value\n");
3088 info
.dwVersion
= CERT_V3
;
3089 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3090 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3091 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
3092 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3095 ok(size
== sizeof(v3Cert
), "Wrong size %d\n", size
);
3096 ok(!memcmp(buf
, v3Cert
, size
), "Got unexpected value\n");
3100 info
.dwVersion
= 3; /* Not a typo, CERT_V3 is 2 */
3101 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3102 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3105 ok(size
== sizeof(v4Cert
), "Wrong size %d\n", size
);
3106 ok(!memcmp(buf
, v4Cert
, size
), "Unexpected value\n");
3109 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
3110 * API doesn't prevent it)
3112 info
.dwVersion
= CERT_V1
;
3113 info
.cExtension
= 1;
3114 info
.rgExtension
= &criticalExt
;
3115 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3116 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3117 ok(ret
|| GetLastError() == OSS_BAD_PTR
/* Win9x */,
3118 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3121 ok(size
== sizeof(v1CertWithConstraints
), "Wrong size %d\n", size
);
3122 ok(!memcmp(buf
, v1CertWithConstraints
, size
), "Got unexpected value\n");
3125 /* test v1 cert with a serial number */
3126 info
.SerialNumber
.cbData
= sizeof(serialNum
);
3127 info
.SerialNumber
.pbData
= (BYTE
*)serialNum
;
3128 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3129 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3132 ok(size
== sizeof(v1CertWithSerial
), "Wrong size %d\n", size
);
3133 ok(!memcmp(buf
, v1CertWithSerial
, size
), "Got unexpected value\n");
3136 /* Test v1 cert with an issuer name, serial number, and issuer unique id */
3137 info
.dwVersion
= CERT_V1
;
3138 info
.cExtension
= 0;
3139 info
.IssuerUniqueId
.cbData
= sizeof(serialNum
);
3140 info
.IssuerUniqueId
.pbData
= (BYTE
*)serialNum
;
3141 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3142 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3143 ok(ret
|| broken(GetLastError() == OSS_BAD_PTR
/* Win98 */),
3144 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3147 ok(size
== sizeof(v1CertWithIssuerUniqueId
), "Wrong size %d\n", size
);
3148 ok(!memcmp(buf
, v1CertWithIssuerUniqueId
, size
),
3149 "Got unexpected value\n");
3152 /* Test v1 cert with an issuer name, a subject name, and a serial number */
3153 info
.IssuerUniqueId
.cbData
= 0;
3154 info
.IssuerUniqueId
.pbData
= NULL
;
3155 info
.cExtension
= 1;
3156 info
.rgExtension
= &criticalExt
;
3157 info
.Issuer
.cbData
= sizeof(encodedCommonName
);
3158 info
.Issuer
.pbData
= (BYTE
*)encodedCommonName
;
3159 info
.Subject
.cbData
= sizeof(encodedCommonName
);
3160 info
.Subject
.pbData
= (BYTE
*)encodedCommonName
;
3161 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3162 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3165 ok(size
== sizeof(bigCert
), "Wrong size %d\n", size
);
3166 ok(!memcmp(buf
, bigCert
, size
), "Got unexpected value\n");
3169 /* Add a public key */
3170 info
.SubjectPublicKeyInfo
.Algorithm
.pszObjId
= oid_rsa_rsa
;
3171 info
.SubjectPublicKeyInfo
.PublicKey
.cbData
= sizeof(aKey
);
3172 info
.SubjectPublicKeyInfo
.PublicKey
.pbData
= (LPBYTE
)aKey
;
3173 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3174 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3177 ok(size
== sizeof(v1CertWithPubKey
) ||
3178 size
== sizeof(v1CertWithPubKeyNoNull
), "Wrong size %d\n", size
);
3179 if (size
== sizeof(v1CertWithPubKey
))
3180 ok(!memcmp(buf
, v1CertWithPubKey
, size
), "Got unexpected value\n");
3181 else if (size
== sizeof(v1CertWithPubKeyNoNull
))
3182 ok(!memcmp(buf
, v1CertWithPubKeyNoNull
, size
),
3183 "Got unexpected value\n");
3186 /* Again add an issuer unique id */
3187 info
.IssuerUniqueId
.cbData
= sizeof(serialNum
);
3188 info
.IssuerUniqueId
.pbData
= (BYTE
*)serialNum
;
3189 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3190 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3191 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3194 ok(size
== sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId
) ||
3195 size
== sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull
),
3196 "Wrong size %d\n", size
);
3197 if (size
== sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId
))
3198 ok(!memcmp(buf
, v1CertWithSubjectIssuerSerialAndIssuerUniqueId
,
3199 size
), "unexpected value\n");
3201 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull
))
3203 v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull
, size
),
3204 "unexpected value\n");
3207 /* Remove the public key, and add a subject key identifier extension */
3208 info
.IssuerUniqueId
.cbData
= 0;
3209 info
.IssuerUniqueId
.pbData
= NULL
;
3210 info
.SubjectPublicKeyInfo
.Algorithm
.pszObjId
= NULL
;
3211 info
.SubjectPublicKeyInfo
.PublicKey
.cbData
= 0;
3212 info
.SubjectPublicKeyInfo
.PublicKey
.pbData
= NULL
;
3213 ext
.pszObjId
= oid_subject_key_identifier
;
3214 ext
.fCritical
= FALSE
;
3215 ext
.Value
.cbData
= sizeof(octetCommonNameValue
);
3216 ext
.Value
.pbData
= octetCommonNameValue
;
3217 info
.cExtension
= 1;
3218 info
.rgExtension
= &ext
;
3219 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, &info
,
3220 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3223 ok(size
== sizeof(v1CertWithSubjectKeyId
), "Wrong size %d\n", size
);
3224 ok(!memcmp(buf
, v1CertWithSubjectKeyId
, size
), "Unexpected value\n");
3229 static void test_decodeCertToBeSigned(DWORD dwEncoding
)
3231 static const BYTE
*corruptCerts
[] = { v1Cert
, v2Cert
, v3Cert
, v4Cert
,
3232 v1CertWithConstraints
, v1CertWithSerial
, v1CertWithIssuerUniqueId
};
3237 /* Test with NULL pbEncoded */
3238 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, NULL
, 0,
3239 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3240 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_EOD
||
3241 GetLastError() == OSS_BAD_ARG
/* Win9x */),
3242 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
3245 /* Crashes on win9x */
3246 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, NULL
, 1,
3247 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3248 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
3249 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3251 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT or
3252 * CRYPT_E_ASN1_BADTAG, because at a minimum a cert must have a non-zero
3253 * serial number, an issuer, a subject, and a public key.
3255 for (i
= 0; i
< ARRAY_SIZE(corruptCerts
); i
++)
3257 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
,
3258 corruptCerts
[i
], corruptCerts
[i
][1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3260 ok(!ret
, "Expected failure\n");
3262 /* The following succeeds, even though v1 certs are not allowed to have
3265 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
,
3266 v1CertWithSubjectKeyId
, sizeof(v1CertWithSubjectKeyId
),
3267 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3268 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3271 CERT_INFO
*info
= (CERT_INFO
*)buf
;
3273 ok(size
>= sizeof(CERT_INFO
), "Wrong size %d\n", size
);
3274 ok(info
->dwVersion
== CERT_V1
, "expected CERT_V1, got %d\n",
3276 ok(info
->cExtension
== 1, "expected 1 extension, got %d\n",
3280 /* The following also succeeds, even though V1 certs are not allowed to
3281 * have issuer unique ids.
3283 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
,
3284 v1CertWithSubjectIssuerSerialAndIssuerUniqueId
,
3285 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId
),
3286 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3287 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3290 CERT_INFO
*info
= (CERT_INFO
*)buf
;
3292 ok(size
>= sizeof(CERT_INFO
), "Wrong size %d\n", size
);
3293 ok(info
->dwVersion
== CERT_V1
, "expected CERT_V1, got %d\n",
3295 ok(info
->IssuerUniqueId
.cbData
== sizeof(serialNum
),
3296 "unexpected issuer unique id size %d\n", info
->IssuerUniqueId
.cbData
);
3297 ok(!memcmp(info
->IssuerUniqueId
.pbData
, serialNum
, sizeof(serialNum
)),
3298 "unexpected issuer unique id value\n");
3301 /* Now check with serial number, subject and issuer specified */
3302 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, bigCert
,
3303 sizeof(bigCert
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3304 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3307 CERT_INFO
*info
= (CERT_INFO
*)buf
;
3309 ok(size
>= sizeof(CERT_INFO
), "Wrong size %d\n", size
);
3310 ok(info
->SerialNumber
.cbData
== 1,
3311 "Expected serial number size 1, got %d\n", info
->SerialNumber
.cbData
);
3312 ok(*info
->SerialNumber
.pbData
== *serialNum
,
3313 "Expected serial number %d, got %d\n", *serialNum
,
3314 *info
->SerialNumber
.pbData
);
3315 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
3316 "Wrong size %d\n", info
->Issuer
.cbData
);
3317 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
3318 "Unexpected issuer\n");
3319 ok(info
->Subject
.cbData
== sizeof(encodedCommonName
),
3320 "Wrong size %d\n", info
->Subject
.cbData
);
3321 ok(!memcmp(info
->Subject
.pbData
, encodedCommonName
,
3322 info
->Subject
.cbData
), "Unexpected subject\n");
3325 /* Check again with pub key specified */
3326 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
,
3327 v1CertWithPubKey
, sizeof(v1CertWithPubKey
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3329 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3332 CERT_INFO
*info
= (CERT_INFO
*)buf
;
3334 ok(size
>= sizeof(CERT_INFO
), "Wrong size %d\n", size
);
3335 ok(info
->SerialNumber
.cbData
== 1,
3336 "Expected serial number size 1, got %d\n", info
->SerialNumber
.cbData
);
3337 ok(*info
->SerialNumber
.pbData
== *serialNum
,
3338 "Expected serial number %d, got %d\n", *serialNum
,
3339 *info
->SerialNumber
.pbData
);
3340 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
3341 "Wrong size %d\n", info
->Issuer
.cbData
);
3342 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
3343 "Unexpected issuer\n");
3344 ok(info
->Subject
.cbData
== sizeof(encodedCommonName
),
3345 "Wrong size %d\n", info
->Subject
.cbData
);
3346 ok(!memcmp(info
->Subject
.pbData
, encodedCommonName
,
3347 info
->Subject
.cbData
), "Unexpected subject\n");
3348 ok(!strcmp(info
->SubjectPublicKeyInfo
.Algorithm
.pszObjId
,
3349 szOID_RSA_RSA
), "Expected szOID_RSA_RSA, got %s\n",
3350 info
->SubjectPublicKeyInfo
.Algorithm
.pszObjId
);
3351 ok(info
->SubjectPublicKeyInfo
.PublicKey
.cbData
== sizeof(aKey
),
3352 "Wrong size %d\n", info
->SubjectPublicKeyInfo
.PublicKey
.cbData
);
3353 ok(!memcmp(info
->SubjectPublicKeyInfo
.PublicKey
.pbData
, aKey
,
3354 sizeof(aKey
)), "Unexpected public key\n");
3359 static const BYTE hash
[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
3362 static const BYTE signedBigCert
[] = {
3363 ASN_SEQUENCE
,0x81,147,
3365 ASN_INTEGER
,1, 0x01,
3367 ASN_OBJECTIDENTIFIER
,0,
3371 ASN_OBJECTIDENTIFIER
,3, 0x55,0x04,0x03,
3372 0x13,10, 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
3374 0x18,15, 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
3375 0x18,15, 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
3379 ASN_OBJECTIDENTIFIER
,3, 0x55,0x04,0x03,
3380 0x13,10, 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
3383 ASN_OBJECTIDENTIFIER
,0,
3388 ASN_OBJECTIDENTIFIER
,3, 0x55,0x1d,0x13,
3390 ASN_OCTETSTRING
,8, 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,
3392 ASN_OBJECTIDENTIFIER
,0,
3393 ASN_BITS
,17, 0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,
3394 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00
3397 static const BYTE signedBigCertWithIndefiniteSeq
[] = {
3398 ASN_SEQUENCE
,0x81,151,
3400 ASN_INTEGER
,1, 0x01,
3402 ASN_OBJECTIDENTIFIER
,0,
3406 ASN_OBJECTIDENTIFIER
,3, 0x55,0x04,0x03,
3407 0x13,10, 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
3409 0x18,15, 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
3410 0x18,15, 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
3415 ASN_OBJECTIDENTIFIER
,3, 0x55,0x04,0x03,
3416 0x13,10, 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
3419 ASN_OBJECTIDENTIFIER
,0,
3425 ASN_OBJECTIDENTIFIER
,3, 0x55,0x1d,0x13,
3427 ASN_OCTETSTRING
,8, 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,
3429 ASN_OBJECTIDENTIFIER
,0,
3430 ASN_BITS
,17, 0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,
3431 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00
3434 static void test_encodeCert(DWORD dwEncoding
)
3436 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
3437 * also that bigCert is a NULL-terminated string, so don't count its
3438 * last byte (otherwise the signed cert won't decode.)
3440 CERT_SIGNED_CONTENT_INFO info
= { { sizeof(bigCert
), (BYTE
*)bigCert
},
3441 { NULL
, { 0, NULL
} }, { sizeof(hash
), (BYTE
*)hash
, 0 } };
3446 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT
, &info
,
3447 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
3448 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3451 ok(bufSize
== sizeof(signedBigCert
), "Wrong size %d\n", bufSize
);
3452 ok(!memcmp(buf
, signedBigCert
, bufSize
), "Unexpected cert\n");
3457 static void test_decodeCert(DWORD dwEncoding
)
3463 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT
, signedBigCert
,
3464 sizeof(signedBigCert
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3465 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3468 CERT_SIGNED_CONTENT_INFO
*info
= (CERT_SIGNED_CONTENT_INFO
*)buf
;
3470 ok(info
->ToBeSigned
.cbData
== sizeof(bigCert
),
3471 "Wrong cert size %d\n", info
->ToBeSigned
.cbData
);
3472 ok(!memcmp(info
->ToBeSigned
.pbData
, bigCert
, info
->ToBeSigned
.cbData
),
3473 "Unexpected cert\n");
3474 ok(info
->Signature
.cbData
== sizeof(hash
),
3475 "Wrong signature size %d\n", info
->Signature
.cbData
);
3476 ok(!memcmp(info
->Signature
.pbData
, hash
, info
->Signature
.cbData
),
3477 "Unexpected signature\n");
3480 /* A signed cert decodes as a CERT_INFO too */
3481 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, signedBigCert
,
3482 sizeof(signedBigCert
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3483 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3486 CERT_INFO
*info
= (CERT_INFO
*)buf
;
3488 ok(size
>= sizeof(CERT_INFO
), "Wrong size %d\n", size
);
3489 ok(info
->SerialNumber
.cbData
== 1,
3490 "Expected serial number size 1, got %d\n", info
->SerialNumber
.cbData
);
3491 ok(*info
->SerialNumber
.pbData
== *serialNum
,
3492 "Expected serial number %d, got %d\n", *serialNum
,
3493 *info
->SerialNumber
.pbData
);
3494 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
3495 "Wrong size %d\n", info
->Issuer
.cbData
);
3496 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
3497 "Unexpected issuer\n");
3498 ok(info
->Subject
.cbData
== sizeof(encodedCommonName
),
3499 "Wrong size %d\n", info
->Subject
.cbData
);
3500 ok(!memcmp(info
->Subject
.pbData
, encodedCommonName
,
3501 info
->Subject
.cbData
), "Unexpected subject\n");
3504 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_TO_BE_SIGNED
, signedBigCertWithIndefiniteSeq
,
3505 sizeof(signedBigCertWithIndefiniteSeq
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3506 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3509 CERT_INFO
*info
= (CERT_INFO
*)buf
;
3511 ok(size
>= sizeof(CERT_INFO
), "Wrong size %d\n", size
);
3512 ok(info
->SerialNumber
.cbData
== 1,
3513 "Expected serial number size 1, got %d\n", info
->SerialNumber
.cbData
);
3514 ok(*info
->SerialNumber
.pbData
== *serialNum
,
3515 "Expected serial number %d, got %d\n", *serialNum
,
3516 *info
->SerialNumber
.pbData
);
3517 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
3518 "Wrong size %d\n", info
->Issuer
.cbData
);
3519 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
3520 "Unexpected issuer\n");
3521 ok(info
->Subject
.cbData
== sizeof(encodedCommonName
),
3522 "Wrong size %d\n", info
->Subject
.cbData
);
3523 ok(!memcmp(info
->Subject
.pbData
, encodedCommonName
,
3524 info
->Subject
.cbData
), "Unexpected subject\n");
3529 static const BYTE emptyDistPoint
[] = { 0x30, 0x02, 0x30, 0x00 };
3530 static const BYTE distPointWithUrl
[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3531 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3532 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3533 static const BYTE distPointWithReason
[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3535 static const BYTE distPointWithIssuer
[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3536 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3537 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3538 static const BYTE distPointWithUrlAndIssuer
[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3539 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3540 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3541 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3542 0x2e, 0x6f, 0x72, 0x67 };
3543 static const BYTE crlReason
= CRL_REASON_KEY_COMPROMISE
|
3544 CRL_REASON_AFFILIATION_CHANGED
;
3546 static void test_encodeCRLDistPoints(DWORD dwEncoding
)
3548 CRL_DIST_POINTS_INFO info
= { 0 };
3549 CRL_DIST_POINT point
= { { 0 } };
3550 CERT_ALT_NAME_ENTRY entry
= { 0 };
3555 /* Test with an empty info */
3556 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3557 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3558 ok(!ret
&& GetLastError() == E_INVALIDARG
,
3559 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3560 /* Test with one empty dist point */
3561 info
.cDistPoint
= 1;
3562 info
.rgDistPoint
= &point
;
3563 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3564 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3565 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3568 ok(size
== sizeof(emptyDistPoint
), "Wrong size %d\n", size
);
3569 ok(!memcmp(buf
, emptyDistPoint
, size
), "Unexpected value\n");
3572 /* A dist point with an invalid name */
3573 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3574 entry
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
3575 U(entry
).pwszURL
= (LPWSTR
)nihongoURL
;
3576 U(point
.DistPointName
).FullName
.cAltEntry
= 1;
3577 U(point
.DistPointName
).FullName
.rgAltEntry
= &entry
;
3578 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3579 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3580 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_IA5_STRING
,
3581 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
3582 /* The first invalid character is at index 7 */
3583 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size
) == 7,
3584 "Expected invalid char at index 7, got %d\n",
3585 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size
));
3586 /* A dist point with (just) a valid name */
3587 U(entry
).pwszURL
= (LPWSTR
)url
;
3588 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3589 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3590 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3593 ok(size
== sizeof(distPointWithUrl
), "Wrong size %d\n", size
);
3594 ok(!memcmp(buf
, distPointWithUrl
, size
), "Unexpected value\n");
3597 /* A dist point with (just) reason flags */
3598 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
3599 point
.ReasonFlags
.cbData
= sizeof(crlReason
);
3600 point
.ReasonFlags
.pbData
= (LPBYTE
)&crlReason
;
3601 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3602 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3603 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3606 ok(size
== sizeof(distPointWithReason
), "Wrong size %d\n", size
);
3607 ok(!memcmp(buf
, distPointWithReason
, size
), "Unexpected value\n");
3610 /* A dist point with just an issuer */
3611 point
.ReasonFlags
.cbData
= 0;
3612 point
.CRLIssuer
.cAltEntry
= 1;
3613 point
.CRLIssuer
.rgAltEntry
= &entry
;
3614 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3615 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3616 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3619 ok(size
== sizeof(distPointWithIssuer
), "Wrong size %d\n", size
);
3620 ok(!memcmp(buf
, distPointWithIssuer
, size
), "Unexpected value\n");
3623 /* A dist point with both a name and an issuer */
3624 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3625 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
, &info
,
3626 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3627 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3630 ok(size
== sizeof(distPointWithUrlAndIssuer
),
3631 "Wrong size %d\n", size
);
3632 ok(!memcmp(buf
, distPointWithUrlAndIssuer
, size
), "Unexpected value\n");
3637 static void test_decodeCRLDistPoints(DWORD dwEncoding
)
3642 PCRL_DIST_POINTS_INFO info
;
3643 PCRL_DIST_POINT point
;
3644 PCERT_ALT_NAME_ENTRY entry
;
3646 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
,
3647 emptyDistPoint
, emptyDistPoint
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3649 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3652 info
= (PCRL_DIST_POINTS_INFO
)buf
;
3653 ok(size
>= sizeof(CRL_DIST_POINTS_INFO
) + sizeof(CRL_DIST_POINT
),
3654 "Wrong size %d\n", size
);
3655 ok(info
->cDistPoint
== 1, "Expected 1 dist points, got %d\n",
3657 point
= info
->rgDistPoint
;
3658 ok(point
->DistPointName
.dwDistPointNameChoice
== CRL_DIST_POINT_NO_NAME
,
3659 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3660 point
->DistPointName
.dwDistPointNameChoice
);
3661 ok(point
->ReasonFlags
.cbData
== 0, "Expected no reason\n");
3662 ok(point
->CRLIssuer
.cAltEntry
== 0, "Expected no issuer\n");
3665 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
,
3666 distPointWithUrl
, distPointWithUrl
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3668 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3671 info
= (PCRL_DIST_POINTS_INFO
)buf
;
3672 ok(size
>= sizeof(CRL_DIST_POINTS_INFO
) + sizeof(CRL_DIST_POINT
),
3673 "Wrong size %d\n", size
);
3674 ok(info
->cDistPoint
== 1, "Expected 1 dist points, got %d\n",
3676 point
= info
->rgDistPoint
;
3677 ok(point
->DistPointName
.dwDistPointNameChoice
==
3678 CRL_DIST_POINT_FULL_NAME
,
3679 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3680 point
->DistPointName
.dwDistPointNameChoice
);
3681 ok(U(point
->DistPointName
).FullName
.cAltEntry
== 1,
3682 "Expected 1 name entry, got %d\n",
3683 U(point
->DistPointName
).FullName
.cAltEntry
);
3684 entry
= U(point
->DistPointName
).FullName
.rgAltEntry
;
3685 ok(entry
->dwAltNameChoice
== CERT_ALT_NAME_URL
,
3686 "Expected CERT_ALT_NAME_URL, got %d\n", entry
->dwAltNameChoice
);
3687 ok(!lstrcmpW(U(*entry
).pwszURL
, url
), "Unexpected name\n");
3688 ok(point
->ReasonFlags
.cbData
== 0, "Expected no reason\n");
3689 ok(point
->CRLIssuer
.cAltEntry
== 0, "Expected no issuer\n");
3692 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
,
3693 distPointWithReason
, distPointWithReason
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
,
3695 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3698 info
= (PCRL_DIST_POINTS_INFO
)buf
;
3699 ok(size
>= sizeof(CRL_DIST_POINTS_INFO
) + sizeof(CRL_DIST_POINT
),
3700 "Wrong size %d\n", size
);
3701 ok(info
->cDistPoint
== 1, "Expected 1 dist points, got %d\n",
3703 point
= info
->rgDistPoint
;
3704 ok(point
->DistPointName
.dwDistPointNameChoice
==
3705 CRL_DIST_POINT_NO_NAME
,
3706 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3707 point
->DistPointName
.dwDistPointNameChoice
);
3708 ok(point
->ReasonFlags
.cbData
== sizeof(crlReason
),
3709 "Expected reason length\n");
3710 ok(!memcmp(point
->ReasonFlags
.pbData
, &crlReason
, sizeof(crlReason
)),
3711 "Unexpected reason\n");
3712 ok(point
->CRLIssuer
.cAltEntry
== 0, "Expected no issuer\n");
3715 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
,
3716 distPointWithUrlAndIssuer
, distPointWithUrlAndIssuer
[1] + 2,
3717 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3718 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3721 info
= (PCRL_DIST_POINTS_INFO
)buf
;
3722 ok(size
>= sizeof(CRL_DIST_POINTS_INFO
) + sizeof(CRL_DIST_POINT
),
3723 "Wrong size %d\n", size
);
3724 ok(info
->cDistPoint
== 1, "Expected 1 dist points, got %d\n",
3726 point
= info
->rgDistPoint
;
3727 ok(point
->DistPointName
.dwDistPointNameChoice
==
3728 CRL_DIST_POINT_FULL_NAME
,
3729 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3730 point
->DistPointName
.dwDistPointNameChoice
);
3731 ok(U(point
->DistPointName
).FullName
.cAltEntry
== 1,
3732 "Expected 1 name entry, got %d\n",
3733 U(point
->DistPointName
).FullName
.cAltEntry
);
3734 entry
= U(point
->DistPointName
).FullName
.rgAltEntry
;
3735 ok(entry
->dwAltNameChoice
== CERT_ALT_NAME_URL
,
3736 "Expected CERT_ALT_NAME_URL, got %d\n", entry
->dwAltNameChoice
);
3737 ok(!lstrcmpW(U(*entry
).pwszURL
, url
), "Unexpected name\n");
3738 ok(point
->ReasonFlags
.cbData
== 0, "Expected no reason\n");
3739 ok(point
->CRLIssuer
.cAltEntry
== 1,
3740 "Expected 1 issuer entry, got %d\n", point
->CRLIssuer
.cAltEntry
);
3741 entry
= point
->CRLIssuer
.rgAltEntry
;
3742 ok(entry
->dwAltNameChoice
== CERT_ALT_NAME_URL
,
3743 "Expected CERT_ALT_NAME_URL, got %d\n", entry
->dwAltNameChoice
);
3744 ok(!lstrcmpW(U(*entry
).pwszURL
, url
), "Unexpected name\n");
3747 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
,
3748 distPointWithUrlAndIssuer
, distPointWithUrlAndIssuer
[1] + 2, 0,
3750 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3751 buf
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
3754 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CRL_DIST_POINTS
,
3755 distPointWithUrlAndIssuer
, distPointWithUrlAndIssuer
[1] + 2, 0,
3757 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3758 HeapFree(GetProcessHeap(), 0, buf
);
3762 static const BYTE badFlagsIDP
[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3763 static const BYTE emptyNameIDP
[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3764 static const BYTE urlIDP
[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3765 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3768 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding
)
3773 CRL_ISSUING_DIST_POINT point
= { { 0 } };
3774 CERT_ALT_NAME_ENTRY entry
;
3776 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, NULL
,
3777 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3778 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
3780 skip("no X509_ISSUING_DIST_POINT encode support\n");
3783 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
3784 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3785 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, &point
,
3786 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3787 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3790 ok(size
== sizeof(emptySequence
), "Unexpected size %d\n", size
);
3791 ok(!memcmp(buf
, emptySequence
, size
), "Unexpected value\n");
3794 /* nonsensical flags */
3795 point
.fOnlyContainsUserCerts
= TRUE
;
3796 point
.fOnlyContainsCACerts
= TRUE
;
3797 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, &point
,
3798 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3799 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3802 ok(size
== sizeof(badFlagsIDP
), "Unexpected size %d\n", size
);
3803 ok(!memcmp(buf
, badFlagsIDP
, size
), "Unexpected value\n");
3806 /* unimplemented name type */
3807 point
.fOnlyContainsCACerts
= point
.fOnlyContainsUserCerts
= FALSE
;
3808 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_ISSUER_RDN_NAME
;
3809 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, &point
,
3810 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3811 ok(!ret
&& GetLastError() == E_INVALIDARG
,
3812 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3814 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3815 U(point
.DistPointName
).FullName
.cAltEntry
= 0;
3816 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, &point
,
3817 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3818 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3821 ok(size
== sizeof(emptyNameIDP
), "Unexpected size %d\n", size
);
3822 ok(!memcmp(buf
, emptyNameIDP
, size
), "Unexpected value\n");
3825 /* name with URL entry */
3826 entry
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
3827 U(entry
).pwszURL
= (LPWSTR
)url
;
3828 U(point
.DistPointName
).FullName
.cAltEntry
= 1;
3829 U(point
.DistPointName
).FullName
.rgAltEntry
= &entry
;
3830 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
, &point
,
3831 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3832 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3835 ok(size
== sizeof(urlIDP
), "Unexpected size %d\n", size
);
3836 ok(!memcmp(buf
, urlIDP
, size
), "Unexpected value\n");
3841 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY
*expected
,
3842 const CERT_ALT_NAME_ENTRY
*got
)
3844 ok(expected
->dwAltNameChoice
== got
->dwAltNameChoice
,
3845 "Expected name choice %d, got %d\n", expected
->dwAltNameChoice
,
3846 got
->dwAltNameChoice
);
3847 if (expected
->dwAltNameChoice
== got
->dwAltNameChoice
)
3849 switch (got
->dwAltNameChoice
)
3851 case CERT_ALT_NAME_RFC822_NAME
:
3852 case CERT_ALT_NAME_DNS_NAME
:
3853 case CERT_ALT_NAME_EDI_PARTY_NAME
:
3854 case CERT_ALT_NAME_URL
:
3855 case CERT_ALT_NAME_REGISTERED_ID
:
3856 ok((!U(*expected
).pwszURL
&& !U(*got
).pwszURL
) ||
3857 (!U(*expected
).pwszURL
&& !lstrlenW(U(*got
).pwszURL
)) ||
3858 (!U(*got
).pwszURL
&& !lstrlenW(U(*expected
).pwszURL
)) ||
3859 !lstrcmpW(U(*expected
).pwszURL
, U(*got
).pwszURL
),
3860 "Unexpected name\n");
3862 case CERT_ALT_NAME_X400_ADDRESS
:
3863 case CERT_ALT_NAME_DIRECTORY_NAME
:
3864 case CERT_ALT_NAME_IP_ADDRESS
:
3865 ok(U(*got
).IPAddress
.cbData
== U(*expected
).IPAddress
.cbData
,
3866 "Unexpected IP address length %d\n", U(*got
).IPAddress
.cbData
);
3867 ok(!memcmp(U(*got
).IPAddress
.pbData
, U(*expected
).IPAddress
.pbData
,
3868 U(*got
).IPAddress
.cbData
), "Unexpected value\n");
3874 static void compareAltNameInfo(const CERT_ALT_NAME_INFO
*expected
,
3875 const CERT_ALT_NAME_INFO
*got
)
3879 ok(expected
->cAltEntry
== got
->cAltEntry
, "Expected %d entries, got %d\n",
3880 expected
->cAltEntry
, got
->cAltEntry
);
3881 for (i
= 0; i
< min(expected
->cAltEntry
, got
->cAltEntry
); i
++)
3882 compareAltNameEntry(&expected
->rgAltEntry
[i
], &got
->rgAltEntry
[i
]);
3885 static void compareDistPointName(const CRL_DIST_POINT_NAME
*expected
,
3886 const CRL_DIST_POINT_NAME
*got
)
3888 ok(got
->dwDistPointNameChoice
== expected
->dwDistPointNameChoice
,
3889 "Unexpected name choice %d\n", got
->dwDistPointNameChoice
);
3890 if (got
->dwDistPointNameChoice
== CRL_DIST_POINT_FULL_NAME
)
3891 compareAltNameInfo(&(U(*expected
).FullName
), &(U(*got
).FullName
));
3894 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT
*expected
,
3895 const CRL_ISSUING_DIST_POINT
*got
)
3897 compareDistPointName(&expected
->DistPointName
, &got
->DistPointName
);
3898 ok(got
->fOnlyContainsUserCerts
== expected
->fOnlyContainsUserCerts
,
3899 "Unexpected fOnlyContainsUserCerts\n");
3900 ok(got
->fOnlyContainsCACerts
== expected
->fOnlyContainsCACerts
,
3901 "Unexpected fOnlyContainsCACerts\n");
3902 ok(got
->OnlySomeReasonFlags
.cbData
== expected
->OnlySomeReasonFlags
.cbData
,
3903 "Unexpected reason flags\n");
3904 ok(got
->fIndirectCRL
== expected
->fIndirectCRL
,
3905 "Unexpected fIndirectCRL\n");
3908 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding
)
3913 CRL_ISSUING_DIST_POINT point
= { { 0 } };
3915 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
,
3916 emptySequence
, emptySequence
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3918 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
3920 skip("no X509_ISSUING_DIST_POINT decode support\n");
3923 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3926 compareCRLIssuingDistPoints(&point
, (PCRL_ISSUING_DIST_POINT
)buf
);
3929 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
,
3930 badFlagsIDP
, badFlagsIDP
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3932 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3935 point
.fOnlyContainsUserCerts
= point
.fOnlyContainsCACerts
= TRUE
;
3936 compareCRLIssuingDistPoints(&point
, (PCRL_ISSUING_DIST_POINT
)buf
);
3939 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
,
3940 emptyNameIDP
, emptyNameIDP
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
3942 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3945 point
.fOnlyContainsCACerts
= point
.fOnlyContainsUserCerts
= FALSE
;
3946 point
.DistPointName
.dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3947 U(point
.DistPointName
).FullName
.cAltEntry
= 0;
3948 compareCRLIssuingDistPoints(&point
, (PCRL_ISSUING_DIST_POINT
)buf
);
3951 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ISSUING_DIST_POINT
,
3952 urlIDP
, urlIDP
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
3953 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3956 CERT_ALT_NAME_ENTRY entry
;
3958 entry
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
3959 U(entry
).pwszURL
= (LPWSTR
)url
;
3960 U(point
.DistPointName
).FullName
.cAltEntry
= 1;
3961 U(point
.DistPointName
).FullName
.rgAltEntry
= &entry
;
3962 compareCRLIssuingDistPoints(&point
, (PCRL_ISSUING_DIST_POINT
)buf
);
3967 static const BYTE v1CRL
[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3968 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3970 static const BYTE v2CRL
[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3971 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3972 0x30, 0x30, 0x30, 0x30, 0x5a };
3973 static const BYTE v1CRLWithIssuer
[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3974 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3975 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3976 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3978 static const BYTE v1CRLWithIssuerAndEmptyEntry
[] = { 0x30, 0x43, 0x30, 0x02,
3979 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3980 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3981 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3982 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3983 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3984 static const BYTE v1CRLWithIssuerAndEntry
[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3985 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3986 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3987 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3988 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3989 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3990 static const BYTE v1CRLWithEntryExt
[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3991 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3992 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3993 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3994 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3995 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3996 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3997 static const BYTE v1CRLWithExt
[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3998 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3999 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
4000 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
4001 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
4002 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
4003 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
4004 static const BYTE v2CRLWithExt
[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
4005 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
4006 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
4007 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
4008 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
4009 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
4010 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
4012 static void test_encodeCRLToBeSigned(DWORD dwEncoding
)
4017 CRL_INFO info
= { 0 };
4018 CRL_ENTRY entry
= { { 0 }, { 0 }, 0, 0 };
4020 /* Test with a V1 CRL */
4021 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
4022 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4023 ok(ret
|| broken(GetLastError() == OSS_DATA_ERROR
/* Win9x */),
4024 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4027 ok(size
== sizeof(v1CRL
), "Wrong size %d\n", size
);
4028 ok(!memcmp(buf
, v1CRL
, size
), "Got unexpected value\n");
4032 info
.dwVersion
= CRL_V2
;
4033 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
4034 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4035 ok(ret
|| broken(GetLastError() == OSS_DATA_ERROR
/* Win9x */),
4036 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4039 ok(size
== v2CRL
[1] + 2, "Expected size %d, got %d\n",
4040 v2CRL
[1] + 2, size
);
4041 ok(!memcmp(buf
, v2CRL
, size
), "Got unexpected value\n");
4044 /* v1 CRL with a name */
4045 info
.dwVersion
= CRL_V1
;
4046 info
.Issuer
.cbData
= sizeof(encodedCommonName
);
4047 info
.Issuer
.pbData
= (BYTE
*)encodedCommonName
;
4048 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
4049 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4050 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4053 ok(size
== sizeof(v1CRLWithIssuer
), "Wrong size %d\n", size
);
4054 ok(!memcmp(buf
, v1CRLWithIssuer
, size
), "Got unexpected value\n");
4059 /* v1 CRL with a name and a NULL entry pointer (crashes on win9x) */
4061 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
4062 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4063 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
4064 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
4066 /* now set an empty entry */
4068 info
.rgCRLEntry
= &entry
;
4069 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
4070 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4073 ok(size
== sizeof(v1CRLWithIssuerAndEmptyEntry
),
4074 "Wrong size %d\n", size
);
4075 ok(!memcmp(buf
, v1CRLWithIssuerAndEmptyEntry
, size
),
4076 "Got unexpected value\n");
4079 /* an entry with a serial number */
4080 entry
.SerialNumber
.cbData
= sizeof(serialNum
);
4081 entry
.SerialNumber
.pbData
= (BYTE
*)serialNum
;
4082 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
4083 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4086 ok(size
== sizeof(v1CRLWithIssuerAndEntry
),
4087 "Wrong size %d\n", size
);
4088 ok(!memcmp(buf
, v1CRLWithIssuerAndEntry
, size
),
4089 "Got unexpected value\n");
4092 /* an entry with an extension */
4093 entry
.cExtension
= 1;
4094 entry
.rgExtension
= &criticalExt
;
4095 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
4096 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4097 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4100 ok(size
== sizeof(v1CRLWithEntryExt
), "Wrong size %d\n", size
);
4101 ok(!memcmp(buf
, v1CRLWithEntryExt
, size
), "Got unexpected value\n");
4104 /* a CRL with an extension */
4105 entry
.cExtension
= 0;
4106 info
.cExtension
= 1;
4107 info
.rgExtension
= &criticalExt
;
4108 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
4109 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4110 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4113 ok(size
== sizeof(v1CRLWithExt
), "Wrong size %d\n", size
);
4114 ok(!memcmp(buf
, v1CRLWithExt
, size
), "Got unexpected value\n");
4117 /* a v2 CRL with an extension, this time non-critical */
4118 info
.dwVersion
= CRL_V2
;
4119 info
.rgExtension
= &nonCriticalExt
;
4120 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
, &info
,
4121 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4122 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4125 ok(size
== sizeof(v2CRLWithExt
), "Wrong size %d\n", size
);
4126 ok(!memcmp(buf
, v2CRLWithExt
, size
), "Got unexpected value\n");
4131 static const BYTE verisignCRL
[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
4132 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
4133 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
4134 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
4135 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
4136 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
4137 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
4138 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
4139 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
4140 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
4141 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
4142 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
4143 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
4144 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
4145 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
4146 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
4147 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
4148 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
4149 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
4150 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
4151 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
4152 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
4153 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
4154 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
4155 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
4156 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
4157 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
4158 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
4159 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
4160 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
4161 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
4162 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
4163 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
4164 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
4166 static const BYTE verisignCRLWithLotsOfEntries
[] = {
4167 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
4168 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
4169 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
4170 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
4171 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
4172 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
4173 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
4174 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
4175 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
4176 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
4177 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
4178 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
4179 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
4180 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
4181 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
4182 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
4183 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
4184 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
4185 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
4186 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
4187 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
4188 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
4189 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
4190 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
4191 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
4192 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
4193 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
4194 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
4195 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
4196 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
4197 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
4198 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
4199 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
4200 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
4201 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
4202 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
4203 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
4204 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
4205 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
4206 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
4207 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
4208 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
4209 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
4210 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
4211 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
4212 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
4213 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
4214 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
4215 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
4216 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
4217 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
4218 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
4219 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
4220 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
4221 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
4222 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
4223 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
4224 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
4225 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
4226 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
4227 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
4228 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
4229 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
4230 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
4231 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
4232 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
4233 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
4234 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
4235 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
4236 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
4237 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
4238 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
4239 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
4240 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
4241 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
4242 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
4243 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
4244 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
4245 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
4246 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
4247 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
4248 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
4249 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
4250 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
4251 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
4252 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
4253 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
4254 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
4255 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
4256 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
4257 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
4258 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
4259 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
4260 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
4261 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
4262 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
4263 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
4264 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
4265 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
4266 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
4267 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
4268 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
4269 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
4270 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
4271 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
4272 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
4273 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
4274 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
4275 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
4276 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
4277 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
4278 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
4279 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
4280 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
4281 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
4282 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
4283 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
4284 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
4285 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
4286 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
4287 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
4288 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
4289 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
4290 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
4291 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
4292 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
4293 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
4294 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
4295 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
4296 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
4297 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
4298 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
4299 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
4300 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
4301 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
4302 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
4303 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
4304 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
4305 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
4306 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
4307 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
4308 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
4309 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
4310 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
4311 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
4312 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
4313 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
4314 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
4315 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
4316 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
4317 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
4318 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
4319 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
4320 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
4321 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
4322 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
4323 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
4324 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
4325 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
4326 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
4327 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
4328 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
4329 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
4330 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
4331 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
4332 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
4333 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
4334 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
4335 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
4336 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
4337 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
4338 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
4339 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
4340 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
4341 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
4342 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
4343 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
4344 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
4345 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
4346 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
4347 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
4348 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
4349 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
4350 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
4351 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
4352 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
4353 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
4354 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
4355 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
4356 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
4357 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
4358 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
4359 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
4360 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
4361 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
4362 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
4363 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
4364 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
4365 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
4366 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
4367 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
4368 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
4369 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
4370 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
4371 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
4372 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
4373 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
4374 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
4375 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
4376 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
4377 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
4378 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
4379 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
4380 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
4381 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
4382 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
4383 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
4384 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
4385 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
4386 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
4387 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
4388 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
4389 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
4390 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
4391 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
4392 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
4393 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
4394 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
4395 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
4396 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
4397 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
4398 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
4399 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
4400 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
4401 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
4402 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
4403 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
4404 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
4405 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
4406 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
4407 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
4408 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
4409 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
4410 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
4411 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
4412 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
4413 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
4414 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
4415 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
4416 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
4417 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
4418 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
4419 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
4420 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
4421 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
4422 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
4423 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
4424 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
4425 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
4426 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
4427 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
4428 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
4429 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
4430 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
4431 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
4432 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
4433 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
4434 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
4435 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
4436 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
4437 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
4438 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
4439 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
4440 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
4441 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
4442 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
4443 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
4444 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
4445 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
4446 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
4447 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
4448 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
4449 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
4450 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
4451 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
4452 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
4453 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
4454 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
4455 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
4456 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
4457 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
4458 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
4459 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
4460 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
4461 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
4462 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
4463 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
4464 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
4465 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
4466 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
4467 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
4468 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
4469 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
4470 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4471 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4472 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4473 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4474 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4475 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4476 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4477 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4478 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4479 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4480 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4481 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4482 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4483 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4484 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4485 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4486 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4487 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4488 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4489 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4490 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4491 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4492 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4493 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4494 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4495 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4496 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4497 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4498 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4499 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4500 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4501 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4502 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4503 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4504 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4505 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4506 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4507 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4508 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4509 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4510 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4511 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4512 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4513 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4514 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4515 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4516 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4517 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4518 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4519 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4520 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4521 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4522 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4523 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4524 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4525 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4526 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4527 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4528 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4529 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4530 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4531 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4532 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4533 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4534 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4535 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4536 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4537 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4538 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4539 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4540 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4541 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4542 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4543 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4544 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4545 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4546 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4547 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4548 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4549 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4550 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4551 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4552 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4553 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4554 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4555 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4556 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4557 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4558 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4559 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4560 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4561 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4562 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4563 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4564 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4565 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4566 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4567 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4568 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4569 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4570 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4571 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4572 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4573 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4574 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4575 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4576 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4577 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4578 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4579 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4580 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4581 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4582 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4583 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4584 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4585 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4586 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4587 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4588 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4589 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4590 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4591 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4592 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4593 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4594 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4595 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4596 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4597 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4598 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4599 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4600 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4601 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4602 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4603 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4604 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4605 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4606 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4607 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4608 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4609 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4610 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4611 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4612 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4613 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4614 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4615 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4616 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4617 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4618 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4619 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4620 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4621 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4622 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4623 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4624 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4625 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4626 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4627 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4628 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4629 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4630 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4631 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4632 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4633 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4634 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4635 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4636 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4637 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4638 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4639 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4640 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4641 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4642 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4643 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4644 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4645 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4646 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4647 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4648 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4649 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4650 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4651 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4652 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4653 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4654 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4655 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4656 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4657 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4658 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4659 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4660 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4661 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4662 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4663 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4664 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4665 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4666 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4667 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4668 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4669 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4670 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4671 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4672 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4673 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4674 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4676 static void test_decodeCRLToBeSigned(DWORD dwEncoding
)
4678 static const BYTE
*corruptCRLs
[] = { v1CRL
, v2CRL
};
4683 for (i
= 0; i
< ARRAY_SIZE(corruptCRLs
); i
++)
4685 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4686 corruptCRLs
[i
], corruptCRLs
[i
][1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4688 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
4689 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
4690 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4693 /* at a minimum, a CRL must contain an issuer: */
4694 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4695 v1CRLWithIssuer
, v1CRLWithIssuer
[1] + 2, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4697 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4700 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4702 ok(size
>= sizeof(CRL_INFO
), "Wrong size %d\n", size
);
4703 ok(info
->cCRLEntry
== 0, "Expected 0 CRL entries, got %d\n",
4705 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
4706 "Wrong issuer size %d\n", info
->Issuer
.cbData
);
4707 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
4708 "Unexpected issuer\n");
4711 /* check decoding with an empty CRL entry */
4712 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4713 v1CRLWithIssuerAndEmptyEntry
, v1CRLWithIssuerAndEmptyEntry
[1] + 2,
4714 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4715 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
4716 GetLastError() == OSS_DATA_ERROR
/* Win9x */ ||
4717 GetLastError() == CRYPT_E_BAD_ENCODE
/* Win8 */),
4718 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4720 /* with a real CRL entry */
4721 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4722 v1CRLWithIssuerAndEntry
, v1CRLWithIssuerAndEntry
[1] + 2,
4723 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4724 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4727 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4730 ok(size
>= sizeof(CRL_INFO
), "Wrong size %d\n", size
);
4731 ok(info
->cCRLEntry
== 1, "Expected 1 CRL entries, got %d\n",
4733 ok(info
->rgCRLEntry
!= NULL
, "Expected a valid CRL entry array\n");
4734 entry
= info
->rgCRLEntry
;
4735 ok(entry
->SerialNumber
.cbData
== 1,
4736 "Expected serial number size 1, got %d\n",
4737 entry
->SerialNumber
.cbData
);
4738 ok(*entry
->SerialNumber
.pbData
== *serialNum
,
4739 "Expected serial number %d, got %d\n", *serialNum
,
4740 *entry
->SerialNumber
.pbData
);
4741 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
4742 "Wrong issuer size %d\n", info
->Issuer
.cbData
);
4743 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
4744 "Unexpected issuer\n");
4747 /* a real CRL from verisign that has extensions */
4748 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4749 verisignCRL
, sizeof(verisignCRL
), CRYPT_DECODE_ALLOC_FLAG
,
4751 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4754 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4756 ok(size
>= sizeof(CRL_INFO
), "Wrong size %d\n", size
);
4757 ok(info
->cCRLEntry
== 3, "Expected 3 CRL entries, got %d\n",
4759 ok(info
->rgCRLEntry
!= NULL
, "Expected a valid CRL entry array\n");
4760 ok(info
->cExtension
== 2, "Expected 2 extensions, got %d\n",
4764 /* another real CRL from verisign that has lots of entries */
4765 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4766 verisignCRLWithLotsOfEntries
, sizeof(verisignCRLWithLotsOfEntries
),
4767 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4768 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4771 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4773 ok(size
>= sizeof(CRL_INFO
), "Got size %d\n", size
);
4774 ok(info
->cCRLEntry
== 209, "Expected 209 CRL entries, got %d\n",
4776 ok(info
->cExtension
== 0, "Expected 0 extensions, got %d\n",
4780 /* and finally, with an extension */
4781 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4782 v1CRLWithExt
, sizeof(v1CRLWithExt
), CRYPT_DECODE_ALLOC_FLAG
,
4784 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4787 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4790 ok(size
>= sizeof(CRL_INFO
), "Wrong size %d\n", size
);
4791 ok(info
->cCRLEntry
== 1, "Expected 1 CRL entries, got %d\n",
4793 ok(info
->rgCRLEntry
!= NULL
, "Expected a valid CRL entry array\n");
4794 entry
= info
->rgCRLEntry
;
4795 ok(entry
->SerialNumber
.cbData
== 1,
4796 "Expected serial number size 1, got %d\n",
4797 entry
->SerialNumber
.cbData
);
4798 ok(*entry
->SerialNumber
.pbData
== *serialNum
,
4799 "Expected serial number %d, got %d\n", *serialNum
,
4800 *entry
->SerialNumber
.pbData
);
4801 ok(info
->Issuer
.cbData
== sizeof(encodedCommonName
),
4802 "Wrong issuer size %d\n", info
->Issuer
.cbData
);
4803 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonName
, info
->Issuer
.cbData
),
4804 "Unexpected issuer\n");
4805 ok(info
->cExtension
== 1, "Expected 1 extensions, got %d\n",
4809 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_CRL_TO_BE_SIGNED
,
4810 v2CRLWithExt
, sizeof(v2CRLWithExt
), CRYPT_DECODE_ALLOC_FLAG
,
4812 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4815 CRL_INFO
*info
= (CRL_INFO
*)buf
;
4817 ok(info
->cExtension
== 1, "Expected 1 extensions, got %d\n",
4823 static const LPCSTR keyUsages
[] = { szOID_PKIX_KP_CODE_SIGNING
,
4824 szOID_PKIX_KP_CLIENT_AUTH
, szOID_RSA_RSA
};
4825 static const BYTE encodedUsage
[] = {
4826 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4827 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4828 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4830 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding
)
4835 CERT_ENHKEY_USAGE usage
;
4837 /* Test with empty usage */
4838 usage
.cUsageIdentifier
= 0;
4839 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ENHANCED_KEY_USAGE
, &usage
,
4840 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4841 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4844 ok(size
== sizeof(emptySequence
), "Wrong size %d\n", size
);
4845 ok(!memcmp(buf
, emptySequence
, size
), "Got unexpected value\n");
4848 /* Test with a few usages */
4849 usage
.cUsageIdentifier
= ARRAY_SIZE(keyUsages
);
4850 usage
.rgpszUsageIdentifier
= (LPSTR
*)keyUsages
;
4851 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_ENHANCED_KEY_USAGE
, &usage
,
4852 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4853 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4856 ok(size
== sizeof(encodedUsage
), "Wrong size %d\n", size
);
4857 ok(!memcmp(buf
, encodedUsage
, size
), "Got unexpected value\n");
4862 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding
)
4868 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ENHANCED_KEY_USAGE
,
4869 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4871 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4874 CERT_ENHKEY_USAGE
*usage
= (CERT_ENHKEY_USAGE
*)buf
;
4876 ok(size
>= sizeof(CERT_ENHKEY_USAGE
),
4877 "Wrong size %d\n", size
);
4878 ok(usage
->cUsageIdentifier
== 0, "Expected 0 CRL entries, got %d\n",
4879 usage
->cUsageIdentifier
);
4882 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ENHANCED_KEY_USAGE
,
4883 encodedUsage
, sizeof(encodedUsage
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4885 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4888 CERT_ENHKEY_USAGE
*usage
= (CERT_ENHKEY_USAGE
*)buf
;
4891 ok(size
>= sizeof(CERT_ENHKEY_USAGE
),
4892 "Wrong size %d\n", size
);
4893 ok(usage
->cUsageIdentifier
== ARRAY_SIZE(keyUsages
),
4894 "Wrong CRL entries count %d\n", usage
->cUsageIdentifier
);
4895 for (i
= 0; i
< usage
->cUsageIdentifier
; i
++)
4896 ok(!strcmp(usage
->rgpszUsageIdentifier
[i
], keyUsages
[i
]),
4897 "Expected OID %s, got %s\n", keyUsages
[i
],
4898 usage
->rgpszUsageIdentifier
[i
]);
4901 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ENHANCED_KEY_USAGE
,
4902 encodedUsage
, sizeof(encodedUsage
), 0, NULL
, NULL
, &size
);
4903 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4904 buf
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
4907 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_ENHANCED_KEY_USAGE
,
4908 encodedUsage
, sizeof(encodedUsage
), 0, NULL
, buf
, &size
);
4909 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4910 HeapFree(GetProcessHeap(), 0, buf
);
4914 static BYTE keyId
[] = { 1,2,3,4 };
4915 static const BYTE authorityKeyIdWithId
[] = {
4916 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4917 static const BYTE authorityKeyIdWithIssuer
[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4918 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4919 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4920 static const BYTE authorityKeyIdWithSerial
[] = { 0x30,0x03,0x82,0x01,0x01 };
4922 static void test_encodeAuthorityKeyId(DWORD dwEncoding
)
4924 CERT_AUTHORITY_KEY_ID_INFO info
= { { 0 } };
4929 /* Test with empty id */
4930 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
, &info
,
4931 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4932 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4935 ok(size
== sizeof(emptySequence
), "Unexpected size %d\n", size
);
4936 ok(!memcmp(buf
, emptySequence
, size
), "Unexpected value\n");
4939 /* With just a key id */
4940 info
.KeyId
.cbData
= sizeof(keyId
);
4941 info
.KeyId
.pbData
= keyId
;
4942 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
, &info
,
4943 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4944 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4947 ok(size
== sizeof(authorityKeyIdWithId
), "Unexpected size %d\n", size
);
4948 ok(!memcmp(buf
, authorityKeyIdWithId
, size
), "Unexpected value\n");
4951 /* With just an issuer */
4952 info
.KeyId
.cbData
= 0;
4953 info
.CertIssuer
.cbData
= sizeof(encodedCommonName
);
4954 info
.CertIssuer
.pbData
= (BYTE
*)encodedCommonName
;
4955 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
, &info
,
4956 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4957 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4960 ok(size
== sizeof(authorityKeyIdWithIssuer
), "Unexpected size %d\n",
4962 ok(!memcmp(buf
, authorityKeyIdWithIssuer
, size
), "Unexpected value\n");
4965 /* With just a serial number */
4966 info
.CertIssuer
.cbData
= 0;
4967 info
.CertSerialNumber
.cbData
= sizeof(serialNum
);
4968 info
.CertSerialNumber
.pbData
= (BYTE
*)serialNum
;
4969 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
, &info
,
4970 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
4971 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4974 ok(size
== sizeof(authorityKeyIdWithSerial
), "Unexpected size %d\n",
4976 ok(!memcmp(buf
, authorityKeyIdWithSerial
, size
), "Unexpected value\n");
4981 static void test_decodeAuthorityKeyId(DWORD dwEncoding
)
4987 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
,
4988 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4990 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4993 CERT_AUTHORITY_KEY_ID_INFO
*info
= (CERT_AUTHORITY_KEY_ID_INFO
*)buf
;
4995 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID_INFO
), "Unexpected size %d\n",
4997 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
4998 ok(info
->CertIssuer
.cbData
== 0, "Expected no issuer name\n");
4999 ok(info
->CertSerialNumber
.cbData
== 0, "Expected no serial number\n");
5002 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
,
5003 authorityKeyIdWithId
, sizeof(authorityKeyIdWithId
),
5004 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5005 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5008 CERT_AUTHORITY_KEY_ID_INFO
*info
= (CERT_AUTHORITY_KEY_ID_INFO
*)buf
;
5010 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID_INFO
), "Unexpected size %d\n",
5012 ok(info
->KeyId
.cbData
== sizeof(keyId
), "Unexpected key id len\n");
5013 ok(!memcmp(info
->KeyId
.pbData
, keyId
, sizeof(keyId
)),
5014 "Unexpected key id\n");
5015 ok(info
->CertIssuer
.cbData
== 0, "Expected no issuer name\n");
5016 ok(info
->CertSerialNumber
.cbData
== 0, "Expected no serial number\n");
5019 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
,
5020 authorityKeyIdWithIssuer
, sizeof(authorityKeyIdWithIssuer
),
5021 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5022 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5025 CERT_AUTHORITY_KEY_ID_INFO
*info
= (CERT_AUTHORITY_KEY_ID_INFO
*)buf
;
5027 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID_INFO
), "Unexpected size %d\n",
5029 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
5030 ok(info
->CertIssuer
.cbData
== sizeof(encodedCommonName
),
5031 "Unexpected issuer len\n");
5032 ok(!memcmp(info
->CertIssuer
.pbData
, encodedCommonName
,
5033 sizeof(encodedCommonName
)), "Unexpected issuer\n");
5034 ok(info
->CertSerialNumber
.cbData
== 0, "Expected no serial number\n");
5037 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID
,
5038 authorityKeyIdWithSerial
, sizeof(authorityKeyIdWithSerial
),
5039 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5040 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5043 CERT_AUTHORITY_KEY_ID_INFO
*info
= (CERT_AUTHORITY_KEY_ID_INFO
*)buf
;
5045 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID_INFO
), "Unexpected size %d\n",
5047 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
5048 ok(info
->CertIssuer
.cbData
== 0, "Expected no issuer name\n");
5049 ok(info
->CertSerialNumber
.cbData
== sizeof(serialNum
),
5050 "Unexpected serial number len\n");
5051 ok(!memcmp(info
->CertSerialNumber
.pbData
, serialNum
, sizeof(serialNum
)),
5052 "Unexpected serial number\n");
5057 static const BYTE authorityKeyIdWithIssuerUrl
[] = { 0x30,0x15,0xa1,0x13,0x86,
5058 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
5061 static void test_encodeAuthorityKeyId2(DWORD dwEncoding
)
5063 CERT_AUTHORITY_KEY_ID2_INFO info
= { { 0 } };
5064 CERT_ALT_NAME_ENTRY entry
= { 0 };
5069 /* Test with empty id */
5070 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
, &info
,
5071 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5072 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5075 ok(size
== sizeof(emptySequence
), "Unexpected size %d\n", size
);
5076 ok(!memcmp(buf
, emptySequence
, size
), "Unexpected value\n");
5079 /* With just a key id */
5080 info
.KeyId
.cbData
= sizeof(keyId
);
5081 info
.KeyId
.pbData
= keyId
;
5082 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
, &info
,
5083 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5084 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5087 ok(size
== sizeof(authorityKeyIdWithId
), "Unexpected size %d\n",
5089 ok(!memcmp(buf
, authorityKeyIdWithId
, size
), "Unexpected value\n");
5092 /* With a bogus issuer name */
5093 info
.KeyId
.cbData
= 0;
5094 info
.AuthorityCertIssuer
.cAltEntry
= 1;
5095 info
.AuthorityCertIssuer
.rgAltEntry
= &entry
;
5096 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
, &info
,
5097 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5098 ok(!ret
&& GetLastError() == E_INVALIDARG
,
5099 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5100 /* With an issuer name */
5101 entry
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
5102 U(entry
).pwszURL
= (LPWSTR
)url
;
5103 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
, &info
,
5104 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5105 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5108 ok(size
== sizeof(authorityKeyIdWithIssuerUrl
), "Unexpected size %d\n",
5110 ok(!memcmp(buf
, authorityKeyIdWithIssuerUrl
, size
),
5111 "Unexpected value\n");
5114 /* With just a serial number */
5115 info
.AuthorityCertIssuer
.cAltEntry
= 0;
5116 info
.AuthorityCertSerialNumber
.cbData
= sizeof(serialNum
);
5117 info
.AuthorityCertSerialNumber
.pbData
= (BYTE
*)serialNum
;
5118 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
, &info
,
5119 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5120 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5123 ok(size
== sizeof(authorityKeyIdWithSerial
), "Unexpected size %d\n",
5125 ok(!memcmp(buf
, authorityKeyIdWithSerial
, size
), "Unexpected value\n");
5130 static void test_decodeAuthorityKeyId2(DWORD dwEncoding
)
5136 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
,
5137 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5139 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5142 CERT_AUTHORITY_KEY_ID2_INFO
*info
= (CERT_AUTHORITY_KEY_ID2_INFO
*)buf
;
5144 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID2_INFO
), "Unexpected size %d\n",
5146 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
5147 ok(info
->AuthorityCertIssuer
.cAltEntry
== 0,
5148 "Expected no issuer name entries\n");
5149 ok(info
->AuthorityCertSerialNumber
.cbData
== 0,
5150 "Expected no serial number\n");
5153 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
,
5154 authorityKeyIdWithId
, sizeof(authorityKeyIdWithId
),
5155 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5156 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5159 CERT_AUTHORITY_KEY_ID2_INFO
*info
= (CERT_AUTHORITY_KEY_ID2_INFO
*)buf
;
5161 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID2_INFO
), "Unexpected size %d\n",
5163 ok(info
->KeyId
.cbData
== sizeof(keyId
), "Unexpected key id len\n");
5164 ok(!memcmp(info
->KeyId
.pbData
, keyId
, sizeof(keyId
)),
5165 "Unexpected key id\n");
5166 ok(info
->AuthorityCertIssuer
.cAltEntry
== 0,
5167 "Expected no issuer name entries\n");
5168 ok(info
->AuthorityCertSerialNumber
.cbData
== 0,
5169 "Expected no serial number\n");
5172 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
,
5173 authorityKeyIdWithIssuerUrl
, sizeof(authorityKeyIdWithIssuerUrl
),
5174 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5175 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5178 CERT_AUTHORITY_KEY_ID2_INFO
*info
= (CERT_AUTHORITY_KEY_ID2_INFO
*)buf
;
5180 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID2_INFO
), "Unexpected size %d\n",
5182 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
5183 ok(info
->AuthorityCertIssuer
.cAltEntry
== 1,
5184 "Expected 1 issuer entry, got %d\n",
5185 info
->AuthorityCertIssuer
.cAltEntry
);
5186 ok(info
->AuthorityCertIssuer
.rgAltEntry
[0].dwAltNameChoice
==
5187 CERT_ALT_NAME_URL
, "Expected CERT_ALT_NAME_URL, got %d\n",
5188 info
->AuthorityCertIssuer
.rgAltEntry
[0].dwAltNameChoice
);
5189 ok(!lstrcmpW(U(info
->AuthorityCertIssuer
.rgAltEntry
[0]).pwszURL
,
5190 url
), "Unexpected URL\n");
5191 ok(info
->AuthorityCertSerialNumber
.cbData
== 0,
5192 "Expected no serial number\n");
5195 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_KEY_ID2
,
5196 authorityKeyIdWithSerial
, sizeof(authorityKeyIdWithSerial
),
5197 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5198 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5201 CERT_AUTHORITY_KEY_ID2_INFO
*info
= (CERT_AUTHORITY_KEY_ID2_INFO
*)buf
;
5203 ok(size
>= sizeof(CERT_AUTHORITY_KEY_ID2_INFO
), "Unexpected size %d\n",
5205 ok(info
->KeyId
.cbData
== 0, "Expected no key id\n");
5206 ok(info
->AuthorityCertIssuer
.cAltEntry
== 0,
5207 "Expected no issuer name entries\n");
5208 ok(info
->AuthorityCertSerialNumber
.cbData
== sizeof(serialNum
),
5209 "Unexpected serial number len\n");
5210 ok(!memcmp(info
->AuthorityCertSerialNumber
.pbData
, serialNum
,
5211 sizeof(serialNum
)), "Unexpected serial number\n");
5216 static const BYTE authorityInfoAccessWithUrl
[] = {
5217 0x30,0x19,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
5218 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5219 static const BYTE authorityInfoAccessWithUrlAndIPAddr
[] = {
5220 0x30,0x29,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
5221 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x0e,0x06,
5222 0x02,0x2d,0x06,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5224 static void test_encodeAuthorityInfoAccess(DWORD dwEncoding
)
5226 static char oid1
[] = "1.2.3";
5227 static char oid2
[] = "1.5.6";
5231 CERT_ACCESS_DESCRIPTION accessDescription
[2];
5232 CERT_AUTHORITY_INFO_ACCESS aia
;
5234 memset(accessDescription
, 0, sizeof(accessDescription
));
5236 aia
.rgAccDescr
= NULL
;
5237 /* Having no access descriptions is allowed */
5238 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
, &aia
,
5239 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5240 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5243 ok(size
== sizeof(emptySequence
), "unexpected size %d\n", size
);
5244 ok(!memcmp(buf
, emptySequence
, size
), "unexpected value\n");
5248 /* It can't have an empty access method */
5250 aia
.rgAccDescr
= accessDescription
;
5251 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
, &aia
,
5252 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5253 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
5254 GetLastError() == OSS_LIMITED
/* Win9x */),
5255 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
5256 /* It can't have an empty location */
5257 accessDescription
[0].pszAccessMethod
= oid1
;
5258 SetLastError(0xdeadbeef);
5259 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
, &aia
,
5260 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5261 ok(!ret
&& GetLastError() == E_INVALIDARG
,
5262 "expected E_INVALIDARG, got %08x\n", GetLastError());
5263 accessDescription
[0].AccessLocation
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
5264 U(accessDescription
[0].AccessLocation
).pwszURL
= (LPWSTR
)url
;
5265 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
, &aia
,
5266 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5267 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5270 ok(size
== sizeof(authorityInfoAccessWithUrl
), "unexpected size %d\n",
5272 ok(!memcmp(buf
, authorityInfoAccessWithUrl
, size
),
5273 "unexpected value\n");
5277 accessDescription
[1].pszAccessMethod
= oid2
;
5278 accessDescription
[1].AccessLocation
.dwAltNameChoice
=
5279 CERT_ALT_NAME_IP_ADDRESS
;
5280 U(accessDescription
[1].AccessLocation
).IPAddress
.cbData
=
5281 sizeof(encodedIPAddr
);
5282 U(accessDescription
[1].AccessLocation
).IPAddress
.pbData
=
5283 (LPBYTE
)encodedIPAddr
;
5285 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
, &aia
,
5286 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5287 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5290 ok(size
== sizeof(authorityInfoAccessWithUrlAndIPAddr
),
5291 "unexpected size %d\n", size
);
5292 ok(!memcmp(buf
, authorityInfoAccessWithUrlAndIPAddr
, size
),
5293 "unexpected value\n");
5299 static void compareAuthorityInfoAccess(LPCSTR header
,
5300 const CERT_AUTHORITY_INFO_ACCESS
*expected
,
5301 const CERT_AUTHORITY_INFO_ACCESS
*got
)
5305 ok(expected
->cAccDescr
== got
->cAccDescr
,
5306 "%s: expected %d access descriptions, got %d\n", header
,
5307 expected
->cAccDescr
, got
->cAccDescr
);
5308 for (i
= 0; i
< expected
->cAccDescr
; i
++)
5310 ok(!strcmp(expected
->rgAccDescr
[i
].pszAccessMethod
,
5311 got
->rgAccDescr
[i
].pszAccessMethod
), "%s[%d]: expected %s, got %s\n",
5312 header
, i
, expected
->rgAccDescr
[i
].pszAccessMethod
,
5313 got
->rgAccDescr
[i
].pszAccessMethod
);
5314 compareAltNameEntry(&expected
->rgAccDescr
[i
].AccessLocation
,
5315 &got
->rgAccDescr
[i
].AccessLocation
);
5319 static void test_decodeAuthorityInfoAccess(DWORD dwEncoding
)
5321 static char oid1
[] = "1.2.3";
5322 static char oid2
[] = "1.5.6";
5327 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
,
5328 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5330 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5333 CERT_AUTHORITY_INFO_ACCESS aia
= { 0, NULL
};
5335 compareAuthorityInfoAccess("empty AIA", &aia
,
5336 (CERT_AUTHORITY_INFO_ACCESS
*)buf
);
5340 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
,
5341 authorityInfoAccessWithUrl
, sizeof(authorityInfoAccessWithUrl
),
5342 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5343 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5346 CERT_ACCESS_DESCRIPTION accessDescription
;
5347 CERT_AUTHORITY_INFO_ACCESS aia
;
5349 accessDescription
.pszAccessMethod
= oid1
;
5350 accessDescription
.AccessLocation
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
5351 U(accessDescription
.AccessLocation
).pwszURL
= (LPWSTR
)url
;
5353 aia
.rgAccDescr
= &accessDescription
;
5354 compareAuthorityInfoAccess("AIA with URL", &aia
,
5355 (CERT_AUTHORITY_INFO_ACCESS
*)buf
);
5359 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
,
5360 authorityInfoAccessWithUrlAndIPAddr
,
5361 sizeof(authorityInfoAccessWithUrlAndIPAddr
), CRYPT_DECODE_ALLOC_FLAG
,
5363 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5366 CERT_ACCESS_DESCRIPTION accessDescription
[2];
5367 CERT_AUTHORITY_INFO_ACCESS aia
;
5369 accessDescription
[0].pszAccessMethod
= oid1
;
5370 accessDescription
[0].AccessLocation
.dwAltNameChoice
= CERT_ALT_NAME_URL
;
5371 U(accessDescription
[0].AccessLocation
).pwszURL
= (LPWSTR
)url
;
5372 accessDescription
[1].pszAccessMethod
= oid2
;
5373 accessDescription
[1].AccessLocation
.dwAltNameChoice
=
5374 CERT_ALT_NAME_IP_ADDRESS
;
5375 U(accessDescription
[1].AccessLocation
).IPAddress
.cbData
=
5376 sizeof(encodedIPAddr
);
5377 U(accessDescription
[1].AccessLocation
).IPAddress
.pbData
=
5378 (LPBYTE
)encodedIPAddr
;
5380 aia
.rgAccDescr
= accessDescription
;
5381 compareAuthorityInfoAccess("AIA with URL and IP addr", &aia
,
5382 (CERT_AUTHORITY_INFO_ACCESS
*)buf
);
5386 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
,
5387 authorityInfoAccessWithUrlAndIPAddr
,
5388 sizeof(authorityInfoAccessWithUrlAndIPAddr
), 0, NULL
, NULL
, &size
);
5389 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5390 buf
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
5393 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_AUTHORITY_INFO_ACCESS
,
5394 authorityInfoAccessWithUrlAndIPAddr
,
5395 sizeof(authorityInfoAccessWithUrlAndIPAddr
), 0, NULL
, buf
, &size
);
5396 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5397 HeapFree(GetProcessHeap(), 0, buf
);
5401 static const BYTE emptyCTL
[] = {
5402 0x30,0x17,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5403 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5404 static const BYTE emptyCTLWithVersion1
[] = {
5405 0x30,0x1a,0x02,0x01,0x01,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5406 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5407 static const BYTE ctlWithUsageIdentifier
[] = {
5408 0x30,0x1b,0x30,0x04,0x06,0x02,0x2a,0x03,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
5409 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5410 static const BYTE ctlWithListIdentifier
[] = {
5411 0x30,0x1a,0x30,0x00,0x04,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5412 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5413 static const BYTE ctlWithSequenceNumber
[] = {
5414 0x30,0x1a,0x30,0x00,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5415 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5416 static const BYTE ctlWithThisUpdate
[] = {
5417 0x30,0x15,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5418 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5419 static const BYTE ctlWithThisAndNextUpdate
[] = {
5420 0x30,0x24,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5421 0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5422 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5423 static const BYTE ctlWithAlgId
[] = {
5424 0x30,0x1b,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5425 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5426 static const BYTE ctlWithBogusEntry
[] = {
5427 0x30,0x29,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5428 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x10,0x30,0x0e,0x04,
5429 0x01,0x01,0x31,0x09,0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,0x01 };
5430 static const BYTE ctlWithOneEntry
[] = {
5431 0x30,0x2a,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5432 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x11,0x30,0x0f,0x04,
5433 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00 };
5434 static const BYTE ctlWithTwoEntries
[] = {
5435 0x30,0x41,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5436 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x28,0x30,0x0f,0x04,
5437 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00,0x30,
5438 0x15,0x04,0x01,0x01,0x31,0x10,0x30,0x0e,0x06,0x02,0x2d,0x06,0x31,0x08,0x30,
5439 0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5441 static void test_encodeCTL(DWORD dwEncoding
)
5443 static char oid1
[] = "1.2.3";
5444 static char oid2
[] = "1.5.6";
5450 SYSTEMTIME thisUpdate
= { 2005, 6, 1, 6, 16, 10, 0, 0 };
5451 CTL_ENTRY ctlEntry
[2];
5452 CRYPT_ATTRIBUTE attr1
, attr2
;
5453 CRYPT_ATTR_BLOB value1
, value2
;
5455 memset(&info
, 0, sizeof(info
));
5456 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5457 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5458 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5461 ok(size
== sizeof(emptyCTL
), "unexpected size %d\n", size
);
5462 ok(!memcmp(buf
, emptyCTL
, size
), "unexpected value\n");
5467 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5468 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5469 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5472 ok(size
== sizeof(emptyCTLWithVersion1
), "unexpected size %d\n", size
);
5473 ok(!memcmp(buf
, emptyCTLWithVersion1
, size
), "unexpected value\n");
5478 info
.SubjectUsage
.cUsageIdentifier
= 1;
5479 info
.SubjectUsage
.rgpszUsageIdentifier
= &pOid1
;
5480 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5481 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5482 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5485 ok(size
== sizeof(ctlWithUsageIdentifier
), "unexpected size %d\n",
5487 ok(!memcmp(buf
, ctlWithUsageIdentifier
, size
), "unexpected value\n");
5491 info
.SubjectUsage
.cUsageIdentifier
= 0;
5492 info
.ListIdentifier
.cbData
= sizeof(serialNum
);
5493 info
.ListIdentifier
.pbData
= (LPBYTE
)serialNum
;
5494 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5495 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5496 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5499 ok(size
== sizeof(ctlWithListIdentifier
), "unexpected size %d\n", size
);
5500 ok(!memcmp(buf
, ctlWithListIdentifier
, size
), "unexpected value\n");
5504 info
.ListIdentifier
.cbData
= 0;
5505 info
.SequenceNumber
.cbData
= sizeof(serialNum
);
5506 info
.SequenceNumber
.pbData
= (LPBYTE
)serialNum
;
5507 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5508 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5509 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5512 ok(size
== sizeof(ctlWithSequenceNumber
), "unexpected size %d\n",
5514 ok(!memcmp(buf
, ctlWithSequenceNumber
, size
), "unexpected value\n");
5518 info
.SequenceNumber
.cbData
= 0;
5519 SystemTimeToFileTime(&thisUpdate
, &info
.ThisUpdate
);
5520 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5521 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5522 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5525 ok(size
== sizeof(ctlWithThisUpdate
), "unexpected size %d\n", size
);
5526 ok(!memcmp(buf
, ctlWithThisUpdate
, size
), "unexpected value\n");
5530 SystemTimeToFileTime(&thisUpdate
, &info
.NextUpdate
);
5531 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5532 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5533 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5536 ok(size
== sizeof(ctlWithThisAndNextUpdate
), "unexpected size %d\n",
5538 ok(!memcmp(buf
, ctlWithThisAndNextUpdate
, size
), "unexpected value\n");
5542 info
.ThisUpdate
.dwLowDateTime
= info
.ThisUpdate
.dwHighDateTime
= 0;
5543 info
.NextUpdate
.dwLowDateTime
= info
.NextUpdate
.dwHighDateTime
= 0;
5544 info
.SubjectAlgorithm
.pszObjId
= oid2
;
5545 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5546 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5547 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5550 ok(size
== sizeof(ctlWithAlgId
), "unexpected size %d\n", size
);
5551 ok(!memcmp(buf
, ctlWithAlgId
, size
), "unexpected value\n");
5555 /* The value is supposed to be asn.1 encoded, so this'll fail to decode
5556 * (see tests below) but it'll encode fine.
5558 info
.SubjectAlgorithm
.pszObjId
= NULL
;
5559 value1
.cbData
= sizeof(serialNum
);
5560 value1
.pbData
= (LPBYTE
)serialNum
;
5561 attr1
.pszObjId
= oid1
;
5563 attr1
.rgValue
= &value1
;
5564 ctlEntry
[0].SubjectIdentifier
.cbData
= sizeof(serialNum
);
5565 ctlEntry
[0].SubjectIdentifier
.pbData
= (LPBYTE
)serialNum
;
5566 ctlEntry
[0].cAttribute
= 1;
5567 ctlEntry
[0].rgAttribute
= &attr1
;
5569 info
.rgCTLEntry
= ctlEntry
;
5570 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5571 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5572 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5575 ok(size
== sizeof(ctlWithBogusEntry
), "unexpected size %d\n", size
);
5576 ok(!memcmp(buf
, ctlWithBogusEntry
, size
), "unexpected value\n");
5580 value1
.cbData
= sizeof(emptySequence
);
5581 value1
.pbData
= (LPBYTE
)emptySequence
;
5582 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5583 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5584 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5587 ok(size
== sizeof(ctlWithOneEntry
), "unexpected size %d\n", size
);
5588 ok(!memcmp(buf
, ctlWithOneEntry
, size
), "unexpected value\n");
5592 value2
.cbData
= sizeof(encodedIPAddr
);
5593 value2
.pbData
= (LPBYTE
)encodedIPAddr
;
5594 attr2
.pszObjId
= oid2
;
5596 attr2
.rgValue
= &value2
;
5597 ctlEntry
[1].SubjectIdentifier
.cbData
= sizeof(serialNum
);
5598 ctlEntry
[1].SubjectIdentifier
.pbData
= (LPBYTE
)serialNum
;
5599 ctlEntry
[1].cAttribute
= 1;
5600 ctlEntry
[1].rgAttribute
= &attr2
;
5602 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CTL
, &info
,
5603 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5604 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5607 ok(size
== sizeof(ctlWithTwoEntries
), "unexpected size %d\n", size
);
5608 ok(!memcmp(buf
, ctlWithTwoEntries
, size
), "unexpected value\n");
5614 static void compareCTLInfo(LPCSTR header
, const CTL_INFO
*expected
,
5615 const CTL_INFO
*got
)
5619 ok(expected
->dwVersion
== got
->dwVersion
,
5620 "%s: expected version %d, got %d\n", header
, expected
->dwVersion
,
5622 ok(expected
->SubjectUsage
.cUsageIdentifier
==
5623 got
->SubjectUsage
.cUsageIdentifier
,
5624 "%s: expected %d usage identifiers, got %d\n", header
,
5625 expected
->SubjectUsage
.cUsageIdentifier
,
5626 got
->SubjectUsage
.cUsageIdentifier
);
5627 for (i
= 0; i
< expected
->SubjectUsage
.cUsageIdentifier
; i
++)
5628 ok(!strcmp(expected
->SubjectUsage
.rgpszUsageIdentifier
[i
],
5629 got
->SubjectUsage
.rgpszUsageIdentifier
[i
]),
5630 "%s[%d]: expected %s, got %s\n", header
, i
,
5631 expected
->SubjectUsage
.rgpszUsageIdentifier
[i
],
5632 got
->SubjectUsage
.rgpszUsageIdentifier
[i
]);
5633 ok(expected
->ListIdentifier
.cbData
== got
->ListIdentifier
.cbData
,
5634 "%s: expected list identifier of %d bytes, got %d\n", header
,
5635 expected
->ListIdentifier
.cbData
, got
->ListIdentifier
.cbData
);
5636 if (expected
->ListIdentifier
.cbData
)
5637 ok(!memcmp(expected
->ListIdentifier
.pbData
, got
->ListIdentifier
.pbData
,
5638 expected
->ListIdentifier
.cbData
),
5639 "%s: unexpected list identifier value\n", header
);
5640 ok(expected
->SequenceNumber
.cbData
== got
->SequenceNumber
.cbData
,
5641 "%s: expected sequence number of %d bytes, got %d\n", header
,
5642 expected
->SequenceNumber
.cbData
, got
->SequenceNumber
.cbData
);
5643 if (expected
->SequenceNumber
.cbData
)
5644 ok(!memcmp(expected
->SequenceNumber
.pbData
, got
->SequenceNumber
.pbData
,
5645 expected
->SequenceNumber
.cbData
),
5646 "%s: unexpected sequence number value\n", header
);
5647 ok(!memcmp(&expected
->ThisUpdate
, &got
->ThisUpdate
, sizeof(FILETIME
)),
5648 "%s: expected this update = (%d, %d), got (%d, %d)\n", header
,
5649 expected
->ThisUpdate
.dwLowDateTime
, expected
->ThisUpdate
.dwHighDateTime
,
5650 got
->ThisUpdate
.dwLowDateTime
, got
->ThisUpdate
.dwHighDateTime
);
5651 ok(!memcmp(&expected
->NextUpdate
, &got
->NextUpdate
, sizeof(FILETIME
)),
5652 "%s: expected next update = (%d, %d), got (%d, %d)\n", header
,
5653 expected
->NextUpdate
.dwLowDateTime
, expected
->NextUpdate
.dwHighDateTime
,
5654 got
->NextUpdate
.dwLowDateTime
, got
->NextUpdate
.dwHighDateTime
);
5655 if (expected
->SubjectAlgorithm
.pszObjId
&&
5656 *expected
->SubjectAlgorithm
.pszObjId
&& !got
->SubjectAlgorithm
.pszObjId
)
5657 ok(0, "%s: expected subject algorithm %s, got NULL\n", header
,
5658 expected
->SubjectAlgorithm
.pszObjId
);
5659 if (expected
->SubjectAlgorithm
.pszObjId
&& got
->SubjectAlgorithm
.pszObjId
)
5660 ok(!strcmp(expected
->SubjectAlgorithm
.pszObjId
,
5661 got
->SubjectAlgorithm
.pszObjId
),
5662 "%s: expected subject algorithm %s, got %s\n", header
,
5663 expected
->SubjectAlgorithm
.pszObjId
, got
->SubjectAlgorithm
.pszObjId
);
5664 ok(expected
->SubjectAlgorithm
.Parameters
.cbData
==
5665 got
->SubjectAlgorithm
.Parameters
.cbData
,
5666 "%s: expected subject algorithm parameters of %d bytes, got %d\n", header
,
5667 expected
->SubjectAlgorithm
.Parameters
.cbData
,
5668 got
->SubjectAlgorithm
.Parameters
.cbData
);
5669 if (expected
->SubjectAlgorithm
.Parameters
.cbData
)
5670 ok(!memcmp(expected
->SubjectAlgorithm
.Parameters
.pbData
,
5671 got
->SubjectAlgorithm
.Parameters
.pbData
,
5672 expected
->SubjectAlgorithm
.Parameters
.cbData
),
5673 "%s: unexpected subject algorithm parameter value\n", header
);
5674 ok(expected
->cCTLEntry
== got
->cCTLEntry
,
5675 "%s: expected %d CTL entries, got %d\n", header
, expected
->cCTLEntry
,
5677 for (i
= 0; i
< expected
->cCTLEntry
; i
++)
5679 ok(expected
->rgCTLEntry
[i
].SubjectIdentifier
.cbData
==
5680 got
->rgCTLEntry
[i
].SubjectIdentifier
.cbData
,
5681 "%s[%d]: expected subject identifier of %d bytes, got %d\n",
5682 header
, i
, expected
->rgCTLEntry
[i
].SubjectIdentifier
.cbData
,
5683 got
->rgCTLEntry
[i
].SubjectIdentifier
.cbData
);
5684 if (expected
->rgCTLEntry
[i
].SubjectIdentifier
.cbData
)
5685 ok(!memcmp(expected
->rgCTLEntry
[i
].SubjectIdentifier
.pbData
,
5686 got
->rgCTLEntry
[i
].SubjectIdentifier
.pbData
,
5687 expected
->rgCTLEntry
[i
].SubjectIdentifier
.cbData
),
5688 "%s[%d]: unexpected subject identifier value\n",
5690 for (j
= 0; j
< expected
->rgCTLEntry
[i
].cAttribute
; j
++)
5692 ok(!strcmp(expected
->rgCTLEntry
[i
].rgAttribute
[j
].pszObjId
,
5693 got
->rgCTLEntry
[i
].rgAttribute
[j
].pszObjId
),
5694 "%s[%d][%d]: expected attribute OID %s, got %s\n", header
, i
, j
,
5695 expected
->rgCTLEntry
[i
].rgAttribute
[j
].pszObjId
,
5696 got
->rgCTLEntry
[i
].rgAttribute
[j
].pszObjId
);
5697 for (k
= 0; k
< expected
->rgCTLEntry
[i
].rgAttribute
[j
].cValue
; k
++)
5699 ok(expected
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].cbData
==
5700 got
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].cbData
,
5701 "%s[%d][%d][%d]: expected value of %d bytes, got %d\n",
5703 expected
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].cbData
,
5704 got
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].cbData
);
5705 if (expected
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].cbData
)
5707 expected
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].pbData
,
5708 got
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].pbData
,
5709 expected
->rgCTLEntry
[i
].rgAttribute
[j
].rgValue
[k
].cbData
),
5710 "%s[%d][%d][%d]: unexpected value\n",
5715 ok(expected
->cExtension
== got
->cExtension
,
5716 "%s: expected %d extensions, got %d\n", header
, expected
->cExtension
,
5718 for (i
= 0; i
< expected
->cExtension
; i
++)
5720 ok(!strcmp(expected
->rgExtension
[i
].pszObjId
,
5721 got
->rgExtension
[i
].pszObjId
), "%s[%d]: expected %s, got %s\n",
5722 header
, i
, expected
->rgExtension
[i
].pszObjId
,
5723 got
->rgExtension
[i
].pszObjId
);
5724 ok(expected
->rgExtension
[i
].fCritical
== got
->rgExtension
[i
].fCritical
,
5725 "%s[%d]: expected fCritical = %d, got %d\n", header
, i
,
5726 expected
->rgExtension
[i
].fCritical
, got
->rgExtension
[i
].fCritical
);
5727 ok(expected
->rgExtension
[i
].Value
.cbData
==
5728 got
->rgExtension
[i
].Value
.cbData
,
5729 "%s[%d]: expected extension value to have %d bytes, got %d\n",
5730 header
, i
, expected
->rgExtension
[i
].Value
.cbData
,
5731 got
->rgExtension
[i
].Value
.cbData
);
5732 if (expected
->rgExtension
[i
].Value
.cbData
)
5733 ok(!memcmp(expected
->rgExtension
[i
].Value
.pbData
,
5734 got
->rgExtension
[i
].Value
.pbData
,
5735 expected
->rgExtension
[i
].Value
.cbData
),
5736 "%s[%d]: unexpected extension value\n", header
, i
);
5740 static const BYTE signedCTL
[] = {
5741 0x30,0x81,0xc7,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
5742 0x81,0xb9,0x30,0x81,0xb6,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
5743 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x28,0x06,0x09,0x2a,0x86,
5744 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x1b,0x04,0x19,0x30,0x17,0x30,0x00,
5745 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5746 0x30,0x5a,0x30,0x02,0x06,0x00,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
5747 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
5748 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
5749 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5750 0x00,0x04,0x40,0xca,0xd8,0x32,0xd1,0xbd,0x97,0x61,0x54,0xd6,0x80,0xcf,0x0d,
5751 0xbd,0xa2,0x42,0xc7,0xca,0x37,0x91,0x7d,0x9d,0xac,0x8c,0xdf,0x05,0x8a,0x39,
5752 0xc6,0x07,0xc1,0x37,0xe6,0xb9,0xd1,0x0d,0x26,0xec,0xa5,0xb0,0x8a,0x51,0x26,
5753 0x2b,0x4f,0x73,0x44,0x86,0x83,0x5e,0x2b,0x6e,0xcc,0xf8,0x1b,0x85,0x53,0xe9,
5754 0x7a,0x80,0x8f,0x6b,0x42,0x19,0x93 };
5755 static const BYTE signedCTLWithCTLInnerContent
[] = {
5756 0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
5757 0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
5758 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
5759 0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
5760 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5761 0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
5762 0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
5763 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
5764 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
5765 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
5766 0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
5767 0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
5768 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
5769 0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5770 0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
5771 0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
5772 0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
5773 0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
5774 0x57,0x6c,0x0b,0x47,0xb8 };
5776 static void test_decodeCTL(DWORD dwEncoding
)
5778 static char oid1
[] = "1.2.3";
5779 static char oid2
[] = "1.5.6";
5780 static BYTE nullData
[] = { 5,0 };
5786 SYSTEMTIME thisUpdate
= { 2005, 6, 1, 6, 16, 10, 0, 0 };
5787 CTL_ENTRY ctlEntry
[2];
5788 CRYPT_ATTRIBUTE attr1
, attr2
;
5789 CRYPT_ATTR_BLOB value1
, value2
;
5791 memset(&info
, 0, sizeof(info
));
5792 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, emptyCTL
, sizeof(emptyCTL
),
5793 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5794 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5797 compareCTLInfo("empty CTL", &info
, (CTL_INFO
*)buf
);
5802 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, emptyCTLWithVersion1
,
5803 sizeof(emptyCTLWithVersion1
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
,
5805 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5808 compareCTLInfo("v1 CTL", &info
, (CTL_INFO
*)buf
);
5813 info
.SubjectUsage
.cUsageIdentifier
= 1;
5814 info
.SubjectUsage
.rgpszUsageIdentifier
= &pOid1
;
5815 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithUsageIdentifier
,
5816 sizeof(ctlWithUsageIdentifier
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5818 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5821 compareCTLInfo("CTL with usage identifier", &info
, (CTL_INFO
*)buf
);
5825 info
.SubjectUsage
.cUsageIdentifier
= 0;
5826 info
.ListIdentifier
.cbData
= sizeof(serialNum
);
5827 info
.ListIdentifier
.pbData
= (LPBYTE
)serialNum
;
5828 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithListIdentifier
,
5829 sizeof(ctlWithListIdentifier
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5830 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5833 compareCTLInfo("CTL with list identifier", &info
, (CTL_INFO
*)buf
);
5837 info
.ListIdentifier
.cbData
= 0;
5838 info
.SequenceNumber
.cbData
= sizeof(serialNum
);
5839 info
.SequenceNumber
.pbData
= (LPBYTE
)serialNum
;
5840 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithSequenceNumber
,
5841 sizeof(ctlWithSequenceNumber
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5842 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5845 compareCTLInfo("CTL with sequence number", &info
, (CTL_INFO
*)buf
);
5849 info
.SequenceNumber
.cbData
= 0;
5850 SystemTimeToFileTime(&thisUpdate
, &info
.ThisUpdate
);
5851 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithThisUpdate
,
5852 sizeof(ctlWithThisUpdate
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5853 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5856 compareCTLInfo("CTL with this update", &info
, (CTL_INFO
*)buf
);
5860 SystemTimeToFileTime(&thisUpdate
, &info
.NextUpdate
);
5861 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithThisAndNextUpdate
,
5862 sizeof(ctlWithThisAndNextUpdate
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5864 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5867 compareCTLInfo("CTL with this and next update", &info
, (CTL_INFO
*)buf
);
5871 info
.ThisUpdate
.dwLowDateTime
= info
.ThisUpdate
.dwHighDateTime
= 0;
5872 info
.NextUpdate
.dwLowDateTime
= info
.NextUpdate
.dwHighDateTime
= 0;
5873 info
.SubjectAlgorithm
.pszObjId
= oid2
;
5874 info
.SubjectAlgorithm
.Parameters
.cbData
= sizeof(nullData
);
5875 info
.SubjectAlgorithm
.Parameters
.pbData
= nullData
;
5876 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithAlgId
,
5877 sizeof(ctlWithAlgId
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5878 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5881 compareCTLInfo("CTL with algorithm identifier", &info
, (CTL_INFO
*)buf
);
5885 SetLastError(0xdeadbeef);
5886 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithBogusEntry
,
5887 sizeof(ctlWithBogusEntry
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5889 (GetLastError() == CRYPT_E_ASN1_EOD
||
5890 GetLastError() == CRYPT_E_ASN1_CORRUPT
||
5891 GetLastError() == OSS_MORE_INPUT
), /* Win9x */
5892 "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n",
5894 info
.SubjectAlgorithm
.Parameters
.cbData
= 0;
5895 info
.ThisUpdate
.dwLowDateTime
= info
.ThisUpdate
.dwHighDateTime
= 0;
5896 info
.NextUpdate
.dwLowDateTime
= info
.NextUpdate
.dwHighDateTime
= 0;
5897 info
.SubjectAlgorithm
.pszObjId
= NULL
;
5898 value1
.cbData
= sizeof(emptySequence
);
5899 value1
.pbData
= (LPBYTE
)emptySequence
;
5900 attr1
.pszObjId
= oid1
;
5902 attr1
.rgValue
= &value1
;
5903 ctlEntry
[0].SubjectIdentifier
.cbData
= sizeof(serialNum
);
5904 ctlEntry
[0].SubjectIdentifier
.pbData
= (LPBYTE
)serialNum
;
5905 ctlEntry
[0].cAttribute
= 1;
5906 ctlEntry
[0].rgAttribute
= &attr1
;
5908 info
.rgCTLEntry
= ctlEntry
;
5909 SetLastError(0xdeadbeef);
5910 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithOneEntry
,
5911 sizeof(ctlWithOneEntry
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5912 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5915 compareCTLInfo("CTL with one entry", &info
, (CTL_INFO
*)buf
);
5919 value2
.cbData
= sizeof(encodedIPAddr
);
5920 value2
.pbData
= (LPBYTE
)encodedIPAddr
;
5921 attr2
.pszObjId
= oid2
;
5923 attr2
.rgValue
= &value2
;
5924 ctlEntry
[1].SubjectIdentifier
.cbData
= sizeof(serialNum
);
5925 ctlEntry
[1].SubjectIdentifier
.pbData
= (LPBYTE
)serialNum
;
5926 ctlEntry
[1].cAttribute
= 1;
5927 ctlEntry
[1].rgAttribute
= &attr2
;
5929 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, ctlWithTwoEntries
,
5930 sizeof(ctlWithTwoEntries
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5931 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5934 compareCTLInfo("CTL with two entries", &info
, (CTL_INFO
*)buf
);
5938 /* A signed CTL isn't decodable, even if the inner content is a CTL */
5939 SetLastError(0xdeadbeef);
5940 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
, signedCTL
,
5941 sizeof(signedCTL
), CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5942 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_BADTAG
||
5943 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
5944 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5946 SetLastError(0xdeadbeef);
5947 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CTL
,
5948 signedCTLWithCTLInnerContent
, sizeof(signedCTLWithCTLInnerContent
),
5949 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5950 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_BADTAG
||
5951 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
5952 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5956 static const BYTE emptyPKCSContentInfo
[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
5957 static const BYTE emptyPKCSContentInfoExtraBytes
[] = { 0x30,0x04,0x06,0x02,0x2a,
5959 static const BYTE bogusPKCSContentInfo
[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
5961 static const BYTE intPKCSContentInfo
[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
5962 0x03,0x02,0x01,0x01 };
5963 static BYTE bogusDER
[] = { 1 };
5965 static void test_encodePKCSContentInfo(DWORD dwEncoding
)
5970 CRYPT_CONTENT_INFO info
= { 0 };
5971 char oid1
[] = "1.2.3";
5975 /* Crashes on win9x */
5976 SetLastError(0xdeadbeef);
5977 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
, NULL
,
5978 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5979 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
5980 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5982 SetLastError(0xdeadbeef);
5983 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
, &info
,
5984 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5985 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
5986 GetLastError() == OSS_LIMITED
/* Win9x */),
5987 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5988 info
.pszObjId
= oid1
;
5989 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
, &info
,
5990 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
5991 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5994 ok(size
== sizeof(emptyPKCSContentInfo
), "Unexpected size %d\n", size
);
5995 ok(!memcmp(buf
, emptyPKCSContentInfo
, size
), "Unexpected value\n");
5998 info
.Content
.pbData
= bogusDER
;
5999 info
.Content
.cbData
= sizeof(bogusDER
);
6000 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
, &info
,
6001 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6002 ok(ret
, "CryptEncodeObjectEx failed; %x\n", GetLastError());
6005 ok(size
== sizeof(bogusPKCSContentInfo
), "Unexpected size %d\n", size
);
6006 ok(!memcmp(buf
, bogusPKCSContentInfo
, size
), "Unexpected value\n");
6009 info
.Content
.pbData
= (BYTE
*)ints
[0].encoded
;
6010 info
.Content
.cbData
= ints
[0].encoded
[1] + 2;
6011 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
, &info
,
6012 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6015 ok(size
== sizeof(intPKCSContentInfo
), "Unexpected size %d\n", size
);
6016 ok(!memcmp(buf
, intPKCSContentInfo
, size
), "Unexpected value\n");
6021 static const BYTE indefiniteSignedPKCSContent
[] = {
6022 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
6023 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
6024 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
6025 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
6026 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
6027 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
6028 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
6029 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
6030 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
6031 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
6032 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
6033 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
6034 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
6035 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
6036 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
6037 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
6038 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
6039 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
6040 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
6041 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
6042 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
6043 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
6044 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
6045 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
6046 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
6047 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
6048 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
6049 0x00,0x00,0x00,0x00,0x00,0x00 };
6051 static const BYTE content_abcd
[] = {
6053 ASN_OBJECTIDENTIFIER
, 2, 42,3,
6054 ASN_CONTEXT
|ASN_CONSTRUCTOR
, 0x80,
6055 ASN_OCTETSTRING
, 4, 'a','b','c','d',
6060 static const BYTE encoded_abcd
[] = {
6061 ASN_OCTETSTRING
, 4, 'a','b','c','d',
6064 static const BYTE content_constructed_abcd
[] = {
6066 ASN_OBJECTIDENTIFIER
, 2, 42,3,
6067 ASN_CONTEXT
|ASN_CONSTRUCTOR
, 0x80,
6068 ASN_CONSTRUCTOR
|ASN_OCTETSTRING
,0x80,
6069 ASN_OCTETSTRING
, 4, 'a','b','0','0',
6073 1,2,3,4,5,6,7 /* extra garbage */
6076 static void test_decodePKCSContentInfo(DWORD dwEncoding
)
6081 CRYPT_CONTENT_INFO
*info
;
6084 const BYTE
*encoded
;
6087 const BYTE
*content
;
6090 { emptyPKCSContentInfo
, sizeof(emptyPKCSContentInfo
),
6092 { emptyPKCSContentInfoExtraBytes
, sizeof(emptyPKCSContentInfoExtraBytes
),
6094 { intPKCSContentInfo
, sizeof(intPKCSContentInfo
),
6095 "1.2.3", ints
[0].encoded
, ints
[0].encoded
[1] + 2 },
6096 { indefiniteSignedPKCSContent
, sizeof(indefiniteSignedPKCSContent
),
6097 "1.2.840.113549.1.7.2", NULL
, 392 },
6098 { content_abcd
, sizeof(content_abcd
),
6099 "1.2.3", encoded_abcd
, 6 },
6100 { content_constructed_abcd
, sizeof(content_constructed_abcd
),
6101 "1.2.3", content_constructed_abcd
+ 8, 10 }
6104 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
6106 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
, tests
[i
].encoded
,
6107 tests
[i
].encoded_size
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6108 ok(ret
, "[%u] CryptDecodeObjectEx failed: %x\n", i
, GetLastError());
6111 info
= (CRYPT_CONTENT_INFO
*)buf
;
6113 ok(!strcmp(info
->pszObjId
, tests
[i
].obj_id
), "[%u] Expected %s, got %s\n",
6114 i
, tests
[i
].obj_id
, info
->pszObjId
);
6115 ok(info
->Content
.cbData
== tests
[i
].content_size
,
6116 "[%u] Unexpected size %d expected %d\n", i
, info
->Content
.cbData
,
6117 tests
[i
].content_size
);
6118 if (tests
[i
].content
)
6119 ok(!memcmp(info
->Content
.pbData
, tests
[i
].content
, tests
[i
].content_size
),
6120 "[%u] Unexpected value\n", i
);
6124 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_CONTENT_INFO
,
6125 bogusPKCSContentInfo
, sizeof(bogusPKCSContentInfo
),
6126 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6127 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
6128 * I doubt an app depends on that.
6130 ok((!ret
&& (GetLastError() == CRYPT_E_ASN1_EOD
||
6131 GetLastError() == CRYPT_E_ASN1_CORRUPT
)) || broken(ret
),
6132 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
6136 static const BYTE emptyPKCSAttr
[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
6138 static const BYTE bogusPKCSAttr
[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
6140 static const BYTE intPKCSAttr
[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
6143 static void test_encodePKCSAttribute(DWORD dwEncoding
)
6145 CRYPT_ATTRIBUTE attr
= { 0 };
6149 CRYPT_ATTR_BLOB blob
;
6150 char oid
[] = "1.2.3";
6154 /* Crashes on win9x */
6155 SetLastError(0xdeadbeef);
6156 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
, NULL
,
6157 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6158 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
6159 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
6161 SetLastError(0xdeadbeef);
6162 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
, &attr
,
6163 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6164 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
6165 GetLastError() == OSS_LIMITED
/* Win9x */),
6166 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
6167 attr
.pszObjId
= oid
;
6168 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
, &attr
,
6169 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6170 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6173 ok(size
== sizeof(emptyPKCSAttr
), "Unexpected size %d\n", size
);
6174 ok(!memcmp(buf
, emptyPKCSAttr
, size
), "Unexpected value\n");
6177 blob
.cbData
= sizeof(bogusDER
);
6178 blob
.pbData
= bogusDER
;
6180 attr
.rgValue
= &blob
;
6181 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
, &attr
,
6182 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6183 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6186 ok(size
== sizeof(bogusPKCSAttr
), "Unexpected size %d\n", size
);
6187 ok(!memcmp(buf
, bogusPKCSAttr
, size
), "Unexpected value\n");
6190 blob
.pbData
= (BYTE
*)ints
[0].encoded
;
6191 blob
.cbData
= ints
[0].encoded
[1] + 2;
6192 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
, &attr
,
6193 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6196 ok(size
== sizeof(intPKCSAttr
), "Unexpected size %d\n", size
);
6197 ok(!memcmp(buf
, intPKCSAttr
, size
), "Unexpected value\n");
6202 static void test_decodePKCSAttribute(DWORD dwEncoding
)
6207 CRYPT_ATTRIBUTE
*attr
;
6209 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
,
6210 emptyPKCSAttr
, sizeof(emptyPKCSAttr
),
6211 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6212 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6215 attr
= (CRYPT_ATTRIBUTE
*)buf
;
6217 ok(!strcmp(attr
->pszObjId
, "1.2.3"), "Expected 1.2.3, got %s\n",
6219 ok(attr
->cValue
== 0, "Expected no value, got %d\n", attr
->cValue
);
6222 SetLastError(0xdeadbeef);
6223 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
,
6224 bogusPKCSAttr
, sizeof(bogusPKCSAttr
),
6225 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6226 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
6227 * I doubt an app depends on that.
6229 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_EOD
||
6230 GetLastError() == CRYPT_E_ASN1_CORRUPT
||
6231 GetLastError() == OSS_MORE_INPUT
/* Win9x */),
6232 "Expected CRYPT_E_ASN1_EOD, CRYPT_E_ASN1_CORRUPT, or OSS_MORE_INPUT, got %x\n",
6234 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTE
,
6235 intPKCSAttr
, sizeof(intPKCSAttr
),
6236 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6237 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6240 attr
= (CRYPT_ATTRIBUTE
*)buf
;
6242 ok(!strcmp(attr
->pszObjId
, "1.2.3"), "Expected 1.2.3, got %s\n",
6244 ok(attr
->cValue
== 1, "Expected 1 value, got %d\n", attr
->cValue
);
6245 ok(attr
->rgValue
[0].cbData
== ints
[0].encoded
[1] + 2,
6246 "Unexpected size %d\n", attr
->rgValue
[0].cbData
);
6247 ok(!memcmp(attr
->rgValue
[0].pbData
, ints
[0].encoded
,
6248 attr
->rgValue
[0].cbData
), "Unexpected value\n");
6253 static const BYTE emptyPKCSAttributes
[] = { 0x31,0x00 };
6254 static const BYTE singlePKCSAttributes
[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
6255 0x2a,0x03,0x31,0x00 };
6256 static const BYTE doublePKCSAttributes
[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
6257 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
6259 static void test_encodePKCSAttributes(DWORD dwEncoding
)
6261 CRYPT_ATTRIBUTES attributes
= { 0 };
6262 CRYPT_ATTRIBUTE attr
[2] = { { 0 } };
6263 CRYPT_ATTR_BLOB blob
;
6267 char oid1
[] = "1.2.3", oid2
[] = "1.5.6";
6269 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
, &attributes
,
6270 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6271 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6274 ok(size
== sizeof(emptyPKCSAttributes
), "Unexpected size %d\n", size
);
6275 ok(!memcmp(buf
, emptyPKCSAttributes
, size
), "Unexpected value\n");
6278 attributes
.cAttr
= 1;
6279 attributes
.rgAttr
= attr
;
6280 SetLastError(0xdeadbeef);
6281 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
, &attributes
,
6282 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6283 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
6284 GetLastError() == OSS_LIMITED
/* Win9x */),
6285 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6286 attr
[0].pszObjId
= oid1
;
6287 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
, &attributes
,
6288 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6291 ok(size
== sizeof(singlePKCSAttributes
), "Unexpected size %d\n", size
);
6292 ok(!memcmp(buf
, singlePKCSAttributes
, size
), "Unexpected value\n");
6295 attr
[1].pszObjId
= oid2
;
6297 attr
[1].rgValue
= &blob
;
6298 blob
.pbData
= (BYTE
*)ints
[0].encoded
;
6299 blob
.cbData
= ints
[0].encoded
[1] + 2;
6300 attributes
.cAttr
= 2;
6301 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
, &attributes
,
6302 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6303 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6306 ok(size
== sizeof(doublePKCSAttributes
), "Unexpected size %d\n", size
);
6307 ok(!memcmp(buf
, doublePKCSAttributes
, size
), "Unexpected value\n");
6312 static void test_decodePKCSAttributes(DWORD dwEncoding
)
6317 CRYPT_ATTRIBUTES
*attributes
;
6319 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
,
6320 emptyPKCSAttributes
, sizeof(emptyPKCSAttributes
),
6321 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6322 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6325 attributes
= (CRYPT_ATTRIBUTES
*)buf
;
6326 ok(attributes
->cAttr
== 0, "Expected no attributes, got %d\n",
6330 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
,
6331 singlePKCSAttributes
, sizeof(singlePKCSAttributes
),
6332 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6333 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6336 attributes
= (CRYPT_ATTRIBUTES
*)buf
;
6337 ok(attributes
->cAttr
== 1, "Expected 1 attribute, got %d\n",
6339 ok(!strcmp(attributes
->rgAttr
[0].pszObjId
, "1.2.3"),
6340 "Expected 1.2.3, got %s\n", attributes
->rgAttr
[0].pszObjId
);
6341 ok(attributes
->rgAttr
[0].cValue
== 0,
6342 "Expected no attributes, got %d\n", attributes
->rgAttr
[0].cValue
);
6345 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
,
6346 doublePKCSAttributes
, sizeof(doublePKCSAttributes
),
6347 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6348 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6351 attributes
= (CRYPT_ATTRIBUTES
*)buf
;
6352 ok(attributes
->cAttr
== 2, "Expected 2 attributes, got %d\n",
6354 ok(!strcmp(attributes
->rgAttr
[0].pszObjId
, "1.2.3"),
6355 "Expected 1.2.3, got %s\n", attributes
->rgAttr
[0].pszObjId
);
6356 ok(attributes
->rgAttr
[0].cValue
== 0,
6357 "Expected no attributes, got %d\n", attributes
->rgAttr
[0].cValue
);
6358 ok(!strcmp(attributes
->rgAttr
[1].pszObjId
, "1.5.6"),
6359 "Expected 1.5.6, got %s\n", attributes
->rgAttr
[1].pszObjId
);
6360 ok(attributes
->rgAttr
[1].cValue
== 1,
6361 "Expected 1 attribute, got %d\n", attributes
->rgAttr
[1].cValue
);
6362 ok(attributes
->rgAttr
[1].rgValue
[0].cbData
== ints
[0].encoded
[1] + 2,
6363 "Unexpected size %d\n", attributes
->rgAttr
[1].rgValue
[0].cbData
);
6364 ok(!memcmp(attributes
->rgAttr
[1].rgValue
[0].pbData
, ints
[0].encoded
,
6365 attributes
->rgAttr
[1].rgValue
[0].cbData
), "Unexpected value\n");
6368 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
,
6369 doublePKCSAttributes
, sizeof(doublePKCSAttributes
), 0, NULL
, NULL
, &size
);
6370 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6371 buf
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
6374 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_ATTRIBUTES
,
6375 doublePKCSAttributes
, sizeof(doublePKCSAttributes
), 0, NULL
, buf
, &size
);
6376 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6377 HeapFree(GetProcessHeap(), 0, buf
);
6381 static const BYTE singleCapability
[] = {
6382 0x30,0x06,0x30,0x04,0x06,0x02,0x2d,0x06 };
6383 static const BYTE twoCapabilities
[] = {
6384 0x30,0x0c,0x30,0x04,0x06,0x02,0x2d,0x06,0x30,0x04,0x06,0x02,0x2a,0x03 };
6385 static const BYTE singleCapabilitywithNULL
[] = {
6386 0x30,0x08,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
6388 static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding
)
6390 static char oid1
[] = "1.5.6", oid2
[] = "1.2.3";
6394 CRYPT_SMIME_CAPABILITY capability
[2];
6395 CRYPT_SMIME_CAPABILITIES capabilities
;
6397 /* An empty capabilities is allowed */
6398 capabilities
.cCapability
= 0;
6399 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6400 &capabilities
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6401 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6404 ok(size
== sizeof(emptySequence
), "unexpected size %d\n", size
);
6405 ok(!memcmp(buf
, emptySequence
, size
), "unexpected value\n");
6408 /* A non-empty capabilities with an empty capability (lacking an OID) is
6411 capability
[0].pszObjId
= NULL
;
6412 capability
[0].Parameters
.cbData
= 0;
6413 capabilities
.cCapability
= 1;
6414 capabilities
.rgCapability
= capability
;
6415 SetLastError(0xdeadbeef);
6416 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6417 &capabilities
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6418 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
6419 GetLastError() == OSS_LIMITED
/* Win9x */),
6420 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6421 capability
[0].pszObjId
= oid1
;
6422 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6423 &capabilities
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6424 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6427 ok(size
== sizeof(singleCapability
), "unexpected size %d\n", size
);
6428 ok(!memcmp(buf
, singleCapability
, size
), "unexpected value\n");
6431 capability
[1].pszObjId
= oid2
;
6432 capability
[1].Parameters
.cbData
= 0;
6433 capabilities
.cCapability
= 2;
6434 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6435 &capabilities
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6436 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6439 ok(size
== sizeof(twoCapabilities
), "unexpected size %d\n", size
);
6440 ok(!memcmp(buf
, twoCapabilities
, size
), "unexpected value\n");
6445 static void compareSMimeCapabilities(LPCSTR header
,
6446 const CRYPT_SMIME_CAPABILITIES
*expected
, const CRYPT_SMIME_CAPABILITIES
*got
)
6450 ok(got
->cCapability
== expected
->cCapability
,
6451 "%s: expected %d capabilities, got %d\n", header
, expected
->cCapability
,
6453 for (i
= 0; i
< expected
->cCapability
; i
++)
6455 ok(!strcmp(expected
->rgCapability
[i
].pszObjId
,
6456 got
->rgCapability
[i
].pszObjId
), "%s[%d]: expected %s, got %s\n",
6457 header
, i
, expected
->rgCapability
[i
].pszObjId
,
6458 got
->rgCapability
[i
].pszObjId
);
6459 ok(expected
->rgCapability
[i
].Parameters
.cbData
==
6460 got
->rgCapability
[i
].Parameters
.cbData
,
6461 "%s[%d]: expected %d bytes, got %d\n", header
, i
,
6462 expected
->rgCapability
[i
].Parameters
.cbData
,
6463 got
->rgCapability
[i
].Parameters
.cbData
);
6464 if (expected
->rgCapability
[i
].Parameters
.cbData
)
6465 ok(!memcmp(expected
->rgCapability
[i
].Parameters
.pbData
,
6466 got
->rgCapability
[i
].Parameters
.pbData
,
6467 expected
->rgCapability
[i
].Parameters
.cbData
),
6468 "%s[%d]: unexpected value\n", header
, i
);
6472 static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding
)
6474 static char oid1
[] = "1.5.6", oid2
[] = "1.2.3";
6477 CRYPT_SMIME_CAPABILITY capability
[2];
6478 CRYPT_SMIME_CAPABILITIES capabilities
, *ptr
;
6480 SetLastError(0xdeadbeef);
6481 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6482 emptySequence
, sizeof(emptySequence
),
6483 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &ptr
, &size
);
6484 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6487 capabilities
.cCapability
= 0;
6488 compareSMimeCapabilities("empty capabilities", &capabilities
, ptr
);
6491 SetLastError(0xdeadbeef);
6492 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6493 singleCapability
, sizeof(singleCapability
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
6495 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6498 capability
[0].pszObjId
= oid1
;
6499 capability
[0].Parameters
.cbData
= 0;
6500 capabilities
.cCapability
= 1;
6501 capabilities
.rgCapability
= capability
;
6502 compareSMimeCapabilities("single capability", &capabilities
, ptr
);
6505 SetLastError(0xdeadbeef);
6506 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6507 singleCapabilitywithNULL
, sizeof(singleCapabilitywithNULL
),
6508 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &ptr
, &size
);
6509 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6512 BYTE NULLparam
[] = {0x05, 0x00};
6513 capability
[0].pszObjId
= oid1
;
6514 capability
[0].Parameters
.cbData
= 2;
6515 capability
[0].Parameters
.pbData
= NULLparam
;
6516 capabilities
.cCapability
= 1;
6517 capabilities
.rgCapability
= capability
;
6518 compareSMimeCapabilities("single capability with NULL", &capabilities
,
6522 SetLastError(0xdeadbeef);
6523 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6524 twoCapabilities
, sizeof(twoCapabilities
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
6526 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6529 capability
[0].Parameters
.cbData
= 0;
6530 capability
[1].pszObjId
= oid2
;
6531 capability
[1].Parameters
.cbData
= 0;
6532 capabilities
.cCapability
= 2;
6533 compareSMimeCapabilities("two capabilities", &capabilities
, ptr
);
6536 SetLastError(0xdeadbeef);
6537 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6538 twoCapabilities
, sizeof(twoCapabilities
), 0, NULL
, NULL
, &size
);
6539 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6540 ptr
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
6543 SetLastError(0xdeadbeef);
6544 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_SMIME_CAPABILITIES
,
6545 twoCapabilities
, sizeof(twoCapabilities
), 0, NULL
, ptr
, &size
);
6546 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6547 HeapFree(GetProcessHeap(), 0, ptr
);
6551 static BYTE encodedCommonNameNoNull
[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
6552 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
6554 static const BYTE minimalPKCSSigner
[] = {
6555 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6556 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6557 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6558 static const BYTE PKCSSignerWithSerial
[] = {
6559 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6560 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6561 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
6563 static const BYTE PKCSSignerWithHashAlgo
[] = {
6564 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6565 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6566 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
6568 static const BYTE PKCSSignerWithHashAndEncryptionAlgo
[] = {
6569 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6570 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6571 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6572 0x06,0x05,0x00,0x04,0x00 };
6573 static const BYTE PKCSSignerWithHash
[] = {
6574 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6575 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6576 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6577 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
6578 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6579 static const BYTE PKCSSignerWithAuthAttr
[] = {
6580 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6581 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6582 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
6583 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
6584 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
6585 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
6586 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6588 static void test_encodePKCSSignerInfo(DWORD dwEncoding
)
6590 static char oid1
[] = "1.2.3", oid2
[] = "1.5.6";
6594 CMSG_SIGNER_INFO info
= { 0 };
6595 char oid_common_name
[] = szOID_COMMON_NAME
;
6596 CRYPT_ATTR_BLOB commonName
= { sizeof(encodedCommonName
),
6597 (LPBYTE
)encodedCommonName
};
6598 CRYPT_ATTRIBUTE attr
= { oid_common_name
, 1, &commonName
};
6600 SetLastError(0xdeadbeef);
6601 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6602 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6603 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
6605 skip("no PKCS7_SIGNER_INFO encode support\n");
6608 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
6609 GetLastError() == OSS_LIMITED
/* Win9x */),
6610 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6611 /* To be encoded, a signer must have an issuer at least, and the encoding
6612 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
6613 * see decoding tests.)
6615 info
.Issuer
.cbData
= sizeof(encodedCommonNameNoNull
);
6616 info
.Issuer
.pbData
= encodedCommonNameNoNull
;
6617 SetLastError(0xdeadbeef);
6618 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6619 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6620 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6621 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6622 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6625 ok(ret
|| broken(GetLastError() == OSS_LIMITED
/* Win9x */),
6626 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6629 ok(size
== sizeof(minimalPKCSSigner
), "Unexpected size %d\n", size
);
6630 if (size
== sizeof(minimalPKCSSigner
))
6631 ok(!memcmp(buf
, minimalPKCSSigner
, size
), "Unexpected value\n");
6633 ok(0, "Unexpected value\n");
6637 info
.SerialNumber
.cbData
= sizeof(serialNum
);
6638 info
.SerialNumber
.pbData
= (BYTE
*)serialNum
;
6639 SetLastError(0xdeadbeef);
6640 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6641 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6642 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6643 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6644 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6647 ok(ret
|| broken(GetLastError() == OSS_LIMITED
/* Win9x */),
6648 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6651 ok(size
== sizeof(PKCSSignerWithSerial
), "Unexpected size %d\n",
6653 if (size
== sizeof(PKCSSignerWithSerial
))
6654 ok(!memcmp(buf
, PKCSSignerWithSerial
, size
),
6655 "Unexpected value\n");
6657 ok(0, "Unexpected value\n");
6661 info
.HashAlgorithm
.pszObjId
= oid1
;
6662 SetLastError(0xdeadbeef);
6663 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6664 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6665 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6666 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6667 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6670 ok(ret
|| broken(GetLastError() == OSS_LIMITED
/* Win9x */),
6671 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6674 ok(size
== sizeof(PKCSSignerWithHashAlgo
), "Unexpected size %d\n",
6676 if (size
== sizeof(PKCSSignerWithHashAlgo
))
6677 ok(!memcmp(buf
, PKCSSignerWithHashAlgo
, size
),
6678 "Unexpected value\n");
6680 ok(0, "Unexpected value\n");
6684 info
.HashEncryptionAlgorithm
.pszObjId
= oid2
;
6685 SetLastError(0xdeadbeef);
6686 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6687 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6688 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6689 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6690 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6693 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6696 ok(size
== sizeof(PKCSSignerWithHashAndEncryptionAlgo
),
6697 "Unexpected size %d\n", size
);
6698 if (size
== sizeof(PKCSSignerWithHashAndEncryptionAlgo
))
6699 ok(!memcmp(buf
, PKCSSignerWithHashAndEncryptionAlgo
, size
),
6700 "Unexpected value\n");
6702 ok(0, "Unexpected value\n");
6706 info
.EncryptedHash
.cbData
= sizeof(hash
);
6707 info
.EncryptedHash
.pbData
= (BYTE
*)hash
;
6708 SetLastError(0xdeadbeef);
6709 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6710 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6711 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6712 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6713 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6716 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6719 ok(size
== sizeof(PKCSSignerWithHash
), "Unexpected size %d\n",
6721 if (size
== sizeof(PKCSSignerWithHash
))
6722 ok(!memcmp(buf
, PKCSSignerWithHash
, size
),
6723 "Unexpected value\n");
6725 ok(0, "Unexpected value\n");
6729 info
.AuthAttrs
.cAttr
= 1;
6730 info
.AuthAttrs
.rgAttr
= &attr
;
6731 SetLastError(0xdeadbeef);
6732 ret
= pCryptEncodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
, &info
,
6733 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6734 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6735 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6736 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6739 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6742 ok(size
== sizeof(PKCSSignerWithAuthAttr
), "Unexpected size %d\n",
6744 if (size
== sizeof(PKCSSignerWithAuthAttr
))
6745 ok(!memcmp(buf
, PKCSSignerWithAuthAttr
, size
),
6746 "Unexpected value\n");
6748 ok(0, "Unexpected value\n");
6754 static void test_decodePKCSSignerInfo(DWORD dwEncoding
)
6759 CMSG_SIGNER_INFO
*info
;
6761 /* A PKCS signer can't be decoded without a serial number. */
6762 SetLastError(0xdeadbeef);
6763 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
6764 minimalPKCSSigner
, sizeof(minimalPKCSSigner
),
6765 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6766 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_CORRUPT
||
6767 GetLastError() == OSS_DATA_ERROR
/* Win9x */),
6768 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %x\n",
6770 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
6771 PKCSSignerWithSerial
, sizeof(PKCSSignerWithSerial
),
6772 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6773 ok(ret
|| broken(GetLastError() == OSS_DATA_ERROR
),
6774 "CryptDecodeObjectEx failed: %x\n", GetLastError());
6777 info
= (CMSG_SIGNER_INFO
*)buf
;
6778 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6780 ok(info
->Issuer
.cbData
== sizeof(encodedCommonNameNoNull
),
6781 "Unexpected size %d\n", info
->Issuer
.cbData
);
6782 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonNameNoNull
,
6783 info
->Issuer
.cbData
), "Unexpected value\n");
6784 ok(info
->SerialNumber
.cbData
== sizeof(serialNum
),
6785 "Unexpected size %d\n", info
->SerialNumber
.cbData
);
6786 ok(!memcmp(info
->SerialNumber
.pbData
, serialNum
, sizeof(serialNum
)),
6787 "Unexpected value\n");
6790 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
6791 PKCSSignerWithHashAlgo
, sizeof(PKCSSignerWithHashAlgo
),
6792 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6795 info
= (CMSG_SIGNER_INFO
*)buf
;
6796 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6798 ok(info
->Issuer
.cbData
== sizeof(encodedCommonNameNoNull
),
6799 "Unexpected size %d\n", info
->Issuer
.cbData
);
6800 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonNameNoNull
,
6801 info
->Issuer
.cbData
), "Unexpected value\n");
6802 ok(info
->SerialNumber
.cbData
== sizeof(serialNum
),
6803 "Unexpected size %d\n", info
->SerialNumber
.cbData
);
6804 ok(!memcmp(info
->SerialNumber
.pbData
, serialNum
, sizeof(serialNum
)),
6805 "Unexpected value\n");
6806 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, "1.2.3"),
6807 "Expected 1.2.3, got %s\n", info
->HashAlgorithm
.pszObjId
);
6810 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
6811 PKCSSignerWithHashAndEncryptionAlgo
,
6812 sizeof(PKCSSignerWithHashAndEncryptionAlgo
), CRYPT_DECODE_ALLOC_FLAG
,
6816 info
= (CMSG_SIGNER_INFO
*)buf
;
6817 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6819 ok(info
->Issuer
.cbData
== sizeof(encodedCommonNameNoNull
),
6820 "Unexpected size %d\n", info
->Issuer
.cbData
);
6821 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonNameNoNull
,
6822 info
->Issuer
.cbData
), "Unexpected value\n");
6823 ok(info
->SerialNumber
.cbData
== sizeof(serialNum
),
6824 "Unexpected size %d\n", info
->SerialNumber
.cbData
);
6825 ok(!memcmp(info
->SerialNumber
.pbData
, serialNum
, sizeof(serialNum
)),
6826 "Unexpected value\n");
6827 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, "1.2.3"),
6828 "Expected 1.2.3, got %s\n", info
->HashAlgorithm
.pszObjId
);
6829 ok(!strcmp(info
->HashEncryptionAlgorithm
.pszObjId
, "1.5.6"),
6830 "Expected 1.5.6, got %s\n", info
->HashEncryptionAlgorithm
.pszObjId
);
6833 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
6834 PKCSSignerWithHash
, sizeof(PKCSSignerWithHash
),
6835 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6838 info
= (CMSG_SIGNER_INFO
*)buf
;
6839 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
6841 ok(info
->Issuer
.cbData
== sizeof(encodedCommonNameNoNull
),
6842 "Unexpected size %d\n", info
->Issuer
.cbData
);
6843 ok(!memcmp(info
->Issuer
.pbData
, encodedCommonNameNoNull
,
6844 info
->Issuer
.cbData
), "Unexpected value\n");
6845 ok(info
->SerialNumber
.cbData
== sizeof(serialNum
),
6846 "Unexpected size %d\n", info
->SerialNumber
.cbData
);
6847 ok(!memcmp(info
->SerialNumber
.pbData
, serialNum
, sizeof(serialNum
)),
6848 "Unexpected value\n");
6849 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, "1.2.3"),
6850 "Expected 1.2.3, got %s\n", info
->HashAlgorithm
.pszObjId
);
6851 ok(!strcmp(info
->HashEncryptionAlgorithm
.pszObjId
, "1.5.6"),
6852 "Expected 1.5.6, got %s\n", info
->HashEncryptionAlgorithm
.pszObjId
);
6853 ok(info
->EncryptedHash
.cbData
== sizeof(hash
), "Unexpected size %d\n",
6854 info
->EncryptedHash
.cbData
);
6855 ok(!memcmp(info
->EncryptedHash
.pbData
, hash
, sizeof(hash
)),
6856 "Unexpected value\n");
6859 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS7_SIGNER_INFO
,
6860 PKCSSignerWithAuthAttr
, sizeof(PKCSSignerWithAuthAttr
),
6861 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6864 info
= (CMSG_SIGNER_INFO
*)buf
;
6865 ok(info
->AuthAttrs
.cAttr
== 1, "Expected 1 attribute, got %d\n",
6866 info
->AuthAttrs
.cAttr
);
6867 ok(!strcmp(info
->AuthAttrs
.rgAttr
[0].pszObjId
, szOID_COMMON_NAME
),
6868 "Expected %s, got %s\n", szOID_COMMON_NAME
,
6869 info
->AuthAttrs
.rgAttr
[0].pszObjId
);
6870 ok(info
->AuthAttrs
.rgAttr
[0].cValue
== 1, "Expected 1 value, got %d\n",
6871 info
->AuthAttrs
.rgAttr
[0].cValue
);
6872 ok(info
->AuthAttrs
.rgAttr
[0].rgValue
[0].cbData
==
6873 sizeof(encodedCommonName
), "Unexpected size %d\n",
6874 info
->AuthAttrs
.rgAttr
[0].rgValue
[0].cbData
);
6875 ok(!memcmp(info
->AuthAttrs
.rgAttr
[0].rgValue
[0].pbData
,
6876 encodedCommonName
, sizeof(encodedCommonName
)), "Unexpected value\n");
6881 static const BYTE CMSSignerWithKeyId
[] = {
6882 0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,
6883 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6885 static void test_encodeCMSSignerInfo(DWORD dwEncoding
)
6890 CMSG_CMS_SIGNER_INFO info
= { 0 };
6891 static char oid1
[] = "1.2.3", oid2
[] = "1.5.6";
6893 SetLastError(0xdeadbeef);
6894 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6895 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6896 ok(!ret
, "Expected failure, got %d\n", ret
);
6897 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
6899 skip("no CMS_SIGNER_INFO encode support\n");
6902 ok(GetLastError() == E_INVALIDARG
,
6903 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6904 info
.SignerId
.dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
6905 SetLastError(0xdeadbeef);
6906 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6907 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6908 ok(!ret
, "Expected failure, got %d\n", ret
);
6909 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
6911 skip("no CMS_SIGNER_INFO encode support\n");
6914 ok(GetLastError() == E_INVALIDARG
,
6915 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6916 /* To be encoded, a signer must have a valid cert ID, where a valid ID may
6917 * be a key id or an issuer serial number with at least the issuer set, and
6918 * the encoding must include PKCS_7_ASN_ENCODING.
6919 * (That isn't enough to be decoded, see decoding tests.)
6921 U(info
.SignerId
).IssuerSerialNumber
.Issuer
.cbData
=
6922 sizeof(encodedCommonNameNoNull
);
6923 U(info
.SignerId
).IssuerSerialNumber
.Issuer
.pbData
= encodedCommonNameNoNull
;
6924 SetLastError(0xdeadbeef);
6925 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6926 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6927 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6928 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6929 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6932 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6935 ok(size
== sizeof(minimalPKCSSigner
), "Unexpected size %d\n", size
);
6936 ok(!memcmp(buf
, minimalPKCSSigner
, size
), "Unexpected value\n");
6940 U(info
.SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
= sizeof(serialNum
);
6941 U(info
.SignerId
).IssuerSerialNumber
.SerialNumber
.pbData
= (BYTE
*)serialNum
;
6942 SetLastError(0xdeadbeef);
6943 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6944 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6945 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6946 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6947 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6950 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6953 ok(size
== sizeof(PKCSSignerWithSerial
), "Unexpected size %d\n",
6955 ok(!memcmp(buf
, PKCSSignerWithSerial
, size
), "Unexpected value\n");
6959 info
.SignerId
.dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
6960 U(info
.SignerId
).KeyId
.cbData
= sizeof(serialNum
);
6961 U(info
.SignerId
).KeyId
.pbData
= (BYTE
*)serialNum
;
6962 SetLastError(0xdeadbeef);
6963 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6964 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6965 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
6966 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6967 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6970 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6973 ok(size
== sizeof(CMSSignerWithKeyId
), "Unexpected size %d\n",
6975 ok(!memcmp(buf
, CMSSignerWithKeyId
, size
), "Unexpected value\n");
6979 /* While a CERT_ID can have a hash type, that's not allowed in CMS, where
6980 * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed
6981 * (see RFC 3852, section 5.3.)
6983 info
.SignerId
.dwIdChoice
= CERT_ID_SHA1_HASH
;
6984 U(info
.SignerId
).HashId
.cbData
= sizeof(hash
);
6985 U(info
.SignerId
).HashId
.pbData
= (BYTE
*)hash
;
6986 SetLastError(0xdeadbeef);
6987 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6988 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
6989 ok(!ret
&& GetLastError() == E_INVALIDARG
,
6990 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6991 /* Now with a hash algo */
6992 info
.SignerId
.dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
6993 U(info
.SignerId
).IssuerSerialNumber
.Issuer
.cbData
=
6994 sizeof(encodedCommonNameNoNull
);
6995 U(info
.SignerId
).IssuerSerialNumber
.Issuer
.pbData
= encodedCommonNameNoNull
;
6996 info
.HashAlgorithm
.pszObjId
= oid1
;
6997 SetLastError(0xdeadbeef);
6998 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
6999 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7000 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
7001 ok(!ret
&& GetLastError() == E_INVALIDARG
,
7002 "Expected E_INVALIDARG, got %08x\n", GetLastError());
7005 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
7008 ok(size
== sizeof(PKCSSignerWithHashAlgo
), "Unexpected size %d\n",
7010 ok(!memcmp(buf
, PKCSSignerWithHashAlgo
, size
),
7011 "Unexpected value\n");
7015 info
.HashEncryptionAlgorithm
.pszObjId
= oid2
;
7016 SetLastError(0xdeadbeef);
7017 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
7018 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7019 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
7020 ok(!ret
&& GetLastError() == E_INVALIDARG
,
7021 "Expected E_INVALIDARG, got %08x\n", GetLastError());
7024 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
7027 ok(size
== sizeof(PKCSSignerWithHashAndEncryptionAlgo
),
7028 "Unexpected size %d\n", size
);
7029 ok(!memcmp(buf
, PKCSSignerWithHashAndEncryptionAlgo
, size
),
7030 "Unexpected value\n");
7034 info
.EncryptedHash
.cbData
= sizeof(hash
);
7035 info
.EncryptedHash
.pbData
= (BYTE
*)hash
;
7036 SetLastError(0xdeadbeef);
7037 ret
= pCryptEncodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
, &info
,
7038 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7039 if (!(dwEncoding
& PKCS_7_ASN_ENCODING
))
7040 ok(!ret
&& GetLastError() == E_INVALIDARG
,
7041 "Expected E_INVALIDARG, got %08x\n", GetLastError());
7044 ok(ret
, "CryptEncodeObjectEx failed: %x\n", GetLastError());
7047 ok(size
== sizeof(PKCSSignerWithHash
), "Unexpected size %d\n",
7049 ok(!memcmp(buf
, PKCSSignerWithHash
, size
), "Unexpected value\n");
7055 static void test_decodeCMSSignerInfo(DWORD dwEncoding
)
7060 CMSG_CMS_SIGNER_INFO
*info
;
7061 static const char oid1
[] = "1.2.3", oid2
[] = "1.5.6";
7063 /* A CMS signer can't be decoded without a serial number. */
7064 SetLastError(0xdeadbeef);
7065 ret
= pCryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
7066 minimalPKCSSigner
, sizeof(minimalPKCSSigner
),
7067 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7068 ok(!ret
, "expected failure\n");
7069 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7071 skip("no CMS_SIGNER_INFO decode support\n");
7074 ok(GetLastError() == CRYPT_E_ASN1_CORRUPT
,
7075 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
7076 ret
= pCryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
7077 PKCSSignerWithSerial
, sizeof(PKCSSignerWithSerial
),
7078 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7079 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
7082 info
= (CMSG_CMS_SIGNER_INFO
*)buf
;
7083 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
7085 ok(info
->SignerId
.dwIdChoice
== CERT_ID_ISSUER_SERIAL_NUMBER
,
7086 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
7087 info
->SignerId
.dwIdChoice
);
7088 ok(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
==
7089 sizeof(encodedCommonNameNoNull
), "Unexpected size %d\n",
7090 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
);
7091 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.pbData
,
7092 encodedCommonNameNoNull
,
7093 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
),
7094 "Unexpected value\n");
7095 ok(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
==
7096 sizeof(serialNum
), "Unexpected size %d\n",
7097 U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
);
7098 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.pbData
,
7099 serialNum
, sizeof(serialNum
)), "Unexpected value\n");
7102 ret
= pCryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
7103 PKCSSignerWithHashAlgo
, sizeof(PKCSSignerWithHashAlgo
),
7104 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7105 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
7108 info
= (CMSG_CMS_SIGNER_INFO
*)buf
;
7109 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
7111 ok(info
->SignerId
.dwIdChoice
== CERT_ID_ISSUER_SERIAL_NUMBER
,
7112 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
7113 info
->SignerId
.dwIdChoice
);
7114 ok(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
==
7115 sizeof(encodedCommonNameNoNull
), "Unexpected size %d\n",
7116 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
);
7117 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.pbData
,
7118 encodedCommonNameNoNull
,
7119 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
),
7120 "Unexpected value\n");
7121 ok(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
==
7122 sizeof(serialNum
), "Unexpected size %d\n",
7123 U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
);
7124 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.pbData
,
7125 serialNum
, sizeof(serialNum
)), "Unexpected value\n");
7126 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, oid1
),
7127 "Expected %s, got %s\n", oid1
, info
->HashAlgorithm
.pszObjId
);
7130 ret
= pCryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
7131 PKCSSignerWithHashAndEncryptionAlgo
,
7132 sizeof(PKCSSignerWithHashAndEncryptionAlgo
), CRYPT_DECODE_ALLOC_FLAG
,
7134 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
7137 info
= (CMSG_CMS_SIGNER_INFO
*)buf
;
7138 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
7140 ok(info
->SignerId
.dwIdChoice
== CERT_ID_ISSUER_SERIAL_NUMBER
,
7141 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
7142 info
->SignerId
.dwIdChoice
);
7143 ok(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
==
7144 sizeof(encodedCommonNameNoNull
), "Unexpected size %d\n",
7145 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
);
7146 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.pbData
,
7147 encodedCommonNameNoNull
,
7148 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
),
7149 "Unexpected value\n");
7150 ok(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
==
7151 sizeof(serialNum
), "Unexpected size %d\n",
7152 U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
);
7153 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.pbData
,
7154 serialNum
, sizeof(serialNum
)), "Unexpected value\n");
7155 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, oid1
),
7156 "Expected %s, got %s\n", oid1
, info
->HashAlgorithm
.pszObjId
);
7157 ok(!strcmp(info
->HashEncryptionAlgorithm
.pszObjId
, oid2
),
7158 "Expected %s, got %s\n", oid2
, info
->HashEncryptionAlgorithm
.pszObjId
);
7161 ret
= pCryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
7162 PKCSSignerWithHash
, sizeof(PKCSSignerWithHash
),
7163 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7164 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
7167 info
= (CMSG_CMS_SIGNER_INFO
*)buf
;
7168 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
7170 ok(info
->SignerId
.dwIdChoice
== CERT_ID_ISSUER_SERIAL_NUMBER
,
7171 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
7172 info
->SignerId
.dwIdChoice
);
7173 ok(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
==
7174 sizeof(encodedCommonNameNoNull
), "Unexpected size %d\n",
7175 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
);
7176 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.Issuer
.pbData
,
7177 encodedCommonNameNoNull
,
7178 U(info
->SignerId
).IssuerSerialNumber
.Issuer
.cbData
),
7179 "Unexpected value\n");
7180 ok(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
==
7181 sizeof(serialNum
), "Unexpected size %d\n",
7182 U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.cbData
);
7183 ok(!memcmp(U(info
->SignerId
).IssuerSerialNumber
.SerialNumber
.pbData
,
7184 serialNum
, sizeof(serialNum
)), "Unexpected value\n");
7185 ok(!strcmp(info
->HashAlgorithm
.pszObjId
, oid1
),
7186 "Expected %s, got %s\n", oid1
, info
->HashAlgorithm
.pszObjId
);
7187 ok(!strcmp(info
->HashEncryptionAlgorithm
.pszObjId
, oid2
),
7188 "Expected %s, got %s\n", oid2
, info
->HashEncryptionAlgorithm
.pszObjId
);
7189 ok(info
->EncryptedHash
.cbData
== sizeof(hash
), "Unexpected size %d\n",
7190 info
->EncryptedHash
.cbData
);
7191 ok(!memcmp(info
->EncryptedHash
.pbData
, hash
, sizeof(hash
)),
7192 "Unexpected value\n");
7195 ret
= pCryptDecodeObjectEx(dwEncoding
, CMS_SIGNER_INFO
,
7196 CMSSignerWithKeyId
, sizeof(CMSSignerWithKeyId
),
7197 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7198 ok(ret
, "CryptDecodeObjectEx failed: %x\n", GetLastError());
7201 info
= (CMSG_CMS_SIGNER_INFO
*)buf
;
7202 ok(info
->dwVersion
== 0, "Expected version 0, got %d\n",
7204 ok(info
->SignerId
.dwIdChoice
== CERT_ID_KEY_IDENTIFIER
,
7205 "Expected CERT_ID_KEY_IDENTIFIER, got %d\n",
7206 info
->SignerId
.dwIdChoice
);
7207 ok(U(info
->SignerId
).KeyId
.cbData
== sizeof(serialNum
),
7208 "Unexpected size %d\n", U(info
->SignerId
).KeyId
.cbData
);
7209 ok(!memcmp(U(info
->SignerId
).KeyId
.pbData
, serialNum
, sizeof(serialNum
)),
7210 "Unexpected value\n");
7215 static BYTE emptyDNSPermittedConstraints
[] = {
7216 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
7217 static BYTE emptyDNSExcludedConstraints
[] = {
7218 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
7219 static BYTE DNSExcludedConstraints
[] = {
7220 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
7221 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7222 static BYTE permittedAndExcludedConstraints
[] = {
7223 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7224 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
7225 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7226 static BYTE permittedAndExcludedWithMinConstraints
[] = {
7227 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7228 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
7229 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7230 static BYTE permittedAndExcludedWithMinMaxConstraints
[] = {
7231 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7232 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
7233 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7235 static void test_encodeNameConstraints(DWORD dwEncoding
)
7238 CERT_NAME_CONSTRAINTS_INFO constraints
= { 0 };
7239 CERT_GENERAL_SUBTREE permitted
= { { 0 } };
7240 CERT_GENERAL_SUBTREE excluded
= { { 0 } };
7244 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
7245 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7246 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7248 skip("no X509_NAME_CONSTRAINTS encode support\n");
7251 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7254 ok(size
== sizeof(emptySequence
), "Unexpected size\n");
7255 ok(!memcmp(buf
, emptySequence
, size
), "Unexpected value\n");
7258 constraints
.cPermittedSubtree
= 1;
7259 constraints
.rgPermittedSubtree
= &permitted
;
7260 SetLastError(0xdeadbeef);
7261 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
7262 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7263 ok(!ret
&& GetLastError() == E_INVALIDARG
,
7264 "Expected E_INVALIDARG, got %08x\n", GetLastError());
7265 permitted
.Base
.dwAltNameChoice
= CERT_ALT_NAME_DNS_NAME
;
7266 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
7267 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7268 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7271 ok(size
== sizeof(emptyDNSPermittedConstraints
), "Unexpected size\n");
7272 ok(!memcmp(buf
, emptyDNSPermittedConstraints
, size
),
7273 "Unexpected value\n");
7276 constraints
.cPermittedSubtree
= 0;
7277 constraints
.cExcludedSubtree
= 1;
7278 constraints
.rgExcludedSubtree
= &excluded
;
7279 excluded
.Base
.dwAltNameChoice
= CERT_ALT_NAME_DNS_NAME
;
7280 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
7281 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7282 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7285 ok(size
== sizeof(emptyDNSExcludedConstraints
), "Unexpected size\n");
7286 ok(!memcmp(buf
, emptyDNSExcludedConstraints
, size
),
7287 "Unexpected value\n");
7290 U(excluded
.Base
).pwszURL
= (LPWSTR
)url
;
7291 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
7292 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7293 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7296 ok(size
== sizeof(DNSExcludedConstraints
), "Unexpected size\n");
7297 ok(!memcmp(buf
, DNSExcludedConstraints
, size
),
7298 "Unexpected value\n");
7301 permitted
.Base
.dwAltNameChoice
= CERT_ALT_NAME_IP_ADDRESS
;
7302 U(permitted
.Base
).IPAddress
.cbData
= sizeof(encodedIPAddr
);
7303 U(permitted
.Base
).IPAddress
.pbData
= (LPBYTE
)encodedIPAddr
;
7304 constraints
.cPermittedSubtree
= 1;
7305 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
7306 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7307 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7310 ok(size
== sizeof(permittedAndExcludedConstraints
),
7311 "Unexpected size\n");
7312 ok(!memcmp(buf
, permittedAndExcludedConstraints
, size
),
7313 "Unexpected value\n");
7316 permitted
.dwMinimum
= 5;
7317 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
7318 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7319 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7322 ok(size
== sizeof(permittedAndExcludedWithMinConstraints
),
7323 "Unexpected size\n");
7324 ok(!memcmp(buf
, permittedAndExcludedWithMinConstraints
, size
),
7325 "Unexpected value\n");
7328 permitted
.fMaximum
= TRUE
;
7329 permitted
.dwMaximum
= 3;
7330 SetLastError(0xdeadbeef);
7331 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
, &constraints
,
7332 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7333 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7336 ok(size
== sizeof(permittedAndExcludedWithMinMaxConstraints
),
7337 "Unexpected size\n");
7338 ok(!memcmp(buf
, permittedAndExcludedWithMinMaxConstraints
, size
),
7339 "Unexpected value\n");
7344 struct EncodedNameConstraints
7346 CRYPT_DATA_BLOB encoded
;
7347 CERT_NAME_CONSTRAINTS_INFO constraints
;
7350 static CERT_GENERAL_SUBTREE emptyDNSSubtree
= {
7351 { CERT_ALT_NAME_DNS_NAME
, { 0 } }, 0 };
7352 static CERT_GENERAL_SUBTREE DNSSubtree
= {
7353 { CERT_ALT_NAME_DNS_NAME
, { 0 } }, 0 };
7354 static CERT_GENERAL_SUBTREE IPAddressSubtree
= {
7355 { CERT_ALT_NAME_IP_ADDRESS
, { 0 } }, 0 };
7356 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree
= {
7357 { CERT_ALT_NAME_IP_ADDRESS
, { 0 } }, 5, 0 };
7358 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree
= {
7359 { CERT_ALT_NAME_IP_ADDRESS
, { 0 } }, 5, TRUE
, 3 };
7361 static const struct EncodedNameConstraints encodedNameConstraints
[] = {
7362 { { sizeof(emptySequence
), (LPBYTE
)emptySequence
}, { 0 } },
7363 { { sizeof(emptyDNSPermittedConstraints
), emptyDNSPermittedConstraints
},
7364 { 1, &emptyDNSSubtree
, 0, NULL
} },
7365 { { sizeof(emptyDNSExcludedConstraints
), emptyDNSExcludedConstraints
},
7366 { 0, NULL
, 1, &emptyDNSSubtree
} },
7367 { { sizeof(DNSExcludedConstraints
), DNSExcludedConstraints
},
7368 { 0, NULL
, 1, &DNSSubtree
} },
7369 { { sizeof(permittedAndExcludedConstraints
), permittedAndExcludedConstraints
},
7370 { 1, &IPAddressSubtree
, 1, &DNSSubtree
} },
7371 { { sizeof(permittedAndExcludedWithMinConstraints
),
7372 permittedAndExcludedWithMinConstraints
},
7373 { 1, &IPAddressWithMinSubtree
, 1, &DNSSubtree
} },
7374 { { sizeof(permittedAndExcludedWithMinMaxConstraints
),
7375 permittedAndExcludedWithMinMaxConstraints
},
7376 { 1, &IPAddressWithMinMaxSubtree
, 1, &DNSSubtree
} },
7379 static void test_decodeNameConstraints(DWORD dwEncoding
)
7383 CERT_NAME_CONSTRAINTS_INFO
*constraints
;
7385 U(DNSSubtree
.Base
).pwszURL
= (LPWSTR
)url
;
7386 U(IPAddressSubtree
.Base
).IPAddress
.cbData
= sizeof(encodedIPAddr
);
7387 U(IPAddressSubtree
.Base
).IPAddress
.pbData
= (LPBYTE
)encodedIPAddr
;
7388 U(IPAddressWithMinSubtree
.Base
).IPAddress
.cbData
= sizeof(encodedIPAddr
);
7389 U(IPAddressWithMinSubtree
.Base
).IPAddress
.pbData
= (LPBYTE
)encodedIPAddr
;
7390 U(IPAddressWithMinMaxSubtree
.Base
).IPAddress
.cbData
= sizeof(encodedIPAddr
);
7391 U(IPAddressWithMinMaxSubtree
.Base
).IPAddress
.pbData
= (LPBYTE
)encodedIPAddr
;
7392 for (i
= 0; i
< ARRAY_SIZE(encodedNameConstraints
); i
++)
7396 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_NAME_CONSTRAINTS
,
7397 encodedNameConstraints
[i
].encoded
.pbData
,
7398 encodedNameConstraints
[i
].encoded
.cbData
,
7399 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &constraints
, &size
);
7400 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7402 skip("no X509_NAME_CONSTRAINTS decode support\n");
7405 ok(ret
, "%d: CryptDecodeObjectEx failed: %08x\n", i
, GetLastError());
7410 if (constraints
->cPermittedSubtree
!=
7411 encodedNameConstraints
[i
].constraints
.cPermittedSubtree
)
7412 fprintf(stderr
, "%d: expected %u permitted, got %u\n", i
,
7413 encodedNameConstraints
[i
].constraints
.cPermittedSubtree
,
7414 constraints
->cPermittedSubtree
);
7415 if (constraints
->cPermittedSubtree
==
7416 encodedNameConstraints
[i
].constraints
.cPermittedSubtree
)
7418 for (j
= 0; j
< constraints
->cPermittedSubtree
; j
++)
7420 compareAltNameEntry(&constraints
->rgPermittedSubtree
[j
].Base
,
7421 &encodedNameConstraints
[i
].constraints
.rgPermittedSubtree
[j
].Base
);
7424 if (constraints
->cExcludedSubtree
!=
7425 encodedNameConstraints
[i
].constraints
.cExcludedSubtree
)
7426 fprintf(stderr
, "%d: expected %u excluded, got %u\n", i
,
7427 encodedNameConstraints
[i
].constraints
.cExcludedSubtree
,
7428 constraints
->cExcludedSubtree
);
7429 if (constraints
->cExcludedSubtree
==
7430 encodedNameConstraints
[i
].constraints
.cExcludedSubtree
)
7432 for (j
= 0; j
< constraints
->cExcludedSubtree
; j
++)
7434 compareAltNameEntry(&constraints
->rgExcludedSubtree
[j
].Base
,
7435 &encodedNameConstraints
[i
].constraints
.rgExcludedSubtree
[j
].Base
);
7438 LocalFree(constraints
);
7443 static WCHAR noticeText
[] = { 'T','h','i','s',' ','i','s',' ','a',' ',
7444 'n','o','t','i','c','e',0 };
7445 static const BYTE noticeWithDisplayText
[] = {
7446 0x30,0x22,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,0x00,
7447 0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,0x74,
7448 0x00,0x69,0x00,0x63,0x00,0x65
7450 static char org
[] = "Wine";
7451 static int noticeNumbers
[] = { 2,3 };
7452 static BYTE noticeWithReference
[] = {
7453 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7454 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7455 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7456 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7459 static void test_encodePolicyQualifierUserNotice(DWORD dwEncoding
)
7464 CERT_POLICY_QUALIFIER_USER_NOTICE notice
;
7465 CERT_POLICY_QUALIFIER_NOTICE_REFERENCE reference
;
7467 memset(¬ice
, 0, sizeof(notice
));
7468 ret
= pCryptEncodeObjectEx(dwEncoding
,
7469 X509_PKIX_POLICY_QUALIFIER_USERNOTICE
, ¬ice
, CRYPT_ENCODE_ALLOC_FLAG
,
7471 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7473 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE encode support\n");
7476 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7479 ok(sizeof(emptySequence
) == size
, "unexpected size %d\n", size
);
7480 ok(!memcmp(buf
, emptySequence
, size
), "unexpected value\n");
7483 notice
.pszDisplayText
= noticeText
;
7484 ret
= pCryptEncodeObjectEx(dwEncoding
,
7485 X509_PKIX_POLICY_QUALIFIER_USERNOTICE
, ¬ice
, CRYPT_ENCODE_ALLOC_FLAG
,
7487 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7490 ok(sizeof(noticeWithDisplayText
) == size
, "unexpected size %d\n", size
);
7491 ok(!memcmp(buf
, noticeWithDisplayText
, size
), "unexpected value\n");
7494 reference
.pszOrganization
= org
;
7495 reference
.cNoticeNumbers
= 2;
7496 reference
.rgNoticeNumbers
= noticeNumbers
;
7497 notice
.pNoticeReference
= &reference
;
7498 ret
= pCryptEncodeObjectEx(dwEncoding
,
7499 X509_PKIX_POLICY_QUALIFIER_USERNOTICE
, ¬ice
, CRYPT_ENCODE_ALLOC_FLAG
,
7501 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7504 ok(sizeof(noticeWithReference
) == size
, "unexpected size %d\n", size
);
7505 ok(!memcmp(buf
, noticeWithReference
, size
), "unexpected value\n");
7510 static void test_decodePolicyQualifierUserNotice(DWORD dwEncoding
)
7513 CERT_POLICY_QUALIFIER_USER_NOTICE
*notice
;
7516 ret
= pCryptDecodeObjectEx(dwEncoding
,
7517 X509_PKIX_POLICY_QUALIFIER_USERNOTICE
,
7518 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
7520 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7522 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE decode support\n");
7525 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7528 ok(notice
->pszDisplayText
== NULL
, "unexpected display text\n");
7529 ok(notice
->pNoticeReference
== NULL
, "unexpected notice reference\n");
7532 ret
= pCryptDecodeObjectEx(dwEncoding
,
7533 X509_PKIX_POLICY_QUALIFIER_USERNOTICE
,
7534 noticeWithDisplayText
, sizeof(noticeWithDisplayText
),
7535 CRYPT_DECODE_ALLOC_FLAG
, NULL
, ¬ice
, &size
);
7536 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7539 ok(!lstrcmpW(notice
->pszDisplayText
, noticeText
),
7540 "unexpected display text\n");
7541 ok(notice
->pNoticeReference
== NULL
, "unexpected notice reference\n");
7544 ret
= pCryptDecodeObjectEx(dwEncoding
,
7545 X509_PKIX_POLICY_QUALIFIER_USERNOTICE
,
7546 noticeWithReference
, sizeof(noticeWithReference
),
7547 CRYPT_DECODE_ALLOC_FLAG
, NULL
, ¬ice
, &size
);
7548 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7551 ok(!lstrcmpW(notice
->pszDisplayText
, noticeText
),
7552 "unexpected display text\n");
7553 ok(notice
->pNoticeReference
!= NULL
, "expected a notice reference\n");
7554 if (notice
->pNoticeReference
)
7556 ok(!strcmp(notice
->pNoticeReference
->pszOrganization
, org
),
7557 "unexpected organization %s\n",
7558 notice
->pNoticeReference
->pszOrganization
);
7559 ok(notice
->pNoticeReference
->cNoticeNumbers
== 2,
7560 "expected 2 notice numbers, got %d\n",
7561 notice
->pNoticeReference
->cNoticeNumbers
);
7562 ok(notice
->pNoticeReference
->rgNoticeNumbers
[0] == noticeNumbers
[0],
7563 "unexpected notice number %d\n",
7564 notice
->pNoticeReference
->rgNoticeNumbers
[0]);
7565 ok(notice
->pNoticeReference
->rgNoticeNumbers
[1] == noticeNumbers
[1],
7566 "unexpected notice number %d\n",
7567 notice
->pNoticeReference
->rgNoticeNumbers
[1]);
7573 static char oid_any_policy
[] = "2.5.29.32.0";
7574 static const BYTE policiesWithAnyPolicy
[] = {
7575 0x30,0x08,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00
7577 static char oid1
[] = "1.2.3";
7578 static char oid_user_notice
[] = "1.3.6.1.5.5.7.2.2";
7579 static const BYTE twoPolicies
[] = {
7580 0x30,0x50,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00,0x30,0x46,0x06,0x02,0x2a,
7581 0x03,0x30,0x40,0x30,0x3e,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x02,
7582 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7583 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7584 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7585 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7588 static void test_encodeCertPolicies(DWORD dwEncoding
)
7591 CERT_POLICIES_INFO info
;
7592 CERT_POLICY_INFO policy
[2];
7593 CERT_POLICY_QUALIFIER_INFO qualifier
;
7597 memset(&info
, 0, sizeof(info
));
7598 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_POLICIES
, &info
,
7599 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7600 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7603 ok(sizeof(emptySequence
) == size
, "unexpected size %d\n", size
);
7604 ok(!memcmp(buf
, emptySequence
, size
), "unexpected value\n");
7607 memset(policy
, 0, sizeof(policy
));
7608 info
.cPolicyInfo
= 1;
7609 info
.rgPolicyInfo
= policy
;
7610 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_POLICIES
, &info
,
7611 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7612 ok(!ret
&& (GetLastError() == E_INVALIDARG
||
7613 GetLastError() == OSS_LIMITED
/* Win9x/NT4 */),
7614 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
7615 policy
[0].pszPolicyIdentifier
= oid_any_policy
;
7616 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_POLICIES
, &info
,
7617 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7618 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7621 ok(sizeof(policiesWithAnyPolicy
) == size
, "unexpected size %d\n", size
);
7622 ok(!memcmp(buf
, policiesWithAnyPolicy
, size
), "unexpected value\n");
7625 policy
[1].pszPolicyIdentifier
= oid1
;
7626 memset(&qualifier
, 0, sizeof(qualifier
));
7627 qualifier
.pszPolicyQualifierId
= oid_user_notice
;
7628 qualifier
.Qualifier
.cbData
= sizeof(noticeWithReference
);
7629 qualifier
.Qualifier
.pbData
= noticeWithReference
;
7630 policy
[1].cPolicyQualifier
= 1;
7631 policy
[1].rgPolicyQualifier
= &qualifier
;
7632 info
.cPolicyInfo
= 2;
7633 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_CERT_POLICIES
, &info
,
7634 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7635 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7638 ok(sizeof(twoPolicies
) == size
, "unexpected size %d\n", size
);
7639 ok(!memcmp(buf
, twoPolicies
, size
), "unexpected value\n");
7644 static void test_decodeCertPolicies(DWORD dwEncoding
)
7647 CERT_POLICIES_INFO
*info
;
7650 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_POLICIES
,
7651 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
7653 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7656 ok(info
->cPolicyInfo
== 0, "unexpected policy info %d\n",
7660 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_POLICIES
,
7661 policiesWithAnyPolicy
, sizeof(policiesWithAnyPolicy
),
7662 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
);
7663 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7666 ok(info
->cPolicyInfo
== 1, "unexpected policy info %d\n",
7668 ok(!strcmp(info
->rgPolicyInfo
[0].pszPolicyIdentifier
, oid_any_policy
),
7669 "unexpected policy id %s\n",
7670 info
->rgPolicyInfo
[0].pszPolicyIdentifier
);
7671 ok(info
->rgPolicyInfo
[0].cPolicyQualifier
== 0,
7672 "unexpected policy qualifier count %d\n",
7673 info
->rgPolicyInfo
[0].cPolicyQualifier
);
7676 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_POLICIES
,
7677 twoPolicies
, sizeof(twoPolicies
),
7678 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
);
7679 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7682 ok(info
->cPolicyInfo
== 2, "unexpected policy info %d\n",
7684 ok(!strcmp(info
->rgPolicyInfo
[0].pszPolicyIdentifier
, oid_any_policy
),
7685 "unexpected policy id %s\n",
7686 info
->rgPolicyInfo
[0].pszPolicyIdentifier
);
7687 ok(info
->rgPolicyInfo
[0].cPolicyQualifier
== 0,
7688 "unexpected policy qualifier count %d\n",
7689 info
->rgPolicyInfo
[0].cPolicyQualifier
);
7690 ok(!strcmp(info
->rgPolicyInfo
[1].pszPolicyIdentifier
, oid1
),
7691 "unexpected policy id %s\n",
7692 info
->rgPolicyInfo
[1].pszPolicyIdentifier
);
7693 ok(info
->rgPolicyInfo
[1].cPolicyQualifier
== 1,
7694 "unexpected policy qualifier count %d\n",
7695 info
->rgPolicyInfo
[1].cPolicyQualifier
);
7697 info
->rgPolicyInfo
[1].rgPolicyQualifier
[0].pszPolicyQualifierId
,
7698 oid_user_notice
), "unexpected policy qualifier id %s\n",
7699 info
->rgPolicyInfo
[1].rgPolicyQualifier
[0].pszPolicyQualifierId
);
7700 ok(info
->rgPolicyInfo
[1].rgPolicyQualifier
[0].Qualifier
.cbData
==
7701 sizeof(noticeWithReference
), "unexpected qualifier size %d\n",
7702 info
->rgPolicyInfo
[1].rgPolicyQualifier
[0].Qualifier
.cbData
);
7704 info
->rgPolicyInfo
[1].rgPolicyQualifier
[0].Qualifier
.pbData
,
7705 noticeWithReference
, sizeof(noticeWithReference
)),
7706 "unexpected qualifier value\n");
7709 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_POLICIES
,
7710 twoPolicies
, sizeof(twoPolicies
), 0, NULL
, NULL
, &size
);
7711 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7712 info
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
7715 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_CERT_POLICIES
,
7716 twoPolicies
, sizeof(twoPolicies
), 0, NULL
, info
, &size
);
7717 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7718 HeapFree(GetProcessHeap(), 0, info
);
7722 static const BYTE policyMappingWithOneMapping
[] = {
7723 0x30,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04 };
7724 static const BYTE policyMappingWithTwoMappings
[] = {
7725 0x30,0x14,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04,0x30,0x08,0x06,
7726 0x02,0x2b,0x04,0x06,0x02,0x55,0x06 };
7727 static const LPCSTR mappingOids
[] = { X509_POLICY_MAPPINGS
,
7728 szOID_POLICY_MAPPINGS
, szOID_LEGACY_POLICY_MAPPINGS
};
7730 static void test_encodeCertPolicyMappings(DWORD dwEncoding
)
7732 static char oid2
[] = "2.3.4";
7733 static char oid3
[] = "1.3.4";
7734 static char oid4
[] = "2.5.6";
7736 CERT_POLICY_MAPPINGS_INFO info
= { 0 };
7737 CERT_POLICY_MAPPING mapping
[2];
7741 /* Each of the mapping OIDs is equivalent, so check with all of them */
7742 for (i
= 0; i
< ARRAY_SIZE(mappingOids
); i
++)
7744 memset(&info
, 0, sizeof(info
));
7745 ret
= pCryptEncodeObjectEx(dwEncoding
, mappingOids
[i
], &info
,
7746 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7747 ok(ret
|| broken(GetLastError() == ERROR_FILE_NOT_FOUND
),
7748 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7749 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7751 win_skip("no policy mappings support\n");
7756 ok(size
== sizeof(emptySequence
), "unexpected size %d\n", size
);
7757 ok(!memcmp(buf
, emptySequence
, sizeof(emptySequence
)),
7758 "unexpected value\n");
7761 mapping
[0].pszIssuerDomainPolicy
= NULL
;
7762 mapping
[0].pszSubjectDomainPolicy
= NULL
;
7763 info
.cPolicyMapping
= 1;
7764 info
.rgPolicyMapping
= mapping
;
7765 SetLastError(0xdeadbeef);
7766 ret
= pCryptEncodeObjectEx(dwEncoding
, mappingOids
[i
], &info
,
7767 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7768 ok(!ret
&& GetLastError() == E_INVALIDARG
,
7769 "expected E_INVALIDARG, got %08x\n", GetLastError());
7770 mapping
[0].pszIssuerDomainPolicy
= oid1
;
7771 mapping
[0].pszSubjectDomainPolicy
= oid2
;
7772 ret
= pCryptEncodeObjectEx(dwEncoding
, mappingOids
[i
], &info
,
7773 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7774 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7777 ok(size
== sizeof(policyMappingWithOneMapping
),
7778 "unexpected size %d\n", size
);
7779 ok(!memcmp(buf
, policyMappingWithOneMapping
, size
),
7780 "unexpected value\n");
7783 mapping
[1].pszIssuerDomainPolicy
= oid3
;
7784 mapping
[1].pszSubjectDomainPolicy
= oid4
;
7785 info
.cPolicyMapping
= 2;
7786 ret
= pCryptEncodeObjectEx(dwEncoding
, mappingOids
[i
], &info
,
7787 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7788 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7791 ok(size
== sizeof(policyMappingWithTwoMappings
),
7792 "unexpected size %d\n", size
);
7793 ok(!memcmp(buf
, policyMappingWithTwoMappings
, size
),
7794 "unexpected value\n");
7800 static void test_decodeCertPolicyMappings(DWORD dwEncoding
)
7803 CERT_POLICY_MAPPINGS_INFO
*info
;
7806 /* Each of the mapping OIDs is equivalent, so check with all of them */
7807 for (i
= 0; i
< ARRAY_SIZE(mappingOids
); i
++)
7809 ret
= pCryptDecodeObjectEx(dwEncoding
, mappingOids
[i
],
7810 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
7812 ok(ret
|| broken(GetLastError() == ERROR_FILE_NOT_FOUND
),
7813 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7814 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7816 win_skip("no policy mappings support\n");
7821 ok(info
->cPolicyMapping
== 0,
7822 "expected 0 policy mappings, got %d\n", info
->cPolicyMapping
);
7825 ret
= pCryptDecodeObjectEx(dwEncoding
, mappingOids
[i
],
7826 policyMappingWithOneMapping
, sizeof(policyMappingWithOneMapping
),
7827 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
);
7828 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7831 ok(info
->cPolicyMapping
== 1,
7832 "expected 1 policy mappings, got %d\n", info
->cPolicyMapping
);
7833 ok(!strcmp(info
->rgPolicyMapping
[0].pszIssuerDomainPolicy
, "1.2.3"),
7834 "unexpected issuer policy %s\n",
7835 info
->rgPolicyMapping
[0].pszIssuerDomainPolicy
);
7836 ok(!strcmp(info
->rgPolicyMapping
[0].pszSubjectDomainPolicy
,
7837 "2.3.4"), "unexpected subject policy %s\n",
7838 info
->rgPolicyMapping
[0].pszSubjectDomainPolicy
);
7841 ret
= pCryptDecodeObjectEx(dwEncoding
, mappingOids
[i
],
7842 policyMappingWithTwoMappings
, sizeof(policyMappingWithTwoMappings
),
7843 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
);
7844 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7847 ok(info
->cPolicyMapping
== 2,
7848 "expected 2 policy mappings, got %d\n", info
->cPolicyMapping
);
7849 ok(!strcmp(info
->rgPolicyMapping
[0].pszIssuerDomainPolicy
, "1.2.3"),
7850 "unexpected issuer policy %s\n",
7851 info
->rgPolicyMapping
[0].pszIssuerDomainPolicy
);
7852 ok(!strcmp(info
->rgPolicyMapping
[0].pszSubjectDomainPolicy
,
7853 "2.3.4"), "unexpected subject policy %s\n",
7854 info
->rgPolicyMapping
[0].pszSubjectDomainPolicy
);
7855 ok(!strcmp(info
->rgPolicyMapping
[1].pszIssuerDomainPolicy
, "1.3.4"),
7856 "unexpected issuer policy %s\n",
7857 info
->rgPolicyMapping
[1].pszIssuerDomainPolicy
);
7858 ok(!strcmp(info
->rgPolicyMapping
[1].pszSubjectDomainPolicy
,
7859 "2.5.6"), "unexpected subject policy %s\n",
7860 info
->rgPolicyMapping
[1].pszSubjectDomainPolicy
);
7863 ret
= pCryptDecodeObjectEx(dwEncoding
, mappingOids
[i
],
7864 policyMappingWithTwoMappings
, sizeof(policyMappingWithTwoMappings
), 0,
7866 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7867 info
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
7870 ret
= pCryptDecodeObjectEx(dwEncoding
, mappingOids
[i
],
7871 policyMappingWithTwoMappings
, sizeof(policyMappingWithTwoMappings
), 0,
7873 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7874 HeapFree(GetProcessHeap(), 0, info
);
7879 static const BYTE policyConstraintsWithRequireExplicit
[] = {
7880 0x30,0x03,0x80,0x01,0x00 };
7881 static const BYTE policyConstraintsWithInhibitMapping
[] = {
7882 0x30,0x03,0x81,0x01,0x01 };
7883 static const BYTE policyConstraintsWithBoth
[] = {
7884 0x30,0x06,0x80,0x01,0x01,0x81,0x01,0x01 };
7886 static void test_encodeCertPolicyConstraints(DWORD dwEncoding
)
7888 CERT_POLICY_CONSTRAINTS_INFO info
= { 0 };
7893 /* Even though RFC 5280 explicitly states CAs must not issue empty
7894 * policy constraints (section 4.2.1.11), the API doesn't prevent it.
7896 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_POLICY_CONSTRAINTS
, &info
,
7897 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7898 ok(ret
|| broken(GetLastError() == ERROR_FILE_NOT_FOUND
),
7899 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7900 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7902 win_skip("no policy constraints support\n");
7907 ok(size
== sizeof(emptySequence
), "unexpected size %d\n", size
);
7908 ok(!memcmp(buf
, emptySequence
, sizeof(emptySequence
)),
7909 "unexpected value\n");
7912 /* If fRequireExplicitPolicy is set but dwRequireExplicitPolicySkipCerts
7913 * is not, then a skip of 0 is encoded.
7915 info
.fRequireExplicitPolicy
= TRUE
;
7916 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_POLICY_CONSTRAINTS
, &info
,
7917 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7918 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7921 ok(size
== sizeof(policyConstraintsWithRequireExplicit
),
7922 "unexpected size %d\n", size
);
7923 ok(!memcmp(buf
, policyConstraintsWithRequireExplicit
,
7924 sizeof(policyConstraintsWithRequireExplicit
)), "unexpected value\n");
7927 /* With inhibit policy mapping */
7928 info
.fRequireExplicitPolicy
= FALSE
;
7929 info
.dwRequireExplicitPolicySkipCerts
= 0;
7930 info
.fInhibitPolicyMapping
= TRUE
;
7931 info
.dwInhibitPolicyMappingSkipCerts
= 1;
7932 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_POLICY_CONSTRAINTS
, &info
,
7933 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7934 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7937 ok(size
== sizeof(policyConstraintsWithInhibitMapping
),
7938 "unexpected size %d\n", size
);
7939 ok(!memcmp(buf
, policyConstraintsWithInhibitMapping
,
7940 sizeof(policyConstraintsWithInhibitMapping
)), "unexpected value\n");
7944 info
.fRequireExplicitPolicy
= TRUE
;
7945 info
.dwRequireExplicitPolicySkipCerts
= 1;
7946 ret
= pCryptEncodeObjectEx(dwEncoding
, X509_POLICY_CONSTRAINTS
, &info
,
7947 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
7948 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7951 ok(size
== sizeof(policyConstraintsWithBoth
), "unexpected size %d\n",
7953 ok(!memcmp(buf
, policyConstraintsWithBoth
,
7954 sizeof(policyConstraintsWithBoth
)), "unexpected value\n");
7959 static void test_decodeCertPolicyConstraints(DWORD dwEncoding
)
7961 CERT_POLICY_CONSTRAINTS_INFO
*info
;
7965 /* Again, even though CAs must not issue such constraints, they can be
7968 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_POLICY_CONSTRAINTS
,
7969 emptySequence
, sizeof(emptySequence
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
7971 ok(ret
|| broken(GetLastError() == ERROR_FILE_NOT_FOUND
),
7972 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7973 if (!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
7975 win_skip("no policy mappings support\n");
7980 ok(!info
->fRequireExplicitPolicy
,
7981 "expected require explicit = FALSE\n");
7982 ok(!info
->fInhibitPolicyMapping
,
7983 "expected implicit mapping = FALSE\n");
7986 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_POLICY_CONSTRAINTS
,
7987 policyConstraintsWithRequireExplicit
,
7988 sizeof(policyConstraintsWithRequireExplicit
), CRYPT_DECODE_ALLOC_FLAG
,
7989 NULL
, &info
, &size
);
7990 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7993 ok(info
->fRequireExplicitPolicy
,
7994 "expected require explicit = TRUE\n");
7995 ok(info
->dwRequireExplicitPolicySkipCerts
== 0, "expected 0, got %d\n",
7996 info
->dwRequireExplicitPolicySkipCerts
);
7997 ok(!info
->fInhibitPolicyMapping
,
7998 "expected implicit mapping = FALSE\n");
8001 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_POLICY_CONSTRAINTS
,
8002 policyConstraintsWithInhibitMapping
,
8003 sizeof(policyConstraintsWithInhibitMapping
), CRYPT_DECODE_ALLOC_FLAG
,
8004 NULL
, &info
, &size
);
8005 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
8008 ok(!info
->fRequireExplicitPolicy
,
8009 "expected require explicit = FALSE\n");
8010 ok(info
->fInhibitPolicyMapping
,
8011 "expected implicit mapping = TRUE\n");
8012 ok(info
->dwInhibitPolicyMappingSkipCerts
== 1, "expected 1, got %d\n",
8013 info
->dwInhibitPolicyMappingSkipCerts
);
8016 ret
= pCryptDecodeObjectEx(dwEncoding
, X509_POLICY_CONSTRAINTS
,
8017 policyConstraintsWithBoth
, sizeof(policyConstraintsWithBoth
),
8018 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &info
, &size
);
8019 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
8022 ok(info
->fRequireExplicitPolicy
,
8023 "expected require explicit = TRUE\n");
8024 ok(info
->dwRequireExplicitPolicySkipCerts
== 1, "expected 1, got %d\n",
8025 info
->dwRequireExplicitPolicySkipCerts
);
8026 ok(info
->fInhibitPolicyMapping
,
8027 "expected implicit mapping = TRUE\n");
8028 ok(info
->dwInhibitPolicyMappingSkipCerts
== 1, "expected 1, got %d\n",
8029 info
->dwInhibitPolicyMappingSkipCerts
);
8034 static const BYTE rsaPrivKeyDer
[] = {
8035 0x30,0x82,0x04,0xa5,0x02,0x01,0x00,0x02,0x82,0x01,0x01,0x00,
8036 0xae,0xba,0x3c,0x41,0xeb,0x25,0x41,0xb0,0x1c,0x41,0xd4,0x26,
8037 0xf9,0xf8,0x31,0x64,0x7e,0x97,0x65,0x54,0x9c,0x90,0xdf,0x34,
8038 0x07,0xfb,0xb0,0x69,0x99,0x3b,0x45,0x39,0x06,0xe4,0x3a,0x7a,
8039 0x01,0xe0,0xeb,0x3f,0xe1,0xd5,0x91,0xe0,0x16,0xe0,0xf2,0x35,
8040 0x59,0xdf,0x32,0x2d,0x69,0x3a,0x4a,0xbc,0xd1,0xba,0x1b,0x3b,
8041 0x7a,0x55,0x76,0xba,0x11,0xdd,0x2f,0xc7,0x58,0x66,0xf2,0x6c,
8042 0xd1,0x68,0x27,0x6c,0x85,0x74,0x0b,0xc9,0x7b,0x1a,0xde,0x3c,
8043 0x62,0x73,0xe2,0x9e,0x36,0x3a,0x29,0x3b,0x91,0x85,0x3d,0xd2,
8044 0xe1,0xe5,0x61,0x84,0x1e,0x28,0xfd,0xb7,0x97,0x68,0xc1,0xbb,
8045 0x0f,0x93,0x14,0xc2,0x03,0x60,0x41,0x11,0x7a,0xda,0x76,0x01,
8046 0x65,0x08,0xe6,0x0c,0xf6,0xfc,0x1d,0x64,0x12,0x7b,0x42,0xb0,
8047 0xb8,0xfe,0x61,0xe5,0xe2,0xe5,0x61,0x44,0xcc,0x94,0xe8,0xc0,
8048 0x4f,0x58,0x9a,0xea,0x99,0xaf,0x9c,0xa4,0xf2,0xd7,0x2b,0x31,
8049 0x90,0x3b,0x41,0x2e,0x4a,0x74,0x7c,0x1a,0xfc,0x42,0xa9,0x17,
8050 0xff,0x53,0x20,0x76,0xa7,0xf0,0x2c,0xb9,0xd5,0x1f,0xa9,0x8a,
8051 0x77,0xa8,0x09,0x5c,0x0e,0xd1,0x54,0xc5,0xf2,0x86,0xf1,0x2f,
8052 0x23,0xd6,0x63,0xba,0xe9,0x2b,0x73,0xf9,0xf0,0xdc,0xcb,0xf9,
8053 0xcb,0xe8,0x40,0x62,0x47,0x09,0x85,0xe1,0x9c,0xfd,0xcf,0x75,
8054 0x5a,0x65,0xfd,0x86,0x1c,0x50,0xfa,0x24,0x36,0x0f,0x54,0x5e,
8055 0x81,0xe7,0xf6,0x63,0x2d,0x87,0x0c,0x50,0x03,0x25,0x49,0xe7,
8056 0xc5,0x20,0xaa,0xbc,0x6c,0xf9,0xbe,0x49,0x8f,0x4f,0xb8,0x9a,
8057 0x73,0x9f,0x55,0x43,0x02,0x03,0x01,0x00,0x01,0x02,0x82,0x01,
8058 0x01,0x00,0x99,0x03,0xcd,0x5b,0x69,0x03,0x32,0x98,0x78,0xd6,
8059 0x89,0x65,0x2c,0xc9,0xd6,0xef,0x8c,0x11,0x27,0x93,0x46,0x9d,
8060 0x74,0x6a,0xcb,0x86,0xf6,0x02,0x34,0x47,0xfc,0xa2,0x29,0x4f,
8061 0xdb,0x8a,0x17,0x75,0x12,0x6f,0xda,0x65,0x3f,0x1f,0xc0,0xc9,
8062 0x74,0x33,0x96,0xa5,0xe8,0xfa,0x6d,0xc9,0xb7,0xc3,0xcd,0xe3,
8063 0x2e,0x90,0x12,0xdd,0x1f,0x61,0x69,0xdd,0x8b,0x47,0x07,0x3a,
8064 0xf8,0x98,0xa5,0x76,0x91,0xf7,0xee,0x93,0x26,0xf3,0x66,0x54,
8065 0xac,0x44,0xb3,0x6f,0x8b,0x09,0x44,0xb2,0x00,0x84,0x03,0x37,
8066 0x6d,0x61,0xed,0xa4,0x04,0x97,0x40,0x16,0x63,0xc2,0xd0,0xdc,
8067 0xd3,0xb3,0xee,0xba,0xbe,0x95,0xfd,0x80,0xe0,0xda,0xde,0xfc,
8068 0xcc,0x15,0x02,0x97,0x1d,0x68,0x43,0x2f,0x9c,0xc8,0x20,0x23,
8069 0xeb,0x00,0x4c,0x74,0x3d,0x27,0x20,0x14,0x23,0x95,0xfc,0x8c,
8070 0xb7,0x7e,0x7f,0xb0,0xdb,0xaf,0x8a,0x48,0x1b,0xfe,0x59,0xab,
8071 0x75,0xe2,0xbf,0x69,0xf2,0x73,0xe3,0xb9,0x92,0xa9,0x90,0x03,
8072 0xe5,0xd4,0x2d,0x86,0xff,0x12,0x54,0xb3,0xbb,0xe2,0xce,0x81,
8073 0x58,0x71,0xa4,0xde,0x45,0x05,0xf8,0x2d,0x45,0xf5,0xd8,0x5e,
8074 0x4c,0x5d,0x06,0x69,0x0c,0x86,0x9f,0x66,0x9f,0xb1,0x60,0xfd,
8075 0xf2,0x33,0x85,0x15,0xd5,0x18,0xf7,0xba,0x99,0x65,0x15,0x1d,
8076 0xfa,0xaa,0x76,0xdd,0x25,0xed,0xdf,0x90,0x6e,0xba,0x61,0x96,
8077 0x79,0xde,0xd2,0xda,0x66,0x03,0x74,0x3b,0x13,0x39,0x68,0xbc,
8078 0x94,0x01,0x00,0x2d,0xf8,0xf0,0x8c,0xbd,0x4c,0x9c,0x7e,0x87,
8079 0x9c,0x62,0x9f,0xb6,0x90,0x11,0x02,0x81,0x81,0x00,0xe3,0x5e,
8080 0xfe,0xdd,0xed,0x76,0xb6,0x4e,0xfc,0x5b,0xe0,0x20,0x99,0x7b,
8081 0x48,0x3b,0x1e,0x5f,0x7f,0x9f,0xa4,0x68,0xbe,0xc3,0x7f,0xb8,
8082 0x62,0x98,0xb0,0x95,0x8a,0xfa,0x0d,0xa3,0x79,0x63,0x39,0xf7,
8083 0xdb,0x76,0x3d,0x53,0x4a,0x0a,0x33,0xdf,0xe0,0x47,0x22,0xd5,
8084 0x96,0x80,0xc7,0xcd,0x24,0xef,0xac,0x49,0x46,0x37,0x6c,0x25,
8085 0xcf,0x6c,0x4d,0xe5,0x31,0xf8,0x2f,0xd2,0x59,0x74,0x00,0x38,
8086 0xdb,0xce,0xd1,0x72,0xc3,0xa8,0x30,0x70,0xd8,0x02,0x20,0xe7,
8087 0x56,0xe7,0xca,0xf0,0x3b,0x52,0x5d,0x11,0xbe,0x53,0x4e,0xd0,
8088 0xd9,0x2e,0xa6,0xb8,0xe2,0xd9,0xbf,0xb9,0x77,0xe7,0x3b,0xed,
8089 0x5e,0xd7,0x16,0x4a,0x3a,0xc5,0x86,0xd7,0x74,0x20,0xa7,0x8e,
8090 0xbf,0xb7,0x33,0xdb,0x51,0xe9,0x02,0x81,0x81,0x00,0xc4,0xba,
8091 0x57,0xf0,0x6e,0xcf,0xe8,0xce,0xce,0x9d,0x4a,0xe9,0x0f,0xe1,
8092 0xab,0x91,0x62,0xaa,0x66,0x5d,0x82,0x66,0x1c,0x72,0x18,0x6f,
8093 0x68,0x9c,0x7d,0x5e,0xfc,0xaf,0x4a,0xd6,0x8e,0xc6,0xae,0x40,
8094 0xf2,0x40,0x84,0x93,0xee,0x7c,0x87,0xa9,0xa6,0xcd,0x2b,0xc3,
8095 0xe6,0x29,0x3a,0xe2,0x4a,0xed,0xb0,0x4d,0x9f,0xc0,0xe9,0xd6,
8096 0xa3,0xca,0x97,0xee,0xac,0xab,0xa4,0x32,0x05,0x40,0x4d,0xf2,
8097 0x95,0x99,0xaf,0xa0,0xe1,0xe1,0xe7,0x3a,0x64,0xa4,0x70,0x6b,
8098 0x3d,0x1d,0x7b,0xf1,0x53,0xfa,0xb0,0xe0,0xe2,0x68,0x1a,0x61,
8099 0x2c,0x37,0xa5,0x39,0x7b,0xb2,0xcf,0xe6,0x5f,0x9b,0xc6,0x64,
8100 0xaf,0x48,0x86,0xfb,0xc1,0xf3,0x39,0x97,0x10,0x36,0xf5,0xa9,
8101 0x3d,0x08,0xa5,0x2f,0xe6,0x4b,0x02,0x81,0x81,0x00,0x86,0xe7,
8102 0x02,0x08,0xe2,0xaf,0xa0,0x93,0x54,0x9f,0x9e,0x67,0x39,0x29,
8103 0x30,0x3e,0x03,0x53,0x5e,0x01,0x76,0x26,0xbf,0xa8,0x76,0xcb,
8104 0x0b,0x94,0xd4,0x90,0xa5,0x98,0x9f,0x26,0xf3,0x0a,0xb0,0x86,
8105 0x22,0xac,0x10,0xce,0xae,0x0b,0x47,0xa3,0xf9,0x09,0xbb,0xdd,
8106 0x46,0x22,0xba,0x69,0x39,0x15,0x0a,0xff,0x9e,0xad,0x9b,0x79,
8107 0x03,0x8c,0x9a,0xda,0xf5,0xbe,0xef,0x80,0xba,0x9a,0x5c,0xd7,
8108 0x5f,0x73,0x62,0x49,0xd9,0x54,0x9d,0x09,0x16,0xe0,0x8c,0x6d,
8109 0x35,0xde,0xe9,0x45,0x87,0xac,0xe2,0x93,0x78,0x7d,0x2d,0x32,
8110 0x34,0xe9,0xbc,0xf9,0xcd,0x7e,0xac,0x86,0x7a,0x61,0xb3,0xe8,
8111 0xae,0x70,0xa7,0x44,0xfb,0x81,0xde,0xf3,0x4e,0x6f,0x61,0x7b,
8112 0x0c,0xbc,0xc2,0x03,0xca,0xa1,0x02,0x81,0x80,0x69,0x5b,0x4a,
8113 0xa1,0x4f,0x17,0x35,0x9d,0x1b,0xf6,0x0d,0x1a,0x48,0x11,0x19,
8114 0xab,0x20,0xe6,0x15,0x30,0x5b,0x17,0x88,0x80,0x6a,0x29,0xb0,
8115 0x22,0xae,0xd9,0xe2,0x05,0x96,0xd4,0xd5,0x5d,0xfe,0x10,0x76,
8116 0x2c,0xab,0x53,0xf6,0x52,0xe6,0xec,0xaa,0x92,0x12,0xb0,0x35,
8117 0x61,0x3b,0x51,0xd9,0xc2,0xf5,0xba,0x7c,0xa5,0xfa,0x15,0xa3,
8118 0x5e,0x6a,0x83,0xbe,0x21,0xa6,0x2b,0xcb,0xb8,0x26,0x86,0x96,
8119 0x2b,0xda,0x6d,0x14,0xcb,0xc0,0xe3,0xfa,0xe6,0x3d,0xf6,0x90,
8120 0xa2,0x6b,0xb0,0x50,0xc3,0x5f,0x5a,0xf0,0xa5,0xc4,0x0a,0xea,
8121 0x7d,0x5a,0x95,0x30,0x74,0x10,0xf7,0x55,0x98,0xbd,0x65,0x4a,
8122 0xa2,0x52,0xf8,0x1d,0x64,0xbf,0x20,0xf1,0xe4,0x1d,0x28,0x67,
8123 0xb1,0x6b,0x95,0xfd,0x85,0x02,0x81,0x81,0x00,0xda,0xb4,0x31,
8124 0x34,0xe1,0xec,0x9a,0x1e,0x07,0xd7,0xda,0x20,0x46,0xbf,0x6b,
8125 0xf0,0x45,0xbd,0x50,0xa2,0x0f,0x8a,0x14,0x51,0x52,0x83,0x7c,
8126 0x47,0xc8,0x9c,0x4e,0x68,0x6b,0xae,0x00,0x25,0x63,0xdd,0x13,
8127 0x2a,0x66,0x65,0xb6,0x74,0x91,0x5b,0xb6,0x47,0x3e,0x8e,0x46,
8128 0x62,0xcd,0x9d,0xc1,0xf7,0x14,0x14,0xbc,0x60,0xd6,0x3c,0x7c,
8129 0x3a,0xce,0xff,0x96,0x04,0x84,0xf6,0x44,0x1a,0xf8,0xdb,0x40,
8130 0x1c,0xf2,0xf1,0x4d,0xb2,0x68,0x3e,0xa3,0x0b,0xc6,0xb1,0xd0,
8131 0xa6,0x88,0x18,0x68,0xa1,0x05,0x2a,0xfc,0x2b,0x3a,0xa1,0xe6,
8132 0x31,0x4a,0x46,0x88,0x39,0x1e,0x44,0x11,0x6c,0xc5,0x8b,0xb6,
8133 0x8b,0xce,0x3d,0xd5,0xcb,0xbd,0xf0,0xd4,0xd9,0xfb,0x02,0x35,
8134 0x96,0x39,0x26,0x85,0xf9 };
8135 static const BYTE rsaPrivKeyModulus
[] = {
8136 0x43,0x55,0x9f,0x73,0x9a,0xb8,0x4f,0x8f,0x49,0xbe,0xf9,0x6c,
8137 0xbc,0xaa,0x20,0xc5,0xe7,0x49,0x25,0x03,0x50,0x0c,0x87,0x2d,
8138 0x63,0xf6,0xe7,0x81,0x5e,0x54,0x0f,0x36,0x24,0xfa,0x50,0x1c,
8139 0x86,0xfd,0x65,0x5a,0x75,0xcf,0xfd,0x9c,0xe1,0x85,0x09,0x47,
8140 0x62,0x40,0xe8,0xcb,0xf9,0xcb,0xdc,0xf0,0xf9,0x73,0x2b,0xe9,
8141 0xba,0x63,0xd6,0x23,0x2f,0xf1,0x86,0xf2,0xc5,0x54,0xd1,0x0e,
8142 0x5c,0x09,0xa8,0x77,0x8a,0xa9,0x1f,0xd5,0xb9,0x2c,0xf0,0xa7,
8143 0x76,0x20,0x53,0xff,0x17,0xa9,0x42,0xfc,0x1a,0x7c,0x74,0x4a,
8144 0x2e,0x41,0x3b,0x90,0x31,0x2b,0xd7,0xf2,0xa4,0x9c,0xaf,0x99,
8145 0xea,0x9a,0x58,0x4f,0xc0,0xe8,0x94,0xcc,0x44,0x61,0xe5,0xe2,
8146 0xe5,0x61,0xfe,0xb8,0xb0,0x42,0x7b,0x12,0x64,0x1d,0xfc,0xf6,
8147 0x0c,0xe6,0x08,0x65,0x01,0x76,0xda,0x7a,0x11,0x41,0x60,0x03,
8148 0xc2,0x14,0x93,0x0f,0xbb,0xc1,0x68,0x97,0xb7,0xfd,0x28,0x1e,
8149 0x84,0x61,0xe5,0xe1,0xd2,0x3d,0x85,0x91,0x3b,0x29,0x3a,0x36,
8150 0x9e,0xe2,0x73,0x62,0x3c,0xde,0x1a,0x7b,0xc9,0x0b,0x74,0x85,
8151 0x6c,0x27,0x68,0xd1,0x6c,0xf2,0x66,0x58,0xc7,0x2f,0xdd,0x11,
8152 0xba,0x76,0x55,0x7a,0x3b,0x1b,0xba,0xd1,0xbc,0x4a,0x3a,0x69,
8153 0x2d,0x32,0xdf,0x59,0x35,0xf2,0xe0,0x16,0xe0,0x91,0xd5,0xe1,
8154 0x3f,0xeb,0xe0,0x01,0x7a,0x3a,0xe4,0x06,0x39,0x45,0x3b,0x99,
8155 0x69,0xb0,0xfb,0x07,0x34,0xdf,0x90,0x9c,0x54,0x65,0x97,0x7e,
8156 0x64,0x31,0xf8,0xf9,0x26,0xd4,0x41,0x1c,0xb0,0x41,0x25,0xeb,
8157 0x41,0x3c,0xba,0xae };
8158 static const BYTE rsaPrivKeyPrime1
[] = {
8159 0xe9,0x51,0xdb,0x33,0xb7,0xbf,0x8e,0xa7,0x20,0x74,0xd7,0x86,
8160 0xc5,0x3a,0x4a,0x16,0xd7,0x5e,0xed,0x3b,0xe7,0x77,0xb9,0xbf,
8161 0xd9,0xe2,0xb8,0xa6,0x2e,0xd9,0xd0,0x4e,0x53,0xbe,0x11,0x5d,
8162 0x52,0x3b,0xf0,0xca,0xe7,0x56,0xe7,0x20,0x02,0xd8,0x70,0x30,
8163 0xa8,0xc3,0x72,0xd1,0xce,0xdb,0x38,0x00,0x74,0x59,0xd2,0x2f,
8164 0xf8,0x31,0xe5,0x4d,0x6c,0xcf,0x25,0x6c,0x37,0x46,0x49,0xac,
8165 0xef,0x24,0xcd,0xc7,0x80,0x96,0xd5,0x22,0x47,0xe0,0xdf,0x33,
8166 0x0a,0x4a,0x53,0x3d,0x76,0xdb,0xf7,0x39,0x63,0x79,0xa3,0x0d,
8167 0xfa,0x8a,0x95,0xb0,0x98,0x62,0xb8,0x7f,0xc3,0xbe,0x68,0xa4,
8168 0x9f,0x7f,0x5f,0x1e,0x3b,0x48,0x7b,0x99,0x20,0xe0,0x5b,0xfc,
8169 0x4e,0xb6,0x76,0xed,0xdd,0xfe,0x5e,0xe3 };
8170 static const BYTE rsaPrivKeyPrime2
[] = {
8171 0x4b,0xe6,0x2f,0xa5,0x08,0x3d,0xa9,0xf5,0x36,0x10,0x97,0x39,
8172 0xf3,0xc1,0xfb,0x86,0x48,0xaf,0x64,0xc6,0x9b,0x5f,0xe6,0xcf,
8173 0xb2,0x7b,0x39,0xa5,0x37,0x2c,0x61,0x1a,0x68,0xe2,0xe0,0xb0,
8174 0xfa,0x53,0xf1,0x7b,0x1d,0x3d,0x6b,0x70,0xa4,0x64,0x3a,0xe7,
8175 0xe1,0xe1,0xa0,0xaf,0x99,0x95,0xf2,0x4d,0x40,0x05,0x32,0xa4,
8176 0xab,0xac,0xee,0x97,0xca,0xa3,0xd6,0xe9,0xc0,0x9f,0x4d,0xb0,
8177 0xed,0x4a,0xe2,0x3a,0x29,0xe6,0xc3,0x2b,0xcd,0xa6,0xa9,0x87,
8178 0x7c,0xee,0x93,0x84,0x40,0xf2,0x40,0xae,0xc6,0x8e,0xd6,0x4a,
8179 0xaf,0xfc,0x5e,0x7d,0x9c,0x68,0x6f,0x18,0x72,0x1c,0x66,0x82,
8180 0x5d,0x66,0xaa,0x62,0x91,0xab,0xe1,0x0f,0xe9,0x4a,0x9d,0xce,
8181 0xce,0xe8,0xcf,0x6e,0xf0,0x57,0xba,0xc4 };
8182 static const BYTE rsaPrivKeyExponent1
[] = {
8183 0xa1,0xca,0x03,0xc2,0xbc,0x0c,0x7b,0x61,0x6f,0x4e,0xf3,0xde,
8184 0x81,0xfb,0x44,0xa7,0x70,0xae,0xe8,0xb3,0x61,0x7a,0x86,0xac,
8185 0x7e,0xcd,0xf9,0xbc,0xe9,0x34,0x32,0x2d,0x7d,0x78,0x93,0xe2,
8186 0xac,0x87,0x45,0xe9,0xde,0x35,0x6d,0x8c,0xe0,0x16,0x09,0x9d,
8187 0x54,0xd9,0x49,0x62,0x73,0x5f,0xd7,0x5c,0x9a,0xba,0x80,0xef,
8188 0xbe,0xf5,0xda,0x9a,0x8c,0x03,0x79,0x9b,0xad,0x9e,0xff,0x0a,
8189 0x15,0x39,0x69,0xba,0x22,0x46,0xdd,0xbb,0x09,0xf9,0xa3,0x47,
8190 0x0b,0xae,0xce,0x10,0xac,0x22,0x86,0xb0,0x0a,0xf3,0x26,0x9f,
8191 0x98,0xa5,0x90,0xd4,0x94,0x0b,0xcb,0x76,0xa8,0xbf,0x26,0x76,
8192 0x01,0x5e,0x53,0x03,0x3e,0x30,0x29,0x39,0x67,0x9e,0x9f,0x54,
8193 0x93,0xa0,0xaf,0xe2,0x08,0x02,0xe7,0x86 };
8194 static const BYTE rsaPrivKeyExponent2
[] = {
8195 0x85,0xfd,0x95,0x6b,0xb1,0x67,0x28,0x1d,0xe4,0xf1,0x20,0xbf,
8196 0x64,0x1d,0xf8,0x52,0xa2,0x4a,0x65,0xbd,0x98,0x55,0xf7,0x10,
8197 0x74,0x30,0x95,0x5a,0x7d,0xea,0x0a,0xc4,0xa5,0xf0,0x5a,0x5f,
8198 0xc3,0x50,0xb0,0x6b,0xa2,0x90,0xf6,0x3d,0xe6,0xfa,0xe3,0xc0,
8199 0xcb,0x14,0x6d,0xda,0x2b,0x96,0x86,0x26,0xb8,0xcb,0x2b,0xa6,
8200 0x21,0xbe,0x83,0x6a,0x5e,0xa3,0x15,0xfa,0xa5,0x7c,0xba,0xf5,
8201 0xc2,0xd9,0x51,0x3b,0x61,0x35,0xb0,0x12,0x92,0xaa,0xec,0xe6,
8202 0x52,0xf6,0x53,0xab,0x2c,0x76,0x10,0xfe,0x5d,0xd5,0xd4,0x96,
8203 0x05,0xe2,0xd9,0xae,0x22,0xb0,0x29,0x6a,0x80,0x88,0x17,0x5b,
8204 0x30,0x15,0xe6,0x20,0xab,0x19,0x11,0x48,0x1a,0x0d,0xf6,0x1b,
8205 0x9d,0x35,0x17,0x4f,0xa1,0x4a,0x5b,0x69 };
8206 static const BYTE rsaPrivKeyCoefficient
[] = {
8207 0xf9,0x85,0x26,0x39,0x96,0x35,0x02,0xfb,0xd9,0xd4,0xf0,0xbd,
8208 0xcb,0xd5,0x3d,0xce,0x8b,0xb6,0x8b,0xc5,0x6c,0x11,0x44,0x1e,
8209 0x39,0x88,0x46,0x4a,0x31,0xe6,0xa1,0x3a,0x2b,0xfc,0x2a,0x05,
8210 0xa1,0x68,0x18,0x88,0xa6,0xd0,0xb1,0xc6,0x0b,0xa3,0x3e,0x68,
8211 0xb2,0x4d,0xf1,0xf2,0x1c,0x40,0xdb,0xf8,0x1a,0x44,0xf6,0x84,
8212 0x04,0x96,0xff,0xce,0x3a,0x7c,0x3c,0xd6,0x60,0xbc,0x14,0x14,
8213 0xf7,0xc1,0x9d,0xcd,0x62,0x46,0x8e,0x3e,0x47,0xb6,0x5b,0x91,
8214 0x74,0xb6,0x65,0x66,0x2a,0x13,0xdd,0x63,0x25,0x00,0xae,0x6b,
8215 0x68,0x4e,0x9c,0xc8,0x47,0x7c,0x83,0x52,0x51,0x14,0x8a,0x0f,
8216 0xa2,0x50,0xbd,0x45,0xf0,0x6b,0xbf,0x46,0x20,0xda,0xd7,0x07,
8217 0x1e,0x9a,0xec,0xe1,0x34,0x31,0xb4,0xda };
8218 static const BYTE rsaPrivKeyPrivateExponent
[] = {
8219 0x11,0x90,0xb6,0x9f,0x62,0x9c,0x87,0x7e,0x9c,0x4c,0xbd,0x8c,
8220 0xf0,0xf8,0x2d,0x00,0x01,0x94,0xbc,0x68,0x39,0x13,0x3b,0x74,
8221 0x03,0x66,0xda,0xd2,0xde,0x79,0x96,0x61,0xba,0x6e,0x90,0xdf,
8222 0xed,0x25,0xdd,0x76,0xaa,0xfa,0x1d,0x15,0x65,0x99,0xba,0xf7,
8223 0x18,0xd5,0x15,0x85,0x33,0xf2,0xfd,0x60,0xb1,0x9f,0x66,0x9f,
8224 0x86,0x0c,0x69,0x06,0x5d,0x4c,0x5e,0xd8,0xf5,0x45,0x2d,0xf8,
8225 0x05,0x45,0xde,0xa4,0x71,0x58,0x81,0xce,0xe2,0xbb,0xb3,0x54,
8226 0x12,0xff,0x86,0x2d,0xd4,0xe5,0x03,0x90,0xa9,0x92,0xb9,0xe3,
8227 0x73,0xf2,0x69,0xbf,0xe2,0x75,0xab,0x59,0xfe,0x1b,0x48,0x8a,
8228 0xaf,0xdb,0xb0,0x7f,0x7e,0xb7,0x8c,0xfc,0x95,0x23,0x14,0x20,
8229 0x27,0x3d,0x74,0x4c,0x00,0xeb,0x23,0x20,0xc8,0x9c,0x2f,0x43,
8230 0x68,0x1d,0x97,0x02,0x15,0xcc,0xfc,0xde,0xda,0xe0,0x80,0xfd,
8231 0x95,0xbe,0xba,0xee,0xb3,0xd3,0xdc,0xd0,0xc2,0x63,0x16,0x40,
8232 0x97,0x04,0xa4,0xed,0x61,0x6d,0x37,0x03,0x84,0x00,0xb2,0x44,
8233 0x09,0x8b,0x6f,0xb3,0x44,0xac,0x54,0x66,0xf3,0x26,0x93,0xee,
8234 0xf7,0x91,0x76,0xa5,0x98,0xf8,0x3a,0x07,0x47,0x8b,0xdd,0x69,
8235 0x61,0x1f,0xdd,0x12,0x90,0x2e,0xe3,0xcd,0xc3,0xb7,0xc9,0x6d,
8236 0xfa,0xe8,0xa5,0x96,0x33,0x74,0xc9,0xc0,0x1f,0x3f,0x65,0xda,
8237 0x6f,0x12,0x75,0x17,0x8a,0xdb,0x4f,0x29,0xa2,0xfc,0x47,0x34,
8238 0x02,0xf6,0x86,0xcb,0x6a,0x74,0x9d,0x46,0x93,0x27,0x11,0x8c,
8239 0xef,0xd6,0xc9,0x2c,0x65,0x89,0xd6,0x78,0x98,0x32,0x03,0x69,
8240 0x5b,0xcd,0x03,0x99 };
8242 static void test_decodeRsaPrivateKey(DWORD dwEncoding
)
8248 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_RSA_PRIVATE_KEY
,
8249 rsaPrivKeyDer
, sizeof(rsaPrivKeyDer
)-10,
8250 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
8251 ok(!ret
&& (GetLastError() == CRYPT_E_ASN1_EOD
),
8252 "Expected CRYPT_E_ASN1_EOD, got %08x\n",
8257 ret
= pCryptDecodeObjectEx(dwEncoding
, PKCS_RSA_PRIVATE_KEY
,
8258 rsaPrivKeyDer
, sizeof(rsaPrivKeyDer
),
8259 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &buf
, &bufSize
);
8260 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
8264 BLOBHEADER
*hdr
= (BLOBHEADER
*)buf
;
8265 RSAPUBKEY
*rsaPubKey
= (RSAPUBKEY
*)(buf
+ sizeof(BLOBHEADER
));
8266 static const int bitlen
= 2048;
8267 BYTE
*modulus
= (BYTE
*)(rsaPubKey
+ 1);
8268 BYTE
*prime1
= modulus
+ bitlen
/8;
8269 BYTE
*prime2
= prime1
+ bitlen
/16;
8270 BYTE
*exponent1
= prime2
+ bitlen
/16;
8271 BYTE
*exponent2
= exponent1
+ bitlen
/16;
8272 BYTE
*coefficient
= exponent2
+ bitlen
/16;
8273 BYTE
*privateExponent
= coefficient
+ bitlen
/16;
8275 ok(bufSize
>= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
8277 "Wrong size %d\n", bufSize
);
8279 ok(hdr
->bType
== PRIVATEKEYBLOB
,
8280 "Expected type PRIVATEKEYBLOB (%d), got %d\n", PRIVATEKEYBLOB
,
8282 ok(hdr
->bVersion
== CUR_BLOB_VERSION
,
8283 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
8284 CUR_BLOB_VERSION
, hdr
->bVersion
);
8285 ok(hdr
->reserved
== 0, "Expected reserved 0, got %d\n",
8287 ok(hdr
->aiKeyAlg
== CALG_RSA_KEYX
,
8288 "Expected CALG_RSA_KEYX, got %08x\n", hdr
->aiKeyAlg
);
8290 ok(rsaPubKey
->magic
== 0x32415352,
8291 "Expected magic 0x32415352, got 0x%x\n", rsaPubKey
->magic
);
8292 ok(rsaPubKey
->bitlen
== bitlen
,
8293 "Expected bitlen %d, got %d\n", bitlen
, rsaPubKey
->bitlen
);
8294 ok(rsaPubKey
->pubexp
== 65537,
8295 "Expected pubexp 65537, got %d\n", rsaPubKey
->pubexp
);
8297 ok(!memcmp(modulus
, rsaPrivKeyModulus
, bitlen
/8),
8298 "unexpected modulus\n");
8299 ok(!memcmp(prime1
, rsaPrivKeyPrime1
, bitlen
/16),
8300 "unexpected prime1\n");
8301 ok(!memcmp(prime2
, rsaPrivKeyPrime2
, bitlen
/16),
8302 "unexpected prime2\n");
8303 ok(!memcmp(exponent1
, rsaPrivKeyExponent1
, bitlen
/16),
8304 "unexpected exponent1\n");
8305 ok(!memcmp(exponent2
, rsaPrivKeyExponent2
, bitlen
/16),
8306 "unexpected exponent2\n");
8307 ok(!memcmp(coefficient
, rsaPrivKeyCoefficient
, bitlen
/16),
8308 "unexpected coefficient\n");
8309 ok(!memcmp(privateExponent
, rsaPrivKeyPrivateExponent
, bitlen
/8),
8310 "unexpected privateExponent\n");
8316 /* Free *pInfo with HeapFree */
8317 static void testExportPublicKey(HCRYPTPROV csp
, PCERT_PUBLIC_KEY_INFO
*pInfo
)
8324 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
8326 ret
= CryptExportPublicKeyInfoEx(0, 0, 0, NULL
, 0, NULL
, NULL
, &size
);
8327 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
8328 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
8329 ret
= CryptExportPublicKeyInfoEx(0, AT_SIGNATURE
, 0, NULL
, 0, NULL
, NULL
,
8331 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
8332 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
8333 ret
= CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING
, NULL
, 0, NULL
,
8335 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
8336 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
8337 ret
= CryptExportPublicKeyInfoEx(0, AT_SIGNATURE
, X509_ASN_ENCODING
, NULL
,
8338 0, NULL
, NULL
, &size
);
8339 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
8340 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
8341 /* Test with no key */
8342 ret
= CryptExportPublicKeyInfoEx(csp
, AT_SIGNATURE
, X509_ASN_ENCODING
, NULL
,
8343 0, NULL
, NULL
, &size
);
8344 ok(!ret
&& GetLastError() == NTE_NO_KEY
, "Expected NTE_NO_KEY, got %08x\n",
8346 ret
= CryptGenKey(csp
, AT_SIGNATURE
, 0, &key
);
8347 ok(ret
, "CryptGenKey failed: %08x\n", GetLastError());
8350 ret
= CryptExportPublicKeyInfoEx(csp
, AT_SIGNATURE
, X509_ASN_ENCODING
,
8351 NULL
, 0, NULL
, NULL
, &size
);
8352 ok(ret
, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
8353 *pInfo
= HeapAlloc(GetProcessHeap(), 0, size
);
8356 ret
= CryptExportPublicKeyInfoEx(csp
, AT_SIGNATURE
,
8357 X509_ASN_ENCODING
, NULL
, 0, NULL
, *pInfo
, &size
);
8358 ok(ret
, "CryptExportPublicKeyInfoEx failed: %08x\n",
8362 /* By default (we passed NULL as the OID) the OID is
8365 ok(!strcmp((*pInfo
)->Algorithm
.pszObjId
, szOID_RSA_RSA
),
8366 "Expected %s, got %s\n", szOID_RSA_RSA
,
8367 (*pInfo
)->Algorithm
.pszObjId
);
8371 CryptDestroyKey(key
);
8374 static const BYTE expiredCert
[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
8375 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
8376 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
8377 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
8378 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
8379 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
8380 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
8381 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
8382 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
8383 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
8384 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
8385 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
8386 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
8387 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
8388 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
8389 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
8390 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
8391 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
8392 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
8393 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
8394 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
8395 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
8396 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
8397 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
8398 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
8400 static void testImportPublicKey(HCRYPTPROV csp
, PCERT_PUBLIC_KEY_INFO info
)
8404 BCRYPT_KEY_HANDLE key2
;
8405 PCCERT_CONTEXT context
;
8410 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
8411 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
8412 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
8413 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
8416 ret
= CryptImportPublicKeyInfoEx(0, 0, info
, 0, 0, NULL
, &key
);
8417 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
8418 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
8419 ret
= CryptImportPublicKeyInfoEx(csp
, 0, info
, 0, 0, NULL
, &key
);
8420 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
,
8421 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
8422 ret
= CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING
, info
, 0, 0, NULL
,
8424 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
8425 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
8427 /* Export key with standard algorithm (CALG_RSA_KEYX) */
8428 ret
= CryptImportPublicKeyInfoEx(csp
, X509_ASN_ENCODING
, info
, 0, 0, NULL
,
8430 ok(ret
, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
8432 dwSize
= sizeof(ai
);
8433 ret
= CryptGetKeyParam(key
, KP_ALGID
, (LPVOID
)&ai
, &dwSize
, 0);
8434 ok(ret
, "CryptGetKeyParam failed: %08x\n", GetLastError());
8437 ok(dwSize
== sizeof(ai
), "CryptGetKeyParam returned size %d\n",dwSize
);
8438 ok(ai
== CALG_RSA_KEYX
, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai
);
8441 CryptDestroyKey(key
);
8443 /* Repeat with forced algorithm */
8444 ret
= CryptImportPublicKeyInfoEx(csp
, X509_ASN_ENCODING
, info
, CALG_RSA_SIGN
, 0, NULL
,
8446 ok(ret
, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
8448 dwSize
= sizeof(ai
);
8449 ret
= CryptGetKeyParam(key
, KP_ALGID
, (LPVOID
)&ai
, &dwSize
, 0);
8450 ok(ret
, "CryptGetKeyParam failed: %08x\n", GetLastError());
8453 ok(dwSize
== sizeof(ai
), "CryptGetKeyParam returned size %d\n",dwSize
);
8454 ok(ai
== CALG_RSA_SIGN
, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai
);
8457 CryptDestroyKey(key
);
8459 /* Test importing a public key from a certificate context */
8460 context
= CertCreateCertificateContext(X509_ASN_ENCODING
, expiredCert
,
8461 sizeof(expiredCert
));
8462 ok(context
!= NULL
, "CertCreateCertificateContext failed: %08x\n",
8466 ok(!strcmp(szOID_RSA_RSA
,
8467 context
->pCertInfo
->SubjectPublicKeyInfo
.Algorithm
.pszObjId
),
8468 "Expected %s, got %s\n", szOID_RSA_RSA
,
8469 context
->pCertInfo
->SubjectPublicKeyInfo
.Algorithm
.pszObjId
);
8470 ret
= CryptImportPublicKeyInfoEx(csp
, X509_ASN_ENCODING
,
8471 &context
->pCertInfo
->SubjectPublicKeyInfo
, 0, 0, NULL
, &key
);
8472 ok(ret
, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
8473 CryptDestroyKey(key
);
8475 ret
= CryptImportPublicKeyInfoEx2(X509_ASN_ENCODING
,
8476 &context
->pCertInfo
->SubjectPublicKeyInfo
, 0, NULL
, &key2
);
8477 ok(ret
, "CryptImportPublicKeyInfoEx2 failed: %08x\n", GetLastError());
8478 if (pBCryptDestroyKey
) pBCryptDestroyKey(key2
);
8480 CertFreeCertificateContext(context
);
8484 static const char cspName
[] = "WineCryptTemp";
8486 static void testPortPublicKeyInfo(void)
8490 PCERT_PUBLIC_KEY_INFO info
= NULL
;
8492 /* Just in case a previous run failed, delete this thing */
8493 CryptAcquireContextA(&csp
, cspName
, MS_DEF_PROV_A
, PROV_RSA_FULL
,
8494 CRYPT_DELETEKEYSET
);
8495 ret
= CryptAcquireContextA(&csp
, cspName
, MS_DEF_PROV_A
, PROV_RSA_FULL
,
8497 ok(ret
,"CryptAcquireContextA failed\n");
8499 testExportPublicKey(csp
, &info
);
8500 testImportPublicKey(csp
, info
);
8502 HeapFree(GetProcessHeap(), 0, info
);
8503 CryptReleaseContext(csp
, 0);
8504 ret
= CryptAcquireContextA(&csp
, cspName
, MS_DEF_PROV_A
, PROV_RSA_FULL
,
8505 CRYPT_DELETEKEYSET
);
8506 ok(ret
,"CryptAcquireContextA failed\n");
8511 static const DWORD encodings
[] = { X509_ASN_ENCODING
, PKCS_7_ASN_ENCODING
,
8512 X509_ASN_ENCODING
| PKCS_7_ASN_ENCODING
};
8513 HMODULE hCrypt32
, hBcrypt
;
8516 hCrypt32
= GetModuleHandleA("crypt32.dll");
8517 pCryptDecodeObjectEx
= (void*)GetProcAddress(hCrypt32
, "CryptDecodeObjectEx");
8518 pCryptEncodeObjectEx
= (void*)GetProcAddress(hCrypt32
, "CryptEncodeObjectEx");
8519 if (!pCryptDecodeObjectEx
|| !pCryptEncodeObjectEx
)
8521 win_skip("CryptDecodeObjectEx() is not available\n");
8525 hBcrypt
= GetModuleHandleA("bcrypt.dll");
8526 pBCryptDestroyKey
= (void*)GetProcAddress(hBcrypt
, "BCryptDestroyKey");
8528 for (i
= 0; i
< ARRAY_SIZE(encodings
); i
++)
8530 test_encodeInt(encodings
[i
]);
8531 test_decodeInt(encodings
[i
]);
8532 test_encodeEnumerated(encodings
[i
]);
8533 test_decodeEnumerated(encodings
[i
]);
8534 test_encodeFiletime(encodings
[i
]);
8535 test_decodeFiletime(encodings
[i
]);
8536 test_encodeName(encodings
[i
]);
8537 test_decodeName(encodings
[i
]);
8538 test_encodeUnicodeName(encodings
[i
]);
8539 test_decodeUnicodeName(encodings
[i
]);
8540 test_encodeNameValue(encodings
[i
]);
8541 test_decodeNameValue(encodings
[i
]);
8542 test_encodeUnicodeNameValue(encodings
[i
]);
8543 test_decodeUnicodeNameValue(encodings
[i
]);
8544 test_encodeAltName(encodings
[i
]);
8545 test_decodeAltName(encodings
[i
]);
8546 test_encodeOctets(encodings
[i
]);
8547 test_decodeOctets(encodings
[i
]);
8548 test_encodeBits(encodings
[i
]);
8549 test_decodeBits(encodings
[i
]);
8550 test_encodeBasicConstraints(encodings
[i
]);
8551 test_decodeBasicConstraints(encodings
[i
]);
8552 test_encodeRsaPublicKey(encodings
[i
]);
8553 test_decodeRsaPublicKey(encodings
[i
]);
8554 test_encodeSequenceOfAny(encodings
[i
]);
8555 test_decodeSequenceOfAny(encodings
[i
]);
8556 test_encodeExtensions(encodings
[i
]);
8557 test_decodeExtensions(encodings
[i
]);
8558 test_encodePublicKeyInfo(encodings
[i
]);
8559 test_decodePublicKeyInfo(encodings
[i
]);
8560 test_encodeCertToBeSigned(encodings
[i
]);
8561 test_decodeCertToBeSigned(encodings
[i
]);
8562 test_encodeCert(encodings
[i
]);
8563 test_decodeCert(encodings
[i
]);
8564 test_encodeCRLDistPoints(encodings
[i
]);
8565 test_decodeCRLDistPoints(encodings
[i
]);
8566 test_encodeCRLIssuingDistPoint(encodings
[i
]);
8567 test_decodeCRLIssuingDistPoint(encodings
[i
]);
8568 test_encodeCRLToBeSigned(encodings
[i
]);
8569 test_decodeCRLToBeSigned(encodings
[i
]);
8570 test_encodeEnhancedKeyUsage(encodings
[i
]);
8571 test_decodeEnhancedKeyUsage(encodings
[i
]);
8572 test_encodeAuthorityKeyId(encodings
[i
]);
8573 test_decodeAuthorityKeyId(encodings
[i
]);
8574 test_encodeAuthorityKeyId2(encodings
[i
]);
8575 test_decodeAuthorityKeyId2(encodings
[i
]);
8576 test_encodeAuthorityInfoAccess(encodings
[i
]);
8577 test_decodeAuthorityInfoAccess(encodings
[i
]);
8578 test_encodeCTL(encodings
[i
]);
8579 test_decodeCTL(encodings
[i
]);
8580 test_encodePKCSContentInfo(encodings
[i
]);
8581 test_decodePKCSContentInfo(encodings
[i
]);
8582 test_encodePKCSAttribute(encodings
[i
]);
8583 test_decodePKCSAttribute(encodings
[i
]);
8584 test_encodePKCSAttributes(encodings
[i
]);
8585 test_decodePKCSAttributes(encodings
[i
]);
8586 test_encodePKCSSMimeCapabilities(encodings
[i
]);
8587 test_decodePKCSSMimeCapabilities(encodings
[i
]);
8588 test_encodePKCSSignerInfo(encodings
[i
]);
8589 test_decodePKCSSignerInfo(encodings
[i
]);
8590 test_encodeCMSSignerInfo(encodings
[i
]);
8591 test_decodeCMSSignerInfo(encodings
[i
]);
8592 test_encodeNameConstraints(encodings
[i
]);
8593 test_decodeNameConstraints(encodings
[i
]);
8594 test_encodePolicyQualifierUserNotice(encodings
[i
]);
8595 test_decodePolicyQualifierUserNotice(encodings
[i
]);
8596 test_encodeCertPolicies(encodings
[i
]);
8597 test_decodeCertPolicies(encodings
[i
]);
8598 test_encodeCertPolicyMappings(encodings
[i
]);
8599 test_decodeCertPolicyMappings(encodings
[i
]);
8600 test_encodeCertPolicyConstraints(encodings
[i
]);
8601 test_decodeCertPolicyConstraints(encodings
[i
]);
8602 test_decodeRsaPrivateKey(encodings
[i
]);
8604 testPortPublicKeyInfo();