1 /* 2 * Unit test suite for crypt32.dll's CryptEncodeObjectEx/CryptDecodeObjectEx 3 * 4 * Copyright 2005 Juan Lang 5 * 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. 10 * 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. 15 * 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 19 */ 20 21 #include "precomp.h" 22 23 static BOOL (WINAPI *pCryptDecodeObjectEx)(DWORD,LPCSTR,const BYTE*,DWORD,DWORD,PCRYPT_DECODE_PARA,void*,DWORD*); 24 static BOOL (WINAPI *pCryptEncodeObjectEx)(DWORD,LPCSTR,const void*,DWORD,PCRYPT_ENCODE_PARA,void*,DWORD*); 25 26 struct encodedInt 27 { 28 int val; 29 const BYTE *encoded; 30 }; 31 32 static const BYTE bin1[] = {0x02,0x01,0x01}; 33 static const BYTE bin2[] = {0x02,0x01,0x7f}; 34 static const BYTE bin3[] = {0x02,0x02,0x00,0x80}; 35 static const BYTE bin4[] = {0x02,0x02,0x01,0x00}; 36 static const BYTE bin5[] = {0x02,0x01,0x80}; 37 static const BYTE bin6[] = {0x02,0x02,0xff,0x7f}; 38 static const BYTE bin7[] = {0x02,0x04,0xba,0xdd,0xf0,0x0d}; 39 40 static const struct encodedInt ints[] = { 41 { 1, bin1 }, 42 { 127, bin2 }, 43 { 128, bin3 }, 44 { 256, bin4 }, 45 { -128, bin5 }, 46 { -129, bin6 }, 47 { 0xbaddf00d, bin7 }, 48 }; 49 50 struct encodedBigInt 51 { 52 const BYTE *val; 53 const BYTE *encoded; 54 const BYTE *decoded; 55 }; 56 57 static const BYTE bin8[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0}; 58 static const BYTE bin9[] = {0x02,0x0a,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0}; 59 static const BYTE bin10[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0}; 60 61 static const BYTE bin11[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0xff,0}; 62 static const BYTE bin12[] = {0x02,0x09,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0}; 63 static const BYTE bin13[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0}; 64 65 static const struct encodedBigInt bigInts[] = { 66 { bin8, bin9, bin10 }, 67 { bin11, bin12, bin13 }, 68 }; 69 70 static const BYTE bin14[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0}; 71 static const BYTE bin15[] = {0x02,0x0a,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0}; 72 static const BYTE bin16[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0xff,0}; 73 static const BYTE bin17[] = {0x02,0x0c,0x00,0xff,0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0}; 74 75 /* Decoded is the same as original, so don't bother storing a separate copy */ 76 static const struct encodedBigInt bigUInts[] = { 77 { bin14, bin15, NULL }, 78 { bin16, bin17, NULL }, 79 }; 80 81 static void test_encodeInt(DWORD dwEncoding) 82 { 83 DWORD bufSize = 0; 84 int i; 85 BOOL ret; 86 CRYPT_INTEGER_BLOB blob; 87 BYTE *buf = NULL; 88 89 /* CryptEncodeObjectEx with NULL bufSize crashes.. 90 ret = pCryptEncodeObjectEx(3, X509_INTEGER, &ints[0].val, 0, NULL, NULL, 91 NULL); 92 */ 93 /* check bogus encoding */ 94 ret = pCryptEncodeObjectEx(0, X509_INTEGER, &ints[0].val, 0, NULL, NULL, 95 &bufSize); 96 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 97 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError()); 98 if (0) 99 { 100 /* check with NULL integer buffer. Windows XP incorrectly returns an 101 * NTSTATUS (crashes on win9x). 102 */ 103 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, NULL, 0, NULL, NULL, 104 &bufSize); 105 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 106 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError()); 107 } 108 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++) 109 { 110 /* encode as normal integer */ 111 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, &ints[i].val, 0, 112 NULL, NULL, &bufSize); 113 ok(ret, "Expected success, got %d\n", GetLastError()); 114 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, &ints[i].val, 115 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 116 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError()); 117 if (ret) 118 { 119 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n", 120 buf[0]); 121 ok(buf[1] == ints[i].encoded[1], "Got length %d, expected %d\n", 122 buf[1], ints[i].encoded[1]); 123 ok(!memcmp(buf + 1, ints[i].encoded + 1, ints[i].encoded[1] + 1), 124 "Encoded value of 0x%08x didn't match expected\n", ints[i].val); 125 LocalFree(buf); 126 } 127 /* encode as multibyte integer */ 128 blob.cbData = sizeof(ints[i].val); 129 blob.pbData = (BYTE *)&ints[i].val; 130 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob, 131 0, NULL, NULL, &bufSize); 132 ok(ret, "Expected success, got %d\n", GetLastError()); 133 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob, 134 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 135 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError()); 136 if (ret) 137 { 138 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n", 139 buf[0]); 140 ok(buf[1] == ints[i].encoded[1], "Got length %d, expected %d\n", 141 buf[1], ints[i].encoded[1]); 142 ok(!memcmp(buf + 1, ints[i].encoded + 1, ints[i].encoded[1] + 1), 143 "Encoded value of 0x%08x didn't match expected\n", ints[i].val); 144 LocalFree(buf); 145 } 146 } 147 /* encode a couple bigger ints, just to show it's little-endian and leading 148 * sign bytes are dropped 149 */ 150 for (i = 0; i < sizeof(bigInts) / sizeof(bigInts[0]); i++) 151 { 152 blob.cbData = strlen((const char*)bigInts[i].val); 153 blob.pbData = (BYTE *)bigInts[i].val; 154 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob, 155 0, NULL, NULL, &bufSize); 156 ok(ret, "Expected success, got %d\n", GetLastError()); 157 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob, 158 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 159 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError()); 160 if (ret) 161 { 162 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n", 163 buf[0]); 164 ok(buf[1] == bigInts[i].encoded[1], "Got length %d, expected %d\n", 165 buf[1], bigInts[i].encoded[1]); 166 ok(!memcmp(buf + 1, bigInts[i].encoded + 1, 167 bigInts[i].encoded[1] + 1), 168 "Encoded value didn't match expected\n"); 169 LocalFree(buf); 170 } 171 } 172 /* and, encode some uints */ 173 for (i = 0; i < sizeof(bigUInts) / sizeof(bigUInts[0]); i++) 174 { 175 blob.cbData = strlen((const char*)bigUInts[i].val); 176 blob.pbData = (BYTE*)bigUInts[i].val; 177 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, &blob, 178 0, NULL, NULL, &bufSize); 179 ok(ret, "Expected success, got %d\n", GetLastError()); 180 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, &blob, 181 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 182 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError()); 183 if (ret) 184 { 185 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n", 186 buf[0]); 187 ok(buf[1] == bigUInts[i].encoded[1], "Got length %d, expected %d\n", 188 buf[1], bigUInts[i].encoded[1]); 189 ok(!memcmp(buf + 1, bigUInts[i].encoded + 1, 190 bigUInts[i].encoded[1] + 1), 191 "Encoded value didn't match expected\n"); 192 LocalFree(buf); 193 } 194 } 195 } 196 197 static void test_decodeInt(DWORD dwEncoding) 198 { 199 static const BYTE bigInt[] = { 2, 5, 0xff, 0xfe, 0xff, 0xfe, 0xff }; 200 static const BYTE testStr[] = { 0x16, 4, 't', 'e', 's', 't' }; 201 static const BYTE longForm[] = { 2, 0x81, 0x01, 0x01 }; 202 static const BYTE bigBogus[] = { 0x02, 0x84, 0x01, 0xff, 0xff, 0xf9 }; 203 static const BYTE extraBytes[] = { 2, 1, 1, 0, 0, 0, 0 }; 204 BYTE *buf = NULL; 205 DWORD bufSize = 0; 206 int i; 207 BOOL ret; 208 209 /* CryptDecodeObjectEx with NULL bufSize crashes.. 210 ret = pCryptDecodeObjectEx(3, X509_INTEGER, &ints[0].encoded, 211 ints[0].encoded[1] + 2, 0, NULL, NULL, NULL); 212 */ 213 /* check bogus encoding */ 214 ret = pCryptDecodeObjectEx(3, X509_INTEGER, (BYTE *)&ints[0].encoded, 215 ints[0].encoded[1] + 2, 0, NULL, NULL, &bufSize); 216 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 217 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError()); 218 /* check with NULL integer buffer */ 219 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, NULL, 0, 0, NULL, NULL, 220 &bufSize); 221 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD || 222 GetLastError() == OSS_BAD_ARG /* Win9x */), 223 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError()); 224 /* check with a valid, but too large, integer */ 225 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, bigInt, bigInt[1] + 2, 226 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 227 ok((!ret && GetLastError() == CRYPT_E_ASN1_LARGE) || 228 broken(ret) /* Win9x */, 229 "Expected CRYPT_E_ASN1_LARGE, got %d\n", GetLastError()); 230 /* check with a DER-encoded string */ 231 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, testStr, testStr[1] + 2, 232 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 233 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || 234 GetLastError() == OSS_PDU_MISMATCH /* Win9x */ ), 235 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %08x\n", 236 GetLastError()); 237 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++) 238 { 239 /* When the output buffer is NULL, this always succeeds */ 240 SetLastError(0xdeadbeef); 241 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, 242 ints[i].encoded, ints[i].encoded[1] + 2, 0, NULL, NULL, 243 &bufSize); 244 ok(ret && GetLastError() == NOERROR, 245 "Expected success and NOERROR, got %d\n", GetLastError()); 246 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, 247 ints[i].encoded, ints[i].encoded[1] + 2, 248 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 249 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError()); 250 ok(bufSize == sizeof(int), "Wrong size %d\n", bufSize); 251 ok(buf != NULL, "Expected allocated buffer\n"); 252 if (ret) 253 { 254 ok(!memcmp(buf, &ints[i].val, bufSize), "Expected %d, got %d\n", 255 ints[i].val, *(int *)buf); 256 LocalFree(buf); 257 } 258 } 259 for (i = 0; i < sizeof(bigInts) / sizeof(bigInts[0]); i++) 260 { 261 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, 262 bigInts[i].encoded, bigInts[i].encoded[1] + 2, 0, NULL, NULL, 263 &bufSize); 264 ok(ret && GetLastError() == NOERROR, 265 "Expected success and NOERROR, got %d\n", GetLastError()); 266 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, 267 bigInts[i].encoded, bigInts[i].encoded[1] + 2, 268 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 269 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError()); 270 ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %d\n", bufSize); 271 ok(buf != NULL, "Expected allocated buffer\n"); 272 if (ret) 273 { 274 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf; 275 276 ok(blob->cbData == strlen((const char*)bigInts[i].decoded), 277 "Expected len %d, got %d\n", lstrlenA((const char*)bigInts[i].decoded), 278 blob->cbData); 279 ok(!memcmp(blob->pbData, bigInts[i].decoded, blob->cbData), 280 "Unexpected value\n"); 281 LocalFree(buf); 282 } 283 } 284 for (i = 0; i < sizeof(bigUInts) / sizeof(bigUInts[0]); i++) 285 { 286 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, 287 bigUInts[i].encoded, bigUInts[i].encoded[1] + 2, 0, NULL, NULL, 288 &bufSize); 289 ok(ret && GetLastError() == NOERROR, 290 "Expected success and NOERROR, got %d\n", GetLastError()); 291 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, 292 bigUInts[i].encoded, bigUInts[i].encoded[1] + 2, 293 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 294 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError()); 295 ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %d\n", bufSize); 296 ok(buf != NULL, "Expected allocated buffer\n"); 297 if (ret) 298 { 299 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf; 300 301 ok(blob->cbData == strlen((const char*)bigUInts[i].val), 302 "Expected len %d, got %d\n", lstrlenA((const char*)bigUInts[i].val), 303 blob->cbData); 304 ok(!memcmp(blob->pbData, bigUInts[i].val, blob->cbData), 305 "Unexpected value\n"); 306 LocalFree(buf); 307 } 308 } 309 /* Decode the value 1 with long-form length */ 310 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, longForm, 311 sizeof(longForm), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 312 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 313 if (ret) 314 { 315 ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf); 316 LocalFree(buf); 317 } 318 /* check with extra bytes at the end */ 319 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, extraBytes, 320 sizeof(extraBytes), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 321 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 322 if (ret) 323 { 324 ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf); 325 LocalFree(buf); 326 } 327 /* Try to decode some bogus large items */ 328 /* The buffer size is smaller than the encoded length, so this should fail 329 * with CRYPT_E_ASN1_EOD if it's being decoded. 330 * Under XP it fails with CRYPT_E_ASN1_LARGE, which means there's a limit 331 * on the size decoded, but in ME it fails with CRYPT_E_ASN1_EOD or crashes. 332 * So this test unfortunately isn't useful. 333 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, tooBig, 334 0x7fffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 335 ok(!ret && GetLastError() == CRYPT_E_ASN1_LARGE, 336 "Expected CRYPT_E_ASN1_LARGE, got %08x\n", GetLastError()); 337 */ 338 /* This will try to decode the buffer and overflow it, check that it's 339 * caught. 340 */ 341 if (0) 342 { 343 /* a large buffer isn't guaranteed to crash, it depends on memory allocation order */ 344 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, bigBogus, 345 0x01ffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 346 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 347 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError()); 348 } 349 } 350 351 static const BYTE bin18[] = {0x0a,0x01,0x01}; 352 static const BYTE bin19[] = {0x0a,0x05,0x00,0xff,0xff,0xff,0x80}; 353 354 /* These are always encoded unsigned, and aren't constrained to be any 355 * particular value 356 */ 357 static const struct encodedInt enums[] = { 358 { 1, bin18 }, 359 { -128, bin19 }, 360 }; 361 362 /* X509_CRL_REASON_CODE is also an enumerated type, but it's #defined to 363 * X509_ENUMERATED. 364 */ 365 static const LPCSTR enumeratedTypes[] = { X509_ENUMERATED, 366 szOID_CRL_REASON_CODE }; 367 368 static void test_encodeEnumerated(DWORD dwEncoding) 369 { 370 DWORD i, j; 371 372 for (i = 0; i < sizeof(enumeratedTypes) / sizeof(enumeratedTypes[0]); i++) 373 { 374 for (j = 0; j < sizeof(enums) / sizeof(enums[0]); j++) 375 { 376 BOOL ret; 377 BYTE *buf = NULL; 378 DWORD bufSize = 0; 379 380 ret = pCryptEncodeObjectEx(dwEncoding, enumeratedTypes[i], 381 &enums[j].val, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, 382 &bufSize); 383 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError()); 384 if (ret) 385 { 386 ok(buf[0] == 0xa, 387 "Got unexpected type %d for enumerated (expected 0xa)\n", 388 buf[0]); 389 ok(buf[1] == enums[j].encoded[1], 390 "Got length %d, expected %d\n", buf[1], enums[j].encoded[1]); 391 ok(!memcmp(buf + 1, enums[j].encoded + 1, 392 enums[j].encoded[1] + 1), 393 "Encoded value of 0x%08x didn't match expected\n", 394 enums[j].val); 395 LocalFree(buf); 396 } 397 } 398 } 399 } 400 401 static void test_decodeEnumerated(DWORD dwEncoding) 402 { 403 DWORD i, j; 404 405 for (i = 0; i < sizeof(enumeratedTypes) / sizeof(enumeratedTypes[0]); i++) 406 { 407 for (j = 0; j < sizeof(enums) / sizeof(enums[0]); j++) 408 { 409 BOOL ret; 410 DWORD bufSize = sizeof(int); 411 int val; 412 413 ret = pCryptDecodeObjectEx(dwEncoding, enumeratedTypes[i], 414 enums[j].encoded, enums[j].encoded[1] + 2, 0, NULL, 415 &val, &bufSize); 416 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 417 ok(bufSize == sizeof(int), 418 "Got unexpected size %d for enumerated\n", bufSize); 419 ok(val == enums[j].val, "Unexpected value %d, expected %d\n", 420 val, enums[j].val); 421 } 422 } 423 } 424 425 struct encodedFiletime 426 { 427 SYSTEMTIME sysTime; 428 const BYTE *encodedTime; 429 }; 430 431 static void testTimeEncoding(DWORD dwEncoding, LPCSTR structType, 432 const struct encodedFiletime *time) 433 { 434 FILETIME ft = { 0 }; 435 BYTE *buf = NULL; 436 DWORD bufSize = 0; 437 BOOL ret; 438 439 ret = SystemTimeToFileTime(&time->sysTime, &ft); 440 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError()); 441 ret = pCryptEncodeObjectEx(dwEncoding, structType, &ft, 442 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 443 /* years other than 1950-2050 are not allowed for encodings other than 444 * X509_CHOICE_OF_TIME. 445 */ 446 if (structType == X509_CHOICE_OF_TIME || 447 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050)) 448 { 449 ok(ret, "CryptEncodeObjectEx failed: %d (0x%08x)\n", GetLastError(), 450 GetLastError()); 451 ok(buf != NULL, "Expected an allocated buffer\n"); 452 if (ret) 453 { 454 ok(buf[0] == time->encodedTime[0], 455 "Expected type 0x%02x, got 0x%02x\n", time->encodedTime[0], 456 buf[0]); 457 ok(buf[1] == time->encodedTime[1], "Expected %d bytes, got %d\n", 458 time->encodedTime[1], bufSize); 459 ok(!memcmp(time->encodedTime + 2, buf + 2, time->encodedTime[1]), 460 "Got unexpected value for time encoding\n"); 461 LocalFree(buf); 462 } 463 } 464 else 465 ok((!ret && GetLastError() == CRYPT_E_BAD_ENCODE) || 466 broken(GetLastError() == ERROR_SUCCESS), 467 "Expected CRYPT_E_BAD_ENCODE, got 0x%08x\n", GetLastError()); 468 } 469 470 static const char *printSystemTime(const SYSTEMTIME *st) 471 { 472 static char buf[64]; 473 474 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st->wMonth, st->wDay, 475 st->wYear, st->wHour, st->wMinute, st->wSecond, st->wMilliseconds); 476 return buf; 477 } 478 479 static const char *printFileTime(const FILETIME *ft) 480 { 481 static char buf[64]; 482 SYSTEMTIME st; 483 484 FileTimeToSystemTime(ft, &st); 485 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st.wMonth, st.wDay, 486 st.wYear, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); 487 return buf; 488 } 489 490 static void compareTime(const SYSTEMTIME *expected, const FILETIME *got) 491 { 492 SYSTEMTIME st; 493 494 FileTimeToSystemTime(got, &st); 495 ok((expected->wYear == st.wYear && 496 expected->wMonth == st.wMonth && 497 expected->wDay == st.wDay && 498 expected->wHour == st.wHour && 499 expected->wMinute == st.wMinute && 500 expected->wSecond == st.wSecond && 501 abs(expected->wMilliseconds - st.wMilliseconds) <= 1) || 502 /* Some Windows systems only seem to be accurate in their time decoding to 503 * within about an hour. 504 */ 505 broken(expected->wYear == st.wYear && 506 expected->wMonth == st.wMonth && 507 expected->wDay == st.wDay && 508 abs(expected->wHour - st.wHour) <= 1), 509 "Got unexpected value for time decoding:\nexpected %s, got %s\n", 510 printSystemTime(expected), printFileTime(got)); 511 } 512 513 static void testTimeDecoding(DWORD dwEncoding, LPCSTR structType, 514 const struct encodedFiletime *time) 515 { 516 FILETIME ft = { 0 }; 517 DWORD size = sizeof(ft); 518 BOOL ret; 519 520 ret = pCryptDecodeObjectEx(dwEncoding, structType, time->encodedTime, 521 time->encodedTime[1] + 2, 0, NULL, &ft, &size); 522 /* years other than 1950-2050 are not allowed for encodings other than 523 * X509_CHOICE_OF_TIME. 524 */ 525 if (structType == X509_CHOICE_OF_TIME || 526 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050)) 527 { 528 ok(ret || broken(GetLastError() == OSS_DATA_ERROR), 529 "CryptDecodeObjectEx failed: %d (0x%08x)\n", GetLastError(), 530 GetLastError()); 531 if (ret) 532 compareTime(&time->sysTime, &ft); 533 } 534 else 535 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || 536 GetLastError() == OSS_PDU_MISMATCH /* Win9x */ ), 537 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %08x\n", 538 GetLastError()); 539 } 540 541 static const BYTE bin20[] = { 542 0x17,0x0d,'0','5','0','6','0','6','1','6','1','0','0','0','Z'}; 543 static const BYTE bin21[] = { 544 0x18,0x0f,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','Z'}; 545 static const BYTE bin22[] = { 546 0x18,0x0f,'2','1','4','5','0','6','0','6','1','6','1','0','0','0','Z'}; 547 548 static const struct encodedFiletime times[] = { 549 { { 2005, 6, 1, 6, 16, 10, 0, 0 }, bin20 }, 550 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin21 }, 551 { { 2145, 6, 1, 6, 16, 10, 0, 0 }, bin22 }, 552 }; 553 554 static void test_encodeFiletime(DWORD dwEncoding) 555 { 556 DWORD i; 557 558 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++) 559 { 560 testTimeEncoding(dwEncoding, X509_CHOICE_OF_TIME, ×[i]); 561 testTimeEncoding(dwEncoding, PKCS_UTC_TIME, ×[i]); 562 testTimeEncoding(dwEncoding, szOID_RSA_signingTime, ×[i]); 563 } 564 } 565 566 static const BYTE bin23[] = { 567 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','0','0','0','Z'}; 568 static const BYTE bin24[] = { 569 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','9','9','9','Z'}; 570 static const BYTE bin25[] = { 571 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','+','0','1','0','0'}; 572 static const BYTE bin26[] = { 573 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','0','0'}; 574 static const BYTE bin27[] = { 575 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','1','5'}; 576 static const BYTE bin28[] = { 577 0x18,0x0a,'2','1','4','5','0','6','0','6','1','6'}; 578 static const BYTE bin29[] = { 579 0x17,0x0a,'4','5','0','6','0','6','1','6','1','0'}; 580 static const BYTE bin30[] = { 581 0x17,0x0b,'4','5','0','6','0','6','1','6','1','0','Z'}; 582 static const BYTE bin31[] = { 583 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','+','0','1'}; 584 static const BYTE bin32[] = { 585 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','-','0','1'}; 586 static const BYTE bin33[] = { 587 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','+','0','1','0','0'}; 588 static const BYTE bin34[] = { 589 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','-','0','1','0','0'}; 590 static const BYTE bin35[] = { 591 0x17,0x08, '4','5','0','6','0','6','1','6'}; 592 static const BYTE bin36[] = { 593 0x18,0x0f, 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','Z'}; 594 static const BYTE bin37[] = { 595 0x18,0x04, '2','1','4','5'}; 596 static const BYTE bin38[] = { 597 0x18,0x08, '2','1','4','5','0','6','0','6'}; 598 599 static void test_decodeFiletime(DWORD dwEncoding) 600 { 601 static const struct encodedFiletime otherTimes[] = { 602 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin23 }, 603 { { 1945, 6, 1, 6, 16, 10, 0, 999 }, bin24 }, 604 { { 1945, 6, 1, 6, 17, 10, 0, 0 }, bin25 }, 605 { { 1945, 6, 1, 6, 15, 10, 0, 0 }, bin26 }, 606 { { 1945, 6, 1, 6, 14, 55, 0, 0 }, bin27 }, 607 { { 2145, 6, 1, 6, 16, 0, 0, 0 }, bin28 }, 608 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin29 }, 609 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin30 }, 610 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin31 }, 611 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin32 }, 612 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin33 }, 613 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin34 }, 614 }; 615 /* An oddball case that succeeds in Windows, but doesn't seem correct 616 { { 2145, 6, 1, 2, 11, 31, 0, 0 }, "\x18" "\x13" "21450606161000-9999" }, 617 */ 618 static const unsigned char *bogusTimes[] = { 619 /* oddly, this succeeds on Windows, with year 2765 620 "\x18" "\x0f" "21r50606161000Z", 621 */ 622 bin35, 623 bin36, 624 bin37, 625 bin38, 626 }; 627 DWORD i, size; 628 FILETIME ft1 = { 0 }, ft2 = { 0 }; 629 BOOL ret; 630 631 /* Check bogus length with non-NULL buffer */ 632 ret = SystemTimeToFileTime(×[0].sysTime, &ft1); 633 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError()); 634 size = 1; 635 ret = pCryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME, 636 times[0].encodedTime, times[0].encodedTime[1] + 2, 0, NULL, &ft2, &size); 637 ok(!ret && GetLastError() == ERROR_MORE_DATA, 638 "Expected ERROR_MORE_DATA, got %d\n", GetLastError()); 639 /* Normal tests */ 640 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++) 641 { 642 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, ×[i]); 643 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, ×[i]); 644 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, ×[i]); 645 } 646 for (i = 0; i < sizeof(otherTimes) / sizeof(otherTimes[0]); i++) 647 { 648 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &otherTimes[i]); 649 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &otherTimes[i]); 650 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &otherTimes[i]); 651 } 652 for (i = 0; i < sizeof(bogusTimes) / sizeof(bogusTimes[0]); i++) 653 { 654 size = sizeof(ft1); 655 ret = pCryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME, 656 bogusTimes[i], bogusTimes[i][1] + 2, 0, NULL, &ft1, &size); 657 ok((!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT || 658 GetLastError() == OSS_DATA_ERROR /* Win9x */)) || 659 broken(ret), /* Win9x and NT4 for bin38 */ 660 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n", 661 GetLastError()); 662 } 663 } 664 665 static const char commonName[] = "Juan Lang"; 666 static const char surName[] = "Lang"; 667 668 static const BYTE emptySequence[] = { 0x30, 0 }; 669 static const BYTE emptyRDNs[] = { 0x30, 0x02, 0x31, 0 }; 670 static const BYTE twoRDNs[] = { 671 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04, 672 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03, 673 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0}; 674 static const BYTE encodedTwoRDNs[] = { 675 0x30,0x2e,0x31,0x2c,0x30,0x2a,0x06,0x03,0x55,0x04,0x03,0x30,0x23,0x31,0x21, 676 0x30,0x0c,0x06,0x03,0x55,0x04,0x04,0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30, 677 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61, 678 0x6e,0x67,0x00, 679 }; 680 681 static const BYTE us[] = { 0x55, 0x53 }; 682 static const BYTE minnesota[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x73, 0x6f, 683 0x74, 0x61 }; 684 static const BYTE minneapolis[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x61, 0x70, 685 0x6f, 0x6c, 0x69, 0x73 }; 686 static const BYTE codeweavers[] = { 0x43, 0x6f, 0x64, 0x65, 0x57, 0x65, 0x61, 687 0x76, 0x65, 0x72, 0x73 }; 688 static const BYTE wine[] = { 0x57, 0x69, 0x6e, 0x65, 0x20, 0x44, 0x65, 0x76, 689 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74 }; 690 static const BYTE localhostAttr[] = { 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 691 0x73, 0x74 }; 692 static const BYTE aric[] = { 0x61, 0x72, 0x69, 0x63, 0x40, 0x63, 0x6f, 0x64, 693 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d }; 694 695 #define RDNA(arr) oid_ ## arr, CERT_RDN_PRINTABLE_STRING, { sizeof(arr), (LPBYTE)arr } 696 #define RDNIA5(arr) oid_ ## arr, CERT_RDN_IA5_STRING, { sizeof(arr), (LPBYTE)arr } 697 698 static CHAR oid_us[] = "2.5.4.6", 699 oid_minnesota[] = "2.5.4.8", 700 oid_minneapolis[] = "2.5.4.7", 701 oid_codeweavers[] = "2.5.4.10", 702 oid_wine[] = "2.5.4.11", 703 oid_localhostAttr[] = "2.5.4.3", 704 oid_aric[] = "1.2.840.113549.1.9.1"; 705 static CERT_RDN_ATTR rdnAttrs[] = { { RDNA(us) }, 706 { RDNA(minnesota) }, 707 { RDNA(minneapolis) }, 708 { RDNA(codeweavers) }, 709 { RDNA(wine) }, 710 { RDNA(localhostAttr) }, 711 { RDNIA5(aric) } }; 712 static CERT_RDN_ATTR decodedRdnAttrs[] = { { RDNA(us) }, 713 { RDNA(localhostAttr) }, 714 { RDNA(minnesota) }, 715 { RDNA(minneapolis) }, 716 { RDNA(codeweavers) }, 717 { RDNA(wine) }, 718 { RDNIA5(aric) } }; 719 720 #undef RDNIA5 721 #undef RDNA 722 723 static const BYTE encodedRDNAttrs[] = { 724 0x30,0x81,0x96,0x31,0x81,0x93,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55, 725 0x53,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x68, 726 0x6f,0x73,0x74,0x30,0x10,0x06,0x03,0x55,0x04,0x08,0x13,0x09,0x4d,0x69,0x6e,0x6e, 727 0x65,0x73,0x6f,0x74,0x61,0x30,0x12,0x06,0x03,0x55,0x04,0x07,0x13,0x0b,0x4d,0x69, 728 0x6e,0x6e,0x65,0x61,0x70,0x6f,0x6c,0x69,0x73,0x30,0x12,0x06,0x03,0x55,0x04,0x0a, 729 0x13,0x0b,0x43,0x6f,0x64,0x65,0x57,0x65,0x61,0x76,0x65,0x72,0x73,0x30,0x17,0x06, 730 0x03,0x55,0x04,0x0b,0x13,0x10,0x57,0x69,0x6e,0x65,0x20,0x44,0x65,0x76,0x65,0x6c, 731 0x6f,0x70,0x6d,0x65,0x6e,0x74,0x30,0x21,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d, 732 0x01,0x09,0x01,0x16,0x14,0x61,0x72,0x69,0x63,0x40,0x63,0x6f,0x64,0x65,0x77,0x65, 733 0x61,0x76,0x65,0x72,0x73,0x2e,0x63,0x6f,0x6d 734 }; 735 736 static void test_encodeName(DWORD dwEncoding) 737 { 738 CERT_RDN_ATTR attrs[2]; 739 CERT_RDN rdn; 740 CERT_NAME_INFO info; 741 static CHAR oid_common_name[] = szOID_COMMON_NAME, 742 oid_sur_name[] = szOID_SUR_NAME; 743 BYTE *buf = NULL; 744 DWORD size = 0; 745 BOOL ret; 746 747 if (0) 748 { 749 /* Test with NULL pvStructInfo (crashes on win9x) */ 750 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, NULL, 751 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 752 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 753 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError()); 754 } 755 /* Test with empty CERT_NAME_INFO */ 756 info.cRDN = 0; 757 info.rgRDN = NULL; 758 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info, 759 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 760 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 761 if (ret) 762 { 763 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)), 764 "Got unexpected encoding for empty name\n"); 765 LocalFree(buf); 766 } 767 if (0) 768 { 769 /* Test with bogus CERT_RDN (crashes on win9x) */ 770 info.cRDN = 1; 771 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info, 772 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 773 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 774 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError()); 775 } 776 /* Test with empty CERT_RDN */ 777 rdn.cRDNAttr = 0; 778 rdn.rgRDNAttr = NULL; 779 info.cRDN = 1; 780 info.rgRDN = &rdn; 781 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info, 782 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 783 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 784 if (ret) 785 { 786 ok(!memcmp(buf, emptyRDNs, sizeof(emptyRDNs)), 787 "Got unexpected encoding for empty RDN array\n"); 788 LocalFree(buf); 789 } 790 if (0) 791 { 792 /* Test with bogus attr array (crashes on win9x) */ 793 rdn.cRDNAttr = 1; 794 rdn.rgRDNAttr = NULL; 795 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info, 796 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 797 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 798 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError()); 799 } 800 /* oddly, a bogus OID is accepted by Windows XP; not testing. 801 attrs[0].pszObjId = "bogus"; 802 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING; 803 attrs[0].Value.cbData = sizeof(commonName); 804 attrs[0].Value.pbData = commonName; 805 rdn.cRDNAttr = 1; 806 rdn.rgRDNAttr = attrs; 807 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info, 808 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 809 ok(!ret, "Expected failure, got success\n"); 810 */ 811 /* Check with two CERT_RDN_ATTRs. Note DER encoding forces the order of 812 * the encoded attributes to be swapped. 813 */ 814 attrs[0].pszObjId = oid_common_name; 815 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING; 816 attrs[0].Value.cbData = sizeof(commonName); 817 attrs[0].Value.pbData = (BYTE *)commonName; 818 attrs[1].pszObjId = oid_sur_name; 819 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING; 820 attrs[1].Value.cbData = sizeof(surName); 821 attrs[1].Value.pbData = (BYTE *)surName; 822 rdn.cRDNAttr = 2; 823 rdn.rgRDNAttr = attrs; 824 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info, 825 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 826 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 827 if (ret) 828 { 829 ok(!memcmp(buf, twoRDNs, sizeof(twoRDNs)), 830 "Got unexpected encoding for two RDN array\n"); 831 LocalFree(buf); 832 } 833 /* A name can be "encoded" with previously encoded RDN attrs. */ 834 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB; 835 attrs[0].Value.pbData = (LPBYTE)twoRDNs; 836 attrs[0].Value.cbData = sizeof(twoRDNs); 837 rdn.cRDNAttr = 1; 838 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info, 839 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 840 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 841 if (ret) 842 { 843 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size); 844 ok(!memcmp(buf, encodedTwoRDNs, size), 845 "Unexpected value for re-encoded two RDN array\n"); 846 LocalFree(buf); 847 } 848 /* CERT_RDN_ANY_TYPE is too vague for X509_NAMEs, check the return */ 849 rdn.cRDNAttr = 1; 850 attrs[0].dwValueType = CERT_RDN_ANY_TYPE; 851 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info, 852 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 853 ok(!ret && GetLastError() == E_INVALIDARG, 854 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 855 /* Test a more complex name */ 856 rdn.cRDNAttr = sizeof(rdnAttrs) / sizeof(rdnAttrs[0]); 857 rdn.rgRDNAttr = rdnAttrs; 858 info.cRDN = 1; 859 info.rgRDN = &rdn; 860 buf = NULL; 861 size = 0; 862 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, X509_NAME, &info, 863 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 864 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 865 if (ret) 866 { 867 ok(size == sizeof(encodedRDNAttrs), "Wrong size %d\n", size); 868 ok(!memcmp(buf, encodedRDNAttrs, size), "Unexpected value\n"); 869 LocalFree(buf); 870 } 871 } 872 873 static WCHAR commonNameW[] = { 'J','u','a','n',' ','L','a','n','g',0 }; 874 static WCHAR surNameW[] = { 'L','a','n','g',0 }; 875 876 static const BYTE twoRDNsNoNull[] = { 877 0x30,0x21,0x31,0x1f,0x30,0x0b,0x06,0x03,0x55,0x04,0x04,0x13,0x04,0x4c,0x61, 878 0x6e,0x67,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e, 879 0x20,0x4c,0x61,0x6e,0x67 }; 880 static const BYTE anyType[] = { 881 0x30,0x2f,0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x1e,0x24,0x23,0x30, 882 0x21,0x31,0x0c,0x30,0x03,0x06,0x04,0x55,0x13,0x04,0x4c,0x05,0x6e,0x61,0x00, 883 0x67,0x11,0x30,0x03,0x06,0x04,0x55,0x13,0x03,0x4a,0x0a,0x61,0x75,0x20,0x6e, 884 0x61,0x4c,0x67,0x6e }; 885 886 static void test_encodeUnicodeName(DWORD dwEncoding) 887 { 888 CERT_RDN_ATTR attrs[2]; 889 CERT_RDN rdn; 890 CERT_NAME_INFO info; 891 static CHAR oid_common_name[] = szOID_COMMON_NAME, 892 oid_sur_name[] = szOID_SUR_NAME; 893 BYTE *buf = NULL; 894 DWORD size = 0; 895 BOOL ret; 896 897 if (0) 898 { 899 /* Test with NULL pvStructInfo (crashes on win9x) */ 900 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, NULL, 901 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 902 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 903 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError()); 904 } 905 /* Test with empty CERT_NAME_INFO */ 906 info.cRDN = 0; 907 info.rgRDN = NULL; 908 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info, 909 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 910 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 911 if (ret) 912 { 913 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)), 914 "Got unexpected encoding for empty name\n"); 915 LocalFree(buf); 916 } 917 /* Check with one CERT_RDN_ATTR, that has an invalid character for the 918 * encoding (the NULL). 919 */ 920 attrs[0].pszObjId = oid_common_name; 921 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING; 922 attrs[0].Value.cbData = sizeof(commonNameW); 923 attrs[0].Value.pbData = (BYTE *)commonNameW; 924 rdn.cRDNAttr = 1; 925 rdn.rgRDNAttr = attrs; 926 info.cRDN = 1; 927 info.rgRDN = &rdn; 928 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info, 929 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 930 ok(!ret && GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING, 931 "Expected CRYPT_E_INVALID_PRINTABLE_STRING, got %08x\n", GetLastError()); 932 ok(size == 9, "Unexpected error index %08x\n", size); 933 /* Check with two NULL-terminated CERT_RDN_ATTRs. Note DER encoding 934 * forces the order of the encoded attributes to be swapped. 935 */ 936 attrs[0].pszObjId = oid_common_name; 937 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING; 938 attrs[0].Value.cbData = 0; 939 attrs[0].Value.pbData = (BYTE *)commonNameW; 940 attrs[1].pszObjId = oid_sur_name; 941 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING; 942 attrs[1].Value.cbData = 0; 943 attrs[1].Value.pbData = (BYTE *)surNameW; 944 rdn.cRDNAttr = 2; 945 rdn.rgRDNAttr = attrs; 946 info.cRDN = 1; 947 info.rgRDN = &rdn; 948 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info, 949 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 950 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 951 if (ret) 952 { 953 ok(!memcmp(buf, twoRDNsNoNull, sizeof(twoRDNsNoNull)), 954 "Got unexpected encoding for two RDN array\n"); 955 LocalFree(buf); 956 } 957 /* A name can be "encoded" with previously encoded RDN attrs. */ 958 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB; 959 attrs[0].Value.pbData = (LPBYTE)twoRDNs; 960 attrs[0].Value.cbData = sizeof(twoRDNs); 961 rdn.cRDNAttr = 1; 962 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info, 963 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 964 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 965 if (ret) 966 { 967 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size); 968 ok(!memcmp(buf, encodedTwoRDNs, size), 969 "Unexpected value for re-encoded two RDN array\n"); 970 LocalFree(buf); 971 } 972 /* Unicode names infer the type for CERT_RDN_ANY_TYPE */ 973 rdn.cRDNAttr = 1; 974 attrs[0].dwValueType = CERT_RDN_ANY_TYPE; 975 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info, 976 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 977 todo_wine ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 978 if (ret) 979 { 980 ok(size == sizeof(anyType), "Unexpected size %d\n", size); 981 ok(!memcmp(buf, anyType, size), "Unexpected value\n"); 982 LocalFree(buf); 983 } 984 } 985 986 static void compareNameValues(const CERT_NAME_VALUE *expected, 987 const CERT_NAME_VALUE *got) 988 { 989 if (expected->dwValueType == CERT_RDN_UTF8_STRING && 990 got->dwValueType == CERT_RDN_ENCODED_BLOB) 991 { 992 win_skip("Can't handle CERT_RDN_UTF8_STRING\n"); 993 return; 994 } 995 996 ok(got->dwValueType == expected->dwValueType, 997 "Expected string type %d, got %d\n", expected->dwValueType, 998 got->dwValueType); 999 ok(got->Value.cbData == expected->Value.cbData || 1000 got->Value.cbData == expected->Value.cbData - sizeof(WCHAR) /* Win8 */, 1001 "String type %d: unexpected data size, got %d, expected %d\n", 1002 expected->dwValueType, got->Value.cbData, expected->Value.cbData); 1003 if (got->Value.cbData && got->Value.pbData) 1004 ok(!memcmp(got->Value.pbData, expected->Value.pbData, 1005 min(got->Value.cbData, expected->Value.cbData)), 1006 "String type %d: unexpected value\n", expected->dwValueType); 1007 } 1008 1009 static void compareRDNAttrs(const CERT_RDN_ATTR *expected, 1010 const CERT_RDN_ATTR *got) 1011 { 1012 if (expected->pszObjId && strlen(expected->pszObjId)) 1013 { 1014 ok(got->pszObjId != NULL, "Expected OID %s, got NULL\n", 1015 expected->pszObjId); 1016 if (got->pszObjId) 1017 { 1018 ok(!strcmp(got->pszObjId, expected->pszObjId), 1019 "Got unexpected OID %s, expected %s\n", got->pszObjId, 1020 expected->pszObjId); 1021 } 1022 } 1023 compareNameValues((const CERT_NAME_VALUE *)&expected->dwValueType, 1024 (const CERT_NAME_VALUE *)&got->dwValueType); 1025 } 1026 1027 static void compareRDNs(const CERT_RDN *expected, const CERT_RDN *got) 1028 { 1029 ok(got->cRDNAttr == expected->cRDNAttr, 1030 "Expected %d RDN attrs, got %d\n", expected->cRDNAttr, got->cRDNAttr); 1031 if (got->cRDNAttr) 1032 { 1033 DWORD i; 1034 1035 for (i = 0; i < got->cRDNAttr; i++) 1036 compareRDNAttrs(&expected->rgRDNAttr[i], &got->rgRDNAttr[i]); 1037 } 1038 } 1039 1040 static void compareNames(const CERT_NAME_INFO *expected, 1041 const CERT_NAME_INFO *got) 1042 { 1043 ok(got->cRDN == expected->cRDN, "Expected %d RDNs, got %d\n", 1044 expected->cRDN, got->cRDN); 1045 if (got->cRDN) 1046 { 1047 DWORD i; 1048 1049 for (i = 0; i < got->cRDN; i++) 1050 compareRDNs(&expected->rgRDN[i], &got->rgRDN[i]); 1051 } 1052 } 1053 1054 static const BYTE emptyIndefiniteSequence[] = { 0x30,0x80,0x00,0x00 }; 1055 static const BYTE twoRDNsExtraBytes[] = { 1056 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04, 1057 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03, 1058 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0,0,0,0,0,0}; 1059 1060 static void test_decodeName(DWORD dwEncoding) 1061 { 1062 BYTE *buf = NULL; 1063 DWORD bufSize = 0; 1064 BOOL ret; 1065 CERT_RDN rdn; 1066 CERT_NAME_INFO info = { 1, &rdn }; 1067 1068 /* test empty name */ 1069 bufSize = 0; 1070 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptySequence, 1071 emptySequence[1] + 2, 1072 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL, 1073 &buf, &bufSize); 1074 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1075 /* Interestingly, in Windows, if cRDN is 0, rgRGN may not be NULL. My 1076 * decoder works the same way, so only test the count. 1077 */ 1078 if (ret) 1079 { 1080 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize); 1081 ok(((CERT_NAME_INFO *)buf)->cRDN == 0, 1082 "Expected 0 RDNs in empty info, got %d\n", 1083 ((CERT_NAME_INFO *)buf)->cRDN); 1084 LocalFree(buf); 1085 } 1086 /* test empty name with indefinite-length encoding */ 1087 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyIndefiniteSequence, 1088 sizeof(emptyIndefiniteSequence), CRYPT_DECODE_ALLOC_FLAG, NULL, 1089 &buf, &bufSize); 1090 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1091 if (ret) 1092 { 1093 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize); 1094 ok(((CERT_NAME_INFO *)buf)->cRDN == 0, 1095 "Expected 0 RDNs in empty info, got %d\n", 1096 ((CERT_NAME_INFO *)buf)->cRDN); 1097 LocalFree(buf); 1098 } 1099 /* test empty RDN */ 1100 bufSize = 0; 1101 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyRDNs, 1102 emptyRDNs[1] + 2, 1103 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL, 1104 &buf, &bufSize); 1105 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1106 if (ret) 1107 { 1108 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf; 1109 1110 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) && 1111 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0, 1112 "Got unexpected value for empty RDN\n"); 1113 LocalFree(buf); 1114 } 1115 /* test two RDN attrs */ 1116 bufSize = 0; 1117 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNs, 1118 twoRDNs[1] + 2, 1119 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL, 1120 &buf, &bufSize); 1121 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1122 if (ret) 1123 { 1124 static CHAR oid_sur_name[] = szOID_SUR_NAME, 1125 oid_common_name[] = szOID_COMMON_NAME; 1126 1127 CERT_RDN_ATTR attrs[] = { 1128 { oid_sur_name, CERT_RDN_PRINTABLE_STRING, { sizeof(surName), 1129 (BYTE *)surName } }, 1130 { oid_common_name, CERT_RDN_PRINTABLE_STRING, { sizeof(commonName), 1131 (BYTE *)commonName } }, 1132 }; 1133 1134 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]); 1135 rdn.rgRDNAttr = attrs; 1136 compareNames(&info, (CERT_NAME_INFO *)buf); 1137 LocalFree(buf); 1138 } 1139 /* test that two RDN attrs with extra bytes succeeds */ 1140 bufSize = 0; 1141 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNsExtraBytes, 1142 sizeof(twoRDNsExtraBytes), 0, NULL, NULL, &bufSize); 1143 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1144 /* And, a slightly more complicated name */ 1145 buf = NULL; 1146 bufSize = 0; 1147 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME, encodedRDNAttrs, 1148 sizeof(encodedRDNAttrs), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 1149 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1150 if (ret) 1151 { 1152 rdn.cRDNAttr = sizeof(decodedRdnAttrs) / sizeof(decodedRdnAttrs[0]); 1153 rdn.rgRDNAttr = decodedRdnAttrs; 1154 compareNames(&info, (CERT_NAME_INFO *)buf); 1155 LocalFree(buf); 1156 } 1157 } 1158 1159 static void test_decodeUnicodeName(DWORD dwEncoding) 1160 { 1161 BYTE *buf = NULL; 1162 DWORD bufSize = 0; 1163 BOOL ret; 1164 CERT_RDN rdn; 1165 CERT_NAME_INFO info = { 1, &rdn }; 1166 1167 /* test empty name */ 1168 bufSize = 0; 1169 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptySequence, 1170 emptySequence[1] + 2, 1171 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL, 1172 &buf, &bufSize); 1173 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1174 if (ret) 1175 { 1176 ok(bufSize == sizeof(CERT_NAME_INFO), 1177 "Got wrong bufSize %d\n", bufSize); 1178 ok(((CERT_NAME_INFO *)buf)->cRDN == 0, 1179 "Expected 0 RDNs in empty info, got %d\n", 1180 ((CERT_NAME_INFO *)buf)->cRDN); 1181 LocalFree(buf); 1182 } 1183 /* test empty RDN */ 1184 bufSize = 0; 1185 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptyRDNs, 1186 emptyRDNs[1] + 2, 1187 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL, 1188 &buf, &bufSize); 1189 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1190 if (ret) 1191 { 1192 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf; 1193 1194 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) && 1195 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0, 1196 "Got unexpected value for empty RDN\n"); 1197 LocalFree(buf); 1198 } 1199 /* test two RDN attrs */ 1200 bufSize = 0; 1201 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, twoRDNsNoNull, 1202 sizeof(twoRDNsNoNull), 1203 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL, 1204 &buf, &bufSize); 1205 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1206 if (ret) 1207 { 1208 static CHAR oid_sur_name[] = szOID_SUR_NAME, 1209 oid_common_name[] = szOID_COMMON_NAME; 1210 1211 CERT_RDN_ATTR attrs[] = { 1212 { oid_sur_name, CERT_RDN_PRINTABLE_STRING, 1213 { lstrlenW(surNameW) * sizeof(WCHAR), (BYTE *)surNameW } }, 1214 { oid_common_name, CERT_RDN_PRINTABLE_STRING, 1215 { lstrlenW(commonNameW) * sizeof(WCHAR), (BYTE *)commonNameW } }, 1216 }; 1217 1218 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]); 1219 rdn.rgRDNAttr = attrs; 1220 compareNames(&info, (CERT_NAME_INFO *)buf); 1221 LocalFree(buf); 1222 } 1223 } 1224 1225 struct EncodedNameValue 1226 { 1227 CERT_NAME_VALUE value; 1228 const BYTE *encoded; 1229 DWORD encodedSize; 1230 }; 1231 1232 static const char bogusIA5[] = "\x80"; 1233 static const char bogusPrintable[] = "~"; 1234 static const char bogusNumeric[] = "A"; 1235 static const BYTE bin42[] = { 0x16,0x02,0x80,0x00 }; 1236 static const BYTE bin43[] = { 0x13,0x02,0x7e,0x00 }; 1237 static const BYTE bin44[] = { 0x12,0x02,0x41,0x00 }; 1238 static BYTE octetCommonNameValue[] = { 1239 0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 }; 1240 static BYTE numericCommonNameValue[] = { 1241 0x12,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 }; 1242 static BYTE printableCommonNameValue[] = { 1243 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 }; 1244 static BYTE t61CommonNameValue[] = { 1245 0x14,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 }; 1246 static BYTE videotexCommonNameValue[] = { 1247 0x15,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 }; 1248 static BYTE ia5CommonNameValue[] = { 1249 0x16,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 }; 1250 static BYTE graphicCommonNameValue[] = { 1251 0x19,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 }; 1252 static BYTE visibleCommonNameValue[] = { 1253 0x1a,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 }; 1254 static BYTE generalCommonNameValue[] = { 1255 0x1b,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 }; 1256 static BYTE bmpCommonNameValue[] = { 1257 0x1e,0x14,0x00,0x4a,0x00,0x75,0x00,0x61,0x00,0x6e,0x00,0x20,0x00,0x4c,0x00, 1258 0x61,0x00,0x6e,0x00,0x67,0x00,0x00 }; 1259 static BYTE utf8CommonNameValue[] = { 1260 0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 }; 1261 static char embedded_null[] = "foo\0com"; 1262 static BYTE ia5EmbeddedNull[] = { 1263 0x16,0x07,0x66,0x6f,0x6f,0x00,0x63,0x6f,0x6d }; 1264 1265 static struct EncodedNameValue nameValues[] = { 1266 { { CERT_RDN_OCTET_STRING, { sizeof(commonName), (BYTE *)commonName } }, 1267 octetCommonNameValue, sizeof(octetCommonNameValue) }, 1268 { { CERT_RDN_NUMERIC_STRING, { sizeof(commonName), (BYTE *)commonName } }, 1269 numericCommonNameValue, sizeof(numericCommonNameValue) }, 1270 { { CERT_RDN_PRINTABLE_STRING, { sizeof(commonName), (BYTE *)commonName } }, 1271 printableCommonNameValue, sizeof(printableCommonNameValue) }, 1272 { { CERT_RDN_T61_STRING, { sizeof(commonName), (BYTE *)commonName } }, 1273 t61CommonNameValue, sizeof(t61CommonNameValue) }, 1274 { { CERT_RDN_VIDEOTEX_STRING, { sizeof(commonName), (BYTE *)commonName } }, 1275 videotexCommonNameValue, sizeof(videotexCommonNameValue) }, 1276 { { CERT_RDN_IA5_STRING, { sizeof(commonName), (BYTE *)commonName } }, 1277 ia5CommonNameValue, sizeof(ia5CommonNameValue) }, 1278 { { CERT_RDN_GRAPHIC_STRING, { sizeof(commonName), (BYTE *)commonName } }, 1279 graphicCommonNameValue, sizeof(graphicCommonNameValue) }, 1280 { { CERT_RDN_VISIBLE_STRING, { sizeof(commonName), (BYTE *)commonName } }, 1281 visibleCommonNameValue, sizeof(visibleCommonNameValue) }, 1282 { { CERT_RDN_GENERAL_STRING, { sizeof(commonName), (BYTE *)commonName } }, 1283 generalCommonNameValue, sizeof(generalCommonNameValue) }, 1284 { { CERT_RDN_BMP_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } }, 1285 bmpCommonNameValue, sizeof(bmpCommonNameValue) }, 1286 { { CERT_RDN_UTF8_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } }, 1287 utf8CommonNameValue, sizeof(utf8CommonNameValue) }, 1288 /* The following tests succeed under Windows, but really should fail, 1289 * they contain characters that are illegal for the encoding. I'm 1290 * including them to justify my lazy encoding. 1291 */ 1292 { { CERT_RDN_IA5_STRING, { sizeof(bogusIA5), (BYTE *)bogusIA5 } }, bin42, 1293 sizeof(bin42) }, 1294 { { CERT_RDN_PRINTABLE_STRING, { sizeof(bogusPrintable), 1295 (BYTE *)bogusPrintable } }, bin43, sizeof(bin43) }, 1296 { { CERT_RDN_NUMERIC_STRING, { sizeof(bogusNumeric), (BYTE *)bogusNumeric } }, 1297 bin44, sizeof(bin44) }, 1298 }; 1299 /* This is kept separate, because the decoding doesn't return to the original 1300 * value. 1301 */ 1302 static struct EncodedNameValue embeddedNullNameValue = { 1303 { CERT_RDN_IA5_STRING, { sizeof(embedded_null) - 1, (BYTE *)embedded_null } }, 1304 ia5EmbeddedNull, sizeof(ia5EmbeddedNull) }; 1305 1306 static void test_encodeNameValue(DWORD dwEncoding) 1307 { 1308 BYTE *buf = NULL; 1309 DWORD size = 0, i; 1310 BOOL ret; 1311 CERT_NAME_VALUE value = { 0, { 0, NULL } }; 1312 1313 value.dwValueType = CERT_RDN_ENCODED_BLOB; 1314 value.Value.pbData = printableCommonNameValue; 1315 value.Value.cbData = sizeof(printableCommonNameValue); 1316 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, &value, 1317 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1318 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 1319 if (ret) 1320 { 1321 ok(size == sizeof(printableCommonNameValue), "Unexpected size %d\n", 1322 size); 1323 ok(!memcmp(buf, printableCommonNameValue, size), 1324 "Unexpected encoding\n"); 1325 LocalFree(buf); 1326 } 1327 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++) 1328 { 1329 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, 1330 &nameValues[i].value, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1331 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH) /* NT4/Win9x */, 1332 "Type %d: CryptEncodeObjectEx failed: %08x\n", 1333 nameValues[i].value.dwValueType, GetLastError()); 1334 if (ret) 1335 { 1336 ok(size == nameValues[i].encodedSize, 1337 "Expected size %d, got %d\n", nameValues[i].encodedSize, size); 1338 ok(!memcmp(buf, nameValues[i].encoded, size), 1339 "Got unexpected encoding\n"); 1340 LocalFree(buf); 1341 } 1342 } 1343 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, 1344 &embeddedNullNameValue.value, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1345 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH) /* NT4/Win9x */, 1346 "Type %d: CryptEncodeObjectEx failed: %08x\n", 1347 embeddedNullNameValue.value.dwValueType, GetLastError()); 1348 if (ret) 1349 { 1350 ok(size == embeddedNullNameValue.encodedSize, 1351 "Expected size %d, got %d\n", embeddedNullNameValue.encodedSize, size); 1352 ok(!memcmp(buf, embeddedNullNameValue.encoded, size), 1353 "Got unexpected encoding\n"); 1354 LocalFree(buf); 1355 } 1356 } 1357 1358 static void test_decodeNameValue(DWORD dwEncoding) 1359 { 1360 int i; 1361 BYTE *buf = NULL; 1362 DWORD bufSize = 0; 1363 BOOL ret; 1364 1365 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++) 1366 { 1367 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE, 1368 nameValues[i].encoded, nameValues[i].encoded[1] + 2, 1369 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL, 1370 &buf, &bufSize); 1371 ok(ret, "Value type %d: CryptDecodeObjectEx failed: %08x\n", 1372 nameValues[i].value.dwValueType, GetLastError()); 1373 if (ret) 1374 { 1375 compareNameValues(&nameValues[i].value, 1376 (const CERT_NAME_VALUE *)buf); 1377 LocalFree(buf); 1378 } 1379 } 1380 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE, 1381 embeddedNullNameValue.encoded, embeddedNullNameValue.encodedSize, 1382 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL, 1383 &buf, &bufSize); 1384 /* Some Windows versions disallow name values with embedded NULLs, so 1385 * either success or failure is acceptable. 1386 */ 1387 if (ret) 1388 { 1389 CERT_NAME_VALUE rdnEncodedValue = { CERT_RDN_ENCODED_BLOB, 1390 { sizeof(ia5EmbeddedNull), ia5EmbeddedNull } }; 1391 CERT_NAME_VALUE embeddedNullValue = { CERT_RDN_IA5_STRING, 1392 { sizeof(embedded_null) - 1, (BYTE *)embedded_null } }; 1393 const CERT_NAME_VALUE *got = (const CERT_NAME_VALUE *)buf, 1394 *expected = NULL; 1395 1396 /* Some Windows versions decode name values with embedded NULLs, 1397 * others leave them encoded, even with the same version of crypt32. 1398 * Accept either. 1399 */ 1400 ok(got->dwValueType == CERT_RDN_ENCODED_BLOB || 1401 got->dwValueType == CERT_RDN_IA5_STRING, 1402 "Expected CERT_RDN_ENCODED_BLOB or CERT_RDN_IA5_STRING, got %d\n", 1403 got->dwValueType); 1404 if (got->dwValueType == CERT_RDN_ENCODED_BLOB) 1405 expected = &rdnEncodedValue; 1406 else if (got->dwValueType == CERT_RDN_IA5_STRING) 1407 expected = &embeddedNullValue; 1408 if (expected) 1409 { 1410 ok(got->Value.cbData == expected->Value.cbData, 1411 "String type %d: unexpected data size, got %d, expected %d\n", 1412 got->dwValueType, got->Value.cbData, expected->Value.cbData); 1413 if (got->Value.cbData && got->Value.pbData) 1414 ok(!memcmp(got->Value.pbData, expected->Value.pbData, 1415 min(got->Value.cbData, expected->Value.cbData)), 1416 "String type %d: unexpected value\n", expected->dwValueType); 1417 } 1418 LocalFree(buf); 1419 } 1420 } 1421 1422 static const BYTE emptyURL[] = { 0x30, 0x02, 0x86, 0x00 }; 1423 static const BYTE emptyURLExtraBytes[] = { 0x30, 0x02, 0x86, 0x00, 0, 0, 0 }; 1424 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e', 1425 'h','q','.','o','r','g',0 }; 1426 static const BYTE encodedURL[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74, 1427 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 1428 0x6f, 0x72, 0x67 }; 1429 static const WCHAR nihongoURL[] = { 'h','t','t','p',':','/','/',0x226f, 1430 0x575b, 0 }; 1431 static const WCHAR dnsName[] = { 'w','i','n','e','h','q','.','o','r','g',0 }; 1432 static const BYTE encodedDnsName[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69, 1433 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 }; 1434 static const BYTE localhost[] = { 127, 0, 0, 1 }; 1435 static const BYTE encodedIPAddr[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00, 1436 0x01 }; 1437 static const unsigned char encodedCommonName[] = { 1438 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0}; 1439 static const BYTE encodedOidName[] = { 0x30,0x04,0x88,0x02,0x2a,0x03 }; 1440 static const BYTE encodedDirectoryName[] = { 1441 0x30,0x19,0xa4,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03, 1442 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 }; 1443 1444 static void test_encodeAltName(DWORD dwEncoding) 1445 { 1446 CERT_ALT_NAME_INFO info = { 0 }; 1447 CERT_ALT_NAME_ENTRY entry = { 0 }; 1448 BYTE *buf = NULL; 1449 DWORD size = 0; 1450 BOOL ret; 1451 char oid[] = "1.2.3"; 1452 1453 /* Test with empty info */ 1454 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, 1455 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1456 if (ret) 1457 { 1458 ok(size == sizeof(emptySequence), "Wrong size %d\n", size); 1459 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n"); 1460 LocalFree(buf); 1461 } 1462 /* Test with an empty entry */ 1463 info.cAltEntry = 1; 1464 info.rgAltEntry = &entry; 1465 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, 1466 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1467 ok(!ret && GetLastError() == E_INVALIDARG, 1468 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 1469 /* Test with an empty pointer */ 1470 entry.dwAltNameChoice = CERT_ALT_NAME_URL; 1471 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, 1472 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1473 if (ret) 1474 { 1475 ok(size == sizeof(emptyURL), "Wrong size %d\n", size); 1476 ok(!memcmp(buf, emptyURL, size), "Unexpected value\n"); 1477 LocalFree(buf); 1478 } 1479 /* Test with a real URL */ 1480 U(entry).pwszURL = (LPWSTR)url; 1481 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, 1482 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1483 if (ret) 1484 { 1485 ok(size == sizeof(encodedURL), "Wrong size %d\n", size); 1486 ok(!memcmp(buf, encodedURL, size), "Unexpected value\n"); 1487 LocalFree(buf); 1488 } 1489 /* Now with the URL containing an invalid IA5 char */ 1490 U(entry).pwszURL = (LPWSTR)nihongoURL; 1491 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, 1492 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1493 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING, 1494 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError()); 1495 /* The first invalid character is at index 7 */ 1496 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7, 1497 "Expected invalid char at index 7, got %d\n", 1498 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size)); 1499 /* Now with the URL missing a scheme */ 1500 U(entry).pwszURL = (LPWSTR)dnsName; 1501 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, 1502 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1503 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 1504 if (ret) 1505 { 1506 /* This succeeds, but it shouldn't, so don't worry about conforming */ 1507 LocalFree(buf); 1508 } 1509 /* Now with a DNS name */ 1510 entry.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME; 1511 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, 1512 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1513 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 1514 if (ret) 1515 { 1516 ok(size == sizeof(encodedDnsName), "Wrong size %d\n", size); 1517 ok(!memcmp(buf, encodedDnsName, size), "Unexpected value\n"); 1518 LocalFree(buf); 1519 } 1520 /* Test with an IP address */ 1521 entry.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS; 1522 U(entry).IPAddress.cbData = sizeof(localhost); 1523 U(entry).IPAddress.pbData = (LPBYTE)localhost; 1524 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, 1525 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1526 if (ret) 1527 { 1528 ok(size == sizeof(encodedIPAddr), "Wrong size %d\n", size); 1529 ok(!memcmp(buf, encodedIPAddr, size), "Unexpected value\n"); 1530 LocalFree(buf); 1531 } 1532 /* Test with OID */ 1533 entry.dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID; 1534 U(entry).pszRegisteredID = oid; 1535 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, 1536 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1537 if (ret) 1538 { 1539 ok(size == sizeof(encodedOidName), "Wrong size %d\n", size); 1540 ok(!memcmp(buf, encodedOidName, size), "Unexpected value\n"); 1541 LocalFree(buf); 1542 } 1543 /* Test with directory name */ 1544 entry.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME; 1545 U(entry).DirectoryName.cbData = sizeof(encodedCommonName); 1546 U(entry).DirectoryName.pbData = (LPBYTE)encodedCommonName; 1547 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, 1548 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1549 if (ret) 1550 { 1551 ok(size == sizeof(encodedDirectoryName), "Wrong size %d\n", size); 1552 ok(!memcmp(buf, encodedDirectoryName, size), "Unexpected value\n"); 1553 LocalFree(buf); 1554 } 1555 } 1556 1557 static void test_decodeAltName(DWORD dwEncoding) 1558 { 1559 static const BYTE unimplementedType[] = { 0x30, 0x06, 0x85, 0x04, 0x7f, 1560 0x00, 0x00, 0x01 }; 1561 static const BYTE bogusType[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00, 1562 0x01 }; 1563 static const BYTE dns_embedded_null[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f, 1564 0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 }; 1565 static const BYTE dns_embedded_bell[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f, 1566 0x6f,0x2e,0x63,0x6f,0x6d,0x07,0x62,0x61,0x64,0x64,0x69,0x65 }; 1567 static const BYTE url_embedded_null[] = { 0x30,0x10,0x86,0x0e,0x66,0x6f, 1568 0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 }; 1569 BOOL ret; 1570 BYTE *buf = NULL; 1571 DWORD bufSize = 0; 1572 CERT_ALT_NAME_INFO *info; 1573 1574 /* Test some bogus ones first */ 1575 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, 1576 unimplementedType, sizeof(unimplementedType), CRYPT_DECODE_ALLOC_FLAG, 1577 NULL, &buf, &bufSize); 1578 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || 1579 GetLastError() == OSS_DATA_ERROR /* Win9x */), 1580 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n", 1581 GetLastError()); 1582 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, 1583 bogusType, sizeof(bogusType), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, 1584 &bufSize); 1585 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT || 1586 GetLastError() == OSS_DATA_ERROR /* Win9x */), 1587 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n", 1588 GetLastError()); 1589 /* Now expected cases */ 1590 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptySequence, 1591 emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 1592 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1593 if (ret) 1594 { 1595 info = (CERT_ALT_NAME_INFO *)buf; 1596 1597 ok(info->cAltEntry == 0, "Expected 0 entries, got %d\n", 1598 info->cAltEntry); 1599 LocalFree(buf); 1600 } 1601 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptyURL, 1602 emptyURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 1603 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1604 if (ret) 1605 { 1606 info = (CERT_ALT_NAME_INFO *)buf; 1607 1608 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n", 1609 info->cAltEntry); 1610 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL, 1611 "Expected CERT_ALT_NAME_URL, got %d\n", 1612 info->rgAltEntry[0].dwAltNameChoice); 1613 ok(U(info->rgAltEntry[0]).pwszURL == NULL || !*U(info->rgAltEntry[0]).pwszURL, 1614 "Expected empty URL\n"); 1615 LocalFree(buf); 1616 } 1617 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, 1618 emptyURLExtraBytes, sizeof(emptyURLExtraBytes), 0, NULL, NULL, &bufSize); 1619 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1620 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedURL, 1621 encodedURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 1622 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1623 if (ret) 1624 { 1625 info = (CERT_ALT_NAME_INFO *)buf; 1626 1627 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n", 1628 info->cAltEntry); 1629 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL, 1630 "Expected CERT_ALT_NAME_URL, got %d\n", 1631 info->rgAltEntry[0].dwAltNameChoice); 1632 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszURL, url), "Unexpected URL\n"); 1633 LocalFree(buf); 1634 } 1635 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedDnsName, 1636 encodedDnsName[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 1637 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1638 if (ret) 1639 { 1640 info = (CERT_ALT_NAME_INFO *)buf; 1641 1642 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n", 1643 info->cAltEntry); 1644 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME, 1645 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n", 1646 info->rgAltEntry[0].dwAltNameChoice); 1647 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszDNSName, dnsName), 1648 "Unexpected DNS name\n"); 1649 LocalFree(buf); 1650 } 1651 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedIPAddr, 1652 encodedIPAddr[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 1653 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1654 if (ret) 1655 { 1656 info = (CERT_ALT_NAME_INFO *)buf; 1657 1658 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n", 1659 info->cAltEntry); 1660 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS, 1661 "Expected CERT_ALT_NAME_IP_ADDRESS, got %d\n", 1662 info->rgAltEntry[0].dwAltNameChoice); 1663 ok(U(info->rgAltEntry[0]).IPAddress.cbData == sizeof(localhost), 1664 "Unexpected IP address length %d\n", 1665 U(info->rgAltEntry[0]).IPAddress.cbData); 1666 ok(!memcmp(U(info->rgAltEntry[0]).IPAddress.pbData, localhost, 1667 sizeof(localhost)), "Unexpected IP address value\n"); 1668 LocalFree(buf); 1669 } 1670 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedOidName, 1671 sizeof(encodedOidName), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 1672 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1673 if (ret) 1674 { 1675 info = (CERT_ALT_NAME_INFO *)buf; 1676 1677 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n", 1678 info->cAltEntry); 1679 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_REGISTERED_ID, 1680 "Expected CERT_ALT_NAME_REGISTERED_ID, got %d\n", 1681 info->rgAltEntry[0].dwAltNameChoice); 1682 ok(!strcmp(U(info->rgAltEntry[0]).pszRegisteredID, "1.2.3"), 1683 "Expected OID 1.2.3, got %s\n", U(info->rgAltEntry[0]).pszRegisteredID); 1684 LocalFree(buf); 1685 } 1686 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, 1687 encodedDirectoryName, sizeof(encodedDirectoryName), 1688 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 1689 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1690 if (ret) 1691 { 1692 info = (CERT_ALT_NAME_INFO *)buf; 1693 1694 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n", 1695 info->cAltEntry); 1696 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME, 1697 "Expected CERT_ALT_NAME_DIRECTORY_NAME, got %d\n", 1698 info->rgAltEntry[0].dwAltNameChoice); 1699 ok(U(info->rgAltEntry[0]).DirectoryName.cbData == 1700 sizeof(encodedCommonName), "Unexpected directory name length %d\n", 1701 U(info->rgAltEntry[0]).DirectoryName.cbData); 1702 ok(!memcmp(U(info->rgAltEntry[0]).DirectoryName.pbData, 1703 encodedCommonName, sizeof(encodedCommonName)), 1704 "Unexpected directory name value\n"); 1705 LocalFree(buf); 1706 } 1707 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, 1708 dns_embedded_null, sizeof(dns_embedded_null), CRYPT_DECODE_ALLOC_FLAG, 1709 NULL, &buf, &bufSize); 1710 /* Fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned about the 1711 * particular failure, just that it doesn't decode. 1712 * It succeeds on (broken) Windows versions that haven't addressed 1713 * embedded NULLs in alternate names. 1714 */ 1715 ok(!ret || broken(ret), "expected failure\n"); 1716 /* An embedded bell character is allowed, however. */ 1717 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, 1718 dns_embedded_bell, sizeof(dns_embedded_bell), CRYPT_DECODE_ALLOC_FLAG, 1719 NULL, &buf, &bufSize); 1720 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1721 if (ret) 1722 { 1723 info = (CERT_ALT_NAME_INFO *)buf; 1724 1725 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n", 1726 info->cAltEntry); 1727 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME, 1728 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n", 1729 info->rgAltEntry[0].dwAltNameChoice); 1730 LocalFree(buf); 1731 } 1732 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, 1733 url_embedded_null, sizeof(dns_embedded_null), CRYPT_DECODE_ALLOC_FLAG, 1734 NULL, &buf, &bufSize); 1735 /* Again, fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned 1736 * about the particular failure, just that it doesn't decode. 1737 * It succeeds on (broken) Windows versions that haven't addressed 1738 * embedded NULLs in alternate names. 1739 */ 1740 ok(!ret || broken(ret), "expected failure\n"); 1741 } 1742 1743 struct UnicodeExpectedError 1744 { 1745 DWORD valueType; 1746 LPCWSTR str; 1747 DWORD errorIndex; 1748 DWORD error; 1749 }; 1750 1751 static const WCHAR oneW[] = { '1',0 }; 1752 static const WCHAR aW[] = { 'a',0 }; 1753 static const WCHAR quoteW[] = { '"', 0 }; 1754 1755 static struct UnicodeExpectedError unicodeErrors[] = { 1756 { CERT_RDN_ANY_TYPE, oneW, 0, CRYPT_E_NOT_CHAR_STRING }, 1757 { CERT_RDN_ENCODED_BLOB, oneW, 0, CRYPT_E_NOT_CHAR_STRING }, 1758 { CERT_RDN_OCTET_STRING, oneW, 0, CRYPT_E_NOT_CHAR_STRING }, 1759 { CERT_RDN_NUMERIC_STRING, aW, 0, CRYPT_E_INVALID_NUMERIC_STRING }, 1760 { CERT_RDN_PRINTABLE_STRING, quoteW, 0, CRYPT_E_INVALID_PRINTABLE_STRING }, 1761 { CERT_RDN_IA5_STRING, nihongoURL, 7, CRYPT_E_INVALID_IA5_STRING }, 1762 }; 1763 1764 struct UnicodeExpectedResult 1765 { 1766 DWORD valueType; 1767 LPCWSTR str; 1768 CRYPT_DATA_BLOB encoded; 1769 }; 1770 1771 static BYTE oneNumeric[] = { 0x12, 0x01, 0x31 }; 1772 static BYTE onePrintable[] = { 0x13, 0x01, 0x31 }; 1773 static BYTE oneTeletex[] = { 0x14, 0x01, 0x31 }; 1774 static BYTE oneVideotex[] = { 0x15, 0x01, 0x31 }; 1775 static BYTE oneIA5[] = { 0x16, 0x01, 0x31 }; 1776 static BYTE oneGraphic[] = { 0x19, 0x01, 0x31 }; 1777 static BYTE oneVisible[] = { 0x1a, 0x01, 0x31 }; 1778 static BYTE oneUniversal[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 }; 1779 static BYTE oneGeneral[] = { 0x1b, 0x01, 0x31 }; 1780 static BYTE oneBMP[] = { 0x1e, 0x02, 0x00, 0x31 }; 1781 static BYTE oneUTF8[] = { 0x0c, 0x01, 0x31 }; 1782 static BYTE nihongoT61[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f, 1783 0x5b }; 1784 static BYTE nihongoGeneral[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, 1785 0x6f,0x5b }; 1786 static BYTE nihongoBMP[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70, 1787 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b }; 1788 static BYTE nihongoUTF8[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, 1789 0xe2,0x89,0xaf,0xe5,0x9d,0x9b }; 1790 1791 static struct UnicodeExpectedResult unicodeResults[] = { 1792 { CERT_RDN_NUMERIC_STRING, oneW, { sizeof(oneNumeric), oneNumeric } }, 1793 { CERT_RDN_PRINTABLE_STRING, oneW, { sizeof(onePrintable), onePrintable } }, 1794 { CERT_RDN_TELETEX_STRING, oneW, { sizeof(oneTeletex), oneTeletex } }, 1795 { CERT_RDN_VIDEOTEX_STRING, oneW, { sizeof(oneVideotex), oneVideotex } }, 1796 { CERT_RDN_IA5_STRING, oneW, { sizeof(oneIA5), oneIA5 } }, 1797 { CERT_RDN_GRAPHIC_STRING, oneW, { sizeof(oneGraphic), oneGraphic } }, 1798 { CERT_RDN_VISIBLE_STRING, oneW, { sizeof(oneVisible), oneVisible } }, 1799 { CERT_RDN_UNIVERSAL_STRING, oneW, { sizeof(oneUniversal), oneUniversal } }, 1800 { CERT_RDN_GENERAL_STRING, oneW, { sizeof(oneGeneral), oneGeneral } }, 1801 { CERT_RDN_BMP_STRING, oneW, { sizeof(oneBMP), oneBMP } }, 1802 { CERT_RDN_UTF8_STRING, oneW, { sizeof(oneUTF8), oneUTF8 } }, 1803 { CERT_RDN_BMP_STRING, nihongoURL, { sizeof(nihongoBMP), nihongoBMP } }, 1804 { CERT_RDN_UTF8_STRING, nihongoURL, { sizeof(nihongoUTF8), nihongoUTF8 } }, 1805 }; 1806 1807 static struct UnicodeExpectedResult unicodeWeirdness[] = { 1808 { CERT_RDN_TELETEX_STRING, nihongoURL, { sizeof(nihongoT61), nihongoT61 } }, 1809 { CERT_RDN_GENERAL_STRING, nihongoURL, { sizeof(nihongoGeneral), nihongoGeneral } }, 1810 }; 1811 1812 static void test_encodeUnicodeNameValue(DWORD dwEncoding) 1813 { 1814 BYTE *buf = NULL; 1815 DWORD size = 0, i; 1816 BOOL ret; 1817 CERT_NAME_VALUE value; 1818 1819 if (0) 1820 { 1821 /* Crashes on win9x */ 1822 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, NULL, 1823 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1824 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 1825 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError()); 1826 } 1827 /* Have to have a string of some sort */ 1828 value.dwValueType = 0; /* aka CERT_RDN_ANY_TYPE */ 1829 value.Value.pbData = NULL; 1830 value.Value.cbData = 0; 1831 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value, 1832 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1833 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING, 1834 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError()); 1835 value.dwValueType = CERT_RDN_ENCODED_BLOB; 1836 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value, 1837 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1838 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING, 1839 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError()); 1840 value.dwValueType = CERT_RDN_ANY_TYPE; 1841 value.Value.pbData = (LPBYTE)oneW; 1842 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value, 1843 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1844 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING, 1845 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError()); 1846 value.Value.cbData = sizeof(oneW); 1847 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value, 1848 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1849 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING, 1850 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError()); 1851 /* An encoded string with specified length isn't good enough either */ 1852 value.dwValueType = CERT_RDN_ENCODED_BLOB; 1853 value.Value.pbData = oneUniversal; 1854 value.Value.cbData = sizeof(oneUniversal); 1855 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value, 1856 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1857 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING, 1858 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError()); 1859 /* More failure checking */ 1860 value.Value.cbData = 0; 1861 for (i = 0; i < sizeof(unicodeErrors) / sizeof(unicodeErrors[0]); i++) 1862 { 1863 value.Value.pbData = (LPBYTE)unicodeErrors[i].str; 1864 value.dwValueType = unicodeErrors[i].valueType; 1865 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value, 1866 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1867 ok(!ret && GetLastError() == unicodeErrors[i].error, 1868 "Value type %d: expected %08x, got %08x\n", value.dwValueType, 1869 unicodeErrors[i].error, GetLastError()); 1870 ok(size == unicodeErrors[i].errorIndex, 1871 "Expected error index %d, got %d\n", unicodeErrors[i].errorIndex, 1872 size); 1873 } 1874 /* cbData can be zero if the string is NULL-terminated */ 1875 value.Value.cbData = 0; 1876 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++) 1877 { 1878 value.Value.pbData = (LPBYTE)unicodeResults[i].str; 1879 value.dwValueType = unicodeResults[i].valueType; 1880 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value, 1881 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1882 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH /* Win9x */), 1883 "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 1884 if (ret) 1885 { 1886 ok(size == unicodeResults[i].encoded.cbData, 1887 "Value type %d: expected size %d, got %d\n", 1888 value.dwValueType, unicodeResults[i].encoded.cbData, size); 1889 ok(!memcmp(unicodeResults[i].encoded.pbData, buf, size), 1890 "Value type %d: unexpected value\n", value.dwValueType); 1891 LocalFree(buf); 1892 } 1893 } 1894 /* These "encode," but they do so by truncating each unicode character 1895 * rather than properly encoding it. Kept separate from the proper results, 1896 * because the encoded forms won't decode to their original strings. 1897 */ 1898 for (i = 0; i < sizeof(unicodeWeirdness) / sizeof(unicodeWeirdness[0]); i++) 1899 { 1900 value.Value.pbData = (LPBYTE)unicodeWeirdness[i].str; 1901 value.dwValueType = unicodeWeirdness[i].valueType; 1902 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value, 1903 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1904 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 1905 if (ret) 1906 { 1907 ok(size == unicodeWeirdness[i].encoded.cbData, 1908 "Value type %d: expected size %d, got %d\n", 1909 value.dwValueType, unicodeWeirdness[i].encoded.cbData, size); 1910 ok(!memcmp(unicodeWeirdness[i].encoded.pbData, buf, size), 1911 "Value type %d: unexpected value\n", value.dwValueType); 1912 LocalFree(buf); 1913 } 1914 } 1915 } 1916 1917 static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n ) 1918 { 1919 if (n <= 0) return 0; 1920 while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; } 1921 return *str1 - *str2; 1922 } 1923 1924 static void test_decodeUnicodeNameValue(DWORD dwEncoding) 1925 { 1926 DWORD i; 1927 1928 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++) 1929 { 1930 BYTE *buf = NULL; 1931 BOOL ret; 1932 DWORD size = 0; 1933 1934 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, 1935 unicodeResults[i].encoded.pbData, unicodeResults[i].encoded.cbData, 1936 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 1937 ok(ret || broken(GetLastError() == CRYPT_E_NOT_CHAR_STRING /* Win9x */), 1938 "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1939 if (ret && buf) 1940 { 1941 PCERT_NAME_VALUE value = (PCERT_NAME_VALUE)buf; 1942 1943 ok(value->dwValueType == unicodeResults[i].valueType, 1944 "Expected value type %d, got %d\n", unicodeResults[i].valueType, 1945 value->dwValueType); 1946 ok(!strncmpW((LPWSTR)value->Value.pbData, unicodeResults[i].str, 1947 value->Value.cbData / sizeof(WCHAR)), 1948 "Unexpected decoded value for index %d (value type %d)\n", i, 1949 unicodeResults[i].valueType); 1950 LocalFree(buf); 1951 } 1952 } 1953 } 1954 1955 struct encodedOctets 1956 { 1957 const BYTE *val; 1958 const BYTE *encoded; 1959 }; 1960 1961 static const unsigned char bin46[] = { 'h','i',0 }; 1962 static const unsigned char bin47[] = { 0x04,0x02,'h','i',0 }; 1963 static const unsigned char bin48[] = { 1964 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 }; 1965 static const unsigned char bin49[] = { 1966 0x04,0x0f,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 }; 1967 static const unsigned char bin50[] = { 0 }; 1968 static const unsigned char bin51[] = { 0x04,0x00,0 }; 1969 1970 static const struct encodedOctets octets[] = { 1971 { bin46, bin47 }, 1972 { bin48, bin49 }, 1973 { bin50, bin51 }, 1974 }; 1975 1976 static void test_encodeOctets(DWORD dwEncoding) 1977 { 1978 CRYPT_DATA_BLOB blob; 1979 DWORD i; 1980 1981 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++) 1982 { 1983 BYTE *buf = NULL; 1984 BOOL ret; 1985 DWORD bufSize = 0; 1986 1987 blob.cbData = strlen((const char*)octets[i].val); 1988 blob.pbData = (BYTE*)octets[i].val; 1989 ret = pCryptEncodeObjectEx(dwEncoding, X509_OCTET_STRING, &blob, 1990 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 1991 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError()); 1992 if (ret) 1993 { 1994 ok(buf[0] == 4, 1995 "Got unexpected type %d for octet string (expected 4)\n", buf[0]); 1996 ok(buf[1] == octets[i].encoded[1], "Got length %d, expected %d\n", 1997 buf[1], octets[i].encoded[1]); 1998 ok(!memcmp(buf + 1, octets[i].encoded + 1, 1999 octets[i].encoded[1] + 1), "Got unexpected value\n"); 2000 LocalFree(buf); 2001 } 2002 } 2003 } 2004 2005 static void test_decodeOctets(DWORD dwEncoding) 2006 { 2007 DWORD i; 2008 2009 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++) 2010 { 2011 BYTE *buf = NULL; 2012 BOOL ret; 2013 DWORD bufSize = 0; 2014 2015 ret = pCryptDecodeObjectEx(dwEncoding, X509_OCTET_STRING, 2016 octets[i].encoded, octets[i].encoded[1] + 2, 2017 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2018 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 2019 ok(bufSize >= sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1], 2020 "Expected size >= %d, got %d\n", 2021 (int)sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1], bufSize); 2022 ok(buf != NULL, "Expected allocated buffer\n"); 2023 if (ret) 2024 { 2025 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)buf; 2026 2027 if (blob->cbData) 2028 ok(!memcmp(blob->pbData, octets[i].val, blob->cbData), 2029 "Unexpected value\n"); 2030 LocalFree(buf); 2031 } 2032 } 2033 } 2034 2035 static const BYTE bytesToEncode[] = { 0xff, 0xff }; 2036 2037 struct encodedBits 2038 { 2039 DWORD cUnusedBits; 2040 const BYTE *encoded; 2041 DWORD cbDecoded; 2042 const BYTE *decoded; 2043 }; 2044 2045 static const unsigned char bin52[] = { 0x03,0x03,0x00,0xff,0xff }; 2046 static const unsigned char bin53[] = { 0xff,0xff }; 2047 static const unsigned char bin54[] = { 0x03,0x03,0x01,0xff,0xfe }; 2048 static const unsigned char bin55[] = { 0xff,0xfe }; 2049 static const unsigned char bin56[] = { 0x03,0x02,0x01,0xfe }; 2050 static const unsigned char bin57[] = { 0xfe }; 2051 2052 static const struct encodedBits bits[] = { 2053 /* normal test cases */ 2054 { 0, bin52, 2, bin53 }, 2055 { 1, bin54, 2, bin55 }, 2056 /* strange test case, showing cUnusedBits >= 8 is allowed */ 2057 { 9, bin56, 1, bin57 }, 2058 }; 2059 2060 static void test_encodeBits(DWORD dwEncoding) 2061 { 2062 DWORD i; 2063 2064 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++) 2065 { 2066 CRYPT_BIT_BLOB blob; 2067 BOOL ret; 2068 BYTE *buf = NULL; 2069 DWORD bufSize = 0; 2070 2071 blob.cbData = sizeof(bytesToEncode); 2072 blob.pbData = (BYTE *)bytesToEncode; 2073 blob.cUnusedBits = bits[i].cUnusedBits; 2074 ret = pCryptEncodeObjectEx(dwEncoding, X509_BITS, &blob, 2075 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2076 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 2077 if (ret) 2078 { 2079 ok(bufSize == bits[i].encoded[1] + 2, 2080 "%d: Got unexpected size %d, expected %d\n", i, bufSize, 2081 bits[i].encoded[1] + 2); 2082 ok(!memcmp(buf, bits[i].encoded, bits[i].encoded[1] + 2), 2083 "%d: Unexpected value\n", i); 2084 LocalFree(buf); 2085 } 2086 } 2087 } 2088 2089 static void test_decodeBits(DWORD dwEncoding) 2090 { 2091 static const BYTE ber[] = "\x03\x02\x01\xff"; 2092 static const BYTE berDecoded = 0xfe; 2093 DWORD i; 2094 BOOL ret; 2095 BYTE *buf = NULL; 2096 DWORD bufSize = 0; 2097 2098 /* normal cases */ 2099 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++) 2100 { 2101 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, bits[i].encoded, 2102 bits[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, 2103 &bufSize); 2104 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 2105 if (ret) 2106 { 2107 CRYPT_BIT_BLOB *blob; 2108 2109 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + bits[i].cbDecoded, 2110 "Got unexpected size %d\n", bufSize); 2111 blob = (CRYPT_BIT_BLOB *)buf; 2112 ok(blob->cbData == bits[i].cbDecoded, 2113 "Got unexpected length %d, expected %d\n", blob->cbData, 2114 bits[i].cbDecoded); 2115 if (blob->cbData && bits[i].cbDecoded) 2116 ok(!memcmp(blob->pbData, bits[i].decoded, bits[i].cbDecoded), 2117 "Unexpected value\n"); 2118 LocalFree(buf); 2119 } 2120 } 2121 /* special case: check that something that's valid in BER but not in DER 2122 * decodes successfully 2123 */ 2124 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, ber, ber[1] + 2, 2125 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2126 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 2127 if (ret) 2128 { 2129 CRYPT_BIT_BLOB *blob; 2130 2131 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + sizeof(berDecoded), 2132 "Got unexpected size %d\n", bufSize); 2133 blob = (CRYPT_BIT_BLOB *)buf; 2134 ok(blob->cbData == sizeof(berDecoded), 2135 "Got unexpected length %d\n", blob->cbData); 2136 if (blob->cbData) 2137 ok(*blob->pbData == berDecoded, "Unexpected value\n"); 2138 LocalFree(buf); 2139 } 2140 } 2141 2142 struct Constraints2 2143 { 2144 CERT_BASIC_CONSTRAINTS2_INFO info; 2145 const BYTE *encoded; 2146 }; 2147 2148 static const unsigned char bin59[] = { 0x30,0x00 }; 2149 static const unsigned char bin60[] = { 0x30,0x03,0x01,0x01,0xff }; 2150 static const unsigned char bin61[] = { 0x30,0x03,0x02,0x01,0x00 }; 2151 static const unsigned char bin62[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 }; 2152 static const struct Constraints2 constraints2[] = { 2153 /* empty constraints */ 2154 { { FALSE, FALSE, 0}, bin59 }, 2155 /* can be a CA */ 2156 { { TRUE, FALSE, 0}, bin60 }, 2157 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well, 2158 * but that's not the case 2159 */ 2160 { { FALSE, TRUE, 0}, bin61 }, 2161 /* can be a CA and has path length constraints set */ 2162 { { TRUE, TRUE, 1}, bin62 }, 2163 }; 2164 2165 static const BYTE emptyConstraint[] = { 0x30, 0x03, 0x03, 0x01, 0x00 }; 2166 static const BYTE encodedDomainName[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 2167 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 2168 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 2169 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 }; 2170 static const BYTE constraintWithDomainName[] = { 0x30, 0x32, 0x03, 0x01, 0x00, 2171 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26, 2172 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30, 2173 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 2174 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 }; 2175 2176 static void test_encodeBasicConstraints(DWORD dwEncoding) 2177 { 2178 DWORD i, bufSize = 0; 2179 CERT_BASIC_CONSTRAINTS_INFO info = { { 0 } }; 2180 CERT_NAME_BLOB nameBlob = { sizeof(encodedDomainName), 2181 (LPBYTE)encodedDomainName }; 2182 BOOL ret; 2183 BYTE *buf = NULL; 2184 2185 /* First test with the simpler info2 */ 2186 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++) 2187 { 2188 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2, 2189 &constraints2[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, 2190 &bufSize); 2191 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 2192 if (ret) 2193 { 2194 ok(bufSize == constraints2[i].encoded[1] + 2, 2195 "Expected %d bytes, got %d\n", constraints2[i].encoded[1] + 2, 2196 bufSize); 2197 ok(!memcmp(buf, constraints2[i].encoded, 2198 constraints2[i].encoded[1] + 2), "Unexpected value\n"); 2199 LocalFree(buf); 2200 } 2201 } 2202 /* Now test with more complex basic constraints */ 2203 info.SubjectType.cbData = 0; 2204 info.fPathLenConstraint = FALSE; 2205 info.cSubtreesConstraint = 0; 2206 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info, 2207 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2208 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */, 2209 "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 2210 if (ret) 2211 { 2212 ok(bufSize == sizeof(emptyConstraint), "Wrong size %d\n", bufSize); 2213 ok(!memcmp(buf, emptyConstraint, sizeof(emptyConstraint)), 2214 "Unexpected value\n"); 2215 LocalFree(buf); 2216 } 2217 /* None of the certs I examined had any subtree constraint, but I test one 2218 * anyway just in case. 2219 */ 2220 info.cSubtreesConstraint = 1; 2221 info.rgSubtreesConstraint = &nameBlob; 2222 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info, 2223 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2224 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */, 2225 "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 2226 if (ret) 2227 { 2228 ok(bufSize == sizeof(constraintWithDomainName), "Wrong size %d\n", bufSize); 2229 ok(!memcmp(buf, constraintWithDomainName, 2230 sizeof(constraintWithDomainName)), "Unexpected value\n"); 2231 LocalFree(buf); 2232 } 2233 /* FIXME: test encoding with subject type. */ 2234 } 2235 2236 static const unsigned char bin63[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 }; 2237 2238 static void test_decodeBasicConstraints(DWORD dwEncoding) 2239 { 2240 static const BYTE inverted[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01, 2241 0xff }; 2242 static const struct Constraints2 badBool = { { TRUE, TRUE, 1 }, bin63 }; 2243 DWORD i; 2244 BOOL ret; 2245 BYTE *buf = NULL; 2246 DWORD bufSize = 0; 2247 2248 /* First test with simpler info2 */ 2249 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++) 2250 { 2251 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2, 2252 constraints2[i].encoded, constraints2[i].encoded[1] + 2, 2253 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2254 ok(ret, "CryptDecodeObjectEx failed for item %d: %08x\n", i, 2255 GetLastError()); 2256 if (ret) 2257 { 2258 CERT_BASIC_CONSTRAINTS2_INFO *info = 2259 (CERT_BASIC_CONSTRAINTS2_INFO *)buf; 2260 2261 ok(!memcmp(info, &constraints2[i].info, sizeof(*info)), 2262 "Unexpected value for item %d\n", i); 2263 LocalFree(buf); 2264 } 2265 } 2266 /* Check with the order of encoded elements inverted */ 2267 buf = (PBYTE)1; 2268 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2, 2269 inverted, inverted[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, 2270 &bufSize); 2271 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT || 2272 GetLastError() == OSS_DATA_ERROR /* Win9x */), 2273 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n", 2274 GetLastError()); 2275 ok(!buf, "Expected buf to be set to NULL\n"); 2276 /* Check with a non-DER bool */ 2277 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2, 2278 badBool.encoded, badBool.encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, 2279 &buf, &bufSize); 2280 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 2281 if (ret) 2282 { 2283 CERT_BASIC_CONSTRAINTS2_INFO *info = 2284 (CERT_BASIC_CONSTRAINTS2_INFO *)buf; 2285 2286 ok(!memcmp(info, &badBool.info, sizeof(*info)), "Unexpected value\n"); 2287 LocalFree(buf); 2288 } 2289 /* Check with a non-basic constraints value */ 2290 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2, 2291 encodedCommonName, encodedCommonName[1] + 2, 2292 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2293 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT || 2294 GetLastError() == OSS_DATA_ERROR /* Win9x */), 2295 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n", 2296 GetLastError()); 2297 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */ 2298 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, 2299 emptyConstraint, sizeof(emptyConstraint), CRYPT_DECODE_ALLOC_FLAG, NULL, 2300 &buf, &bufSize); 2301 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 2302 if (ret) 2303 { 2304 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf; 2305 2306 ok(info->SubjectType.cbData == 0, "Expected no subject type\n"); 2307 ok(!info->fPathLenConstraint, "Expected no path length constraint\n"); 2308 ok(info->cSubtreesConstraint == 0, "Expected no subtree constraints\n"); 2309 LocalFree(buf); 2310 } 2311 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, 2312 constraintWithDomainName, sizeof(constraintWithDomainName), 2313 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2314 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 2315 if (ret) 2316 { 2317 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf; 2318 2319 ok(info->SubjectType.cbData == 0, "Expected no subject type\n"); 2320 ok(!info->fPathLenConstraint, "Expected no path length constraint\n"); 2321 ok(info->cSubtreesConstraint == 1, "Expected a subtree constraint\n"); 2322 if (info->cSubtreesConstraint && info->rgSubtreesConstraint) 2323 { 2324 ok(info->rgSubtreesConstraint[0].cbData == 2325 sizeof(encodedDomainName), "Wrong size %d\n", 2326 info->rgSubtreesConstraint[0].cbData); 2327 ok(!memcmp(info->rgSubtreesConstraint[0].pbData, encodedDomainName, 2328 sizeof(encodedDomainName)), "Unexpected value\n"); 2329 } 2330 LocalFree(buf); 2331 } 2332 } 2333 2334 /* These are terrible public keys of course, I'm just testing encoding */ 2335 static const BYTE modulus1[] = { 0,0,0,1,1,1,1,1 }; 2336 static const BYTE modulus2[] = { 1,1,1,1,1,0,0,0 }; 2337 static const BYTE modulus3[] = { 0x80,1,1,1,1,0,0,0 }; 2338 static const BYTE modulus4[] = { 1,1,1,1,1,0,0,0x80 }; 2339 static const BYTE mod1_encoded[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 }; 2340 static const BYTE mod2_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 }; 2341 static const BYTE mod3_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 }; 2342 static const BYTE mod4_encoded[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 }; 2343 2344 struct EncodedRSAPubKey 2345 { 2346 const BYTE *modulus; 2347 size_t modulusLen; 2348 const BYTE *encoded; 2349 size_t decodedModulusLen; 2350 }; 2351 2352 static const struct EncodedRSAPubKey rsaPubKeys[] = { 2353 { modulus1, sizeof(modulus1), mod1_encoded, sizeof(modulus1) }, 2354 { modulus2, sizeof(modulus2), mod2_encoded, 5 }, 2355 { modulus3, sizeof(modulus3), mod3_encoded, 5 }, 2356 { modulus4, sizeof(modulus4), mod4_encoded, 8 }, 2357 }; 2358 2359 static void test_encodeRsaPublicKey(DWORD dwEncoding) 2360 { 2361 BYTE toEncode[sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + sizeof(modulus1)]; 2362 BLOBHEADER *hdr = (BLOBHEADER *)toEncode; 2363 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(toEncode + sizeof(BLOBHEADER)); 2364 BOOL ret; 2365 BYTE *buf = NULL; 2366 DWORD bufSize = 0, i; 2367 2368 /* Try with a bogus blob type */ 2369 hdr->bType = 2; 2370 hdr->bVersion = CUR_BLOB_VERSION; 2371 hdr->reserved = 0; 2372 hdr->aiKeyAlg = CALG_RSA_KEYX; 2373 rsaPubKey->magic = 0x31415352; 2374 rsaPubKey->bitlen = sizeof(modulus1) * 8; 2375 rsaPubKey->pubexp = 65537; 2376 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), modulus1, 2377 sizeof(modulus1)); 2378 2379 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB, 2380 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2381 ok(!ret && GetLastError() == E_INVALIDARG, 2382 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 2383 /* Now with a bogus reserved field */ 2384 hdr->bType = PUBLICKEYBLOB; 2385 hdr->reserved = 1; 2386 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB, 2387 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2388 if (ret) 2389 { 2390 ok(bufSize == rsaPubKeys[0].encoded[1] + 2, 2391 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize); 2392 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n"); 2393 LocalFree(buf); 2394 } 2395 /* Now with a bogus blob version */ 2396 hdr->reserved = 0; 2397 hdr->bVersion = 0; 2398 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB, 2399 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2400 if (ret) 2401 { 2402 ok(bufSize == rsaPubKeys[0].encoded[1] + 2, 2403 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize); 2404 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n"); 2405 LocalFree(buf); 2406 } 2407 /* And with a bogus alg ID */ 2408 hdr->bVersion = CUR_BLOB_VERSION; 2409 hdr->aiKeyAlg = CALG_DES; 2410 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB, 2411 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2412 if (ret) 2413 { 2414 ok(bufSize == rsaPubKeys[0].encoded[1] + 2, 2415 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize); 2416 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n"); 2417 LocalFree(buf); 2418 } 2419 /* Check a couple of RSA-related OIDs */ 2420 hdr->aiKeyAlg = CALG_RSA_KEYX; 2421 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_RSA, 2422 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2423 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 2424 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); 2425 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA, 2426 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2427 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 2428 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); 2429 /* Finally, all valid */ 2430 hdr->aiKeyAlg = CALG_RSA_KEYX; 2431 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++) 2432 { 2433 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), 2434 rsaPubKeys[i].modulus, rsaPubKeys[i].modulusLen); 2435 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB, 2436 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2437 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 2438 if (ret) 2439 { 2440 ok(bufSize == rsaPubKeys[i].encoded[1] + 2, 2441 "Expected size %d, got %d\n", rsaPubKeys[i].encoded[1] + 2, 2442 bufSize); 2443 ok(!memcmp(buf, rsaPubKeys[i].encoded, bufSize), 2444 "Unexpected value\n"); 2445 LocalFree(buf); 2446 } 2447 } 2448 } 2449 2450 static void test_decodeRsaPublicKey(DWORD dwEncoding) 2451 { 2452 DWORD i; 2453 LPBYTE buf = NULL; 2454 DWORD bufSize = 0; 2455 BOOL ret; 2456 2457 /* Try with a bad length */ 2458 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB, 2459 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1], 2460 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2461 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD || 2462 GetLastError() == OSS_MORE_INPUT /* Win9x/NT4 */), 2463 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n", 2464 GetLastError()); 2465 /* Try with a couple of RSA-related OIDs */ 2466 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_RSA, 2467 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2, 2468 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2469 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 2470 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); 2471 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA, 2472 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2, 2473 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2474 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 2475 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); 2476 /* Now try success cases */ 2477 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++) 2478 { 2479 bufSize = 0; 2480 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB, 2481 rsaPubKeys[i].encoded, rsaPubKeys[i].encoded[1] + 2, 2482 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2483 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 2484 if (ret) 2485 { 2486 BLOBHEADER *hdr = (BLOBHEADER *)buf; 2487 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER)); 2488 2489 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + 2490 rsaPubKeys[i].decodedModulusLen, 2491 "Wrong size %d\n", bufSize); 2492 ok(hdr->bType == PUBLICKEYBLOB, 2493 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB, 2494 hdr->bType); 2495 ok(hdr->bVersion == CUR_BLOB_VERSION, 2496 "Expected version CUR_BLOB_VERSION (%d), got %d\n", 2497 CUR_BLOB_VERSION, hdr->bVersion); 2498 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n", 2499 hdr->reserved); 2500 ok(hdr->aiKeyAlg == CALG_RSA_KEYX, 2501 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg); 2502 ok(rsaPubKey->magic == 0x31415352, 2503 "Expected magic RSA1, got %08x\n", rsaPubKey->magic); 2504 ok(rsaPubKey->bitlen == rsaPubKeys[i].decodedModulusLen * 8, 2505 "Wrong bit len %d\n", rsaPubKey->bitlen); 2506 ok(rsaPubKey->pubexp == 65537, "Expected pubexp 65537, got %d\n", 2507 rsaPubKey->pubexp); 2508 ok(!memcmp(buf + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), 2509 rsaPubKeys[i].modulus, rsaPubKeys[i].decodedModulusLen), 2510 "Unexpected modulus\n"); 2511 LocalFree(buf); 2512 } 2513 } 2514 } 2515 2516 static const BYTE intSequence[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01, 2517 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 2518 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d }; 2519 2520 static const BYTE mixedSequence[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30, 2521 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f, 2522 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02, 2523 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d }; 2524 2525 static void test_encodeSequenceOfAny(DWORD dwEncoding) 2526 { 2527 CRYPT_DER_BLOB blobs[sizeof(ints) / sizeof(ints[0])]; 2528 CRYPT_SEQUENCE_OF_ANY seq; 2529 DWORD i; 2530 BOOL ret; 2531 BYTE *buf = NULL; 2532 DWORD bufSize = 0; 2533 2534 /* Encode a homogeneous sequence */ 2535 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++) 2536 { 2537 blobs[i].cbData = ints[i].encoded[1] + 2; 2538 blobs[i].pbData = (BYTE *)ints[i].encoded; 2539 } 2540 seq.cValue = sizeof(ints) / sizeof(ints[0]); 2541 seq.rgValue = blobs; 2542 2543 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq, 2544 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2545 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 2546 if (ret) 2547 { 2548 ok(bufSize == sizeof(intSequence), "Wrong size %d\n", bufSize); 2549 ok(!memcmp(buf, intSequence, intSequence[1] + 2), "Unexpected value\n"); 2550 LocalFree(buf); 2551 } 2552 /* Change the type of the first element in the sequence, and give it 2553 * another go 2554 */ 2555 blobs[0].cbData = times[0].encodedTime[1] + 2; 2556 blobs[0].pbData = (BYTE *)times[0].encodedTime; 2557 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq, 2558 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2559 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 2560 if (ret) 2561 { 2562 ok(bufSize == sizeof(mixedSequence), "Wrong size %d\n", bufSize); 2563 ok(!memcmp(buf, mixedSequence, mixedSequence[1] + 2), 2564 "Unexpected value\n"); 2565 LocalFree(buf); 2566 } 2567 } 2568 2569 static void test_decodeSequenceOfAny(DWORD dwEncoding) 2570 { 2571 BOOL ret; 2572 BYTE *buf = NULL; 2573 DWORD bufSize = 0; 2574 2575 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, intSequence, 2576 intSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2577 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 2578 if (ret) 2579 { 2580 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf; 2581 DWORD i; 2582 2583 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]), 2584 "Wrong elements %d\n", seq->cValue); 2585 for (i = 0; i < min(seq->cValue, sizeof(ints) / sizeof(ints[0])); i++) 2586 { 2587 ok(seq->rgValue[i].cbData == ints[i].encoded[1] + 2, 2588 "Expected %d bytes, got %d\n", ints[i].encoded[1] + 2, 2589 seq->rgValue[i].cbData); 2590 ok(!memcmp(seq->rgValue[i].pbData, ints[i].encoded, 2591 ints[i].encoded[1] + 2), "Unexpected value\n"); 2592 } 2593 LocalFree(buf); 2594 } 2595 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, mixedSequence, 2596 mixedSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, 2597 &bufSize); 2598 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 2599 if (ret) 2600 { 2601 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf; 2602 2603 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]), 2604 "Wrong elements %d\n", seq->cValue); 2605 /* Just check the first element since it's all that changed */ 2606 ok(seq->rgValue[0].cbData == times[0].encodedTime[1] + 2, 2607 "Expected %d bytes, got %d\n", times[0].encodedTime[1] + 2, 2608 seq->rgValue[0].cbData); 2609 ok(!memcmp(seq->rgValue[0].pbData, times[0].encodedTime, 2610 times[0].encodedTime[1] + 2), "Unexpected value\n"); 2611 LocalFree(buf); 2612 } 2613 } 2614 2615 struct encodedExtensions 2616 { 2617 CERT_EXTENSIONS exts; 2618 const BYTE *encoded; 2619 }; 2620 2621 static BYTE crit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 }; 2622 static BYTE noncrit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 }; 2623 static CHAR oid_basic_constraints2[] = szOID_BASIC_CONSTRAINTS2; 2624 static CERT_EXTENSION criticalExt = 2625 { oid_basic_constraints2, TRUE, { 8, crit_ext_data } }; 2626 static CERT_EXTENSION nonCriticalExt = 2627 { oid_basic_constraints2, FALSE, { 8, noncrit_ext_data } }; 2628 static CHAR oid_short[] = "1.1"; 2629 static CERT_EXTENSION extWithShortOid = 2630 { oid_short, FALSE, { 0, NULL } }; 2631 2632 static const BYTE ext0[] = { 0x30,0x00 }; 2633 static const BYTE ext1[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01, 2634 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 }; 2635 static const BYTE ext2[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04, 2636 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 }; 2637 static const BYTE ext3[] = { 0x30,0x07,0x30,0x05,0x06,0x01,0x29,0x04,0x00 }; 2638 2639 static const struct encodedExtensions exts[] = { 2640 { { 0, NULL }, ext0 }, 2641 { { 1, &criticalExt }, ext1 }, 2642 { { 1, &nonCriticalExt }, ext2 }, 2643 { { 1, &extWithShortOid }, ext3 } 2644 }; 2645 2646 static void test_encodeExtensions(DWORD dwEncoding) 2647 { 2648 DWORD i; 2649 2650 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++) 2651 { 2652 BOOL ret; 2653 BYTE *buf = NULL; 2654 DWORD bufSize = 0; 2655 2656 ret = pCryptEncodeObjectEx(dwEncoding, X509_EXTENSIONS, &exts[i].exts, 2657 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2658 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 2659 if (ret) 2660 { 2661 ok(bufSize == exts[i].encoded[1] + 2, 2662 "Expected %d bytes, got %d\n", exts[i].encoded[1] + 2, bufSize); 2663 ok(!memcmp(buf, exts[i].encoded, exts[i].encoded[1] + 2), 2664 "Unexpected value\n"); 2665 LocalFree(buf); 2666 } 2667 } 2668 } 2669 2670 static void test_decodeExtensions(DWORD dwEncoding) 2671 { 2672 DWORD i; 2673 2674 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++) 2675 { 2676 BOOL ret; 2677 BYTE *buf = NULL; 2678 DWORD bufSize = 0; 2679 2680 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS, 2681 exts[i].encoded, exts[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, 2682 NULL, &buf, &bufSize); 2683 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 2684 if (ret) 2685 { 2686 CERT_EXTENSIONS *ext = (CERT_EXTENSIONS *)buf; 2687 DWORD j; 2688 2689 ok(ext->cExtension == exts[i].exts.cExtension, 2690 "Expected %d extensions, see %d\n", exts[i].exts.cExtension, 2691 ext->cExtension); 2692 for (j = 0; j < min(ext->cExtension, exts[i].exts.cExtension); j++) 2693 { 2694 ok(!strcmp(ext->rgExtension[j].pszObjId, 2695 exts[i].exts.rgExtension[j].pszObjId), 2696 "Expected OID %s, got %s\n", 2697 exts[i].exts.rgExtension[j].pszObjId, 2698 ext->rgExtension[j].pszObjId); 2699 ok(!memcmp(ext->rgExtension[j].Value.pbData, 2700 exts[i].exts.rgExtension[j].Value.pbData, 2701 exts[i].exts.rgExtension[j].Value.cbData), 2702 "Unexpected value\n"); 2703 } 2704 LocalFree(buf); 2705 } 2706 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS, 2707 exts[i].encoded, exts[i].encoded[1] + 2, 0, NULL, NULL, &bufSize); 2708 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 2709 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bufSize); 2710 if (buf) 2711 { 2712 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS, 2713 exts[i].encoded, exts[i].encoded[1] + 2, 0, NULL, buf, &bufSize); 2714 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 2715 HeapFree(GetProcessHeap(), 0, buf); 2716 } 2717 } 2718 } 2719 2720 /* MS encodes public key info with a NULL if the algorithm identifier's 2721 * parameters are empty. However, when encoding an algorithm in a CERT_INFO, 2722 * it encodes them by omitting the algorithm parameters. It accepts either 2723 * form for decoding. 2724 */ 2725 struct encodedPublicKey 2726 { 2727 CERT_PUBLIC_KEY_INFO info; 2728 const BYTE *encoded; 2729 const BYTE *encodedNoNull; 2730 CERT_PUBLIC_KEY_INFO decoded; 2731 }; 2732 2733 static const BYTE aKey[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 2734 0xe, 0xf }; 2735 static const BYTE params[] = { 0x02, 0x01, 0x01 }; 2736 2737 static const unsigned char bin64[] = { 2738 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00}; 2739 static const unsigned char bin65[] = { 2740 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00}; 2741 static const unsigned char bin66[] = { 2742 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00}; 2743 static const unsigned char bin67[] = { 2744 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00}; 2745 static const unsigned char bin68[] = { 2746 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01, 2747 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; 2748 static const unsigned char bin69[] = { 2749 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01, 2750 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; 2751 static const unsigned char bin70[] = { 2752 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01, 2753 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e, 2754 0x0f}; 2755 static const unsigned char bin71[] = { 2756 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01, 2757 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e, 2758 0x0f}; 2759 static unsigned char bin72[] = { 0x05,0x00}; 2760 2761 static CHAR oid_bogus[] = "1.2.3", 2762 oid_rsa[] = szOID_RSA; 2763 2764 static const struct encodedPublicKey pubKeys[] = { 2765 /* with a bogus OID */ 2766 { { { oid_bogus, { 0, NULL } }, { 0, NULL, 0 } }, 2767 bin64, bin65, 2768 { { oid_bogus, { 2, bin72 } }, { 0, NULL, 0 } } }, 2769 /* some normal keys */ 2770 { { { oid_rsa, { 0, NULL } }, { 0, NULL, 0} }, 2771 bin66, bin67, 2772 { { oid_rsa, { 2, bin72 } }, { 0, NULL, 0 } } }, 2773 { { { oid_rsa, { 0, NULL } }, { sizeof(aKey), (BYTE *)aKey, 0} }, 2774 bin68, bin69, 2775 { { oid_rsa, { 2, bin72 } }, { sizeof(aKey), (BYTE *)aKey, 0} } }, 2776 /* with add'l parameters--note they must be DER-encoded */ 2777 { { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey), 2778 (BYTE *)aKey, 0 } }, 2779 bin70, bin71, 2780 { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey), 2781 (BYTE *)aKey, 0 } } }, 2782 }; 2783 2784 static void test_encodePublicKeyInfo(DWORD dwEncoding) 2785 { 2786 DWORD i; 2787 2788 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++) 2789 { 2790 BOOL ret; 2791 BYTE *buf = NULL; 2792 DWORD bufSize = 0; 2793 2794 ret = pCryptEncodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO, 2795 &pubKeys[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, 2796 &bufSize); 2797 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */, 2798 "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 2799 if (ret) 2800 { 2801 ok(bufSize == pubKeys[i].encoded[1] + 2, 2802 "Expected %d bytes, got %d\n", pubKeys[i].encoded[1] + 2, bufSize); 2803 if (bufSize == pubKeys[i].encoded[1] + 2) 2804 ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2), 2805 "Unexpected value\n"); 2806 LocalFree(buf); 2807 } 2808 } 2809 } 2810 2811 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO *expected, 2812 const CERT_PUBLIC_KEY_INFO *got) 2813 { 2814 ok(!strcmp(expected->Algorithm.pszObjId, got->Algorithm.pszObjId), 2815 "Expected OID %s, got %s\n", expected->Algorithm.pszObjId, 2816 got->Algorithm.pszObjId); 2817 ok(expected->Algorithm.Parameters.cbData == 2818 got->Algorithm.Parameters.cbData, 2819 "Expected parameters of %d bytes, got %d\n", 2820 expected->Algorithm.Parameters.cbData, got->Algorithm.Parameters.cbData); 2821 if (expected->Algorithm.Parameters.cbData) 2822 ok(!memcmp(expected->Algorithm.Parameters.pbData, 2823 got->Algorithm.Parameters.pbData, got->Algorithm.Parameters.cbData), 2824 "Unexpected algorithm parameters\n"); 2825 ok(expected->PublicKey.cbData == got->PublicKey.cbData, 2826 "Expected public key of %d bytes, got %d\n", 2827 expected->PublicKey.cbData, got->PublicKey.cbData); 2828 if (expected->PublicKey.cbData) 2829 ok(!memcmp(expected->PublicKey.pbData, got->PublicKey.pbData, 2830 got->PublicKey.cbData), "Unexpected public key value\n"); 2831 } 2832 2833 static void test_decodePublicKeyInfo(DWORD dwEncoding) 2834 { 2835 static const BYTE bogusPubKeyInfo[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06, 2836 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 2837 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 2838 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; 2839 DWORD i; 2840 BOOL ret; 2841 BYTE *buf = NULL; 2842 DWORD bufSize = 0; 2843 2844 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++) 2845 { 2846 /* The NULL form decodes to the decoded member */ 2847 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO, 2848 pubKeys[i].encoded, pubKeys[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, 2849 NULL, &buf, &bufSize); 2850 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 2851 if (ret) 2852 { 2853 comparePublicKeyInfo(&pubKeys[i].decoded, 2854 (CERT_PUBLIC_KEY_INFO *)buf); 2855 LocalFree(buf); 2856 } 2857 /* The non-NULL form decodes to the original */ 2858 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO, 2859 pubKeys[i].encodedNoNull, pubKeys[i].encodedNoNull[1] + 2, 2860 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2861 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 2862 if (ret) 2863 { 2864 comparePublicKeyInfo(&pubKeys[i].info, (CERT_PUBLIC_KEY_INFO *)buf); 2865 LocalFree(buf); 2866 } 2867 } 2868 /* Test with bogus (not valid DER) parameters */ 2869 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO, 2870 bogusPubKeyInfo, bogusPubKeyInfo[1] + 2, CRYPT_DECODE_ALLOC_FLAG, 2871 NULL, &buf, &bufSize); 2872 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT || 2873 GetLastError() == OSS_DATA_ERROR /* Win9x */), 2874 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n", 2875 GetLastError()); 2876 } 2877 2878 static const BYTE v1Cert[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00, 2879 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 2880 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 2881 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30, 2882 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 }; 2883 static const BYTE v2Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02, 2884 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 2885 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 2886 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 2887 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 }; 2888 static const BYTE v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 2889 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 2890 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 2891 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 2892 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 }; 2893 static const BYTE v4Cert[] = { 2894 0x30,0x38,0xa0,0x03,0x02,0x01,0x03,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22, 2895 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, 2896 0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30, 2897 0x30,0x30,0x30,0x5a,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00 }; 2898 static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30, 2899 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 2900 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 2901 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 2902 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 2903 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 2904 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 }; 2905 static const BYTE v1CertWithSerial[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30, 2906 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 2907 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 2908 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 2909 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 2910 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 2911 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 }; 2912 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 2913 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 2914 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 2915 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 2916 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 2917 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 2918 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 2919 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 2920 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 2921 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 }; 2922 static const BYTE v1CertWithPubKey[] = { 2923 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30, 2924 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61, 2925 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31, 2926 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, 2927 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11, 2928 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 2929 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 2930 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 2931 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06, 2932 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02, 2933 0x01,0x01 }; 2934 static const BYTE v1CertWithPubKeyNoNull[] = { 2935 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30, 2936 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61, 2937 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31, 2938 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, 2939 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11, 2940 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 2941 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 2942 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09, 2943 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55, 2944 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 }; 2945 static const BYTE v1CertWithSubjectKeyId[] = { 2946 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11, 2947 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 2948 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30, 2949 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30, 2950 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06, 2951 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67, 2952 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30, 2953 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20, 2954 0x4c,0x61,0x6e,0x67,0x00 }; 2955 static const BYTE v1CertWithIssuerUniqueId[] = { 2956 0x30,0x38,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36, 2957 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f, 2958 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a, 2959 0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x81,0x02,0x00,0x01 }; 2960 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueId[] = { 2961 0x30,0x81,0x99,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30, 2962 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61, 2963 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31, 2964 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, 2965 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11, 2966 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 2967 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 2968 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 2969 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30, 2970 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06, 2971 0x01,0x01,0xff,0x02,0x01,0x01 }; 2972 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull[] = { 2973 0x30,0x81,0x97,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30, 2974 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61, 2975 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31, 2976 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, 2977 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11, 2978 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 2979 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 2980 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09, 2981 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,0x14,0x30, 2982 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01, 2983 0xff,0x02,0x01,0x01 }; 2984 2985 static const BYTE serialNum[] = { 0x01 }; 2986 2987 static void test_encodeCertToBeSigned(DWORD dwEncoding) 2988 { 2989 BOOL ret; 2990 BYTE *buf = NULL; 2991 DWORD size = 0; 2992 CERT_INFO info = { 0 }; 2993 static char oid_rsa_rsa[] = szOID_RSA_RSA; 2994 static char oid_subject_key_identifier[] = szOID_SUBJECT_KEY_IDENTIFIER; 2995 CERT_EXTENSION ext; 2996 2997 if (0) 2998 { 2999 /* Test with NULL pvStructInfo (crashes on win9x) */ 3000 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 3001 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3002 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 3003 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError()); 3004 } 3005 /* Test with a V1 cert */ 3006 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, 3007 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3008 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */, 3009 "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3010 if (ret) 3011 { 3012 ok(size == v1Cert[1] + 2, "Expected size %d, got %d\n", 3013 v1Cert[1] + 2, size); 3014 ok(!memcmp(buf, v1Cert, size), "Got unexpected value\n"); 3015 LocalFree(buf); 3016 } 3017 /* Test v2 cert */ 3018 info.dwVersion = CERT_V2; 3019 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, 3020 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3021 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */, 3022 "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3023 if (ret) 3024 { 3025 ok(size == sizeof(v2Cert), "Wrong size %d\n", size); 3026 ok(!memcmp(buf, v2Cert, size), "Got unexpected value\n"); 3027 LocalFree(buf); 3028 } 3029 /* Test v3 cert */ 3030 info.dwVersion = CERT_V3; 3031 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, 3032 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3033 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */, 3034 "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3035 if (ret) 3036 { 3037 ok(size == sizeof(v3Cert), "Wrong size %d\n", size); 3038 ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n"); 3039 LocalFree(buf); 3040 } 3041 /* A v4 cert? */ 3042 info.dwVersion = 3; /* Not a typo, CERT_V3 is 2 */ 3043 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, 3044 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3045 if (ret) 3046 { 3047 ok(size == sizeof(v4Cert), "Wrong size %d\n", size); 3048 ok(!memcmp(buf, v4Cert, size), "Unexpected value\n"); 3049 LocalFree(buf); 3050 } 3051 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but 3052 * API doesn't prevent it) 3053 */ 3054 info.dwVersion = CERT_V1; 3055 info.cExtension = 1; 3056 info.rgExtension = &criticalExt; 3057 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, 3058 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3059 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */, 3060 "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3061 if (ret) 3062 { 3063 ok(size == sizeof(v1CertWithConstraints), "Wrong size %d\n", size); 3064 ok(!memcmp(buf, v1CertWithConstraints, size), "Got unexpected value\n"); 3065 LocalFree(buf); 3066 } 3067 /* test v1 cert with a serial number */ 3068 info.SerialNumber.cbData = sizeof(serialNum); 3069 info.SerialNumber.pbData = (BYTE *)serialNum; 3070 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, 3071 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3072 if (ret) 3073 { 3074 ok(size == sizeof(v1CertWithSerial), "Wrong size %d\n", size); 3075 ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n"); 3076 LocalFree(buf); 3077 } 3078 /* Test v1 cert with an issuer name, serial number, and issuer unique id */ 3079 info.dwVersion = CERT_V1; 3080 info.cExtension = 0; 3081 info.IssuerUniqueId.cbData = sizeof(serialNum); 3082 info.IssuerUniqueId.pbData = (BYTE *)serialNum; 3083 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, 3084 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3085 ok(ret || broken(GetLastError() == OSS_BAD_PTR /* Win98 */), 3086 "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3087 if (ret) 3088 { 3089 ok(size == sizeof(v1CertWithIssuerUniqueId), "Wrong size %d\n", size); 3090 ok(!memcmp(buf, v1CertWithIssuerUniqueId, size), 3091 "Got unexpected value\n"); 3092 LocalFree(buf); 3093 } 3094 /* Test v1 cert with an issuer name, a subject name, and a serial number */ 3095 info.IssuerUniqueId.cbData = 0; 3096 info.IssuerUniqueId.pbData = NULL; 3097 info.cExtension = 1; 3098 info.rgExtension = &criticalExt; 3099 info.Issuer.cbData = sizeof(encodedCommonName); 3100 info.Issuer.pbData = (BYTE *)encodedCommonName; 3101 info.Subject.cbData = sizeof(encodedCommonName); 3102 info.Subject.pbData = (BYTE *)encodedCommonName; 3103 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, 3104 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3105 if (ret) 3106 { 3107 ok(size == sizeof(bigCert), "Wrong size %d\n", size); 3108 ok(!memcmp(buf, bigCert, size), "Got unexpected value\n"); 3109 LocalFree(buf); 3110 } 3111 /* Add a public key */ 3112 info.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa; 3113 info.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey); 3114 info.SubjectPublicKeyInfo.PublicKey.pbData = (LPBYTE)aKey; 3115 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, 3116 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3117 if (ret) 3118 { 3119 ok(size == sizeof(v1CertWithPubKey) || 3120 size == sizeof(v1CertWithPubKeyNoNull), "Wrong size %d\n", size); 3121 if (size == sizeof(v1CertWithPubKey)) 3122 ok(!memcmp(buf, v1CertWithPubKey, size), "Got unexpected value\n"); 3123 else if (size == sizeof(v1CertWithPubKeyNoNull)) 3124 ok(!memcmp(buf, v1CertWithPubKeyNoNull, size), 3125 "Got unexpected value\n"); 3126 LocalFree(buf); 3127 } 3128 /* Again add an issuer unique id */ 3129 info.IssuerUniqueId.cbData = sizeof(serialNum); 3130 info.IssuerUniqueId.pbData = (BYTE *)serialNum; 3131 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, 3132 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3133 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3134 if (ret) 3135 { 3136 ok(size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId) || 3137 size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull), 3138 "Wrong size %d\n", size); 3139 if (size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId)) 3140 ok(!memcmp(buf, v1CertWithSubjectIssuerSerialAndIssuerUniqueId, 3141 size), "unexpected value\n"); 3142 else if (size == 3143 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull)) 3144 ok(!memcmp(buf, 3145 v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull, size), 3146 "unexpected value\n"); 3147 LocalFree(buf); 3148 } 3149 /* Remove the public key, and add a subject key identifier extension */ 3150 info.IssuerUniqueId.cbData = 0; 3151 info.IssuerUniqueId.pbData = NULL; 3152 info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL; 3153 info.SubjectPublicKeyInfo.PublicKey.cbData = 0; 3154 info.SubjectPublicKeyInfo.PublicKey.pbData = NULL; 3155 ext.pszObjId = oid_subject_key_identifier; 3156 ext.fCritical = FALSE; 3157 ext.Value.cbData = sizeof(octetCommonNameValue); 3158 ext.Value.pbData = octetCommonNameValue; 3159 info.cExtension = 1; 3160 info.rgExtension = &ext; 3161 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, 3162 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3163 if (ret) 3164 { 3165 ok(size == sizeof(v1CertWithSubjectKeyId), "Wrong size %d\n", size); 3166 ok(!memcmp(buf, v1CertWithSubjectKeyId, size), "Unexpected value\n"); 3167 LocalFree(buf); 3168 } 3169 } 3170 3171 static void test_decodeCertToBeSigned(DWORD dwEncoding) 3172 { 3173 static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert, v4Cert, 3174 v1CertWithConstraints, v1CertWithSerial, v1CertWithIssuerUniqueId }; 3175 BOOL ret; 3176 BYTE *buf = NULL; 3177 DWORD size = 0, i; 3178 3179 /* Test with NULL pbEncoded */ 3180 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 0, 3181 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 3182 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD || 3183 GetLastError() == OSS_BAD_ARG /* Win9x */), 3184 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError()); 3185 if (0) 3186 { 3187 /* Crashes on win9x */ 3188 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 1, 3189 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 3190 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 3191 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError()); 3192 } 3193 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT or 3194 * CRYPT_E_ASN1_BADTAG, because at a minimum a cert must have a non-zero 3195 * serial number, an issuer, a subject, and a public key. 3196 */ 3197 for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++) 3198 { 3199 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, 3200 corruptCerts[i], corruptCerts[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, 3201 &buf, &size); 3202 ok(!ret, "Expected failure\n"); 3203 } 3204 /* The following succeeds, even though v1 certs are not allowed to have 3205 * extensions. 3206 */ 3207 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, 3208 v1CertWithSubjectKeyId, sizeof(v1CertWithSubjectKeyId), 3209 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 3210 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3211 if (ret) 3212 { 3213 CERT_INFO *info = (CERT_INFO *)buf; 3214 3215 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size); 3216 ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %d\n", 3217 info->dwVersion); 3218 ok(info->cExtension == 1, "expected 1 extension, got %d\n", 3219 info->cExtension); 3220 LocalFree(buf); 3221 } 3222 /* The following also succeeds, even though V1 certs are not allowed to 3223 * have issuer unique ids. 3224 */ 3225 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, 3226 v1CertWithSubjectIssuerSerialAndIssuerUniqueId, 3227 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId), 3228 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 3229 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3230 if (ret) 3231 { 3232 CERT_INFO *info = (CERT_INFO *)buf; 3233 3234 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size); 3235 ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %d\n", 3236 info->dwVersion); 3237 ok(info->IssuerUniqueId.cbData == sizeof(serialNum), 3238 "unexpected issuer unique id size %d\n", info->IssuerUniqueId.cbData); 3239 ok(!memcmp(info->IssuerUniqueId.pbData, serialNum, sizeof(serialNum)), 3240 "unexpected issuer unique id value\n"); 3241 LocalFree(buf); 3242 } 3243 /* Now check with serial number, subject and issuer specified */ 3244 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert, 3245 sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 3246 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3247 if (ret) 3248 { 3249 CERT_INFO *info = (CERT_INFO *)buf; 3250 3251 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size); 3252 ok(info->SerialNumber.cbData == 1, 3253 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData); 3254 ok(*info->SerialNumber.pbData == *serialNum, 3255 "Expected serial number %d, got %d\n", *serialNum, 3256 *info->SerialNumber.pbData); 3257 ok(info->Issuer.cbData == sizeof(encodedCommonName), 3258 "Wrong size %d\n", info->Issuer.cbData); 3259 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData), 3260 "Unexpected issuer\n"); 3261 ok(info->Subject.cbData == sizeof(encodedCommonName), 3262 "Wrong size %d\n", info->Subject.cbData); 3263 ok(!memcmp(info->Subject.pbData, encodedCommonName, 3264 info->Subject.cbData), "Unexpected subject\n"); 3265 LocalFree(buf); 3266 } 3267 /* Check again with pub key specified */ 3268 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, 3269 v1CertWithPubKey, sizeof(v1CertWithPubKey), CRYPT_DECODE_ALLOC_FLAG, NULL, 3270 &buf, &size); 3271 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3272 if (ret) 3273 { 3274 CERT_INFO *info = (CERT_INFO *)buf; 3275 3276 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size); 3277 ok(info->SerialNumber.cbData == 1, 3278 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData); 3279 ok(*info->SerialNumber.pbData == *serialNum, 3280 "Expected serial number %d, got %d\n", *serialNum, 3281 *info->SerialNumber.pbData); 3282 ok(info->Issuer.cbData == sizeof(encodedCommonName), 3283 "Wrong size %d\n", info->Issuer.cbData); 3284 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData), 3285 "Unexpected issuer\n"); 3286 ok(info->Subject.cbData == sizeof(encodedCommonName), 3287 "Wrong size %d\n", info->Subject.cbData); 3288 ok(!memcmp(info->Subject.pbData, encodedCommonName, 3289 info->Subject.cbData), "Unexpected subject\n"); 3290 ok(!strcmp(info->SubjectPublicKeyInfo.Algorithm.pszObjId, 3291 szOID_RSA_RSA), "Expected szOID_RSA_RSA, got %s\n", 3292 info->SubjectPublicKeyInfo.Algorithm.pszObjId); 3293 ok(info->SubjectPublicKeyInfo.PublicKey.cbData == sizeof(aKey), 3294 "Wrong size %d\n", info->SubjectPublicKeyInfo.PublicKey.cbData); 3295 ok(!memcmp(info->SubjectPublicKeyInfo.PublicKey.pbData, aKey, 3296 sizeof(aKey)), "Unexpected public key\n"); 3297 LocalFree(buf); 3298 } 3299 } 3300 3301 static const BYTE hash[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 3302 0xe, 0xf }; 3303 3304 static const BYTE signedBigCert[] = { 3305 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30, 3306 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 3307 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f, 3308 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 3309 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 3310 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 3311 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 3312 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 3313 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 3314 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 3315 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 3316 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 }; 3317 3318 static void test_encodeCert(DWORD dwEncoding) 3319 { 3320 /* Note the SignatureAlgorithm must match that in the encoded cert. Note 3321 * also that bigCert is a NULL-terminated string, so don't count its 3322 * last byte (otherwise the signed cert won't decode.) 3323 */ 3324 CERT_SIGNED_CONTENT_INFO info = { { sizeof(bigCert), (BYTE *)bigCert }, 3325 { NULL, { 0, NULL } }, { sizeof(hash), (BYTE *)hash, 0 } }; 3326 BOOL ret; 3327 BYTE *buf = NULL; 3328 DWORD bufSize = 0; 3329 3330 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT, &info, 3331 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 3332 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3333 if (ret) 3334 { 3335 ok(bufSize == sizeof(signedBigCert), "Wrong size %d\n", bufSize); 3336 ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n"); 3337 LocalFree(buf); 3338 } 3339 } 3340 3341 static void test_decodeCert(DWORD dwEncoding) 3342 { 3343 BOOL ret; 3344 BYTE *buf = NULL; 3345 DWORD size = 0; 3346 3347 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert, 3348 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 3349 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3350 if (ret) 3351 { 3352 CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf; 3353 3354 ok(info->ToBeSigned.cbData == sizeof(bigCert), 3355 "Wrong cert size %d\n", info->ToBeSigned.cbData); 3356 ok(!memcmp(info->ToBeSigned.pbData, bigCert, info->ToBeSigned.cbData), 3357 "Unexpected cert\n"); 3358 ok(info->Signature.cbData == sizeof(hash), 3359 "Wrong signature size %d\n", info->Signature.cbData); 3360 ok(!memcmp(info->Signature.pbData, hash, info->Signature.cbData), 3361 "Unexpected signature\n"); 3362 LocalFree(buf); 3363 } 3364 /* A signed cert decodes as a CERT_INFO too */ 3365 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCert, 3366 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 3367 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3368 if (ret) 3369 { 3370 CERT_INFO *info = (CERT_INFO *)buf; 3371 3372 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size); 3373 ok(info->SerialNumber.cbData == 1, 3374 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData); 3375 ok(*info->SerialNumber.pbData == *serialNum, 3376 "Expected serial number %d, got %d\n", *serialNum, 3377 *info->SerialNumber.pbData); 3378 ok(info->Issuer.cbData == sizeof(encodedCommonName), 3379 "Wrong size %d\n", info->Issuer.cbData); 3380 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData), 3381 "Unexpected issuer\n"); 3382 ok(info->Subject.cbData == sizeof(encodedCommonName), 3383 "Wrong size %d\n", info->Subject.cbData); 3384 ok(!memcmp(info->Subject.pbData, encodedCommonName, 3385 info->Subject.cbData), "Unexpected subject\n"); 3386 LocalFree(buf); 3387 } 3388 } 3389 3390 static const BYTE emptyDistPoint[] = { 0x30, 0x02, 0x30, 0x00 }; 3391 static const BYTE distPointWithUrl[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15, 3392 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 3393 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 }; 3394 static const BYTE distPointWithReason[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02, 3395 0x00, 0x03 }; 3396 static const BYTE distPointWithIssuer[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13, 3397 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 3398 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 }; 3399 static const BYTE distPointWithUrlAndIssuer[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0, 3400 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 3401 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11, 3402 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 3403 0x2e, 0x6f, 0x72, 0x67 }; 3404 static const BYTE crlReason = CRL_REASON_KEY_COMPROMISE | 3405 CRL_REASON_AFFILIATION_CHANGED; 3406 3407 static void test_encodeCRLDistPoints(DWORD dwEncoding) 3408 { 3409 CRL_DIST_POINTS_INFO info = { 0 }; 3410 CRL_DIST_POINT point = { { 0 } }; 3411 CERT_ALT_NAME_ENTRY entry = { 0 }; 3412 BOOL ret; 3413 BYTE *buf = NULL; 3414 DWORD size = 0; 3415 3416 /* Test with an empty info */ 3417 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info, 3418 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3419 ok(!ret && GetLastError() == E_INVALIDARG, 3420 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 3421 /* Test with one empty dist point */ 3422 info.cDistPoint = 1; 3423 info.rgDistPoint = &point; 3424 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info, 3425 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3426 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3427 if (ret) 3428 { 3429 ok(size == sizeof(emptyDistPoint), "Wrong size %d\n", size); 3430 ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n"); 3431 LocalFree(buf); 3432 } 3433 /* A dist point with an invalid name */ 3434 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME; 3435 entry.dwAltNameChoice = CERT_ALT_NAME_URL; 3436 U(entry).pwszURL = (LPWSTR)nihongoURL; 3437 U(point.DistPointName).FullName.cAltEntry = 1; 3438 U(point.DistPointName).FullName.rgAltEntry = &entry; 3439 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info, 3440 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3441 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING, 3442 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError()); 3443 /* The first invalid character is at index 7 */ 3444 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7, 3445 "Expected invalid char at index 7, got %d\n", 3446 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size)); 3447 /* A dist point with (just) a valid name */ 3448 U(entry).pwszURL = (LPWSTR)url; 3449 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info, 3450 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3451 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3452 if (ret) 3453 { 3454 ok(size == sizeof(distPointWithUrl), "Wrong size %d\n", size); 3455 ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n"); 3456 LocalFree(buf); 3457 } 3458 /* A dist point with (just) reason flags */ 3459 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME; 3460 point.ReasonFlags.cbData = sizeof(crlReason); 3461 point.ReasonFlags.pbData = (LPBYTE)&crlReason; 3462 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info, 3463 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3464 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3465 if (ret) 3466 { 3467 ok(size == sizeof(distPointWithReason), "Wrong size %d\n", size); 3468 ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n"); 3469 LocalFree(buf); 3470 } 3471 /* A dist point with just an issuer */ 3472 point.ReasonFlags.cbData = 0; 3473 point.CRLIssuer.cAltEntry = 1; 3474 point.CRLIssuer.rgAltEntry = &entry; 3475 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info, 3476 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3477 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3478 if (ret) 3479 { 3480 ok(size == sizeof(distPointWithIssuer), "Wrong size %d\n", size); 3481 ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n"); 3482 LocalFree(buf); 3483 } 3484 /* A dist point with both a name and an issuer */ 3485 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME; 3486 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info, 3487 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3488 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3489 if (ret) 3490 { 3491 ok(size == sizeof(distPointWithUrlAndIssuer), 3492 "Wrong size %d\n", size); 3493 ok(!memcmp(buf, distPointWithUrlAndIssuer, size), "Unexpected value\n"); 3494 LocalFree(buf); 3495 } 3496 } 3497 3498 static void test_decodeCRLDistPoints(DWORD dwEncoding) 3499 { 3500 BOOL ret; 3501 BYTE *buf = NULL; 3502 DWORD size = 0; 3503 PCRL_DIST_POINTS_INFO info; 3504 PCRL_DIST_POINT point; 3505 PCERT_ALT_NAME_ENTRY entry; 3506 3507 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, 3508 emptyDistPoint, emptyDistPoint[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, 3509 &buf, &size); 3510 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3511 if (ret) 3512 { 3513 info = (PCRL_DIST_POINTS_INFO)buf; 3514 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT), 3515 "Wrong size %d\n", size); 3516 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n", 3517 info->cDistPoint); 3518 point = info->rgDistPoint; 3519 ok(point->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_NO_NAME, 3520 "Expected CRL_DIST_POINT_NO_NAME, got %d\n", 3521 point->DistPointName.dwDistPointNameChoice); 3522 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n"); 3523 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n"); 3524 LocalFree(buf); 3525 } 3526 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, 3527 distPointWithUrl, distPointWithUrl[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, 3528 &buf, &size); 3529 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3530 if (ret) 3531 { 3532 info = (PCRL_DIST_POINTS_INFO)buf; 3533 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT), 3534 "Wrong size %d\n", size); 3535 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n", 3536 info->cDistPoint); 3537 point = info->rgDistPoint; 3538 ok(point->DistPointName.dwDistPointNameChoice == 3539 CRL_DIST_POINT_FULL_NAME, 3540 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n", 3541 point->DistPointName.dwDistPointNameChoice); 3542 ok(U(point->DistPointName).FullName.cAltEntry == 1, 3543 "Expected 1 name entry, got %d\n", 3544 U(point->DistPointName).FullName.cAltEntry); 3545 entry = U(point->DistPointName).FullName.rgAltEntry; 3546 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL, 3547 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice); 3548 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n"); 3549 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n"); 3550 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n"); 3551 LocalFree(buf); 3552 } 3553 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, 3554 distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG, 3555 NULL, &buf, &size); 3556 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3557 if (ret) 3558 { 3559 info = (PCRL_DIST_POINTS_INFO)buf; 3560 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT), 3561 "Wrong size %d\n", size); 3562 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n", 3563 info->cDistPoint); 3564 point = info->rgDistPoint; 3565 ok(point->DistPointName.dwDistPointNameChoice == 3566 CRL_DIST_POINT_NO_NAME, 3567 "Expected CRL_DIST_POINT_NO_NAME, got %d\n", 3568 point->DistPointName.dwDistPointNameChoice); 3569 ok(point->ReasonFlags.cbData == sizeof(crlReason), 3570 "Expected reason length\n"); 3571 ok(!memcmp(point->ReasonFlags.pbData, &crlReason, sizeof(crlReason)), 3572 "Unexpected reason\n"); 3573 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n"); 3574 LocalFree(buf); 3575 } 3576 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, 3577 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2, 3578 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 3579 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3580 if (ret) 3581 { 3582 info = (PCRL_DIST_POINTS_INFO)buf; 3583 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT), 3584 "Wrong size %d\n", size); 3585 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n", 3586 info->cDistPoint); 3587 point = info->rgDistPoint; 3588 ok(point->DistPointName.dwDistPointNameChoice == 3589 CRL_DIST_POINT_FULL_NAME, 3590 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n", 3591 point->DistPointName.dwDistPointNameChoice); 3592 ok(U(point->DistPointName).FullName.cAltEntry == 1, 3593 "Expected 1 name entry, got %d\n", 3594 U(point->DistPointName).FullName.cAltEntry); 3595 entry = U(point->DistPointName).FullName.rgAltEntry; 3596 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL, 3597 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice); 3598 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n"); 3599 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n"); 3600 ok(point->CRLIssuer.cAltEntry == 1, 3601 "Expected 1 issuer entry, got %d\n", point->CRLIssuer.cAltEntry); 3602 entry = point->CRLIssuer.rgAltEntry; 3603 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL, 3604 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice); 3605 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n"); 3606 LocalFree(buf); 3607 } 3608 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, 3609 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2, 0, 3610 NULL, NULL, &size); 3611 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3612 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); 3613 if (buf) 3614 { 3615 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, 3616 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2, 0, 3617 NULL, buf, &size); 3618 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3619 HeapFree(GetProcessHeap(), 0, buf); 3620 } 3621 } 3622 3623 static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff }; 3624 static const BYTE emptyNameIDP[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 }; 3625 static const BYTE urlIDP[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68, 3626 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72, 3627 0x67 }; 3628 3629 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding) 3630 { 3631 BOOL ret; 3632 BYTE *buf = NULL; 3633 DWORD size = 0; 3634 CRL_ISSUING_DIST_POINT point = { { 0 } }; 3635 CERT_ALT_NAME_ENTRY entry; 3636 3637 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, NULL, 3638 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3639 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 3640 { 3641 skip("no X509_ISSUING_DIST_POINT encode support\n"); 3642 return; 3643 } 3644 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 3645 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError()); 3646 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point, 3647 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3648 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3649 if (ret) 3650 { 3651 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size); 3652 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n"); 3653 LocalFree(buf); 3654 } 3655 /* nonsensical flags */ 3656 point.fOnlyContainsUserCerts = TRUE; 3657 point.fOnlyContainsCACerts = TRUE; 3658 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point, 3659 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3660 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3661 if (ret) 3662 { 3663 ok(size == sizeof(badFlagsIDP), "Unexpected size %d\n", size); 3664 ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n"); 3665 LocalFree(buf); 3666 } 3667 /* unimplemented name type */ 3668 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE; 3669 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_ISSUER_RDN_NAME; 3670 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point, 3671 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3672 ok(!ret && GetLastError() == E_INVALIDARG, 3673 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 3674 /* empty name */ 3675 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME; 3676 U(point.DistPointName).FullName.cAltEntry = 0; 3677 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point, 3678 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3679 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3680 if (ret) 3681 { 3682 ok(size == sizeof(emptyNameIDP), "Unexpected size %d\n", size); 3683 ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n"); 3684 LocalFree(buf); 3685 } 3686 /* name with URL entry */ 3687 entry.dwAltNameChoice = CERT_ALT_NAME_URL; 3688 U(entry).pwszURL = (LPWSTR)url; 3689 U(point.DistPointName).FullName.cAltEntry = 1; 3690 U(point.DistPointName).FullName.rgAltEntry = &entry; 3691 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point, 3692 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3693 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3694 if (ret) 3695 { 3696 ok(size == sizeof(urlIDP), "Unexpected size %d\n", size); 3697 ok(!memcmp(buf, urlIDP, size), "Unexpected value\n"); 3698 LocalFree(buf); 3699 } 3700 } 3701 3702 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY *expected, 3703 const CERT_ALT_NAME_ENTRY *got) 3704 { 3705 ok(expected->dwAltNameChoice == got->dwAltNameChoice, 3706 "Expected name choice %d, got %d\n", expected->dwAltNameChoice, 3707 got->dwAltNameChoice); 3708 if (expected->dwAltNameChoice == got->dwAltNameChoice) 3709 { 3710 switch (got->dwAltNameChoice) 3711 { 3712 case CERT_ALT_NAME_RFC822_NAME: 3713 case CERT_ALT_NAME_DNS_NAME: 3714 case CERT_ALT_NAME_EDI_PARTY_NAME: 3715 case CERT_ALT_NAME_URL: 3716 case CERT_ALT_NAME_REGISTERED_ID: 3717 ok((!U(*expected).pwszURL && !U(*got).pwszURL) || 3718 (!U(*expected).pwszURL && !lstrlenW(U(*got).pwszURL)) || 3719 (!U(*got).pwszURL && !lstrlenW(U(*expected).pwszURL)) || 3720 !lstrcmpW(U(*expected).pwszURL, U(*got).pwszURL), 3721 "Unexpected name\n"); 3722 break; 3723 case CERT_ALT_NAME_X400_ADDRESS: 3724 case CERT_ALT_NAME_DIRECTORY_NAME: 3725 case CERT_ALT_NAME_IP_ADDRESS: 3726 ok(U(*got).IPAddress.cbData == U(*expected).IPAddress.cbData, 3727 "Unexpected IP address length %d\n", U(*got).IPAddress.cbData); 3728 ok(!memcmp(U(*got).IPAddress.pbData, U(*expected).IPAddress.pbData, 3729 U(*got).IPAddress.cbData), "Unexpected value\n"); 3730 break; 3731 } 3732 } 3733 } 3734 3735 static void compareAltNameInfo(const CERT_ALT_NAME_INFO *expected, 3736 const CERT_ALT_NAME_INFO *got) 3737 { 3738 DWORD i; 3739 3740 ok(expected->cAltEntry == got->cAltEntry, "Expected %d entries, got %d\n", 3741 expected->cAltEntry, got->cAltEntry); 3742 for (i = 0; i < min(expected->cAltEntry, got->cAltEntry); i++) 3743 compareAltNameEntry(&expected->rgAltEntry[i], &got->rgAltEntry[i]); 3744 } 3745 3746 static void compareDistPointName(const CRL_DIST_POINT_NAME *expected, 3747 const CRL_DIST_POINT_NAME *got) 3748 { 3749 ok(got->dwDistPointNameChoice == expected->dwDistPointNameChoice, 3750 "Unexpected name choice %d\n", got->dwDistPointNameChoice); 3751 if (got->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME) 3752 compareAltNameInfo(&(U(*expected).FullName), &(U(*got).FullName)); 3753 } 3754 3755 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT *expected, 3756 const CRL_ISSUING_DIST_POINT *got) 3757 { 3758 compareDistPointName(&expected->DistPointName, &got->DistPointName); 3759 ok(got->fOnlyContainsUserCerts == expected->fOnlyContainsUserCerts, 3760 "Unexpected fOnlyContainsUserCerts\n"); 3761 ok(got->fOnlyContainsCACerts == expected->fOnlyContainsCACerts, 3762 "Unexpected fOnlyContainsCACerts\n"); 3763 ok(got->OnlySomeReasonFlags.cbData == expected->OnlySomeReasonFlags.cbData, 3764 "Unexpected reason flags\n"); 3765 ok(got->fIndirectCRL == expected->fIndirectCRL, 3766 "Unexpected fIndirectCRL\n"); 3767 } 3768 3769 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding) 3770 { 3771 BOOL ret; 3772 BYTE *buf = NULL; 3773 DWORD size = 0; 3774 CRL_ISSUING_DIST_POINT point = { { 0 } }; 3775 3776 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, 3777 emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, 3778 &buf, &size); 3779 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 3780 { 3781 skip("no X509_ISSUING_DIST_POINT decode support\n"); 3782 return; 3783 } 3784 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3785 if (ret) 3786 { 3787 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf); 3788 LocalFree(buf); 3789 } 3790 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, 3791 badFlagsIDP, badFlagsIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, 3792 &buf, &size); 3793 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3794 if (ret) 3795 { 3796 point.fOnlyContainsUserCerts = point.fOnlyContainsCACerts = TRUE; 3797 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf); 3798 LocalFree(buf); 3799 } 3800 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, 3801 emptyNameIDP, emptyNameIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, 3802 &buf, &size); 3803 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3804 if (ret) 3805 { 3806 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE; 3807 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME; 3808 U(point.DistPointName).FullName.cAltEntry = 0; 3809 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf); 3810 LocalFree(buf); 3811 } 3812 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, 3813 urlIDP, urlIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 3814 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3815 if (ret) 3816 { 3817 CERT_ALT_NAME_ENTRY entry; 3818 3819 entry.dwAltNameChoice = CERT_ALT_NAME_URL; 3820 U(entry).pwszURL = (LPWSTR)url; 3821 U(point.DistPointName).FullName.cAltEntry = 1; 3822 U(point.DistPointName).FullName.rgAltEntry = &entry; 3823 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf); 3824 LocalFree(buf); 3825 } 3826 } 3827 3828 static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f, 3829 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 3830 0x30, 0x5a }; 3831 static const BYTE v2CRL[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 3832 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 3833 0x30, 0x30, 0x30, 0x30, 0x5a }; 3834 static const BYTE v1CRLWithIssuer[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00, 3835 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 3836 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31, 3837 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 3838 0x5a }; 3839 static const BYTE v1CRLWithIssuerAndEmptyEntry[] = { 0x30, 0x43, 0x30, 0x02, 3840 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 3841 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 3842 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 3843 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36, 3844 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a }; 3845 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06, 3846 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 3847 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 3848 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 3849 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36, 3850 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a }; 3851 static const BYTE v1CRLWithEntryExt[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30, 3852 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61, 3853 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, 3854 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01, 3855 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30, 3856 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff, 3857 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 }; 3858 static const BYTE v1CRLWithExt[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15, 3859 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e, 3860 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30, 3861 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01, 3862 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, 3863 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01, 3864 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 }; 3865 static const BYTE v2CRLWithExt[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06, 3866 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a, 3867 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31, 3868 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14, 3869 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30, 3870 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d, 3871 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 }; 3872 3873 static void test_encodeCRLToBeSigned(DWORD dwEncoding) 3874 { 3875 BOOL ret; 3876 BYTE *buf = NULL; 3877 DWORD size = 0; 3878 CRL_INFO info = { 0 }; 3879 CRL_ENTRY entry = { { 0 }, { 0 }, 0, 0 }; 3880 3881 /* Test with a V1 CRL */ 3882 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info, 3883 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3884 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */), 3885 "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3886 if (ret) 3887 { 3888 ok(size == sizeof(v1CRL), "Wrong size %d\n", size); 3889 ok(!memcmp(buf, v1CRL, size), "Got unexpected value\n"); 3890 LocalFree(buf); 3891 } 3892 /* Test v2 CRL */ 3893 info.dwVersion = CRL_V2; 3894 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info, 3895 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3896 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */), 3897 "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3898 if (ret) 3899 { 3900 ok(size == v2CRL[1] + 2, "Expected size %d, got %d\n", 3901 v2CRL[1] + 2, size); 3902 ok(!memcmp(buf, v2CRL, size), "Got unexpected value\n"); 3903 LocalFree(buf); 3904 } 3905 /* v1 CRL with a name */ 3906 info.dwVersion = CRL_V1; 3907 info.Issuer.cbData = sizeof(encodedCommonName); 3908 info.Issuer.pbData = (BYTE *)encodedCommonName; 3909 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info, 3910 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3911 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3912 if (ret) 3913 { 3914 ok(size == sizeof(v1CRLWithIssuer), "Wrong size %d\n", size); 3915 ok(!memcmp(buf, v1CRLWithIssuer, size), "Got unexpected value\n"); 3916 LocalFree(buf); 3917 } 3918 if (0) 3919 { 3920 /* v1 CRL with a name and a NULL entry pointer (crashes on win9x) */ 3921 info.cCRLEntry = 1; 3922 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info, 3923 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3924 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 3925 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError()); 3926 } 3927 /* now set an empty entry */ 3928 info.cCRLEntry = 1; 3929 info.rgCRLEntry = &entry; 3930 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info, 3931 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3932 if (ret) 3933 { 3934 ok(size == sizeof(v1CRLWithIssuerAndEmptyEntry), 3935 "Wrong size %d\n", size); 3936 ok(!memcmp(buf, v1CRLWithIssuerAndEmptyEntry, size), 3937 "Got unexpected value\n"); 3938 LocalFree(buf); 3939 } 3940 /* an entry with a serial number */ 3941 entry.SerialNumber.cbData = sizeof(serialNum); 3942 entry.SerialNumber.pbData = (BYTE *)serialNum; 3943 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info, 3944 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3945 if (ret) 3946 { 3947 ok(size == sizeof(v1CRLWithIssuerAndEntry), 3948 "Wrong size %d\n", size); 3949 ok(!memcmp(buf, v1CRLWithIssuerAndEntry, size), 3950 "Got unexpected value\n"); 3951 LocalFree(buf); 3952 } 3953 /* an entry with an extension */ 3954 entry.cExtension = 1; 3955 entry.rgExtension = &criticalExt; 3956 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info, 3957 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3958 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3959 if (ret) 3960 { 3961 ok(size == sizeof(v1CRLWithEntryExt), "Wrong size %d\n", size); 3962 ok(!memcmp(buf, v1CRLWithEntryExt, size), "Got unexpected value\n"); 3963 LocalFree(buf); 3964 } 3965 /* a CRL with an extension */ 3966 entry.cExtension = 0; 3967 info.cExtension = 1; 3968 info.rgExtension = &criticalExt; 3969 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info, 3970 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3971 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3972 if (ret) 3973 { 3974 ok(size == sizeof(v1CRLWithExt), "Wrong size %d\n", size); 3975 ok(!memcmp(buf, v1CRLWithExt, size), "Got unexpected value\n"); 3976 LocalFree(buf); 3977 } 3978 /* a v2 CRL with an extension, this time non-critical */ 3979 info.dwVersion = CRL_V2; 3980 info.rgExtension = &nonCriticalExt; 3981 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info, 3982 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3983 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3984 if (ret) 3985 { 3986 ok(size == sizeof(v2CRLWithExt), "Wrong size %d\n", size); 3987 ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n"); 3988 LocalFree(buf); 3989 } 3990 } 3991 3992 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01, 3993 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 3994 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06, 3995 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 3996 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 3997 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 3998 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65, 3999 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72, 4000 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 4001 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43, 4002 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30, 4003 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33, 4004 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51, 4005 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99, 4006 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31, 4007 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0, 4008 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30, 4009 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30, 4010 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75, 4011 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33, 4012 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30, 4013 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06, 4014 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06, 4015 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03, 4016 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88, 4017 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd, 4018 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf, 4019 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46, 4020 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f, 4021 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75, 4022 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f, 4023 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82, 4024 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07, 4025 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c, 4026 0xcd }; 4027 static const BYTE verisignCRLWithLotsOfEntries[] = { 4028 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, 4029 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06, 4030 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31, 4031 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53, 4032 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03, 4033 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43, 4034 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77, 4035 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20, 4036 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30, 4037 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35, 4038 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3, 4039 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32, 4040 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10, 4041 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13, 4042 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38, 4043 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16, 4044 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31, 4045 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94, 4046 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32, 4047 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10, 4048 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67, 4049 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30, 4050 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87, 4051 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30, 4052 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f, 4053 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32, 4054 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10, 4055 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac, 4056 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31, 4057 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee, 4058 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31, 4059 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37, 4060 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32, 4061 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10, 4062 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c, 4063 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34, 4064 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11, 4065 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30, 4066 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5, 4067 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32, 4068 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10, 4069 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d, 4070 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39, 4071 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70, 4072 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30, 4073 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5, 4074 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33, 4075 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10, 4076 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39, 4077 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30, 4078 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98, 4079 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32, 4080 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4, 4081 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32, 4082 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10, 4083 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1, 4084 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32, 4085 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05, 4086 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31, 4087 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32, 4088 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32, 4089 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10, 4090 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7, 4091 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31, 4092 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79, 4093 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30, 4094 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4, 4095 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32, 4096 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10, 4097 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a, 4098 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35, 4099 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d, 4100 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31, 4101 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b, 4102 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32, 4103 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10, 4104 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40, 4105 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37, 4106 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6, 4107 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31, 4108 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28, 4109 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32, 4110 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10, 4111 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65, 4112 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39, 4113 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2, 4114 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32, 4115 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f, 4116 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32, 4117 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10, 4118 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21, 4119 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36, 4120 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33, 4121 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30, 4122 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2, 4123 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32, 4124 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10, 4125 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc, 4126 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33, 4127 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8, 4128 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31, 4129 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48, 4130 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32, 4131 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10, 4132 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40, 4133 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34, 4134 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54, 4135 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30, 4136 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6, 4137 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32, 4138 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10, 4139 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd, 4140 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32, 4141 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9, 4142 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31, 4143 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd, 4144 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32, 4145 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10, 4146 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5, 4147 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31, 4148 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb, 4149 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30, 4150 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5, 4151 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32, 4152 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10, 4153 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45, 4154 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32, 4155 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf, 4156 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35, 4157 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88, 4158 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30, 4159 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20, 4160 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92, 4161 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a, 4162 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45, 4163 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33, 4164 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9, 4165 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30, 4166 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22, 4167 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a, 4168 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a, 4169 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e, 4170 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30, 4171 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f, 4172 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30, 4173 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25, 4174 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0, 4175 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a, 4176 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84, 4177 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31, 4178 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec, 4179 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30, 4180 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27, 4181 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16, 4182 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a, 4183 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81, 4184 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31, 4185 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e, 4186 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30, 4187 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29, 4188 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59, 4189 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a, 4190 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9, 4191 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38, 4192 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3, 4193 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30, 4194 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a, 4195 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1, 4196 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a, 4197 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f, 4198 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30, 4199 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71, 4200 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30, 4201 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c, 4202 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85, 4203 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a, 4204 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b, 4205 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33, 4206 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92, 4207 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30, 4208 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d, 4209 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e, 4210 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a, 4211 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13, 4212 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37, 4213 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01, 4214 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30, 4215 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e, 4216 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3, 4217 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a, 4218 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70, 4219 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31, 4220 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20, 4221 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30, 4222 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f, 4223 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c, 4224 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a, 4225 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f, 4226 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33, 4227 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3, 4228 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30, 4229 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30, 4230 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b, 4231 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a, 4232 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0, 4233 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37, 4234 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63, 4235 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30, 4236 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32, 4237 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09, 4238 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a, 4239 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b, 4240 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37, 4241 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61, 4242 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30, 4243 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34, 4244 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe, 4245 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a, 4246 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30, 4247 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31, 4248 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85, 4249 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30, 4250 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37, 4251 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4, 4252 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a, 4253 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55, 4254 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30, 4255 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36, 4256 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30, 4257 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a, 4258 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d, 4259 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a, 4260 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f, 4261 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33, 4262 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97, 4263 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30, 4264 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b, 4265 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4, 4266 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a, 4267 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76, 4268 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30, 4269 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a, 4270 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30, 4271 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c, 4272 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd, 4273 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a, 4274 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae, 4275 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39, 4276 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39, 4277 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31, 4278 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d, 4279 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80, 4280 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a, 4281 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b, 4282 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31, 4283 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd, 4284 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30, 4285 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41, 4286 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e, 4287 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a, 4288 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93, 4289 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32, 4290 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28, 4291 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30, 4292 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42, 4293 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c, 4294 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a, 4295 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74, 4296 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36, 4297 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c, 4298 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30, 4299 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45, 4300 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83, 4301 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a, 4302 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12, 4303 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36, 4304 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98, 4305 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30, 4306 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47, 4307 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75, 4308 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a, 4309 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b, 4310 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34, 4311 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81, 4312 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30, 4313 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49, 4314 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51, 4315 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a, 4316 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53, 4317 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31, 4318 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5, 4319 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30, 4320 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c, 4321 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd, 4322 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a, 4323 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37, 4324 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39, 4325 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9, 4326 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30, 4327 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d, 4328 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32, 4329 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a, 4330 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1, 4331 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30, 4332 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86, 4333 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30, 4334 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50, 4335 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82, 4336 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a, 4337 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03, 4338 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30, 4339 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b, 4340 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30, 4341 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52, 4342 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f, 4343 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a, 4344 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69, 4345 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31, 4346 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c, 4347 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30, 4348 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57, 4349 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a, 4350 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a, 4351 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68, 4352 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34, 4353 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62, 4354 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30, 4355 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58, 4356 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d, 4357 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a, 4358 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25, 4359 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37, 4360 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3, 4361 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30, 4362 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59, 4363 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd, 4364 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a, 4365 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb, 4366 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30, 4367 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9, 4368 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30, 4369 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a, 4370 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d, 4371 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a, 4372 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58, 4373 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37, 4374 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3, 4375 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30, 4376 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b, 4377 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e, 4378 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a, 4379 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd, 4380 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35, 4381 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1, 4382 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31, 4383 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e, 4384 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca, 4385 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a, 4386 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a, 4387 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35, 4388 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd, 4389 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30, 4390 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f, 4391 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2, 4392 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a, 4393 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5, 4394 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36, 4395 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5, 4396 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30, 4397 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60, 4398 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4, 4399 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a, 4400 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09, 4401 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37, 4402 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83, 4403 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30, 4404 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60, 4405 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2, 4406 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a, 4407 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70, 4408 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39, 4409 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17, 4410 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30, 4411 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61, 4412 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97, 4413 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a, 4414 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd, 4415 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38, 4416 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82, 4417 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30, 4418 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62, 4419 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2, 4420 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a, 4421 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee, 4422 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36, 4423 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d, 4424 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30, 4425 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63, 4426 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86, 4427 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a, 4428 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3, 4429 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31, 4430 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22, 4431 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31, 4432 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65, 4433 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7, 4434 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a, 4435 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e, 4436 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37, 4437 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7, 4438 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30, 4439 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67, 4440 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0, 4441 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a, 4442 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0, 4443 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31, 4444 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04, 4445 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30, 4446 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69, 4447 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16, 4448 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a, 4449 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6, 4450 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39, 4451 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9, 4452 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31, 4453 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b, 4454 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53, 4455 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a, 4456 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e, 4457 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34, 4458 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a, 4459 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30, 4460 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d, 4461 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c, 4462 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a, 4463 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16, 4464 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32, 4465 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae, 4466 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30, 4467 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f, 4468 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1, 4469 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a, 4470 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c, 4471 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30, 4472 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5, 4473 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30, 4474 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70, 4475 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48, 4476 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a, 4477 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8, 4478 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39, 4479 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b, 4480 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30, 4481 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72, 4482 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39, 4483 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a, 4484 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39, 4485 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33, 4486 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17, 4487 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30, 4488 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75, 4489 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd, 4490 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a, 4491 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd, 4492 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38, 4493 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde, 4494 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30, 4495 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76, 4496 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03, 4497 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a, 4498 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d, 4499 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31, 4500 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93, 4501 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30, 4502 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78, 4503 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51, 4504 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a, 4505 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10, 4506 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38, 4507 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f, 4508 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30, 4509 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78, 4510 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67, 4511 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a, 4512 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79, 4513 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36, 4514 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02, 4515 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30, 4516 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b, 4517 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea, 4518 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a, 4519 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc, 4520 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30, 4521 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5, 4522 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30, 4523 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f, 4524 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b, 4525 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a, 4526 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00, 4527 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2, 4528 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08, 4529 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84, 4530 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68, 4531 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c, 4532 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f, 4533 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43, 4534 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c, 4535 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 }; 4536 4537 static void test_decodeCRLToBeSigned(DWORD dwEncoding) 4538 { 4539 static const BYTE *corruptCRLs[] = { v1CRL, v2CRL }; 4540 BOOL ret; 4541 BYTE *buf = NULL; 4542 DWORD size = 0, i; 4543 4544 for (i = 0; i < sizeof(corruptCRLs) / sizeof(corruptCRLs[0]); i++) 4545 { 4546 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, 4547 corruptCRLs[i], corruptCRLs[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, 4548 &buf, &size); 4549 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT || 4550 GetLastError() == OSS_DATA_ERROR /* Win9x */), 4551 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n", 4552 GetLastError()); 4553 } 4554 /* at a minimum, a CRL must contain an issuer: */ 4555 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, 4556 v1CRLWithIssuer, v1CRLWithIssuer[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, 4557 &buf, &size); 4558 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 4559 if (ret) 4560 { 4561 CRL_INFO *info = (CRL_INFO *)buf; 4562 4563 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size); 4564 ok(info->cCRLEntry == 0, "Expected 0 CRL entries, got %d\n", 4565 info->cCRLEntry); 4566 ok(info->Issuer.cbData == sizeof(encodedCommonName), 4567 "Wrong issuer size %d\n", info->Issuer.cbData); 4568 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData), 4569 "Unexpected issuer\n"); 4570 LocalFree(buf); 4571 } 4572 /* check decoding with an empty CRL entry */ 4573 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, 4574 v1CRLWithIssuerAndEmptyEntry, v1CRLWithIssuerAndEmptyEntry[1] + 2, 4575 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 4576 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT || 4577 GetLastError() == OSS_DATA_ERROR /* Win9x */ || 4578 GetLastError() == CRYPT_E_BAD_ENCODE /* Win8 */), 4579 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n", 4580 GetLastError()); 4581 /* with a real CRL entry */ 4582 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, 4583 v1CRLWithIssuerAndEntry, v1CRLWithIssuerAndEntry[1] + 2, 4584 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 4585 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 4586 if (ret) 4587 { 4588 CRL_INFO *info = (CRL_INFO *)buf; 4589 CRL_ENTRY *entry; 4590 4591 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size); 4592 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n", 4593 info->cCRLEntry); 4594 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n"); 4595 entry = info->rgCRLEntry; 4596 ok(entry->SerialNumber.cbData == 1, 4597 "Expected serial number size 1, got %d\n", 4598 entry->SerialNumber.cbData); 4599 ok(*entry->SerialNumber.pbData == *serialNum, 4600 "Expected serial number %d, got %d\n", *serialNum, 4601 *entry->SerialNumber.pbData); 4602 ok(info->Issuer.cbData == sizeof(encodedCommonName), 4603 "Wrong issuer size %d\n", info->Issuer.cbData); 4604 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData), 4605 "Unexpected issuer\n"); 4606 LocalFree(buf); 4607 } 4608 /* a real CRL from verisign that has extensions */ 4609 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, 4610 verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG, 4611 NULL, &buf, &size); 4612 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 4613 if (ret) 4614 { 4615 CRL_INFO *info = (CRL_INFO *)buf; 4616 4617 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size); 4618 ok(info->cCRLEntry == 3, "Expected 3 CRL entries, got %d\n", 4619 info->cCRLEntry); 4620 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n"); 4621 ok(info->cExtension == 2, "Expected 2 extensions, got %d\n", 4622 info->cExtension); 4623 LocalFree(buf); 4624 } 4625 /* another real CRL from verisign that has lots of entries */ 4626 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, 4627 verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries), 4628 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 4629 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 4630 if (ret) 4631 { 4632 CRL_INFO *info = (CRL_INFO *)buf; 4633 4634 ok(size >= sizeof(CRL_INFO), "Got size %d\n", size); 4635 ok(info->cCRLEntry == 209, "Expected 209 CRL entries, got %d\n", 4636 info->cCRLEntry); 4637 ok(info->cExtension == 0, "Expected 0 extensions, got %d\n", 4638 info->cExtension); 4639 LocalFree(buf); 4640 } 4641 /* and finally, with an extension */ 4642 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, 4643 v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG, 4644 NULL, &buf, &size); 4645 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 4646 if (ret) 4647 { 4648 CRL_INFO *info = (CRL_INFO *)buf; 4649 CRL_ENTRY *entry; 4650 4651 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size); 4652 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n", 4653 info->cCRLEntry); 4654 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n"); 4655 entry = info->rgCRLEntry; 4656 ok(entry->SerialNumber.cbData == 1, 4657 "Expected serial number size 1, got %d\n", 4658 entry->SerialNumber.cbData); 4659 ok(*entry->SerialNumber.pbData == *serialNum, 4660 "Expected serial number %d, got %d\n", *serialNum, 4661 *entry->SerialNumber.pbData); 4662 ok(info->Issuer.cbData == sizeof(encodedCommonName), 4663 "Wrong issuer size %d\n", info->Issuer.cbData); 4664 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData), 4665 "Unexpected issuer\n"); 4666 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n", 4667 info->cExtension); 4668 LocalFree(buf); 4669 } 4670 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, 4671 v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG, 4672 NULL, &buf, &size); 4673 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 4674 if (ret) 4675 { 4676 CRL_INFO *info = (CRL_INFO *)buf; 4677 4678 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n", 4679 info->cExtension); 4680 LocalFree(buf); 4681 } 4682 } 4683 4684 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING, 4685 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA }; 4686 static const BYTE encodedUsage[] = { 4687 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03, 4688 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09, 4689 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 }; 4690 4691 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding) 4692 { 4693 BOOL ret; 4694 BYTE *buf = NULL; 4695 DWORD size = 0; 4696 CERT_ENHKEY_USAGE usage; 4697 4698 /* Test with empty usage */ 4699 usage.cUsageIdentifier = 0; 4700 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage, 4701 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 4702 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 4703 if (ret) 4704 { 4705 ok(size == sizeof(emptySequence), "Wrong size %d\n", size); 4706 ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n"); 4707 LocalFree(buf); 4708 } 4709 /* Test with a few usages */ 4710 usage.cUsageIdentifier = sizeof(keyUsages) / sizeof(keyUsages[0]); 4711 usage.rgpszUsageIdentifier = (LPSTR *)keyUsages; 4712 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage, 4713 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 4714 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 4715 if (ret) 4716 { 4717 ok(size == sizeof(encodedUsage), "Wrong size %d\n", size); 4718 ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n"); 4719 LocalFree(buf); 4720 } 4721 } 4722 4723 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding) 4724 { 4725 BOOL ret; 4726 LPBYTE buf = NULL; 4727 DWORD size = 0; 4728 4729 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, 4730 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL, 4731 &buf, &size); 4732 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 4733 if (ret) 4734 { 4735 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf; 4736 4737 ok(size >= sizeof(CERT_ENHKEY_USAGE), 4738 "Wrong size %d\n", size); 4739 ok(usage->cUsageIdentifier == 0, "Expected 0 CRL entries, got %d\n", 4740 usage->cUsageIdentifier); 4741 LocalFree(buf); 4742 } 4743 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, 4744 encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL, 4745 &buf, &size); 4746 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 4747 if (ret) 4748 { 4749 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf; 4750 DWORD i; 4751 4752 ok(size >= sizeof(CERT_ENHKEY_USAGE), 4753 "Wrong size %d\n", size); 4754 ok(usage->cUsageIdentifier == sizeof(keyUsages) / sizeof(keyUsages[0]), 4755 "Wrong CRL entries count %d\n", usage->cUsageIdentifier); 4756 for (i = 0; i < usage->cUsageIdentifier; i++) 4757 ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]), 4758 "Expected OID %s, got %s\n", keyUsages[i], 4759 usage->rgpszUsageIdentifier[i]); 4760 LocalFree(buf); 4761 } 4762 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, 4763 encodedUsage, sizeof(encodedUsage), 0, NULL, NULL, &size); 4764 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 4765 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); 4766 if (buf) 4767 { 4768 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, 4769 encodedUsage, sizeof(encodedUsage), 0, NULL, buf, &size); 4770 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 4771 HeapFree(GetProcessHeap(), 0, buf); 4772 } 4773 } 4774 4775 static BYTE keyId[] = { 1,2,3,4 }; 4776 static const BYTE authorityKeyIdWithId[] = { 4777 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 }; 4778 static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15, 4779 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e, 4780 0x20,0x4c,0x61,0x6e,0x67,0x00 }; 4781 static const BYTE authorityKeyIdWithSerial[] = { 0x30,0x03,0x82,0x01,0x01 }; 4782 4783 static void test_encodeAuthorityKeyId(DWORD dwEncoding) 4784 { 4785 CERT_AUTHORITY_KEY_ID_INFO info = { { 0 } }; 4786 BOOL ret; 4787 BYTE *buf = NULL; 4788 DWORD size = 0; 4789 4790 /* Test with empty id */ 4791 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info, 4792 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 4793 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 4794 if (ret) 4795 { 4796 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size); 4797 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n"); 4798 LocalFree(buf); 4799 } 4800 /* With just a key id */ 4801 info.KeyId.cbData = sizeof(keyId); 4802 info.KeyId.pbData = keyId; 4803 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info, 4804 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 4805 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 4806 if (ret) 4807 { 4808 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", size); 4809 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n"); 4810 LocalFree(buf); 4811 } 4812 /* With just an issuer */ 4813 info.KeyId.cbData = 0; 4814 info.CertIssuer.cbData = sizeof(encodedCommonName); 4815 info.CertIssuer.pbData = (BYTE *)encodedCommonName; 4816 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info, 4817 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 4818 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 4819 if (ret) 4820 { 4821 ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %d\n", 4822 size); 4823 ok(!memcmp(buf, authorityKeyIdWithIssuer, size), "Unexpected value\n"); 4824 LocalFree(buf); 4825 } 4826 /* With just a serial number */ 4827 info.CertIssuer.cbData = 0; 4828 info.CertSerialNumber.cbData = sizeof(serialNum); 4829 info.CertSerialNumber.pbData = (BYTE *)serialNum; 4830 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info, 4831 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 4832 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 4833 if (ret) 4834 { 4835 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n", 4836 size); 4837 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n"); 4838 LocalFree(buf); 4839 } 4840 } 4841 4842 static void test_decodeAuthorityKeyId(DWORD dwEncoding) 4843 { 4844 BOOL ret; 4845 LPBYTE buf = NULL; 4846 DWORD size = 0; 4847 4848 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, 4849 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL, 4850 &buf, &size); 4851 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 4852 if (ret) 4853 { 4854 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf; 4855 4856 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n", 4857 size); 4858 ok(info->KeyId.cbData == 0, "Expected no key id\n"); 4859 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n"); 4860 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n"); 4861 LocalFree(buf); 4862 } 4863 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, 4864 authorityKeyIdWithId, sizeof(authorityKeyIdWithId), 4865 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 4866 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 4867 if (ret) 4868 { 4869 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf; 4870 4871 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n", 4872 size); 4873 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n"); 4874 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)), 4875 "Unexpected key id\n"); 4876 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n"); 4877 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n"); 4878 LocalFree(buf); 4879 } 4880 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, 4881 authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer), 4882 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 4883 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 4884 if (ret) 4885 { 4886 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf; 4887 4888 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n", 4889 size); 4890 ok(info->KeyId.cbData == 0, "Expected no key id\n"); 4891 ok(info->CertIssuer.cbData == sizeof(encodedCommonName), 4892 "Unexpected issuer len\n"); 4893 ok(!memcmp(info->CertIssuer.pbData, encodedCommonName, 4894 sizeof(encodedCommonName)), "Unexpected issuer\n"); 4895 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n"); 4896 LocalFree(buf); 4897 } 4898 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, 4899 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial), 4900 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 4901 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 4902 if (ret) 4903 { 4904 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf; 4905 4906 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n", 4907 size); 4908 ok(info->KeyId.cbData == 0, "Expected no key id\n"); 4909 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n"); 4910 ok(info->CertSerialNumber.cbData == sizeof(serialNum), 4911 "Unexpected serial number len\n"); 4912 ok(!memcmp(info->CertSerialNumber.pbData, serialNum, sizeof(serialNum)), 4913 "Unexpected serial number\n"); 4914 LocalFree(buf); 4915 } 4916 } 4917 4918 static const BYTE authorityKeyIdWithIssuerUrl[] = { 0x30,0x15,0xa1,0x13,0x86, 4919 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e, 4920 0x6f,0x72,0x67 }; 4921 4922 static void test_encodeAuthorityKeyId2(DWORD dwEncoding) 4923 { 4924 CERT_AUTHORITY_KEY_ID2_INFO info = { { 0 } }; 4925 CERT_ALT_NAME_ENTRY entry = { 0 }; 4926 BOOL ret; 4927 BYTE *buf = NULL; 4928 DWORD size = 0; 4929 4930 /* Test with empty id */ 4931 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info, 4932 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 4933 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 4934 if (ret) 4935 { 4936 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size); 4937 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n"); 4938 LocalFree(buf); 4939 } 4940 /* With just a key id */ 4941 info.KeyId.cbData = sizeof(keyId); 4942 info.KeyId.pbData = keyId; 4943 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info, 4944 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 4945 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 4946 if (ret) 4947 { 4948 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", 4949 size); 4950 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n"); 4951 LocalFree(buf); 4952 } 4953 /* With a bogus issuer name */ 4954 info.KeyId.cbData = 0; 4955 info.AuthorityCertIssuer.cAltEntry = 1; 4956 info.AuthorityCertIssuer.rgAltEntry = &entry; 4957 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info, 4958 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 4959 ok(!ret && GetLastError() == E_INVALIDARG, 4960 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 4961 /* With an issuer name */ 4962 entry.dwAltNameChoice = CERT_ALT_NAME_URL; 4963 U(entry).pwszURL = (LPWSTR)url; 4964 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info, 4965 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 4966 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 4967 if (ret) 4968 { 4969 ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %d\n", 4970 size); 4971 ok(!memcmp(buf, authorityKeyIdWithIssuerUrl, size), 4972 "Unexpected value\n"); 4973 LocalFree(buf); 4974 } 4975 /* With just a serial number */ 4976 info.AuthorityCertIssuer.cAltEntry = 0; 4977 info.AuthorityCertSerialNumber.cbData = sizeof(serialNum); 4978 info.AuthorityCertSerialNumber.pbData = (BYTE *)serialNum; 4979 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info, 4980 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 4981 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 4982 if (ret) 4983 { 4984 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n", 4985 size); 4986 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n"); 4987 LocalFree(buf); 4988 } 4989 } 4990 4991 static void test_decodeAuthorityKeyId2(DWORD dwEncoding) 4992 { 4993 BOOL ret; 4994 LPBYTE buf = NULL; 4995 DWORD size = 0; 4996 4997 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, 4998 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL, 4999 &buf, &size); 5000 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5001 if (ret) 5002 { 5003 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf; 5004 5005 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n", 5006 size); 5007 ok(info->KeyId.cbData == 0, "Expected no key id\n"); 5008 ok(info->AuthorityCertIssuer.cAltEntry == 0, 5009 "Expected no issuer name entries\n"); 5010 ok(info->AuthorityCertSerialNumber.cbData == 0, 5011 "Expected no serial number\n"); 5012 LocalFree(buf); 5013 } 5014 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, 5015 authorityKeyIdWithId, sizeof(authorityKeyIdWithId), 5016 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5017 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5018 if (ret) 5019 { 5020 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf; 5021 5022 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n", 5023 size); 5024 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n"); 5025 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)), 5026 "Unexpected key id\n"); 5027 ok(info->AuthorityCertIssuer.cAltEntry == 0, 5028 "Expected no issuer name entries\n"); 5029 ok(info->AuthorityCertSerialNumber.cbData == 0, 5030 "Expected no serial number\n"); 5031 LocalFree(buf); 5032 } 5033 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, 5034 authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl), 5035 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5036 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5037 if (ret) 5038 { 5039 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf; 5040 5041 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n", 5042 size); 5043 ok(info->KeyId.cbData == 0, "Expected no key id\n"); 5044 ok(info->AuthorityCertIssuer.cAltEntry == 1, 5045 "Expected 1 issuer entry, got %d\n", 5046 info->AuthorityCertIssuer.cAltEntry); 5047 ok(info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice == 5048 CERT_ALT_NAME_URL, "Expected CERT_ALT_NAME_URL, got %d\n", 5049 info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice); 5050 ok(!lstrcmpW(U(info->AuthorityCertIssuer.rgAltEntry[0]).pwszURL, 5051 url), "Unexpected URL\n"); 5052 ok(info->AuthorityCertSerialNumber.cbData == 0, 5053 "Expected no serial number\n"); 5054 LocalFree(buf); 5055 } 5056 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, 5057 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial), 5058 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5059 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5060 if (ret) 5061 { 5062 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf; 5063 5064 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n", 5065 size); 5066 ok(info->KeyId.cbData == 0, "Expected no key id\n"); 5067 ok(info->AuthorityCertIssuer.cAltEntry == 0, 5068 "Expected no issuer name entries\n"); 5069 ok(info->AuthorityCertSerialNumber.cbData == sizeof(serialNum), 5070 "Unexpected serial number len\n"); 5071 ok(!memcmp(info->AuthorityCertSerialNumber.pbData, serialNum, 5072 sizeof(serialNum)), "Unexpected serial number\n"); 5073 LocalFree(buf); 5074 } 5075 } 5076 5077 static const BYTE authorityInfoAccessWithUrl[] = { 5078 0x30,0x19,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a, 5079 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 }; 5080 static const BYTE authorityInfoAccessWithUrlAndIPAddr[] = { 5081 0x30,0x29,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a, 5082 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x0e,0x06, 5083 0x02,0x2d,0x06,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,0x01 }; 5084 5085 static void test_encodeAuthorityInfoAccess(DWORD dwEncoding) 5086 { 5087 static char oid1[] = "1.2.3"; 5088 static char oid2[] = "1.5.6"; 5089 BOOL ret; 5090 BYTE *buf = NULL; 5091 DWORD size = 0; 5092 CERT_ACCESS_DESCRIPTION accessDescription[2]; 5093 CERT_AUTHORITY_INFO_ACCESS aia; 5094 5095 memset(accessDescription, 0, sizeof(accessDescription)); 5096 aia.cAccDescr = 0; 5097 aia.rgAccDescr = NULL; 5098 /* Having no access descriptions is allowed */ 5099 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia, 5100 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5101 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5102 if (ret) 5103 { 5104 ok(size == sizeof(emptySequence), "unexpected size %d\n", size); 5105 ok(!memcmp(buf, emptySequence, size), "unexpected value\n"); 5106 LocalFree(buf); 5107 buf = NULL; 5108 } 5109 /* It can't have an empty access method */ 5110 aia.cAccDescr = 1; 5111 aia.rgAccDescr = accessDescription; 5112 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia, 5113 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5114 ok(!ret && (GetLastError() == E_INVALIDARG || 5115 GetLastError() == OSS_LIMITED /* Win9x */), 5116 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError()); 5117 /* It can't have an empty location */ 5118 accessDescription[0].pszAccessMethod = oid1; 5119 SetLastError(0xdeadbeef); 5120 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia, 5121 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5122 ok(!ret && GetLastError() == E_INVALIDARG, 5123 "expected E_INVALIDARG, got %08x\n", GetLastError()); 5124 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL; 5125 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url; 5126 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia, 5127 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5128 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5129 if (ret) 5130 { 5131 ok(size == sizeof(authorityInfoAccessWithUrl), "unexpected size %d\n", 5132 size); 5133 ok(!memcmp(buf, authorityInfoAccessWithUrl, size), 5134 "unexpected value\n"); 5135 LocalFree(buf); 5136 buf = NULL; 5137 } 5138 accessDescription[1].pszAccessMethod = oid2; 5139 accessDescription[1].AccessLocation.dwAltNameChoice = 5140 CERT_ALT_NAME_IP_ADDRESS; 5141 U(accessDescription[1].AccessLocation).IPAddress.cbData = 5142 sizeof(encodedIPAddr); 5143 U(accessDescription[1].AccessLocation).IPAddress.pbData = 5144 (LPBYTE)encodedIPAddr; 5145 aia.cAccDescr = 2; 5146 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia, 5147 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5148 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5149 if (ret) 5150 { 5151 ok(size == sizeof(authorityInfoAccessWithUrlAndIPAddr), 5152 "unexpected size %d\n", size); 5153 ok(!memcmp(buf, authorityInfoAccessWithUrlAndIPAddr, size), 5154 "unexpected value\n"); 5155 LocalFree(buf); 5156 buf = NULL; 5157 } 5158 } 5159 5160 static void compareAuthorityInfoAccess(LPCSTR header, 5161 const CERT_AUTHORITY_INFO_ACCESS *expected, 5162 const CERT_AUTHORITY_INFO_ACCESS *got) 5163 { 5164 DWORD i; 5165 5166 ok(expected->cAccDescr == got->cAccDescr, 5167 "%s: expected %d access descriptions, got %d\n", header, 5168 expected->cAccDescr, got->cAccDescr); 5169 for (i = 0; i < expected->cAccDescr; i++) 5170 { 5171 ok(!strcmp(expected->rgAccDescr[i].pszAccessMethod, 5172 got->rgAccDescr[i].pszAccessMethod), "%s[%d]: expected %s, got %s\n", 5173 header, i, expected->rgAccDescr[i].pszAccessMethod, 5174 got->rgAccDescr[i].pszAccessMethod); 5175 compareAltNameEntry(&expected->rgAccDescr[i].AccessLocation, 5176 &got->rgAccDescr[i].AccessLocation); 5177 } 5178 } 5179 5180 static void test_decodeAuthorityInfoAccess(DWORD dwEncoding) 5181 { 5182 static char oid1[] = "1.2.3"; 5183 static char oid2[] = "1.5.6"; 5184 BOOL ret; 5185 LPBYTE buf = NULL; 5186 DWORD size = 0; 5187 5188 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, 5189 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL, 5190 &buf, &size); 5191 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 5192 if (ret) 5193 { 5194 CERT_AUTHORITY_INFO_ACCESS aia = { 0, NULL }; 5195 5196 compareAuthorityInfoAccess("empty AIA", &aia, 5197 (CERT_AUTHORITY_INFO_ACCESS *)buf); 5198 LocalFree(buf); 5199 buf = NULL; 5200 } 5201 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, 5202 authorityInfoAccessWithUrl, sizeof(authorityInfoAccessWithUrl), 5203 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5204 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 5205 if (ret) 5206 { 5207 CERT_ACCESS_DESCRIPTION accessDescription; 5208 CERT_AUTHORITY_INFO_ACCESS aia; 5209 5210 accessDescription.pszAccessMethod = oid1; 5211 accessDescription.AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL; 5212 U(accessDescription.AccessLocation).pwszURL = (LPWSTR)url; 5213 aia.cAccDescr = 1; 5214 aia.rgAccDescr = &accessDescription; 5215 compareAuthorityInfoAccess("AIA with URL", &aia, 5216 (CERT_AUTHORITY_INFO_ACCESS *)buf); 5217 LocalFree(buf); 5218 buf = NULL; 5219 } 5220 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, 5221 authorityInfoAccessWithUrlAndIPAddr, 5222 sizeof(authorityInfoAccessWithUrlAndIPAddr), CRYPT_DECODE_ALLOC_FLAG, 5223 NULL, &buf, &size); 5224 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 5225 if (ret) 5226 { 5227 CERT_ACCESS_DESCRIPTION accessDescription[2]; 5228 CERT_AUTHORITY_INFO_ACCESS aia; 5229 5230 accessDescription[0].pszAccessMethod = oid1; 5231 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL; 5232 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url; 5233 accessDescription[1].pszAccessMethod = oid2; 5234 accessDescription[1].AccessLocation.dwAltNameChoice = 5235 CERT_ALT_NAME_IP_ADDRESS; 5236 U(accessDescription[1].AccessLocation).IPAddress.cbData = 5237 sizeof(encodedIPAddr); 5238 U(accessDescription[1].AccessLocation).IPAddress.pbData = 5239 (LPBYTE)encodedIPAddr; 5240 aia.cAccDescr = 2; 5241 aia.rgAccDescr = accessDescription; 5242 compareAuthorityInfoAccess("AIA with URL and IP addr", &aia, 5243 (CERT_AUTHORITY_INFO_ACCESS *)buf); 5244 LocalFree(buf); 5245 buf = NULL; 5246 } 5247 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, 5248 authorityInfoAccessWithUrlAndIPAddr, 5249 sizeof(authorityInfoAccessWithUrlAndIPAddr), 0, NULL, NULL, &size); 5250 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 5251 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); 5252 if (buf) 5253 { 5254 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, 5255 authorityInfoAccessWithUrlAndIPAddr, 5256 sizeof(authorityInfoAccessWithUrlAndIPAddr), 0, NULL, buf, &size); 5257 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 5258 HeapFree(GetProcessHeap(), 0, buf); 5259 } 5260 } 5261 5262 static const BYTE emptyCTL[] = { 5263 0x30,0x17,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30, 5264 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 }; 5265 static const BYTE emptyCTLWithVersion1[] = { 5266 0x30,0x1a,0x02,0x01,0x01,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, 5267 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 }; 5268 static const BYTE ctlWithUsageIdentifier[] = { 5269 0x30,0x1b,0x30,0x04,0x06,0x02,0x2a,0x03,0x18,0x0f,0x31,0x36,0x30,0x31,0x30, 5270 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 }; 5271 static const BYTE ctlWithListIdentifier[] = { 5272 0x30,0x1a,0x30,0x00,0x04,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, 5273 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 }; 5274 static const BYTE ctlWithSequenceNumber[] = { 5275 0x30,0x1a,0x30,0x00,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, 5276 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 }; 5277 static const BYTE ctlWithThisUpdate[] = { 5278 0x30,0x15,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31, 5279 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 }; 5280 static const BYTE ctlWithThisAndNextUpdate[] = { 5281 0x30,0x24,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31, 5282 0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31, 5283 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 }; 5284 static const BYTE ctlWithAlgId[] = { 5285 0x30,0x1b,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30, 5286 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 }; 5287 static const BYTE ctlWithBogusEntry[] = { 5288 0x30,0x29,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30, 5289 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x10,0x30,0x0e,0x04, 5290 0x01,0x01,0x31,0x09,0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,0x01 }; 5291 static const BYTE ctlWithOneEntry[] = { 5292 0x30,0x2a,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30, 5293 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x11,0x30,0x0f,0x04, 5294 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00 }; 5295 static const BYTE ctlWithTwoEntries[] = { 5296 0x30,0x41,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30, 5297 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x28,0x30,0x0f,0x04, 5298 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00,0x30, 5299 0x15,0x04,0x01,0x01,0x31,0x10,0x30,0x0e,0x06,0x02,0x2d,0x06,0x31,0x08,0x30, 5300 0x06,0x87,0x04,0x7f,0x00,0x00,0x01 }; 5301 5302 static void test_encodeCTL(DWORD dwEncoding) 5303 { 5304 static char oid1[] = "1.2.3"; 5305 static char oid2[] = "1.5.6"; 5306 char *pOid1 = oid1; 5307 BOOL ret; 5308 BYTE *buf = NULL; 5309 DWORD size = 0; 5310 CTL_INFO info; 5311 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 }; 5312 CTL_ENTRY ctlEntry[2]; 5313 CRYPT_ATTRIBUTE attr1, attr2; 5314 CRYPT_ATTR_BLOB value1, value2; 5315 5316 memset(&info, 0, sizeof(info)); 5317 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, 5318 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5319 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5320 if (ret) 5321 { 5322 ok(size == sizeof(emptyCTL), "unexpected size %d\n", size); 5323 ok(!memcmp(buf, emptyCTL, size), "unexpected value\n"); 5324 LocalFree(buf); 5325 buf = NULL; 5326 } 5327 info.dwVersion = 1; 5328 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, 5329 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5330 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5331 if (ret) 5332 { 5333 ok(size == sizeof(emptyCTLWithVersion1), "unexpected size %d\n", size); 5334 ok(!memcmp(buf, emptyCTLWithVersion1, size), "unexpected value\n"); 5335 LocalFree(buf); 5336 buf = NULL; 5337 } 5338 info.dwVersion = 0; 5339 info.SubjectUsage.cUsageIdentifier = 1; 5340 info.SubjectUsage.rgpszUsageIdentifier = &pOid1; 5341 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, 5342 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5343 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5344 if (ret) 5345 { 5346 ok(size == sizeof(ctlWithUsageIdentifier), "unexpected size %d\n", 5347 size); 5348 ok(!memcmp(buf, ctlWithUsageIdentifier, size), "unexpected value\n"); 5349 LocalFree(buf); 5350 buf = NULL; 5351 } 5352 info.SubjectUsage.cUsageIdentifier = 0; 5353 info.ListIdentifier.cbData = sizeof(serialNum); 5354 info.ListIdentifier.pbData = (LPBYTE)serialNum; 5355 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, 5356 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5357 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5358 if (ret) 5359 { 5360 ok(size == sizeof(ctlWithListIdentifier), "unexpected size %d\n", size); 5361 ok(!memcmp(buf, ctlWithListIdentifier, size), "unexpected value\n"); 5362 LocalFree(buf); 5363 buf = NULL; 5364 } 5365 info.ListIdentifier.cbData = 0; 5366 info.SequenceNumber.cbData = sizeof(serialNum); 5367 info.SequenceNumber.pbData = (LPBYTE)serialNum; 5368 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, 5369 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5370 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5371 if (ret) 5372 { 5373 ok(size == sizeof(ctlWithSequenceNumber), "unexpected size %d\n", 5374 size); 5375 ok(!memcmp(buf, ctlWithSequenceNumber, size), "unexpected value\n"); 5376 LocalFree(buf); 5377 buf = NULL; 5378 } 5379 info.SequenceNumber.cbData = 0; 5380 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate); 5381 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, 5382 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5383 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5384 if (ret) 5385 { 5386 ok(size == sizeof(ctlWithThisUpdate), "unexpected size %d\n", size); 5387 ok(!memcmp(buf, ctlWithThisUpdate, size), "unexpected value\n"); 5388 LocalFree(buf); 5389 buf = NULL; 5390 } 5391 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate); 5392 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, 5393 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5394 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5395 if (ret) 5396 { 5397 ok(size == sizeof(ctlWithThisAndNextUpdate), "unexpected size %d\n", 5398 size); 5399 ok(!memcmp(buf, ctlWithThisAndNextUpdate, size), "unexpected value\n"); 5400 LocalFree(buf); 5401 buf = NULL; 5402 } 5403 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0; 5404 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0; 5405 info.SubjectAlgorithm.pszObjId = oid2; 5406 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, 5407 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5408 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5409 if (ret) 5410 { 5411 ok(size == sizeof(ctlWithAlgId), "unexpected size %d\n", size); 5412 ok(!memcmp(buf, ctlWithAlgId, size), "unexpected value\n"); 5413 LocalFree(buf); 5414 buf = NULL; 5415 } 5416 /* The value is supposed to be asn.1 encoded, so this'll fail to decode 5417 * (see tests below) but it'll encode fine. 5418 */ 5419 info.SubjectAlgorithm.pszObjId = NULL; 5420 value1.cbData = sizeof(serialNum); 5421 value1.pbData = (LPBYTE)serialNum; 5422 attr1.pszObjId = oid1; 5423 attr1.cValue = 1; 5424 attr1.rgValue = &value1; 5425 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum); 5426 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum; 5427 ctlEntry[0].cAttribute = 1; 5428 ctlEntry[0].rgAttribute = &attr1; 5429 info.cCTLEntry = 1; 5430 info.rgCTLEntry = ctlEntry; 5431 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, 5432 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5433 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5434 if (ret) 5435 { 5436 ok(size == sizeof(ctlWithBogusEntry), "unexpected size %d\n", size); 5437 ok(!memcmp(buf, ctlWithBogusEntry, size), "unexpected value\n"); 5438 LocalFree(buf); 5439 buf = NULL; 5440 } 5441 value1.cbData = sizeof(emptySequence); 5442 value1.pbData = (LPBYTE)emptySequence; 5443 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, 5444 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5445 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5446 if (ret) 5447 { 5448 ok(size == sizeof(ctlWithOneEntry), "unexpected size %d\n", size); 5449 ok(!memcmp(buf, ctlWithOneEntry, size), "unexpected value\n"); 5450 LocalFree(buf); 5451 buf = NULL; 5452 } 5453 value2.cbData = sizeof(encodedIPAddr); 5454 value2.pbData = (LPBYTE)encodedIPAddr; 5455 attr2.pszObjId = oid2; 5456 attr2.cValue = 1; 5457 attr2.rgValue = &value2; 5458 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum); 5459 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum; 5460 ctlEntry[1].cAttribute = 1; 5461 ctlEntry[1].rgAttribute = &attr2; 5462 info.cCTLEntry = 2; 5463 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, 5464 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5465 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5466 if (ret) 5467 { 5468 ok(size == sizeof(ctlWithTwoEntries), "unexpected size %d\n", size); 5469 ok(!memcmp(buf, ctlWithTwoEntries, size), "unexpected value\n"); 5470 LocalFree(buf); 5471 buf = NULL; 5472 } 5473 } 5474 5475 static void compareCTLInfo(LPCSTR header, const CTL_INFO *expected, 5476 const CTL_INFO *got) 5477 { 5478 DWORD i, j, k; 5479 5480 ok(expected->dwVersion == got->dwVersion, 5481 "%s: expected version %d, got %d\n", header, expected->dwVersion, 5482 got->dwVersion); 5483 ok(expected->SubjectUsage.cUsageIdentifier == 5484 got->SubjectUsage.cUsageIdentifier, 5485 "%s: expected %d usage identifiers, got %d\n", header, 5486 expected->SubjectUsage.cUsageIdentifier, 5487 got->SubjectUsage.cUsageIdentifier); 5488 for (i = 0; i < expected->SubjectUsage.cUsageIdentifier; i++) 5489 ok(!strcmp(expected->SubjectUsage.rgpszUsageIdentifier[i], 5490 got->SubjectUsage.rgpszUsageIdentifier[i]), 5491 "%s[%d]: expected %s, got %s\n", header, i, 5492 expected->SubjectUsage.rgpszUsageIdentifier[i], 5493 got->SubjectUsage.rgpszUsageIdentifier[i]); 5494 ok(expected->ListIdentifier.cbData == got->ListIdentifier.cbData, 5495 "%s: expected list identifier of %d bytes, got %d\n", header, 5496 expected->ListIdentifier.cbData, got->ListIdentifier.cbData); 5497 if (expected->ListIdentifier.cbData) 5498 ok(!memcmp(expected->ListIdentifier.pbData, got->ListIdentifier.pbData, 5499 expected->ListIdentifier.cbData), 5500 "%s: unexpected list identifier value\n", header); 5501 ok(expected->SequenceNumber.cbData == got->SequenceNumber.cbData, 5502 "%s: expected sequence number of %d bytes, got %d\n", header, 5503 expected->SequenceNumber.cbData, got->SequenceNumber.cbData); 5504 if (expected->SequenceNumber.cbData) 5505 ok(!memcmp(expected->SequenceNumber.pbData, got->SequenceNumber.pbData, 5506 expected->SequenceNumber.cbData), 5507 "%s: unexpected sequence number value\n", header); 5508 ok(!memcmp(&expected->ThisUpdate, &got->ThisUpdate, sizeof(FILETIME)), 5509 "%s: expected this update = (%d, %d), got (%d, %d)\n", header, 5510 expected->ThisUpdate.dwLowDateTime, expected->ThisUpdate.dwHighDateTime, 5511 got->ThisUpdate.dwLowDateTime, got->ThisUpdate.dwHighDateTime); 5512 ok(!memcmp(&expected->NextUpdate, &got->NextUpdate, sizeof(FILETIME)), 5513 "%s: expected next update = (%d, %d), got (%d, %d)\n", header, 5514 expected->NextUpdate.dwLowDateTime, expected->NextUpdate.dwHighDateTime, 5515 got->NextUpdate.dwLowDateTime, got->NextUpdate.dwHighDateTime); 5516 if (expected->SubjectAlgorithm.pszObjId && 5517 *expected->SubjectAlgorithm.pszObjId && !got->SubjectAlgorithm.pszObjId) 5518 ok(0, "%s: expected subject algorithm %s, got NULL\n", header, 5519 expected->SubjectAlgorithm.pszObjId); 5520 if (expected->SubjectAlgorithm.pszObjId && got->SubjectAlgorithm.pszObjId) 5521 ok(!strcmp(expected->SubjectAlgorithm.pszObjId, 5522 got->SubjectAlgorithm.pszObjId), 5523 "%s: expected subject algorithm %s, got %s\n", header, 5524 expected->SubjectAlgorithm.pszObjId, got->SubjectAlgorithm.pszObjId); 5525 ok(expected->SubjectAlgorithm.Parameters.cbData == 5526 got->SubjectAlgorithm.Parameters.cbData, 5527 "%s: expected subject algorithm parameters of %d bytes, got %d\n", header, 5528 expected->SubjectAlgorithm.Parameters.cbData, 5529 got->SubjectAlgorithm.Parameters.cbData); 5530 if (expected->SubjectAlgorithm.Parameters.cbData) 5531 ok(!memcmp(expected->SubjectAlgorithm.Parameters.pbData, 5532 got->SubjectAlgorithm.Parameters.pbData, 5533 expected->SubjectAlgorithm.Parameters.cbData), 5534 "%s: unexpected subject algorithm parameter value\n", header); 5535 ok(expected->cCTLEntry == got->cCTLEntry, 5536 "%s: expected %d CTL entries, got %d\n", header, expected->cCTLEntry, 5537 got->cCTLEntry); 5538 for (i = 0; i < expected->cCTLEntry; i++) 5539 { 5540 ok(expected->rgCTLEntry[i].SubjectIdentifier.cbData == 5541 got->rgCTLEntry[i].SubjectIdentifier.cbData, 5542 "%s[%d]: expected subject identifier of %d bytes, got %d\n", 5543 header, i, expected->rgCTLEntry[i].SubjectIdentifier.cbData, 5544 got->rgCTLEntry[i].SubjectIdentifier.cbData); 5545 if (expected->rgCTLEntry[i].SubjectIdentifier.cbData) 5546 ok(!memcmp(expected->rgCTLEntry[i].SubjectIdentifier.pbData, 5547 got->rgCTLEntry[i].SubjectIdentifier.pbData, 5548 expected->rgCTLEntry[i].SubjectIdentifier.cbData), 5549 "%s[%d]: unexpected subject identifier value\n", 5550 header, i); 5551 for (j = 0; j < expected->rgCTLEntry[i].cAttribute; j++) 5552 { 5553 ok(!strcmp(expected->rgCTLEntry[i].rgAttribute[j].pszObjId, 5554 got->rgCTLEntry[i].rgAttribute[j].pszObjId), 5555 "%s[%d][%d]: expected attribute OID %s, got %s\n", header, i, j, 5556 expected->rgCTLEntry[i].rgAttribute[j].pszObjId, 5557 got->rgCTLEntry[i].rgAttribute[j].pszObjId); 5558 for (k = 0; k < expected->rgCTLEntry[i].rgAttribute[j].cValue; k++) 5559 { 5560 ok(expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData == 5561 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData, 5562 "%s[%d][%d][%d]: expected value of %d bytes, got %d\n", 5563 header, i, j, k, 5564 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData, 5565 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData); 5566 if (expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData) 5567 ok(!memcmp( 5568 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData, 5569 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData, 5570 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData), 5571 "%s[%d][%d][%d]: unexpected value\n", 5572 header, i, j, k); 5573 } 5574 } 5575 } 5576 ok(expected->cExtension == got->cExtension, 5577 "%s: expected %d extensions, got %d\n", header, expected->cExtension, 5578 got->cExtension); 5579 for (i = 0; i < expected->cExtension; i++) 5580 { 5581 ok(!strcmp(expected->rgExtension[i].pszObjId, 5582 got->rgExtension[i].pszObjId), "%s[%d]: expected %s, got %s\n", 5583 header, i, expected->rgExtension[i].pszObjId, 5584 got->rgExtension[i].pszObjId); 5585 ok(expected->rgExtension[i].fCritical == got->rgExtension[i].fCritical, 5586 "%s[%d]: expected fCritical = %d, got %d\n", header, i, 5587 expected->rgExtension[i].fCritical, got->rgExtension[i].fCritical); 5588 ok(expected->rgExtension[i].Value.cbData == 5589 got->rgExtension[i].Value.cbData, 5590 "%s[%d]: expected extension value to have %d bytes, got %d\n", 5591 header, i, expected->rgExtension[i].Value.cbData, 5592 got->rgExtension[i].Value.cbData); 5593 if (expected->rgExtension[i].Value.cbData) 5594 ok(!memcmp(expected->rgExtension[i].Value.pbData, 5595 got->rgExtension[i].Value.pbData, 5596 expected->rgExtension[i].Value.cbData), 5597 "%s[%d]: unexpected extension value\n", header, i); 5598 } 5599 } 5600 5601 static const BYTE signedCTL[] = { 5602 0x30,0x81,0xc7,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0, 5603 0x81,0xb9,0x30,0x81,0xb6,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a, 5604 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x28,0x06,0x09,0x2a,0x86, 5605 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x1b,0x04,0x19,0x30,0x17,0x30,0x00, 5606 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, 5607 0x30,0x5a,0x30,0x02,0x06,0x00,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a, 5608 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75, 5609 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08, 5610 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05, 5611 0x00,0x04,0x40,0xca,0xd8,0x32,0xd1,0xbd,0x97,0x61,0x54,0xd6,0x80,0xcf,0x0d, 5612 0xbd,0xa2,0x42,0xc7,0xca,0x37,0x91,0x7d,0x9d,0xac,0x8c,0xdf,0x05,0x8a,0x39, 5613 0xc6,0x07,0xc1,0x37,0xe6,0xb9,0xd1,0x0d,0x26,0xec,0xa5,0xb0,0x8a,0x51,0x26, 5614 0x2b,0x4f,0x73,0x44,0x86,0x83,0x5e,0x2b,0x6e,0xcc,0xf8,0x1b,0x85,0x53,0xe9, 5615 0x7a,0x80,0x8f,0x6b,0x42,0x19,0x93 }; 5616 static const BYTE signedCTLWithCTLInnerContent[] = { 5617 0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02, 5618 0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06, 5619 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09, 5620 0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00, 5621 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, 5622 0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05, 5623 0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31, 5624 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20, 5625 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48, 5626 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86, 5627 0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04, 5628 0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d, 5629 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9, 5630 0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04, 5631 0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf, 5632 0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1, 5633 0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f, 5634 0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23, 5635 0x57,0x6c,0x0b,0x47,0xb8 }; 5636 5637 static void test_decodeCTL(DWORD dwEncoding) 5638 { 5639 static char oid1[] = "1.2.3"; 5640 static char oid2[] = "1.5.6"; 5641 static BYTE nullData[] = { 5,0 }; 5642 char *pOid1 = oid1; 5643 BOOL ret; 5644 BYTE *buf = NULL; 5645 DWORD size = 0; 5646 CTL_INFO info; 5647 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 }; 5648 CTL_ENTRY ctlEntry[2]; 5649 CRYPT_ATTRIBUTE attr1, attr2; 5650 CRYPT_ATTR_BLOB value1, value2; 5651 5652 memset(&info, 0, sizeof(info)); 5653 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTL, sizeof(emptyCTL), 5654 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5655 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5656 if (ret) 5657 { 5658 compareCTLInfo("empty CTL", &info, (CTL_INFO *)buf); 5659 LocalFree(buf); 5660 buf = NULL; 5661 } 5662 info.dwVersion = 1; 5663 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTLWithVersion1, 5664 sizeof(emptyCTLWithVersion1), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, 5665 &size); 5666 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5667 if (ret) 5668 { 5669 compareCTLInfo("v1 CTL", &info, (CTL_INFO *)buf); 5670 LocalFree(buf); 5671 buf = NULL; 5672 } 5673 info.dwVersion = 0; 5674 info.SubjectUsage.cUsageIdentifier = 1; 5675 info.SubjectUsage.rgpszUsageIdentifier = &pOid1; 5676 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithUsageIdentifier, 5677 sizeof(ctlWithUsageIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL, 5678 &buf, &size); 5679 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5680 if (ret) 5681 { 5682 compareCTLInfo("CTL with usage identifier", &info, (CTL_INFO *)buf); 5683 LocalFree(buf); 5684 buf = NULL; 5685 } 5686 info.SubjectUsage.cUsageIdentifier = 0; 5687 info.ListIdentifier.cbData = sizeof(serialNum); 5688 info.ListIdentifier.pbData = (LPBYTE)serialNum; 5689 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithListIdentifier, 5690 sizeof(ctlWithListIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5691 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5692 if (ret) 5693 { 5694 compareCTLInfo("CTL with list identifier", &info, (CTL_INFO *)buf); 5695 LocalFree(buf); 5696 buf = NULL; 5697 } 5698 info.ListIdentifier.cbData = 0; 5699 info.SequenceNumber.cbData = sizeof(serialNum); 5700 info.SequenceNumber.pbData = (LPBYTE)serialNum; 5701 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithSequenceNumber, 5702 sizeof(ctlWithSequenceNumber), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5703 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5704 if (ret) 5705 { 5706 compareCTLInfo("CTL with sequence number", &info, (CTL_INFO *)buf); 5707 LocalFree(buf); 5708 buf = NULL; 5709 } 5710 info.SequenceNumber.cbData = 0; 5711 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate); 5712 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisUpdate, 5713 sizeof(ctlWithThisUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5714 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5715 if (ret) 5716 { 5717 compareCTLInfo("CTL with this update", &info, (CTL_INFO *)buf); 5718 LocalFree(buf); 5719 buf = NULL; 5720 } 5721 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate); 5722 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisAndNextUpdate, 5723 sizeof(ctlWithThisAndNextUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL, 5724 &buf, &size); 5725 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5726 if (ret) 5727 { 5728 compareCTLInfo("CTL with this and next update", &info, (CTL_INFO *)buf); 5729 LocalFree(buf); 5730 buf = NULL; 5731 } 5732 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0; 5733 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0; 5734 info.SubjectAlgorithm.pszObjId = oid2; 5735 info.SubjectAlgorithm.Parameters.cbData = sizeof(nullData); 5736 info.SubjectAlgorithm.Parameters.pbData = nullData; 5737 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithAlgId, 5738 sizeof(ctlWithAlgId), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5739 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5740 if (ret) 5741 { 5742 compareCTLInfo("CTL with algorithm identifier", &info, (CTL_INFO *)buf); 5743 LocalFree(buf); 5744 buf = NULL; 5745 } 5746 SetLastError(0xdeadbeef); 5747 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithBogusEntry, 5748 sizeof(ctlWithBogusEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5749 ok(!ret && 5750 (GetLastError() == CRYPT_E_ASN1_EOD || 5751 GetLastError() == CRYPT_E_ASN1_CORRUPT || 5752 GetLastError() == OSS_MORE_INPUT), /* Win9x */ 5753 "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n", 5754 GetLastError()); 5755 info.SubjectAlgorithm.Parameters.cbData = 0; 5756 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0; 5757 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0; 5758 info.SubjectAlgorithm.pszObjId = NULL; 5759 value1.cbData = sizeof(emptySequence); 5760 value1.pbData = (LPBYTE)emptySequence; 5761 attr1.pszObjId = oid1; 5762 attr1.cValue = 1; 5763 attr1.rgValue = &value1; 5764 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum); 5765 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum; 5766 ctlEntry[0].cAttribute = 1; 5767 ctlEntry[0].rgAttribute = &attr1; 5768 info.cCTLEntry = 1; 5769 info.rgCTLEntry = ctlEntry; 5770 SetLastError(0xdeadbeef); 5771 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithOneEntry, 5772 sizeof(ctlWithOneEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5773 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5774 if (ret) 5775 { 5776 compareCTLInfo("CTL with one entry", &info, (CTL_INFO *)buf); 5777 LocalFree(buf); 5778 buf = NULL; 5779 } 5780 value2.cbData = sizeof(encodedIPAddr); 5781 value2.pbData = (LPBYTE)encodedIPAddr; 5782 attr2.pszObjId = oid2; 5783 attr2.cValue = 1; 5784 attr2.rgValue = &value2; 5785 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum); 5786 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum; 5787 ctlEntry[1].cAttribute = 1; 5788 ctlEntry[1].rgAttribute = &attr2; 5789 info.cCTLEntry = 2; 5790 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithTwoEntries, 5791 sizeof(ctlWithTwoEntries), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5792 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5793 if (ret) 5794 { 5795 compareCTLInfo("CTL with two entries", &info, (CTL_INFO *)buf); 5796 LocalFree(buf); 5797 buf = NULL; 5798 } 5799 /* A signed CTL isn't decodable, even if the inner content is a CTL */ 5800 SetLastError(0xdeadbeef); 5801 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, signedCTL, 5802 sizeof(signedCTL), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5803 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || 5804 GetLastError() == OSS_DATA_ERROR /* Win9x */), 5805 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n", 5806 GetLastError()); 5807 SetLastError(0xdeadbeef); 5808 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, 5809 signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent), 5810 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5811 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || 5812 GetLastError() == OSS_DATA_ERROR /* Win9x */), 5813 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n", 5814 GetLastError()); 5815 } 5816 5817 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 }; 5818 static const BYTE emptyPKCSContentInfoExtraBytes[] = { 0x30,0x04,0x06,0x02,0x2a, 5819 0x03,0,0,0,0,0,0 }; 5820 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03, 5821 0xa0,0x01,0x01 }; 5822 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0, 5823 0x03,0x02,0x01,0x01 }; 5824 static BYTE bogusDER[] = { 1 }; 5825 5826 static void test_encodePKCSContentInfo(DWORD dwEncoding) 5827 { 5828 BOOL ret; 5829 BYTE *buf = NULL; 5830 DWORD size = 0; 5831 CRYPT_CONTENT_INFO info = { 0 }; 5832 char oid1[] = "1.2.3"; 5833 5834 if (0) 5835 { 5836 /* Crashes on win9x */ 5837 SetLastError(0xdeadbeef); 5838 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL, 5839 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5840 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 5841 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError()); 5842 } 5843 SetLastError(0xdeadbeef); 5844 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info, 5845 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5846 ok(!ret && (GetLastError() == E_INVALIDARG || 5847 GetLastError() == OSS_LIMITED /* Win9x */), 5848 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError()); 5849 info.pszObjId = oid1; 5850 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info, 5851 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5852 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 5853 if (ret) 5854 { 5855 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size); 5856 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n"); 5857 LocalFree(buf); 5858 } 5859 info.Content.pbData = bogusDER; 5860 info.Content.cbData = sizeof(bogusDER); 5861 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info, 5862 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5863 ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError()); 5864 if (ret) 5865 { 5866 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size); 5867 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n"); 5868 LocalFree(buf); 5869 } 5870 info.Content.pbData = (BYTE *)ints[0].encoded; 5871 info.Content.cbData = ints[0].encoded[1] + 2; 5872 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info, 5873 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5874 if (ret) 5875 { 5876 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size); 5877 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n"); 5878 LocalFree(buf); 5879 } 5880 } 5881 5882 static const BYTE indefiniteSignedPKCSContent[] = { 5883 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80, 5884 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86, 5885 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7, 5886 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04, 5887 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30, 5888 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11, 5889 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 5890 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30, 5891 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30, 5892 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06, 5893 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67, 5894 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01, 5895 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7, 5896 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21, 5897 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3, 5898 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21, 5899 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79, 5900 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d, 5901 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31, 5902 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06, 5903 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67, 5904 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02, 5905 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad, 5906 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8, 5907 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3, 5908 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d, 5909 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61, 5910 0x00,0x00,0x00,0x00,0x00,0x00 }; 5911 5912 static void test_decodePKCSContentInfo(DWORD dwEncoding) 5913 { 5914 BOOL ret; 5915 LPBYTE buf = NULL; 5916 DWORD size = 0; 5917 CRYPT_CONTENT_INFO *info; 5918 5919 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, 5920 emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo), 5921 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5922 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 5923 if (ret) 5924 { 5925 info = (CRYPT_CONTENT_INFO *)buf; 5926 5927 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n", 5928 info->pszObjId); 5929 ok(info->Content.cbData == 0, "Expected no data, got %d\n", 5930 info->Content.cbData); 5931 LocalFree(buf); 5932 } 5933 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, 5934 emptyPKCSContentInfoExtraBytes, sizeof(emptyPKCSContentInfoExtraBytes), 5935 0, NULL, NULL, &size); 5936 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 5937 SetLastError(0xdeadbeef); 5938 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, 5939 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo), 5940 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5941 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as 5942 * I doubt an app depends on that. 5943 */ 5944 ok((!ret && (GetLastError() == CRYPT_E_ASN1_EOD || 5945 GetLastError() == CRYPT_E_ASN1_CORRUPT)) || broken(ret), 5946 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n", 5947 GetLastError()); 5948 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, 5949 intPKCSContentInfo, sizeof(intPKCSContentInfo), 5950 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5951 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 5952 if (ret) 5953 { 5954 info = (CRYPT_CONTENT_INFO *)buf; 5955 5956 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n", 5957 info->pszObjId); 5958 ok(info->Content.cbData == ints[0].encoded[1] + 2, 5959 "Unexpected size %d\n", info->Content.cbData); 5960 ok(!memcmp(info->Content.pbData, ints[0].encoded, 5961 info->Content.cbData), "Unexpected value\n"); 5962 LocalFree(buf); 5963 } 5964 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, 5965 indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent), 5966 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5967 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 5968 if (ret) 5969 { 5970 info = (CRYPT_CONTENT_INFO *)buf; 5971 5972 ok(!strcmp(info->pszObjId, szOID_RSA_signedData), 5973 "Expected %s, got %s\n", szOID_RSA_signedData, info->pszObjId); 5974 ok(info->Content.cbData == 392, "Expected 392, got %d\n", 5975 info->Content.cbData); 5976 LocalFree(buf); 5977 } 5978 } 5979 5980 static const BYTE emptyPKCSAttr[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31, 5981 0x00 }; 5982 static const BYTE bogusPKCSAttr[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01, 5983 0x01 }; 5984 static const BYTE intPKCSAttr[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03, 5985 0x02,0x01,0x01 }; 5986 5987 static void test_encodePKCSAttribute(DWORD dwEncoding) 5988 { 5989 CRYPT_ATTRIBUTE attr = { 0 }; 5990 BOOL ret; 5991 LPBYTE buf = NULL; 5992 DWORD size = 0; 5993 CRYPT_ATTR_BLOB blob; 5994 char oid[] = "1.2.3"; 5995 5996 if (0) 5997 { 5998 /* Crashes on win9x */ 5999 SetLastError(0xdeadbeef); 6000 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, NULL, 6001 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6002 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 6003 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError()); 6004 } 6005 SetLastError(0xdeadbeef); 6006 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr, 6007 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6008 ok(!ret && (GetLastError() == E_INVALIDARG || 6009 GetLastError() == OSS_LIMITED /* Win9x */), 6010 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError()); 6011 attr.pszObjId = oid; 6012 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr, 6013 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6014 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6015 if (ret) 6016 { 6017 ok(size == sizeof(emptyPKCSAttr), "Unexpected size %d\n", size); 6018 ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n"); 6019 LocalFree(buf); 6020 } 6021 blob.cbData = sizeof(bogusDER); 6022 blob.pbData = bogusDER; 6023 attr.cValue = 1; 6024 attr.rgValue = &blob; 6025 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr, 6026 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6027 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6028 if (ret) 6029 { 6030 ok(size == sizeof(bogusPKCSAttr), "Unexpected size %d\n", size); 6031 ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n"); 6032 LocalFree(buf); 6033 } 6034 blob.pbData = (BYTE *)ints[0].encoded; 6035 blob.cbData = ints[0].encoded[1] + 2; 6036 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr, 6037 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6038 if (ret) 6039 { 6040 ok(size == sizeof(intPKCSAttr), "Unexpected size %d\n", size); 6041 ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n"); 6042 LocalFree(buf); 6043 } 6044 } 6045 6046 static void test_decodePKCSAttribute(DWORD dwEncoding) 6047 { 6048 BOOL ret; 6049 LPBYTE buf = NULL; 6050 DWORD size = 0; 6051 CRYPT_ATTRIBUTE *attr; 6052 6053 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, 6054 emptyPKCSAttr, sizeof(emptyPKCSAttr), 6055 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 6056 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 6057 if (ret) 6058 { 6059 attr = (CRYPT_ATTRIBUTE *)buf; 6060 6061 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n", 6062 attr->pszObjId); 6063 ok(attr->cValue == 0, "Expected no value, got %d\n", attr->cValue); 6064 LocalFree(buf); 6065 } 6066 SetLastError(0xdeadbeef); 6067 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, 6068 bogusPKCSAttr, sizeof(bogusPKCSAttr), 6069 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 6070 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as 6071 * I doubt an app depends on that. 6072 */ 6073 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD || 6074 GetLastError() == CRYPT_E_ASN1_CORRUPT || 6075 GetLastError() == OSS_MORE_INPUT /* Win9x */), 6076 "Expected CRYPT_E_ASN1_EOD, CRYPT_E_ASN1_CORRUPT, or OSS_MORE_INPUT, got %x\n", 6077 GetLastError()); 6078 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, 6079 intPKCSAttr, sizeof(intPKCSAttr), 6080 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 6081 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 6082 if (ret) 6083 { 6084 attr = (CRYPT_ATTRIBUTE *)buf; 6085 6086 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n", 6087 attr->pszObjId); 6088 ok(attr->cValue == 1, "Expected 1 value, got %d\n", attr->cValue); 6089 ok(attr->rgValue[0].cbData == ints[0].encoded[1] + 2, 6090 "Unexpected size %d\n", attr->rgValue[0].cbData); 6091 ok(!memcmp(attr->rgValue[0].pbData, ints[0].encoded, 6092 attr->rgValue[0].cbData), "Unexpected value\n"); 6093 LocalFree(buf); 6094 } 6095 } 6096 6097 static const BYTE emptyPKCSAttributes[] = { 0x31,0x00 }; 6098 static const BYTE singlePKCSAttributes[] = { 0x31,0x08,0x30,0x06,0x06,0x02, 6099 0x2a,0x03,0x31,0x00 }; 6100 static const BYTE doublePKCSAttributes[] = { 0x31,0x13,0x30,0x06,0x06,0x02, 6101 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 }; 6102 6103 static void test_encodePKCSAttributes(DWORD dwEncoding) 6104 { 6105 CRYPT_ATTRIBUTES attributes = { 0 }; 6106 CRYPT_ATTRIBUTE attr[2] = { { 0 } }; 6107 CRYPT_ATTR_BLOB blob; 6108 BOOL ret; 6109 LPBYTE buf = NULL; 6110 DWORD size = 0; 6111 char oid1[] = "1.2.3", oid2[] = "1.5.6"; 6112 6113 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes, 6114 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6115 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6116 if (ret) 6117 { 6118 ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %d\n", size); 6119 ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n"); 6120 LocalFree(buf); 6121 } 6122 attributes.cAttr = 1; 6123 attributes.rgAttr = attr; 6124 SetLastError(0xdeadbeef); 6125 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes, 6126 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6127 ok(!ret && (GetLastError() == E_INVALIDARG || 6128 GetLastError() == OSS_LIMITED /* Win9x */), 6129 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError()); 6130 attr[0].pszObjId = oid1; 6131 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes, 6132 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6133 if (ret) 6134 { 6135 ok(size == sizeof(singlePKCSAttributes), "Unexpected size %d\n", size); 6136 ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n"); 6137 LocalFree(buf); 6138 } 6139 attr[1].pszObjId = oid2; 6140 attr[1].cValue = 1; 6141 attr[1].rgValue = &blob; 6142 blob.pbData = (BYTE *)ints[0].encoded; 6143 blob.cbData = ints[0].encoded[1] + 2; 6144 attributes.cAttr = 2; 6145 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes, 6146 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6147 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6148 if (ret) 6149 { 6150 ok(size == sizeof(doublePKCSAttributes), "Unexpected size %d\n", size); 6151 ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n"); 6152 LocalFree(buf); 6153 } 6154 } 6155 6156 static void test_decodePKCSAttributes(DWORD dwEncoding) 6157 { 6158 BOOL ret; 6159 LPBYTE buf = NULL; 6160 DWORD size = 0; 6161 CRYPT_ATTRIBUTES *attributes; 6162 6163 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, 6164 emptyPKCSAttributes, sizeof(emptyPKCSAttributes), 6165 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 6166 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 6167 if (ret) 6168 { 6169 attributes = (CRYPT_ATTRIBUTES *)buf; 6170 ok(attributes->cAttr == 0, "Expected no attributes, got %d\n", 6171 attributes->cAttr); 6172 LocalFree(buf); 6173 } 6174 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, 6175 singlePKCSAttributes, sizeof(singlePKCSAttributes), 6176 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 6177 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 6178 if (ret) 6179 { 6180 attributes = (CRYPT_ATTRIBUTES *)buf; 6181 ok(attributes->cAttr == 1, "Expected 1 attribute, got %d\n", 6182 attributes->cAttr); 6183 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"), 6184 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId); 6185 ok(attributes->rgAttr[0].cValue == 0, 6186 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue); 6187 LocalFree(buf); 6188 } 6189 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, 6190 doublePKCSAttributes, sizeof(doublePKCSAttributes), 6191 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 6192 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 6193 if (ret) 6194 { 6195 attributes = (CRYPT_ATTRIBUTES *)buf; 6196 ok(attributes->cAttr == 2, "Expected 2 attributes, got %d\n", 6197 attributes->cAttr); 6198 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"), 6199 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId); 6200 ok(attributes->rgAttr[0].cValue == 0, 6201 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue); 6202 ok(!strcmp(attributes->rgAttr[1].pszObjId, "1.5.6"), 6203 "Expected 1.5.6, got %s\n", attributes->rgAttr[1].pszObjId); 6204 ok(attributes->rgAttr[1].cValue == 1, 6205 "Expected 1 attribute, got %d\n", attributes->rgAttr[1].cValue); 6206 ok(attributes->rgAttr[1].rgValue[0].cbData == ints[0].encoded[1] + 2, 6207 "Unexpected size %d\n", attributes->rgAttr[1].rgValue[0].cbData); 6208 ok(!memcmp(attributes->rgAttr[1].rgValue[0].pbData, ints[0].encoded, 6209 attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n"); 6210 LocalFree(buf); 6211 } 6212 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, 6213 doublePKCSAttributes, sizeof(doublePKCSAttributes), 0, NULL, NULL, &size); 6214 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 6215 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); 6216 if (buf) 6217 { 6218 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, 6219 doublePKCSAttributes, sizeof(doublePKCSAttributes), 0, NULL, buf, &size); 6220 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 6221 HeapFree(GetProcessHeap(), 0, buf); 6222 } 6223 } 6224 6225 static const BYTE singleCapability[] = { 6226 0x30,0x06,0x30,0x04,0x06,0x02,0x2d,0x06 }; 6227 static const BYTE twoCapabilities[] = { 6228 0x30,0x0c,0x30,0x04,0x06,0x02,0x2d,0x06,0x30,0x04,0x06,0x02,0x2a,0x03 }; 6229 static const BYTE singleCapabilitywithNULL[] = { 6230 0x30,0x08,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 }; 6231 6232 static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding) 6233 { 6234 static char oid1[] = "1.5.6", oid2[] = "1.2.3"; 6235 BOOL ret; 6236 LPBYTE buf = NULL; 6237 DWORD size = 0; 6238 CRYPT_SMIME_CAPABILITY capability[2]; 6239 CRYPT_SMIME_CAPABILITIES capabilities; 6240 6241 /* An empty capabilities is allowed */ 6242 capabilities.cCapability = 0; 6243 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES, 6244 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6245 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 6246 if (ret) 6247 { 6248 ok(size == sizeof(emptySequence), "unexpected size %d\n", size); 6249 ok(!memcmp(buf, emptySequence, size), "unexpected value\n"); 6250 LocalFree(buf); 6251 } 6252 /* A non-empty capabilities with an empty capability (lacking an OID) is 6253 * not allowed 6254 */ 6255 capability[0].pszObjId = NULL; 6256 capability[0].Parameters.cbData = 0; 6257 capabilities.cCapability = 1; 6258 capabilities.rgCapability = capability; 6259 SetLastError(0xdeadbeef); 6260 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES, 6261 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6262 ok(!ret && (GetLastError() == E_INVALIDARG || 6263 GetLastError() == OSS_LIMITED /* Win9x */), 6264 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError()); 6265 capability[0].pszObjId = oid1; 6266 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES, 6267 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6268 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 6269 if (ret) 6270 { 6271 ok(size == sizeof(singleCapability), "unexpected size %d\n", size); 6272 ok(!memcmp(buf, singleCapability, size), "unexpected value\n"); 6273 LocalFree(buf); 6274 } 6275 capability[1].pszObjId = oid2; 6276 capability[1].Parameters.cbData = 0; 6277 capabilities.cCapability = 2; 6278 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES, 6279 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6280 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 6281 if (ret) 6282 { 6283 ok(size == sizeof(twoCapabilities), "unexpected size %d\n", size); 6284 ok(!memcmp(buf, twoCapabilities, size), "unexpected value\n"); 6285 LocalFree(buf); 6286 } 6287 } 6288 6289 static void compareSMimeCapabilities(LPCSTR header, 6290 const CRYPT_SMIME_CAPABILITIES *expected, const CRYPT_SMIME_CAPABILITIES *got) 6291 { 6292 DWORD i; 6293 6294 ok(got->cCapability == expected->cCapability, 6295 "%s: expected %d capabilities, got %d\n", header, expected->cCapability, 6296 got->cCapability); 6297 for (i = 0; i < expected->cCapability; i++) 6298 { 6299 ok(!strcmp(expected->rgCapability[i].pszObjId, 6300 got->rgCapability[i].pszObjId), "%s[%d]: expected %s, got %s\n", 6301 header, i, expected->rgCapability[i].pszObjId, 6302 got->rgCapability[i].pszObjId); 6303 ok(expected->rgCapability[i].Parameters.cbData == 6304 got->rgCapability[i].Parameters.cbData, 6305 "%s[%d]: expected %d bytes, got %d\n", header, i, 6306 expected->rgCapability[i].Parameters.cbData, 6307 got->rgCapability[i].Parameters.cbData); 6308 if (expected->rgCapability[i].Parameters.cbData) 6309 ok(!memcmp(expected->rgCapability[i].Parameters.pbData, 6310 got->rgCapability[i].Parameters.pbData, 6311 expected->rgCapability[i].Parameters.cbData), 6312 "%s[%d]: unexpected value\n", header, i); 6313 } 6314 } 6315 6316 static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding) 6317 { 6318 static char oid1[] = "1.5.6", oid2[] = "1.2.3"; 6319 BOOL ret; 6320 DWORD size = 0; 6321 CRYPT_SMIME_CAPABILITY capability[2]; 6322 CRYPT_SMIME_CAPABILITIES capabilities, *ptr; 6323 6324 SetLastError(0xdeadbeef); 6325 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES, 6326 emptySequence, sizeof(emptySequence), 6327 CRYPT_DECODE_ALLOC_FLAG, NULL, &ptr, &size); 6328 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 6329 if (ret) 6330 { 6331 capabilities.cCapability = 0; 6332 compareSMimeCapabilities("empty capabilities", &capabilities, ptr); 6333 LocalFree(ptr); 6334 } 6335 SetLastError(0xdeadbeef); 6336 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES, 6337 singleCapability, sizeof(singleCapability), CRYPT_DECODE_ALLOC_FLAG, NULL, 6338 &ptr, &size); 6339 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 6340 if (ret) 6341 { 6342 capability[0].pszObjId = oid1; 6343 capability[0].Parameters.cbData = 0; 6344 capabilities.cCapability = 1; 6345 capabilities.rgCapability = capability; 6346 compareSMimeCapabilities("single capability", &capabilities, ptr); 6347 LocalFree(ptr); 6348 } 6349 SetLastError(0xdeadbeef); 6350 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES, 6351 singleCapabilitywithNULL, sizeof(singleCapabilitywithNULL), 6352 CRYPT_DECODE_ALLOC_FLAG, NULL, &ptr, &size); 6353 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 6354 if (ret) 6355 { 6356 BYTE NULLparam[] = {0x05, 0x00}; 6357 capability[0].pszObjId = oid1; 6358 capability[0].Parameters.cbData = 2; 6359 capability[0].Parameters.pbData = NULLparam; 6360 capabilities.cCapability = 1; 6361 capabilities.rgCapability = capability; 6362 compareSMimeCapabilities("single capability with NULL", &capabilities, 6363 ptr); 6364 LocalFree(ptr); 6365 } 6366 SetLastError(0xdeadbeef); 6367 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES, 6368 twoCapabilities, sizeof(twoCapabilities), CRYPT_DECODE_ALLOC_FLAG, NULL, 6369 &ptr, &size); 6370 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 6371 if (ret) 6372 { 6373 capability[0].Parameters.cbData = 0; 6374 capability[1].pszObjId = oid2; 6375 capability[1].Parameters.cbData = 0; 6376 capabilities.cCapability = 2; 6377 compareSMimeCapabilities("two capabilities", &capabilities, ptr); 6378 LocalFree(ptr); 6379 } 6380 SetLastError(0xdeadbeef); 6381 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES, 6382 twoCapabilities, sizeof(twoCapabilities), 0, NULL, NULL, &size); 6383 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 6384 ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); 6385 if (ptr) 6386 { 6387 SetLastError(0xdeadbeef); 6388 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES, 6389 twoCapabilities, sizeof(twoCapabilities), 0, NULL, ptr, &size); 6390 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 6391 HeapFree(GetProcessHeap(), 0, ptr); 6392 } 6393 } 6394 6395 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10, 6396 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 6397 0x67 }; 6398 static const BYTE minimalPKCSSigner[] = { 6399 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03, 6400 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02, 6401 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 }; 6402 static const BYTE PKCSSignerWithSerial[] = { 6403 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03, 6404 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02, 6405 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04, 6406 0x00 }; 6407 static const BYTE PKCSSignerWithHashAlgo[] = { 6408 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03, 6409 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02, 6410 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05, 6411 0x00,0x04,0x00 }; 6412 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = { 6413 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03, 6414 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02, 6415 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d, 6416 0x06,0x05,0x00,0x04,0x00 }; 6417 static const BYTE PKCSSignerWithHash[] = { 6418 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03, 6419 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02, 6420 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d, 6421 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09, 6422 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f }; 6423 static const BYTE PKCSSignerWithAuthAttr[] = { 6424 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03, 6425 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02, 6426 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06, 6427 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55, 6428 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30, 6429 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05, 6430 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f }; 6431 6432 static void test_encodePKCSSignerInfo(DWORD dwEncoding) 6433 { 6434 static char oid1[] = "1.2.3", oid2[] = "1.5.6"; 6435 BOOL ret; 6436 LPBYTE buf = NULL; 6437 DWORD size = 0; 6438 CMSG_SIGNER_INFO info = { 0 }; 6439 char oid_common_name[] = szOID_COMMON_NAME; 6440 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName), 6441 (LPBYTE)encodedCommonName }; 6442 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName }; 6443 6444 SetLastError(0xdeadbeef); 6445 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info, 6446 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6447 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 6448 { 6449 skip("no PKCS7_SIGNER_INFO encode support\n"); 6450 return; 6451 } 6452 ok(!ret && (GetLastError() == E_INVALIDARG || 6453 GetLastError() == OSS_LIMITED /* Win9x */), 6454 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError()); 6455 /* To be encoded, a signer must have an issuer at least, and the encoding 6456 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded, 6457 * see decoding tests.) 6458 */ 6459 info.Issuer.cbData = sizeof(encodedCommonNameNoNull); 6460 info.Issuer.pbData = encodedCommonNameNoNull; 6461 SetLastError(0xdeadbeef); 6462 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info, 6463 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6464 if (!(dwEncoding & PKCS_7_ASN_ENCODING)) 6465 ok(!ret && GetLastError() == E_INVALIDARG, 6466 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 6467 else 6468 { 6469 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */), 6470 "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6471 if (ret) 6472 { 6473 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size); 6474 if (size == sizeof(minimalPKCSSigner)) 6475 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n"); 6476 else 6477 ok(0, "Unexpected value\n"); 6478 LocalFree(buf); 6479 } 6480 } 6481 info.SerialNumber.cbData = sizeof(serialNum); 6482 info.SerialNumber.pbData = (BYTE *)serialNum; 6483 SetLastError(0xdeadbeef); 6484 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info, 6485 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6486 if (!(dwEncoding & PKCS_7_ASN_ENCODING)) 6487 ok(!ret && GetLastError() == E_INVALIDARG, 6488 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 6489 else 6490 { 6491 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */), 6492 "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6493 if (ret) 6494 { 6495 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n", 6496 size); 6497 if (size == sizeof(PKCSSignerWithSerial)) 6498 ok(!memcmp(buf, PKCSSignerWithSerial, size), 6499 "Unexpected value\n"); 6500 else 6501 ok(0, "Unexpected value\n"); 6502 LocalFree(buf); 6503 } 6504 } 6505 info.HashAlgorithm.pszObjId = oid1; 6506 SetLastError(0xdeadbeef); 6507 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info, 6508 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6509 if (!(dwEncoding & PKCS_7_ASN_ENCODING)) 6510 ok(!ret && GetLastError() == E_INVALIDARG, 6511 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 6512 else 6513 { 6514 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */), 6515 "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6516 if (ret) 6517 { 6518 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n", 6519 size); 6520 if (size == sizeof(PKCSSignerWithHashAlgo)) 6521 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size), 6522 "Unexpected value\n"); 6523 else 6524 ok(0, "Unexpected value\n"); 6525 LocalFree(buf); 6526 } 6527 } 6528 info.HashEncryptionAlgorithm.pszObjId = oid2; 6529 SetLastError(0xdeadbeef); 6530 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info, 6531 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6532 if (!(dwEncoding & PKCS_7_ASN_ENCODING)) 6533 ok(!ret && GetLastError() == E_INVALIDARG, 6534 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 6535 else 6536 { 6537 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6538 if (ret) 6539 { 6540 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo), 6541 "Unexpected size %d\n", size); 6542 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo)) 6543 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size), 6544 "Unexpected value\n"); 6545 else 6546 ok(0, "Unexpected value\n"); 6547 LocalFree(buf); 6548 } 6549 } 6550 info.EncryptedHash.cbData = sizeof(hash); 6551 info.EncryptedHash.pbData = (BYTE *)hash; 6552 SetLastError(0xdeadbeef); 6553 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info, 6554 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6555 if (!(dwEncoding & PKCS_7_ASN_ENCODING)) 6556 ok(!ret && GetLastError() == E_INVALIDARG, 6557 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 6558 else 6559 { 6560 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6561 if (ret) 6562 { 6563 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n", 6564 size); 6565 if (size == sizeof(PKCSSignerWithHash)) 6566 ok(!memcmp(buf, PKCSSignerWithHash, size), 6567 "Unexpected value\n"); 6568 else 6569 ok(0, "Unexpected value\n"); 6570 LocalFree(buf); 6571 } 6572 } 6573 info.AuthAttrs.cAttr = 1; 6574 info.AuthAttrs.rgAttr = &attr; 6575 SetLastError(0xdeadbeef); 6576 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info, 6577 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6578 if (!(dwEncoding & PKCS_7_ASN_ENCODING)) 6579 ok(!ret && GetLastError() == E_INVALIDARG, 6580 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 6581 else 6582 { 6583 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6584 if (ret) 6585 { 6586 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n", 6587 size); 6588 if (size == sizeof(PKCSSignerWithAuthAttr)) 6589 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size), 6590 "Unexpected value\n"); 6591 else 6592 ok(0, "Unexpected value\n"); 6593 LocalFree(buf); 6594 } 6595 } 6596 } 6597 6598 static void test_decodePKCSSignerInfo(DWORD dwEncoding) 6599 { 6600 BOOL ret; 6601 LPBYTE buf = NULL; 6602 DWORD size = 0; 6603 CMSG_SIGNER_INFO *info; 6604 6605 /* A PKCS signer can't be decoded without a serial number. */ 6606 SetLastError(0xdeadbeef); 6607 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, 6608 minimalPKCSSigner, sizeof(minimalPKCSSigner), 6609 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 6610 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT || 6611 GetLastError() == OSS_DATA_ERROR /* Win9x */), 6612 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %x\n", 6613 GetLastError()); 6614 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, 6615 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial), 6616 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 6617 ok(ret || broken(GetLastError() == OSS_DATA_ERROR), 6618 "CryptDecodeObjectEx failed: %x\n", GetLastError()); 6619 if (ret) 6620 { 6621 info = (CMSG_SIGNER_INFO *)buf; 6622 ok(info->dwVersion == 0, "Expected version 0, got %d\n", 6623 info->dwVersion); 6624 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull), 6625 "Unexpected size %d\n", info->Issuer.cbData); 6626 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull, 6627 info->Issuer.cbData), "Unexpected value\n"); 6628 ok(info->SerialNumber.cbData == sizeof(serialNum), 6629 "Unexpected size %d\n", info->SerialNumber.cbData); 6630 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)), 6631 "Unexpected value\n"); 6632 LocalFree(buf); 6633 } 6634 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, 6635 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo), 6636 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 6637 if (ret) 6638 { 6639 info = (CMSG_SIGNER_INFO *)buf; 6640 ok(info->dwVersion == 0, "Expected version 0, got %d\n", 6641 info->dwVersion); 6642 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull), 6643 "Unexpected size %d\n", info->Issuer.cbData); 6644 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull, 6645 info->Issuer.cbData), "Unexpected value\n"); 6646 ok(info->SerialNumber.cbData == sizeof(serialNum), 6647 "Unexpected size %d\n", info->SerialNumber.cbData); 6648 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)), 6649 "Unexpected value\n"); 6650 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"), 6651 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId); 6652 LocalFree(buf); 6653 } 6654 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, 6655 PKCSSignerWithHashAndEncryptionAlgo, 6656 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG, 6657 NULL, &buf, &size); 6658 if (ret) 6659 { 6660 info = (CMSG_SIGNER_INFO *)buf; 6661 ok(info->dwVersion == 0, "Expected version 0, got %d\n", 6662 info->dwVersion); 6663 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull), 6664 "Unexpected size %d\n", info->Issuer.cbData); 6665 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull, 6666 info->Issuer.cbData), "Unexpected value\n"); 6667 ok(info->SerialNumber.cbData == sizeof(serialNum), 6668 "Unexpected size %d\n", info->SerialNumber.cbData); 6669 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)), 6670 "Unexpected value\n"); 6671 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"), 6672 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId); 6673 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"), 6674 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId); 6675 LocalFree(buf); 6676 } 6677 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, 6678 PKCSSignerWithHash, sizeof(PKCSSignerWithHash), 6679 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 6680 if (ret) 6681 { 6682 info = (CMSG_SIGNER_INFO *)buf; 6683 ok(info->dwVersion == 0, "Expected version 0, got %d\n", 6684 info->dwVersion); 6685 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull), 6686 "Unexpected size %d\n", info->Issuer.cbData); 6687 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull, 6688 info->Issuer.cbData), "Unexpected value\n"); 6689 ok(info->SerialNumber.cbData == sizeof(serialNum), 6690 "Unexpected size %d\n", info->SerialNumber.cbData); 6691 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)), 6692 "Unexpected value\n"); 6693 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"), 6694 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId); 6695 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"), 6696 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId); 6697 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n", 6698 info->EncryptedHash.cbData); 6699 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)), 6700 "Unexpected value\n"); 6701 LocalFree(buf); 6702 } 6703 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, 6704 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr), 6705 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 6706 if (ret) 6707 { 6708 info = (CMSG_SIGNER_INFO *)buf; 6709 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n", 6710 info->AuthAttrs.cAttr); 6711 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME), 6712 "Expected %s, got %s\n", szOID_COMMON_NAME, 6713 info->AuthAttrs.rgAttr[0].pszObjId); 6714 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n", 6715 info->AuthAttrs.rgAttr[0].cValue); 6716 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData == 6717 sizeof(encodedCommonName), "Unexpected size %d\n", 6718 info->AuthAttrs.rgAttr[0].rgValue[0].cbData); 6719 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData, 6720 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n"); 6721 LocalFree(buf); 6722 } 6723 } 6724 6725 static const BYTE CMSSignerWithKeyId[] = { 6726 0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30, 6727 0x04,0x06,0x00,0x05,0x00,0x04,0x00 }; 6728 6729 static void test_encodeCMSSignerInfo(DWORD dwEncoding) 6730 { 6731 BOOL ret; 6732 LPBYTE buf = NULL; 6733 DWORD size = 0; 6734 CMSG_CMS_SIGNER_INFO info = { 0 }; 6735 static char oid1[] = "1.2.3", oid2[] = "1.5.6"; 6736 6737 SetLastError(0xdeadbeef); 6738 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, 6739 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6740 ok(!ret, "Expected failure, got %d\n", ret); 6741 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 6742 { 6743 skip("no CMS_SIGNER_INFO encode support\n"); 6744 return; 6745 } 6746 ok(GetLastError() == E_INVALIDARG, 6747 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 6748 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER; 6749 SetLastError(0xdeadbeef); 6750 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, 6751 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6752 ok(!ret, "Expected failure, got %d\n", ret); 6753 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 6754 { 6755 skip("no CMS_SIGNER_INFO encode support\n"); 6756 return; 6757 } 6758 ok(GetLastError() == E_INVALIDARG, 6759 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 6760 /* To be encoded, a signer must have a valid cert ID, where a valid ID may 6761 * be a key id or an issuer serial number with at least the issuer set, and 6762 * the encoding must include PKCS_7_ASN_ENCODING. 6763 * (That isn't enough to be decoded, see decoding tests.) 6764 */ 6765 U(info.SignerId).IssuerSerialNumber.Issuer.cbData = 6766 sizeof(encodedCommonNameNoNull); 6767 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull; 6768 SetLastError(0xdeadbeef); 6769 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, 6770 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6771 if (!(dwEncoding & PKCS_7_ASN_ENCODING)) 6772 ok(!ret && GetLastError() == E_INVALIDARG, 6773 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 6774 else 6775 { 6776 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6777 if (ret) 6778 { 6779 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size); 6780 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n"); 6781 LocalFree(buf); 6782 } 6783 } 6784 U(info.SignerId).IssuerSerialNumber.SerialNumber.cbData = sizeof(serialNum); 6785 U(info.SignerId).IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum; 6786 SetLastError(0xdeadbeef); 6787 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, 6788 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6789 if (!(dwEncoding & PKCS_7_ASN_ENCODING)) 6790 ok(!ret && GetLastError() == E_INVALIDARG, 6791 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 6792 else 6793 { 6794 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6795 if (ret) 6796 { 6797 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n", 6798 size); 6799 ok(!memcmp(buf, PKCSSignerWithSerial, size), "Unexpected value\n"); 6800 LocalFree(buf); 6801 } 6802 } 6803 info.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER; 6804 U(info.SignerId).KeyId.cbData = sizeof(serialNum); 6805 U(info.SignerId).KeyId.pbData = (BYTE *)serialNum; 6806 SetLastError(0xdeadbeef); 6807 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, 6808 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6809 if (!(dwEncoding & PKCS_7_ASN_ENCODING)) 6810 ok(!ret && GetLastError() == E_INVALIDARG, 6811 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 6812 else 6813 { 6814 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6815 if (ret) 6816 { 6817 ok(size == sizeof(CMSSignerWithKeyId), "Unexpected size %d\n", 6818 size); 6819 ok(!memcmp(buf, CMSSignerWithKeyId, size), "Unexpected value\n"); 6820 LocalFree(buf); 6821 } 6822 } 6823 /* While a CERT_ID can have a hash type, that's not allowed in CMS, where 6824 * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed 6825 * (see RFC 3852, section 5.3.) 6826 */ 6827 info.SignerId.dwIdChoice = CERT_ID_SHA1_HASH; 6828 U(info.SignerId).HashId.cbData = sizeof(hash); 6829 U(info.SignerId).HashId.pbData = (BYTE *)hash; 6830 SetLastError(0xdeadbeef); 6831 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, 6832 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6833 ok(!ret && GetLastError() == E_INVALIDARG, 6834 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 6835 /* Now with a hash algo */ 6836 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER; 6837 U(info.SignerId).IssuerSerialNumber.Issuer.cbData = 6838 sizeof(encodedCommonNameNoNull); 6839 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull; 6840 info.HashAlgorithm.pszObjId = oid1; 6841 SetLastError(0xdeadbeef); 6842 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, 6843 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6844 if (!(dwEncoding & PKCS_7_ASN_ENCODING)) 6845 ok(!ret && GetLastError() == E_INVALIDARG, 6846 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 6847 else 6848 { 6849 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6850 if (ret) 6851 { 6852 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n", 6853 size); 6854 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size), 6855 "Unexpected value\n"); 6856 LocalFree(buf); 6857 } 6858 } 6859 info.HashEncryptionAlgorithm.pszObjId = oid2; 6860 SetLastError(0xdeadbeef); 6861 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, 6862 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6863 if (!(dwEncoding & PKCS_7_ASN_ENCODING)) 6864 ok(!ret && GetLastError() == E_INVALIDARG, 6865 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 6866 else 6867 { 6868 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6869 if (ret) 6870 { 6871 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo), 6872 "Unexpected size %d\n", size); 6873 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size), 6874 "Unexpected value\n"); 6875 LocalFree(buf); 6876 } 6877 } 6878 info.EncryptedHash.cbData = sizeof(hash); 6879 info.EncryptedHash.pbData = (BYTE *)hash; 6880 SetLastError(0xdeadbeef); 6881 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, 6882 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6883 if (!(dwEncoding & PKCS_7_ASN_ENCODING)) 6884 ok(!ret && GetLastError() == E_INVALIDARG, 6885 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 6886 else 6887 { 6888 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6889 if (ret) 6890 { 6891 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n", 6892 size); 6893 ok(!memcmp(buf, PKCSSignerWithHash, size), "Unexpected value\n"); 6894 LocalFree(buf); 6895 } 6896 } 6897 } 6898 6899 static void test_decodeCMSSignerInfo(DWORD dwEncoding) 6900 { 6901 BOOL ret; 6902 LPBYTE buf = NULL; 6903 DWORD size = 0; 6904 CMSG_CMS_SIGNER_INFO *info; 6905 static const char oid1[] = "1.2.3", oid2[] = "1.5.6"; 6906 6907 /* A CMS signer can't be decoded without a serial number. */ 6908 SetLastError(0xdeadbeef); 6909 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO, 6910 minimalPKCSSigner, sizeof(minimalPKCSSigner), 6911 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 6912 ok(!ret, "expected failure\n"); 6913 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 6914 { 6915 skip("no CMS_SIGNER_INFO decode support\n"); 6916 return; 6917 } 6918 ok(GetLastError() == CRYPT_E_ASN1_CORRUPT, 6919 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError()); 6920 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO, 6921 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial), 6922 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 6923 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 6924 if (ret) 6925 { 6926 info = (CMSG_CMS_SIGNER_INFO *)buf; 6927 ok(info->dwVersion == 0, "Expected version 0, got %d\n", 6928 info->dwVersion); 6929 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER, 6930 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n", 6931 info->SignerId.dwIdChoice); 6932 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData == 6933 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n", 6934 U(info->SignerId).IssuerSerialNumber.Issuer.cbData); 6935 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData, 6936 encodedCommonNameNoNull, 6937 U(info->SignerId).IssuerSerialNumber.Issuer.cbData), 6938 "Unexpected value\n"); 6939 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData == 6940 sizeof(serialNum), "Unexpected size %d\n", 6941 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData); 6942 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData, 6943 serialNum, sizeof(serialNum)), "Unexpected value\n"); 6944 LocalFree(buf); 6945 } 6946 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO, 6947 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo), 6948 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 6949 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 6950 if (ret) 6951 { 6952 info = (CMSG_CMS_SIGNER_INFO *)buf; 6953 ok(info->dwVersion == 0, "Expected version 0, got %d\n", 6954 info->dwVersion); 6955 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER, 6956 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n", 6957 info->SignerId.dwIdChoice); 6958 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData == 6959 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n", 6960 U(info->SignerId).IssuerSerialNumber.Issuer.cbData); 6961 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData, 6962 encodedCommonNameNoNull, 6963 U(info->SignerId).IssuerSerialNumber.Issuer.cbData), 6964 "Unexpected value\n"); 6965 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData == 6966 sizeof(serialNum), "Unexpected size %d\n", 6967 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData); 6968 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData, 6969 serialNum, sizeof(serialNum)), "Unexpected value\n"); 6970 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1), 6971 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId); 6972 LocalFree(buf); 6973 } 6974 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO, 6975 PKCSSignerWithHashAndEncryptionAlgo, 6976 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG, 6977 NULL, &buf, &size); 6978 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 6979 if (ret) 6980 { 6981 info = (CMSG_CMS_SIGNER_INFO *)buf; 6982 ok(info->dwVersion == 0, "Expected version 0, got %d\n", 6983 info->dwVersion); 6984 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER, 6985 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n", 6986 info->SignerId.dwIdChoice); 6987 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData == 6988 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n", 6989 U(info->SignerId).IssuerSerialNumber.Issuer.cbData); 6990 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData, 6991 encodedCommonNameNoNull, 6992 U(info->SignerId).IssuerSerialNumber.Issuer.cbData), 6993 "Unexpected value\n"); 6994 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData == 6995 sizeof(serialNum), "Unexpected size %d\n", 6996 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData); 6997 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData, 6998 serialNum, sizeof(serialNum)), "Unexpected value\n"); 6999 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1), 7000 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId); 7001 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2), 7002 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId); 7003 LocalFree(buf); 7004 } 7005 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO, 7006 PKCSSignerWithHash, sizeof(PKCSSignerWithHash), 7007 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 7008 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 7009 if (ret) 7010 { 7011 info = (CMSG_CMS_SIGNER_INFO *)buf; 7012 ok(info->dwVersion == 0, "Expected version 0, got %d\n", 7013 info->dwVersion); 7014 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER, 7015 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n", 7016 info->SignerId.dwIdChoice); 7017 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData == 7018 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n", 7019 U(info->SignerId).IssuerSerialNumber.Issuer.cbData); 7020 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData, 7021 encodedCommonNameNoNull, 7022 U(info->SignerId).IssuerSerialNumber.Issuer.cbData), 7023 "Unexpected value\n"); 7024 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData == 7025 sizeof(serialNum), "Unexpected size %d\n", 7026 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData); 7027 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData, 7028 serialNum, sizeof(serialNum)), "Unexpected value\n"); 7029 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1), 7030 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId); 7031 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2), 7032 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId); 7033 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n", 7034 info->EncryptedHash.cbData); 7035 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)), 7036 "Unexpected value\n"); 7037 LocalFree(buf); 7038 } 7039 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO, 7040 CMSSignerWithKeyId, sizeof(CMSSignerWithKeyId), 7041 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 7042 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 7043 if (ret) 7044 { 7045 info = (CMSG_CMS_SIGNER_INFO *)buf; 7046 ok(info->dwVersion == 0, "Expected version 0, got %d\n", 7047 info->dwVersion); 7048 ok(info->SignerId.dwIdChoice == CERT_ID_KEY_IDENTIFIER, 7049 "Expected CERT_ID_KEY_IDENTIFIER, got %d\n", 7050 info->SignerId.dwIdChoice); 7051 ok(U(info->SignerId).KeyId.cbData == sizeof(serialNum), 7052 "Unexpected size %d\n", U(info->SignerId).KeyId.cbData); 7053 ok(!memcmp(U(info->SignerId).KeyId.pbData, serialNum, sizeof(serialNum)), 7054 "Unexpected value\n"); 7055 LocalFree(buf); 7056 } 7057 } 7058 7059 static BYTE emptyDNSPermittedConstraints[] = { 7060 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 }; 7061 static BYTE emptyDNSExcludedConstraints[] = { 7062 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 }; 7063 static BYTE DNSExcludedConstraints[] = { 7064 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, 7065 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 }; 7066 static BYTE permittedAndExcludedConstraints[] = { 7067 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00, 7068 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, 7069 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 }; 7070 static BYTE permittedAndExcludedWithMinConstraints[] = { 7071 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00, 7072 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a, 7073 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 }; 7074 static BYTE permittedAndExcludedWithMinMaxConstraints[] = { 7075 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00, 7076 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74, 7077 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 }; 7078 7079 static void test_encodeNameConstraints(DWORD dwEncoding) 7080 { 7081 BOOL ret; 7082 CERT_NAME_CONSTRAINTS_INFO constraints = { 0 }; 7083 CERT_GENERAL_SUBTREE permitted = { { 0 } }; 7084 CERT_GENERAL_SUBTREE excluded = { { 0 } }; 7085 LPBYTE buf; 7086 DWORD size; 7087 7088 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints, 7089 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7090 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 7091 { 7092 skip("no X509_NAME_CONSTRAINTS encode support\n"); 7093 return; 7094 } 7095 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7096 if (ret) 7097 { 7098 ok(size == sizeof(emptySequence), "Unexpected size\n"); 7099 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n"); 7100 LocalFree(buf); 7101 } 7102 constraints.cPermittedSubtree = 1; 7103 constraints.rgPermittedSubtree = &permitted; 7104 SetLastError(0xdeadbeef); 7105 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints, 7106 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7107 ok(!ret && GetLastError() == E_INVALIDARG, 7108 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 7109 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME; 7110 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints, 7111 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7112 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7113 if (ret) 7114 { 7115 ok(size == sizeof(emptyDNSPermittedConstraints), "Unexpected size\n"); 7116 ok(!memcmp(buf, emptyDNSPermittedConstraints, size), 7117 "Unexpected value\n"); 7118 LocalFree(buf); 7119 } 7120 constraints.cPermittedSubtree = 0; 7121 constraints.cExcludedSubtree = 1; 7122 constraints.rgExcludedSubtree = &excluded; 7123 excluded.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME; 7124 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints, 7125 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7126 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7127 if (ret) 7128 { 7129 ok(size == sizeof(emptyDNSExcludedConstraints), "Unexpected size\n"); 7130 ok(!memcmp(buf, emptyDNSExcludedConstraints, size), 7131 "Unexpected value\n"); 7132 LocalFree(buf); 7133 } 7134 U(excluded.Base).pwszURL = (LPWSTR)url; 7135 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints, 7136 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7137 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7138 if (ret) 7139 { 7140 ok(size == sizeof(DNSExcludedConstraints), "Unexpected size\n"); 7141 ok(!memcmp(buf, DNSExcludedConstraints, size), 7142 "Unexpected value\n"); 7143 LocalFree(buf); 7144 } 7145 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS; 7146 U(permitted.Base).IPAddress.cbData = sizeof(encodedIPAddr); 7147 U(permitted.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr; 7148 constraints.cPermittedSubtree = 1; 7149 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints, 7150 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7151 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7152 if (ret) 7153 { 7154 ok(size == sizeof(permittedAndExcludedConstraints), 7155 "Unexpected size\n"); 7156 ok(!memcmp(buf, permittedAndExcludedConstraints, size), 7157 "Unexpected value\n"); 7158 LocalFree(buf); 7159 } 7160 permitted.dwMinimum = 5; 7161 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints, 7162 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7163 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7164 if (ret) 7165 { 7166 ok(size == sizeof(permittedAndExcludedWithMinConstraints), 7167 "Unexpected size\n"); 7168 ok(!memcmp(buf, permittedAndExcludedWithMinConstraints, size), 7169 "Unexpected value\n"); 7170 LocalFree(buf); 7171 } 7172 permitted.fMaximum = TRUE; 7173 permitted.dwMaximum = 3; 7174 SetLastError(0xdeadbeef); 7175 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints, 7176 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7177 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7178 if (ret) 7179 { 7180 ok(size == sizeof(permittedAndExcludedWithMinMaxConstraints), 7181 "Unexpected size\n"); 7182 ok(!memcmp(buf, permittedAndExcludedWithMinMaxConstraints, size), 7183 "Unexpected value\n"); 7184 LocalFree(buf); 7185 } 7186 } 7187 7188 struct EncodedNameConstraints 7189 { 7190 CRYPT_DATA_BLOB encoded; 7191 CERT_NAME_CONSTRAINTS_INFO constraints; 7192 }; 7193 7194 static CERT_GENERAL_SUBTREE emptyDNSSubtree = { 7195 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 }; 7196 static CERT_GENERAL_SUBTREE DNSSubtree = { 7197 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 }; 7198 static CERT_GENERAL_SUBTREE IPAddressSubtree = { 7199 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 0 }; 7200 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree = { 7201 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, 0 }; 7202 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree = { 7203 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, TRUE, 3 }; 7204 7205 static const struct EncodedNameConstraints encodedNameConstraints[] = { 7206 { { sizeof(emptySequence), (LPBYTE)emptySequence }, { 0 } }, 7207 { { sizeof(emptyDNSPermittedConstraints), emptyDNSPermittedConstraints }, 7208 { 1, &emptyDNSSubtree, 0, NULL } }, 7209 { { sizeof(emptyDNSExcludedConstraints), emptyDNSExcludedConstraints }, 7210 { 0, NULL, 1, &emptyDNSSubtree } }, 7211 { { sizeof(DNSExcludedConstraints), DNSExcludedConstraints }, 7212 { 0, NULL, 1, &DNSSubtree } }, 7213 { { sizeof(permittedAndExcludedConstraints), permittedAndExcludedConstraints }, 7214 { 1, &IPAddressSubtree, 1, &DNSSubtree } }, 7215 { { sizeof(permittedAndExcludedWithMinConstraints), 7216 permittedAndExcludedWithMinConstraints }, 7217 { 1, &IPAddressWithMinSubtree, 1, &DNSSubtree } }, 7218 { { sizeof(permittedAndExcludedWithMinMaxConstraints), 7219 permittedAndExcludedWithMinMaxConstraints }, 7220 { 1, &IPAddressWithMinMaxSubtree, 1, &DNSSubtree } }, 7221 }; 7222 7223 static void test_decodeNameConstraints(DWORD dwEncoding) 7224 { 7225 BOOL ret; 7226 DWORD i; 7227 CERT_NAME_CONSTRAINTS_INFO *constraints; 7228 7229 U(DNSSubtree.Base).pwszURL = (LPWSTR)url; 7230 U(IPAddressSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr); 7231 U(IPAddressSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr; 7232 U(IPAddressWithMinSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr); 7233 U(IPAddressWithMinSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr; 7234 U(IPAddressWithMinMaxSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr); 7235 U(IPAddressWithMinMaxSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr; 7236 for (i = 0; 7237 i < sizeof(encodedNameConstraints) / sizeof(encodedNameConstraints[0]); 7238 i++) 7239 { 7240 DWORD size; 7241 7242 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, 7243 encodedNameConstraints[i].encoded.pbData, 7244 encodedNameConstraints[i].encoded.cbData, 7245 CRYPT_DECODE_ALLOC_FLAG, NULL, &constraints, &size); 7246 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 7247 { 7248 skip("no X509_NAME_CONSTRAINTS decode support\n"); 7249 return; 7250 } 7251 ok(ret, "%d: CryptDecodeObjectEx failed: %08x\n", i, GetLastError()); 7252 if (ret) 7253 { 7254 DWORD j; 7255 7256 if (constraints->cPermittedSubtree != 7257 encodedNameConstraints[i].constraints.cPermittedSubtree) 7258 fprintf(stderr, "%d: expected %u permitted, got %u\n", i, 7259 encodedNameConstraints[i].constraints.cPermittedSubtree, 7260 constraints->cPermittedSubtree); 7261 if (constraints->cPermittedSubtree == 7262 encodedNameConstraints[i].constraints.cPermittedSubtree) 7263 { 7264 for (j = 0; j < constraints->cPermittedSubtree; j++) 7265 { 7266 compareAltNameEntry(&constraints->rgPermittedSubtree[j].Base, 7267 &encodedNameConstraints[i].constraints.rgPermittedSubtree[j].Base); 7268 } 7269 } 7270 if (constraints->cExcludedSubtree != 7271 encodedNameConstraints[i].constraints.cExcludedSubtree) 7272 fprintf(stderr, "%d: expected %u excluded, got %u\n", i, 7273 encodedNameConstraints[i].constraints.cExcludedSubtree, 7274 constraints->cExcludedSubtree); 7275 if (constraints->cExcludedSubtree == 7276 encodedNameConstraints[i].constraints.cExcludedSubtree) 7277 { 7278 for (j = 0; j < constraints->cExcludedSubtree; j++) 7279 { 7280 compareAltNameEntry(&constraints->rgExcludedSubtree[j].Base, 7281 &encodedNameConstraints[i].constraints.rgExcludedSubtree[j].Base); 7282 } 7283 } 7284 LocalFree(constraints); 7285 } 7286 } 7287 } 7288 7289 static WCHAR noticeText[] = { 'T','h','i','s',' ','i','s',' ','a',' ', 7290 'n','o','t','i','c','e',0 }; 7291 static const BYTE noticeWithDisplayText[] = { 7292 0x30,0x22,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,0x00, 7293 0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,0x74, 7294 0x00,0x69,0x00,0x63,0x00,0x65 7295 }; 7296 static char org[] = "Wine"; 7297 static int noticeNumbers[] = { 2,3 }; 7298 static BYTE noticeWithReference[] = { 7299 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02, 7300 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20, 7301 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00, 7302 0x74,0x00,0x69,0x00,0x63,0x00,0x65 7303 }; 7304 7305 static void test_encodePolicyQualifierUserNotice(DWORD dwEncoding) 7306 { 7307 BOOL ret; 7308 LPBYTE buf; 7309 DWORD size; 7310 CERT_POLICY_QUALIFIER_USER_NOTICE notice; 7311 CERT_POLICY_QUALIFIER_NOTICE_REFERENCE reference; 7312 7313 memset(¬ice, 0, sizeof(notice)); 7314 ret = pCryptEncodeObjectEx(dwEncoding, 7315 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, ¬ice, CRYPT_ENCODE_ALLOC_FLAG, 7316 NULL, &buf, &size); 7317 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 7318 { 7319 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE encode support\n"); 7320 return; 7321 } 7322 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7323 if (ret) 7324 { 7325 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size); 7326 ok(!memcmp(buf, emptySequence, size), "unexpected value\n"); 7327 LocalFree(buf); 7328 } 7329 notice.pszDisplayText = noticeText; 7330 ret = pCryptEncodeObjectEx(dwEncoding, 7331 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, ¬ice, CRYPT_ENCODE_ALLOC_FLAG, 7332 NULL, &buf, &size); 7333 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7334 if (ret) 7335 { 7336 ok(sizeof(noticeWithDisplayText) == size, "unexpected size %d\n", size); 7337 ok(!memcmp(buf, noticeWithDisplayText, size), "unexpected value\n"); 7338 LocalFree(buf); 7339 } 7340 reference.pszOrganization = org; 7341 reference.cNoticeNumbers = 2; 7342 reference.rgNoticeNumbers = noticeNumbers; 7343 notice.pNoticeReference = &reference; 7344 ret = pCryptEncodeObjectEx(dwEncoding, 7345 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, ¬ice, CRYPT_ENCODE_ALLOC_FLAG, 7346 NULL, &buf, &size); 7347 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7348 if (ret) 7349 { 7350 ok(sizeof(noticeWithReference) == size, "unexpected size %d\n", size); 7351 ok(!memcmp(buf, noticeWithReference, size), "unexpected value\n"); 7352 LocalFree(buf); 7353 } 7354 } 7355 7356 static void test_decodePolicyQualifierUserNotice(DWORD dwEncoding) 7357 { 7358 BOOL ret; 7359 CERT_POLICY_QUALIFIER_USER_NOTICE *notice; 7360 DWORD size; 7361 7362 ret = pCryptDecodeObjectEx(dwEncoding, 7363 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, 7364 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL, 7365 ¬ice, &size); 7366 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 7367 { 7368 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE decode support\n"); 7369 return; 7370 } 7371 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7372 if (ret) 7373 { 7374 ok(notice->pszDisplayText == NULL, "unexpected display text\n"); 7375 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n"); 7376 LocalFree(notice); 7377 } 7378 ret = pCryptDecodeObjectEx(dwEncoding, 7379 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, 7380 noticeWithDisplayText, sizeof(noticeWithDisplayText), 7381 CRYPT_DECODE_ALLOC_FLAG, NULL, ¬ice, &size); 7382 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7383 if (ret) 7384 { 7385 ok(!lstrcmpW(notice->pszDisplayText, noticeText), 7386 "unexpected display text\n"); 7387 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n"); 7388 LocalFree(notice); 7389 } 7390 ret = pCryptDecodeObjectEx(dwEncoding, 7391 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, 7392 noticeWithReference, sizeof(noticeWithReference), 7393 CRYPT_DECODE_ALLOC_FLAG, NULL, ¬ice, &size); 7394 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7395 if (ret) 7396 { 7397 ok(!lstrcmpW(notice->pszDisplayText, noticeText), 7398 "unexpected display text\n"); 7399 ok(notice->pNoticeReference != NULL, "expected a notice reference\n"); 7400 if (notice->pNoticeReference) 7401 { 7402 ok(!strcmp(notice->pNoticeReference->pszOrganization, org), 7403 "unexpected organization %s\n", 7404 notice->pNoticeReference->pszOrganization); 7405 ok(notice->pNoticeReference->cNoticeNumbers == 2, 7406 "expected 2 notice numbers, got %d\n", 7407 notice->pNoticeReference->cNoticeNumbers); 7408 ok(notice->pNoticeReference->rgNoticeNumbers[0] == noticeNumbers[0], 7409 "unexpected notice number %d\n", 7410 notice->pNoticeReference->rgNoticeNumbers[0]); 7411 ok(notice->pNoticeReference->rgNoticeNumbers[1] == noticeNumbers[1], 7412 "unexpected notice number %d\n", 7413 notice->pNoticeReference->rgNoticeNumbers[1]); 7414 } 7415 LocalFree(notice); 7416 } 7417 } 7418 7419 static char oid_any_policy[] = "2.5.29.32.0"; 7420 static const BYTE policiesWithAnyPolicy[] = { 7421 0x30,0x08,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00 7422 }; 7423 static char oid1[] = "1.2.3"; 7424 static char oid_user_notice[] = "1.3.6.1.5.5.7.2.2"; 7425 static const BYTE twoPolicies[] = { 7426 0x30,0x50,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00,0x30,0x46,0x06,0x02,0x2a, 7427 0x03,0x30,0x40,0x30,0x3e,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x02, 7428 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02, 7429 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20, 7430 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00, 7431 0x74,0x00,0x69,0x00,0x63,0x00,0x65 7432 }; 7433 7434 static void test_encodeCertPolicies(DWORD dwEncoding) 7435 { 7436 BOOL ret; 7437 CERT_POLICIES_INFO info; 7438 CERT_POLICY_INFO policy[2]; 7439 CERT_POLICY_QUALIFIER_INFO qualifier; 7440 LPBYTE buf; 7441 DWORD size; 7442 7443 memset(&info, 0, sizeof(info)); 7444 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info, 7445 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7446 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7447 if (ret) 7448 { 7449 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size); 7450 ok(!memcmp(buf, emptySequence, size), "unexpected value\n"); 7451 LocalFree(buf); 7452 } 7453 memset(policy, 0, sizeof(policy)); 7454 info.cPolicyInfo = 1; 7455 info.rgPolicyInfo = policy; 7456 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info, 7457 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7458 ok(!ret && (GetLastError() == E_INVALIDARG || 7459 GetLastError() == OSS_LIMITED /* Win9x/NT4 */), 7460 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError()); 7461 policy[0].pszPolicyIdentifier = oid_any_policy; 7462 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info, 7463 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7464 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7465 if (ret) 7466 { 7467 ok(sizeof(policiesWithAnyPolicy) == size, "unexpected size %d\n", size); 7468 ok(!memcmp(buf, policiesWithAnyPolicy, size), "unexpected value\n"); 7469 LocalFree(buf); 7470 } 7471 policy[1].pszPolicyIdentifier = oid1; 7472 memset(&qualifier, 0, sizeof(qualifier)); 7473 qualifier.pszPolicyQualifierId = oid_user_notice; 7474 qualifier.Qualifier.cbData = sizeof(noticeWithReference); 7475 qualifier.Qualifier.pbData = noticeWithReference; 7476 policy[1].cPolicyQualifier = 1; 7477 policy[1].rgPolicyQualifier = &qualifier; 7478 info.cPolicyInfo = 2; 7479 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info, 7480 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7481 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7482 if (ret) 7483 { 7484 ok(sizeof(twoPolicies) == size, "unexpected size %d\n", size); 7485 ok(!memcmp(buf, twoPolicies, size), "unexpected value\n"); 7486 LocalFree(buf); 7487 } 7488 } 7489 7490 static void test_decodeCertPolicies(DWORD dwEncoding) 7491 { 7492 BOOL ret; 7493 CERT_POLICIES_INFO *info; 7494 DWORD size; 7495 7496 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES, 7497 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL, 7498 &info, &size); 7499 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7500 if (ret) 7501 { 7502 ok(info->cPolicyInfo == 0, "unexpected policy info %d\n", 7503 info->cPolicyInfo); 7504 LocalFree(info); 7505 } 7506 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES, 7507 policiesWithAnyPolicy, sizeof(policiesWithAnyPolicy), 7508 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size); 7509 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7510 if (ret) 7511 { 7512 ok(info->cPolicyInfo == 1, "unexpected policy info %d\n", 7513 info->cPolicyInfo); 7514 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy), 7515 "unexpected policy id %s\n", 7516 info->rgPolicyInfo[0].pszPolicyIdentifier); 7517 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0, 7518 "unexpected policy qualifier count %d\n", 7519 info->rgPolicyInfo[0].cPolicyQualifier); 7520 LocalFree(info); 7521 } 7522 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES, 7523 twoPolicies, sizeof(twoPolicies), 7524 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size); 7525 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7526 if (ret) 7527 { 7528 ok(info->cPolicyInfo == 2, "unexpected policy info %d\n", 7529 info->cPolicyInfo); 7530 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy), 7531 "unexpected policy id %s\n", 7532 info->rgPolicyInfo[0].pszPolicyIdentifier); 7533 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0, 7534 "unexpected policy qualifier count %d\n", 7535 info->rgPolicyInfo[0].cPolicyQualifier); 7536 ok(!strcmp(info->rgPolicyInfo[1].pszPolicyIdentifier, oid1), 7537 "unexpected policy id %s\n", 7538 info->rgPolicyInfo[1].pszPolicyIdentifier); 7539 ok(info->rgPolicyInfo[1].cPolicyQualifier == 1, 7540 "unexpected policy qualifier count %d\n", 7541 info->rgPolicyInfo[1].cPolicyQualifier); 7542 ok(!strcmp( 7543 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId, 7544 oid_user_notice), "unexpected policy qualifier id %s\n", 7545 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId); 7546 ok(info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData == 7547 sizeof(noticeWithReference), "unexpected qualifier size %d\n", 7548 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData); 7549 ok(!memcmp( 7550 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.pbData, 7551 noticeWithReference, sizeof(noticeWithReference)), 7552 "unexpected qualifier value\n"); 7553 LocalFree(info); 7554 } 7555 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES, 7556 twoPolicies, sizeof(twoPolicies), 0, NULL, NULL, &size); 7557 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7558 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); 7559 if (info) 7560 { 7561 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES, 7562 twoPolicies, sizeof(twoPolicies), 0, NULL, info, &size); 7563 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7564 HeapFree(GetProcessHeap(), 0, info); 7565 } 7566 } 7567 7568 static const BYTE policyMappingWithOneMapping[] = { 7569 0x30,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04 }; 7570 static const BYTE policyMappingWithTwoMappings[] = { 7571 0x30,0x14,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04,0x30,0x08,0x06, 7572 0x02,0x2b,0x04,0x06,0x02,0x55,0x06 }; 7573 static const LPCSTR mappingOids[] = { X509_POLICY_MAPPINGS, 7574 szOID_POLICY_MAPPINGS, szOID_LEGACY_POLICY_MAPPINGS }; 7575 7576 static void test_encodeCertPolicyMappings(DWORD dwEncoding) 7577 { 7578 static char oid2[] = "2.3.4"; 7579 static char oid3[] = "1.3.4"; 7580 static char oid4[] = "2.5.6"; 7581 BOOL ret; 7582 CERT_POLICY_MAPPINGS_INFO info = { 0 }; 7583 CERT_POLICY_MAPPING mapping[2]; 7584 LPBYTE buf; 7585 DWORD size, i; 7586 7587 /* Each of the mapping OIDs is equivalent, so check with all of them */ 7588 for (i = 0; i < sizeof(mappingOids) / sizeof(mappingOids[0]); i++) 7589 { 7590 memset(&info, 0, sizeof(info)); 7591 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info, 7592 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7593 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND), 7594 "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7595 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 7596 { 7597 win_skip("no policy mappings support\n"); 7598 return; 7599 } 7600 if (ret) 7601 { 7602 ok(size == sizeof(emptySequence), "unexpected size %d\n", size); 7603 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)), 7604 "unexpected value\n"); 7605 LocalFree(buf); 7606 } 7607 mapping[0].pszIssuerDomainPolicy = NULL; 7608 mapping[0].pszSubjectDomainPolicy = NULL; 7609 info.cPolicyMapping = 1; 7610 info.rgPolicyMapping = mapping; 7611 SetLastError(0xdeadbeef); 7612 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info, 7613 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7614 ok(!ret && GetLastError() == E_INVALIDARG, 7615 "expected E_INVALIDARG, got %08x\n", GetLastError()); 7616 mapping[0].pszIssuerDomainPolicy = oid1; 7617 mapping[0].pszSubjectDomainPolicy = oid2; 7618 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info, 7619 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7620 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7621 if (ret) 7622 { 7623 ok(size == sizeof(policyMappingWithOneMapping), 7624 "unexpected size %d\n", size); 7625 ok(!memcmp(buf, policyMappingWithOneMapping, size), 7626 "unexpected value\n"); 7627 LocalFree(buf); 7628 } 7629 mapping[1].pszIssuerDomainPolicy = oid3; 7630 mapping[1].pszSubjectDomainPolicy = oid4; 7631 info.cPolicyMapping = 2; 7632 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info, 7633 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7634 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7635 if (ret) 7636 { 7637 ok(size == sizeof(policyMappingWithTwoMappings), 7638 "unexpected size %d\n", size); 7639 ok(!memcmp(buf, policyMappingWithTwoMappings, size), 7640 "unexpected value\n"); 7641 LocalFree(buf); 7642 } 7643 } 7644 } 7645 7646 static void test_decodeCertPolicyMappings(DWORD dwEncoding) 7647 { 7648 DWORD size, i; 7649 CERT_POLICY_MAPPINGS_INFO *info; 7650 BOOL ret; 7651 7652 /* Each of the mapping OIDs is equivalent, so check with all of them */ 7653 for (i = 0; i < sizeof(mappingOids) / sizeof(mappingOids[0]); i++) 7654 { 7655 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i], 7656 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL, 7657 &info, &size); 7658 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND), 7659 "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7660 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 7661 { 7662 win_skip("no policy mappings support\n"); 7663 return; 7664 } 7665 if (ret) 7666 { 7667 ok(info->cPolicyMapping == 0, 7668 "expected 0 policy mappings, got %d\n", info->cPolicyMapping); 7669 LocalFree(info); 7670 } 7671 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i], 7672 policyMappingWithOneMapping, sizeof(policyMappingWithOneMapping), 7673 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size); 7674 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7675 if (ret) 7676 { 7677 ok(info->cPolicyMapping == 1, 7678 "expected 1 policy mappings, got %d\n", info->cPolicyMapping); 7679 ok(!strcmp(info->rgPolicyMapping[0].pszIssuerDomainPolicy, "1.2.3"), 7680 "unexpected issuer policy %s\n", 7681 info->rgPolicyMapping[0].pszIssuerDomainPolicy); 7682 ok(!strcmp(info->rgPolicyMapping[0].pszSubjectDomainPolicy, 7683 "2.3.4"), "unexpected subject policy %s\n", 7684 info->rgPolicyMapping[0].pszSubjectDomainPolicy); 7685 LocalFree(info); 7686 } 7687 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i], 7688 policyMappingWithTwoMappings, sizeof(policyMappingWithTwoMappings), 7689 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size); 7690 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7691 if (ret) 7692 { 7693 ok(info->cPolicyMapping == 2, 7694 "expected 2 policy mappings, got %d\n", info->cPolicyMapping); 7695 ok(!strcmp(info->rgPolicyMapping[0].pszIssuerDomainPolicy, "1.2.3"), 7696 "unexpected issuer policy %s\n", 7697 info->rgPolicyMapping[0].pszIssuerDomainPolicy); 7698 ok(!strcmp(info->rgPolicyMapping[0].pszSubjectDomainPolicy, 7699 "2.3.4"), "unexpected subject policy %s\n", 7700 info->rgPolicyMapping[0].pszSubjectDomainPolicy); 7701 ok(!strcmp(info->rgPolicyMapping[1].pszIssuerDomainPolicy, "1.3.4"), 7702 "unexpected issuer policy %s\n", 7703 info->rgPolicyMapping[1].pszIssuerDomainPolicy); 7704 ok(!strcmp(info->rgPolicyMapping[1].pszSubjectDomainPolicy, 7705 "2.5.6"), "unexpected subject policy %s\n", 7706 info->rgPolicyMapping[1].pszSubjectDomainPolicy); 7707 LocalFree(info); 7708 } 7709 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i], 7710 policyMappingWithTwoMappings, sizeof(policyMappingWithTwoMappings), 0, 7711 NULL, NULL, &size); 7712 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7713 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); 7714 if (info) 7715 { 7716 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i], 7717 policyMappingWithTwoMappings, sizeof(policyMappingWithTwoMappings), 0, 7718 NULL, info, &size); 7719 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7720 HeapFree(GetProcessHeap(), 0, info); 7721 } 7722 } 7723 } 7724 7725 static const BYTE policyConstraintsWithRequireExplicit[] = { 7726 0x30,0x03,0x80,0x01,0x00 }; 7727 static const BYTE policyConstraintsWithInhibitMapping[] = { 7728 0x30,0x03,0x81,0x01,0x01 }; 7729 static const BYTE policyConstraintsWithBoth[] = { 7730 0x30,0x06,0x80,0x01,0x01,0x81,0x01,0x01 }; 7731 7732 static void test_encodeCertPolicyConstraints(DWORD dwEncoding) 7733 { 7734 CERT_POLICY_CONSTRAINTS_INFO info = { 0 }; 7735 LPBYTE buf; 7736 DWORD size; 7737 BOOL ret; 7738 7739 /* Even though RFC 5280 explicitly states CAs must not issue empty 7740 * policy constraints (section 4.2.1.11), the API doesn't prevent it. 7741 */ 7742 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info, 7743 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7744 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND), 7745 "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7746 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 7747 { 7748 win_skip("no policy constraints support\n"); 7749 return; 7750 } 7751 if (ret) 7752 { 7753 ok(size == sizeof(emptySequence), "unexpected size %d\n", size); 7754 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)), 7755 "unexpected value\n"); 7756 LocalFree(buf); 7757 } 7758 /* If fRequireExplicitPolicy is set but dwRequireExplicitPolicySkipCerts 7759 * is not, then a skip of 0 is encoded. 7760 */ 7761 info.fRequireExplicitPolicy = TRUE; 7762 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info, 7763 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7764 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7765 if (ret) 7766 { 7767 ok(size == sizeof(policyConstraintsWithRequireExplicit), 7768 "unexpected size %d\n", size); 7769 ok(!memcmp(buf, policyConstraintsWithRequireExplicit, 7770 sizeof(policyConstraintsWithRequireExplicit)), "unexpected value\n"); 7771 LocalFree(buf); 7772 } 7773 /* With inhibit policy mapping */ 7774 info.fRequireExplicitPolicy = FALSE; 7775 info.dwRequireExplicitPolicySkipCerts = 0; 7776 info.fInhibitPolicyMapping = TRUE; 7777 info.dwInhibitPolicyMappingSkipCerts = 1; 7778 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info, 7779 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7780 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7781 if (ret) 7782 { 7783 ok(size == sizeof(policyConstraintsWithInhibitMapping), 7784 "unexpected size %d\n", size); 7785 ok(!memcmp(buf, policyConstraintsWithInhibitMapping, 7786 sizeof(policyConstraintsWithInhibitMapping)), "unexpected value\n"); 7787 LocalFree(buf); 7788 } 7789 /* And with both */ 7790 info.fRequireExplicitPolicy = TRUE; 7791 info.dwRequireExplicitPolicySkipCerts = 1; 7792 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info, 7793 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7794 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7795 if (ret) 7796 { 7797 ok(size == sizeof(policyConstraintsWithBoth), "unexpected size %d\n", 7798 size); 7799 ok(!memcmp(buf, policyConstraintsWithBoth, 7800 sizeof(policyConstraintsWithBoth)), "unexpected value\n"); 7801 LocalFree(buf); 7802 } 7803 } 7804 7805 static void test_decodeCertPolicyConstraints(DWORD dwEncoding) 7806 { 7807 CERT_POLICY_CONSTRAINTS_INFO *info; 7808 DWORD size; 7809 BOOL ret; 7810 7811 /* Again, even though CAs must not issue such constraints, they can be 7812 * decoded. 7813 */ 7814 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, 7815 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL, 7816 &info, &size); 7817 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND), 7818 "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7819 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 7820 { 7821 win_skip("no policy mappings support\n"); 7822 return; 7823 } 7824 if (ret) 7825 { 7826 ok(!info->fRequireExplicitPolicy, 7827 "expected require explicit = FALSE\n"); 7828 ok(!info->fInhibitPolicyMapping, 7829 "expected implicit mapping = FALSE\n"); 7830 LocalFree(info); 7831 } 7832 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, 7833 policyConstraintsWithRequireExplicit, 7834 sizeof(policyConstraintsWithRequireExplicit), CRYPT_DECODE_ALLOC_FLAG, 7835 NULL, &info, &size); 7836 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7837 if (ret) 7838 { 7839 ok(info->fRequireExplicitPolicy, 7840 "expected require explicit = TRUE\n"); 7841 ok(info->dwRequireExplicitPolicySkipCerts == 0, "expected 0, got %d\n", 7842 info->dwRequireExplicitPolicySkipCerts); 7843 ok(!info->fInhibitPolicyMapping, 7844 "expected implicit mapping = FALSE\n"); 7845 LocalFree(info); 7846 } 7847 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, 7848 policyConstraintsWithInhibitMapping, 7849 sizeof(policyConstraintsWithInhibitMapping), CRYPT_DECODE_ALLOC_FLAG, 7850 NULL, &info, &size); 7851 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7852 if (ret) 7853 { 7854 ok(!info->fRequireExplicitPolicy, 7855 "expected require explicit = FALSE\n"); 7856 ok(info->fInhibitPolicyMapping, 7857 "expected implicit mapping = TRUE\n"); 7858 ok(info->dwInhibitPolicyMappingSkipCerts == 1, "expected 1, got %d\n", 7859 info->dwInhibitPolicyMappingSkipCerts); 7860 LocalFree(info); 7861 } 7862 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, 7863 policyConstraintsWithBoth, sizeof(policyConstraintsWithBoth), 7864 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size); 7865 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7866 if (ret) 7867 { 7868 ok(info->fRequireExplicitPolicy, 7869 "expected require explicit = TRUE\n"); 7870 ok(info->dwRequireExplicitPolicySkipCerts == 1, "expected 1, got %d\n", 7871 info->dwRequireExplicitPolicySkipCerts); 7872 ok(info->fInhibitPolicyMapping, 7873 "expected implicit mapping = TRUE\n"); 7874 ok(info->dwInhibitPolicyMappingSkipCerts == 1, "expected 1, got %d\n", 7875 info->dwInhibitPolicyMappingSkipCerts); 7876 LocalFree(info); 7877 } 7878 } 7879 7880 static const BYTE rsaPrivKeyDer[] = { 7881 0x30,0x82,0x04,0xa5,0x02,0x01,0x00,0x02,0x82,0x01,0x01,0x00, 7882 0xae,0xba,0x3c,0x41,0xeb,0x25,0x41,0xb0,0x1c,0x41,0xd4,0x26, 7883 0xf9,0xf8,0x31,0x64,0x7e,0x97,0x65,0x54,0x9c,0x90,0xdf,0x34, 7884 0x07,0xfb,0xb0,0x69,0x99,0x3b,0x45,0x39,0x06,0xe4,0x3a,0x7a, 7885 0x01,0xe0,0xeb,0x3f,0xe1,0xd5,0x91,0xe0,0x16,0xe0,0xf2,0x35, 7886 0x59,0xdf,0x32,0x2d,0x69,0x3a,0x4a,0xbc,0xd1,0xba,0x1b,0x3b, 7887 0x7a,0x55,0x76,0xba,0x11,0xdd,0x2f,0xc7,0x58,0x66,0xf2,0x6c, 7888 0xd1,0x68,0x27,0x6c,0x85,0x74,0x0b,0xc9,0x7b,0x1a,0xde,0x3c, 7889 0x62,0x73,0xe2,0x9e,0x36,0x3a,0x29,0x3b,0x91,0x85,0x3d,0xd2, 7890 0xe1,0xe5,0x61,0x84,0x1e,0x28,0xfd,0xb7,0x97,0x68,0xc1,0xbb, 7891 0x0f,0x93,0x14,0xc2,0x03,0x60,0x41,0x11,0x7a,0xda,0x76,0x01, 7892 0x65,0x08,0xe6,0x0c,0xf6,0xfc,0x1d,0x64,0x12,0x7b,0x42,0xb0, 7893 0xb8,0xfe,0x61,0xe5,0xe2,0xe5,0x61,0x44,0xcc,0x94,0xe8,0xc0, 7894 0x4f,0x58,0x9a,0xea,0x99,0xaf,0x9c,0xa4,0xf2,0xd7,0x2b,0x31, 7895 0x90,0x3b,0x41,0x2e,0x4a,0x74,0x7c,0x1a,0xfc,0x42,0xa9,0x17, 7896 0xff,0x53,0x20,0x76,0xa7,0xf0,0x2c,0xb9,0xd5,0x1f,0xa9,0x8a, 7897 0x77,0xa8,0x09,0x5c,0x0e,0xd1,0x54,0xc5,0xf2,0x86,0xf1,0x2f, 7898 0x23,0xd6,0x63,0xba,0xe9,0x2b,0x73,0xf9,0xf0,0xdc,0xcb,0xf9, 7899 0xcb,0xe8,0x40,0x62,0x47,0x09,0x85,0xe1,0x9c,0xfd,0xcf,0x75, 7900 0x5a,0x65,0xfd,0x86,0x1c,0x50,0xfa,0x24,0x36,0x0f,0x54,0x5e, 7901 0x81,0xe7,0xf6,0x63,0x2d,0x87,0x0c,0x50,0x03,0x25,0x49,0xe7, 7902 0xc5,0x20,0xaa,0xbc,0x6c,0xf9,0xbe,0x49,0x8f,0x4f,0xb8,0x9a, 7903 0x73,0x9f,0x55,0x43,0x02,0x03,0x01,0x00,0x01,0x02,0x82,0x01, 7904 0x01,0x00,0x99,0x03,0xcd,0x5b,0x69,0x03,0x32,0x98,0x78,0xd6, 7905 0x89,0x65,0x2c,0xc9,0xd6,0xef,0x8c,0x11,0x27,0x93,0x46,0x9d, 7906 0x74,0x6a,0xcb,0x86,0xf6,0x02,0x34,0x47,0xfc,0xa2,0x29,0x4f, 7907 0xdb,0x8a,0x17,0x75,0x12,0x6f,0xda,0x65,0x3f,0x1f,0xc0,0xc9, 7908 0x74,0x33,0x96,0xa5,0xe8,0xfa,0x6d,0xc9,0xb7,0xc3,0xcd,0xe3, 7909 0x2e,0x90,0x12,0xdd,0x1f,0x61,0x69,0xdd,0x8b,0x47,0x07,0x3a, 7910 0xf8,0x98,0xa5,0x76,0x91,0xf7,0xee,0x93,0x26,0xf3,0x66,0x54, 7911 0xac,0x44,0xb3,0x6f,0x8b,0x09,0x44,0xb2,0x00,0x84,0x03,0x37, 7912 0x6d,0x61,0xed,0xa4,0x04,0x97,0x40,0x16,0x63,0xc2,0xd0,0xdc, 7913 0xd3,0xb3,0xee,0xba,0xbe,0x95,0xfd,0x80,0xe0,0xda,0xde,0xfc, 7914 0xcc,0x15,0x02,0x97,0x1d,0x68,0x43,0x2f,0x9c,0xc8,0x20,0x23, 7915 0xeb,0x00,0x4c,0x74,0x3d,0x27,0x20,0x14,0x23,0x95,0xfc,0x8c, 7916 0xb7,0x7e,0x7f,0xb0,0xdb,0xaf,0x8a,0x48,0x1b,0xfe,0x59,0xab, 7917 0x75,0xe2,0xbf,0x69,0xf2,0x73,0xe3,0xb9,0x92,0xa9,0x90,0x03, 7918 0xe5,0xd4,0x2d,0x86,0xff,0x12,0x54,0xb3,0xbb,0xe2,0xce,0x81, 7919 0x58,0x71,0xa4,0xde,0x45,0x05,0xf8,0x2d,0x45,0xf5,0xd8,0x5e, 7920 0x4c,0x5d,0x06,0x69,0x0c,0x86,0x9f,0x66,0x9f,0xb1,0x60,0xfd, 7921 0xf2,0x33,0x85,0x15,0xd5,0x18,0xf7,0xba,0x99,0x65,0x15,0x1d, 7922 0xfa,0xaa,0x76,0xdd,0x25,0xed,0xdf,0x90,0x6e,0xba,0x61,0x96, 7923 0x79,0xde,0xd2,0xda,0x66,0x03,0x74,0x3b,0x13,0x39,0x68,0xbc, 7924 0x94,0x01,0x00,0x2d,0xf8,0xf0,0x8c,0xbd,0x4c,0x9c,0x7e,0x87, 7925 0x9c,0x62,0x9f,0xb6,0x90,0x11,0x02,0x81,0x81,0x00,0xe3,0x5e, 7926 0xfe,0xdd,0xed,0x76,0xb6,0x4e,0xfc,0x5b,0xe0,0x20,0x99,0x7b, 7927 0x48,0x3b,0x1e,0x5f,0x7f,0x9f,0xa4,0x68,0xbe,0xc3,0x7f,0xb8, 7928 0x62,0x98,0xb0,0x95,0x8a,0xfa,0x0d,0xa3,0x79,0x63,0x39,0xf7, 7929 0xdb,0x76,0x3d,0x53,0x4a,0x0a,0x33,0xdf,0xe0,0x47,0x22,0xd5, 7930 0x96,0x80,0xc7,0xcd,0x24,0xef,0xac,0x49,0x46,0x37,0x6c,0x25, 7931 0xcf,0x6c,0x4d,0xe5,0x31,0xf8,0x2f,0xd2,0x59,0x74,0x00,0x38, 7932 0xdb,0xce,0xd1,0x72,0xc3,0xa8,0x30,0x70,0xd8,0x02,0x20,0xe7, 7933 0x56,0xe7,0xca,0xf0,0x3b,0x52,0x5d,0x11,0xbe,0x53,0x4e,0xd0, 7934 0xd9,0x2e,0xa6,0xb8,0xe2,0xd9,0xbf,0xb9,0x77,0xe7,0x3b,0xed, 7935 0x5e,0xd7,0x16,0x4a,0x3a,0xc5,0x86,0xd7,0x74,0x20,0xa7,0x8e, 7936 0xbf,0xb7,0x33,0xdb,0x51,0xe9,0x02,0x81,0x81,0x00,0xc4,0xba, 7937 0x57,0xf0,0x6e,0xcf,0xe8,0xce,0xce,0x9d,0x4a,0xe9,0x0f,0xe1, 7938 0xab,0x91,0x62,0xaa,0x66,0x5d,0x82,0x66,0x1c,0x72,0x18,0x6f, 7939 0x68,0x9c,0x7d,0x5e,0xfc,0xaf,0x4a,0xd6,0x8e,0xc6,0xae,0x40, 7940 0xf2,0x40,0x84,0x93,0xee,0x7c,0x87,0xa9,0xa6,0xcd,0x2b,0xc3, 7941 0xe6,0x29,0x3a,0xe2,0x4a,0xed,0xb0,0x4d,0x9f,0xc0,0xe9,0xd6, 7942 0xa3,0xca,0x97,0xee,0xac,0xab,0xa4,0x32,0x05,0x40,0x4d,0xf2, 7943 0x95,0x99,0xaf,0xa0,0xe1,0xe1,0xe7,0x3a,0x64,0xa4,0x70,0x6b, 7944 0x3d,0x1d,0x7b,0xf1,0x53,0xfa,0xb0,0xe0,0xe2,0x68,0x1a,0x61, 7945 0x2c,0x37,0xa5,0x39,0x7b,0xb2,0xcf,0xe6,0x5f,0x9b,0xc6,0x64, 7946 0xaf,0x48,0x86,0xfb,0xc1,0xf3,0x39,0x97,0x10,0x36,0xf5,0xa9, 7947 0x3d,0x08,0xa5,0x2f,0xe6,0x4b,0x02,0x81,0x81,0x00,0x86,0xe7, 7948 0x02,0x08,0xe2,0xaf,0xa0,0x93,0x54,0x9f,0x9e,0x67,0x39,0x29, 7949 0x30,0x3e,0x03,0x53,0x5e,0x01,0x76,0x26,0xbf,0xa8,0x76,0xcb, 7950 0x0b,0x94,0xd4,0x90,0xa5,0x98,0x9f,0x26,0xf3,0x0a,0xb0,0x86, 7951 0x22,0xac,0x10,0xce,0xae,0x0b,0x47,0xa3,0xf9,0x09,0xbb,0xdd, 7952 0x46,0x22,0xba,0x69,0x39,0x15,0x0a,0xff,0x9e,0xad,0x9b,0x79, 7953 0x03,0x8c,0x9a,0xda,0xf5,0xbe,0xef,0x80,0xba,0x9a,0x5c,0xd7, 7954 0x5f,0x73,0x62,0x49,0xd9,0x54,0x9d,0x09,0x16,0xe0,0x8c,0x6d, 7955 0x35,0xde,0xe9,0x45,0x87,0xac,0xe2,0x93,0x78,0x7d,0x2d,0x32, 7956 0x34,0xe9,0xbc,0xf9,0xcd,0x7e,0xac,0x86,0x7a,0x61,0xb3,0xe8, 7957 0xae,0x70,0xa7,0x44,0xfb,0x81,0xde,0xf3,0x4e,0x6f,0x61,0x7b, 7958 0x0c,0xbc,0xc2,0x03,0xca,0xa1,0x02,0x81,0x80,0x69,0x5b,0x4a, 7959 0xa1,0x4f,0x17,0x35,0x9d,0x1b,0xf6,0x0d,0x1a,0x48,0x11,0x19, 7960 0xab,0x20,0xe6,0x15,0x30,0x5b,0x17,0x88,0x80,0x6a,0x29,0xb0, 7961 0x22,0xae,0xd9,0xe2,0x05,0x96,0xd4,0xd5,0x5d,0xfe,0x10,0x76, 7962 0x2c,0xab,0x53,0xf6,0x52,0xe6,0xec,0xaa,0x92,0x12,0xb0,0x35, 7963 0x61,0x3b,0x51,0xd9,0xc2,0xf5,0xba,0x7c,0xa5,0xfa,0x15,0xa3, 7964 0x5e,0x6a,0x83,0xbe,0x21,0xa6,0x2b,0xcb,0xb8,0x26,0x86,0x96, 7965 0x2b,0xda,0x6d,0x14,0xcb,0xc0,0xe3,0xfa,0xe6,0x3d,0xf6,0x90, 7966 0xa2,0x6b,0xb0,0x50,0xc3,0x5f,0x5a,0xf0,0xa5,0xc4,0x0a,0xea, 7967 0x7d,0x5a,0x95,0x30,0x74,0x10,0xf7,0x55,0x98,0xbd,0x65,0x4a, 7968 0xa2,0x52,0xf8,0x1d,0x64,0xbf,0x20,0xf1,0xe4,0x1d,0x28,0x67, 7969 0xb1,0x6b,0x95,0xfd,0x85,0x02,0x81,0x81,0x00,0xda,0xb4,0x31, 7970 0x34,0xe1,0xec,0x9a,0x1e,0x07,0xd7,0xda,0x20,0x46,0xbf,0x6b, 7971 0xf0,0x45,0xbd,0x50,0xa2,0x0f,0x8a,0x14,0x51,0x52,0x83,0x7c, 7972 0x47,0xc8,0x9c,0x4e,0x68,0x6b,0xae,0x00,0x25,0x63,0xdd,0x13, 7973 0x2a,0x66,0x65,0xb6,0x74,0x91,0x5b,0xb6,0x47,0x3e,0x8e,0x46, 7974 0x62,0xcd,0x9d,0xc1,0xf7,0x14,0x14,0xbc,0x60,0xd6,0x3c,0x7c, 7975 0x3a,0xce,0xff,0x96,0x04,0x84,0xf6,0x44,0x1a,0xf8,0xdb,0x40, 7976 0x1c,0xf2,0xf1,0x4d,0xb2,0x68,0x3e,0xa3,0x0b,0xc6,0xb1,0xd0, 7977 0xa6,0x88,0x18,0x68,0xa1,0x05,0x2a,0xfc,0x2b,0x3a,0xa1,0xe6, 7978 0x31,0x4a,0x46,0x88,0x39,0x1e,0x44,0x11,0x6c,0xc5,0x8b,0xb6, 7979 0x8b,0xce,0x3d,0xd5,0xcb,0xbd,0xf0,0xd4,0xd9,0xfb,0x02,0x35, 7980 0x96,0x39,0x26,0x85,0xf9 }; 7981 static const BYTE rsaPrivKeyModulus[] = { 7982 0x43,0x55,0x9f,0x73,0x9a,0xb8,0x4f,0x8f,0x49,0xbe,0xf9,0x6c, 7983 0xbc,0xaa,0x20,0xc5,0xe7,0x49,0x25,0x03,0x50,0x0c,0x87,0x2d, 7984 0x63,0xf6,0xe7,0x81,0x5e,0x54,0x0f,0x36,0x24,0xfa,0x50,0x1c, 7985 0x86,0xfd,0x65,0x5a,0x75,0xcf,0xfd,0x9c,0xe1,0x85,0x09,0x47, 7986 0x62,0x40,0xe8,0xcb,0xf9,0xcb,0xdc,0xf0,0xf9,0x73,0x2b,0xe9, 7987 0xba,0x63,0xd6,0x23,0x2f,0xf1,0x86,0xf2,0xc5,0x54,0xd1,0x0e, 7988 0x5c,0x09,0xa8,0x77,0x8a,0xa9,0x1f,0xd5,0xb9,0x2c,0xf0,0xa7, 7989 0x76,0x20,0x53,0xff,0x17,0xa9,0x42,0xfc,0x1a,0x7c,0x74,0x4a, 7990 0x2e,0x41,0x3b,0x90,0x31,0x2b,0xd7,0xf2,0xa4,0x9c,0xaf,0x99, 7991 0xea,0x9a,0x58,0x4f,0xc0,0xe8,0x94,0xcc,0x44,0x61,0xe5,0xe2, 7992 0xe5,0x61,0xfe,0xb8,0xb0,0x42,0x7b,0x12,0x64,0x1d,0xfc,0xf6, 7993 0x0c,0xe6,0x08,0x65,0x01,0x76,0xda,0x7a,0x11,0x41,0x60,0x03, 7994 0xc2,0x14,0x93,0x0f,0xbb,0xc1,0x68,0x97,0xb7,0xfd,0x28,0x1e, 7995 0x84,0x61,0xe5,0xe1,0xd2,0x3d,0x85,0x91,0x3b,0x29,0x3a,0x36, 7996 0x9e,0xe2,0x73,0x62,0x3c,0xde,0x1a,0x7b,0xc9,0x0b,0x74,0x85, 7997 0x6c,0x27,0x68,0xd1,0x6c,0xf2,0x66,0x58,0xc7,0x2f,0xdd,0x11, 7998 0xba,0x76,0x55,0x7a,0x3b,0x1b,0xba,0xd1,0xbc,0x4a,0x3a,0x69, 7999 0x2d,0x32,0xdf,0x59,0x35,0xf2,0xe0,0x16,0xe0,0x91,0xd5,0xe1, 8000 0x3f,0xeb,0xe0,0x01,0x7a,0x3a,0xe4,0x06,0x39,0x45,0x3b,0x99, 8001 0x69,0xb0,0xfb,0x07,0x34,0xdf,0x90,0x9c,0x54,0x65,0x97,0x7e, 8002 0x64,0x31,0xf8,0xf9,0x26,0xd4,0x41,0x1c,0xb0,0x41,0x25,0xeb, 8003 0x41,0x3c,0xba,0xae }; 8004 static const BYTE rsaPrivKeyPrime1[] = { 8005 0xe9,0x51,0xdb,0x33,0xb7,0xbf,0x8e,0xa7,0x20,0x74,0xd7,0x86, 8006 0xc5,0x3a,0x4a,0x16,0xd7,0x5e,0xed,0x3b,0xe7,0x77,0xb9,0xbf, 8007 0xd9,0xe2,0xb8,0xa6,0x2e,0xd9,0xd0,0x4e,0x53,0xbe,0x11,0x5d, 8008 0x52,0x3b,0xf0,0xca,0xe7,0x56,0xe7,0x20,0x02,0xd8,0x70,0x30, 8009 0xa8,0xc3,0x72,0xd1,0xce,0xdb,0x38,0x00,0x74,0x59,0xd2,0x2f, 8010 0xf8,0x31,0xe5,0x4d,0x6c,0xcf,0x25,0x6c,0x37,0x46,0x49,0xac, 8011 0xef,0x24,0xcd,0xc7,0x80,0x96,0xd5,0x22,0x47,0xe0,0xdf,0x33, 8012 0x0a,0x4a,0x53,0x3d,0x76,0xdb,0xf7,0x39,0x63,0x79,0xa3,0x0d, 8013 0xfa,0x8a,0x95,0xb0,0x98,0x62,0xb8,0x7f,0xc3,0xbe,0x68,0xa4, 8014 0x9f,0x7f,0x5f,0x1e,0x3b,0x48,0x7b,0x99,0x20,0xe0,0x5b,0xfc, 8015 0x4e,0xb6,0x76,0xed,0xdd,0xfe,0x5e,0xe3 }; 8016 static const BYTE rsaPrivKeyPrime2[] = { 8017 0x4b,0xe6,0x2f,0xa5,0x08,0x3d,0xa9,0xf5,0x36,0x10,0x97,0x39, 8018 0xf3,0xc1,0xfb,0x86,0x48,0xaf,0x64,0xc6,0x9b,0x5f,0xe6,0xcf, 8019 0xb2,0x7b,0x39,0xa5,0x37,0x2c,0x61,0x1a,0x68,0xe2,0xe0,0xb0, 8020 0xfa,0x53,0xf1,0x7b,0x1d,0x3d,0x6b,0x70,0xa4,0x64,0x3a,0xe7, 8021 0xe1,0xe1,0xa0,0xaf,0x99,0x95,0xf2,0x4d,0x40,0x05,0x32,0xa4, 8022 0xab,0xac,0xee,0x97,0xca,0xa3,0xd6,0xe9,0xc0,0x9f,0x4d,0xb0, 8023 0xed,0x4a,0xe2,0x3a,0x29,0xe6,0xc3,0x2b,0xcd,0xa6,0xa9,0x87, 8024 0x7c,0xee,0x93,0x84,0x40,0xf2,0x40,0xae,0xc6,0x8e,0xd6,0x4a, 8025 0xaf,0xfc,0x5e,0x7d,0x9c,0x68,0x6f,0x18,0x72,0x1c,0x66,0x82, 8026 0x5d,0x66,0xaa,0x62,0x91,0xab,0xe1,0x0f,0xe9,0x4a,0x9d,0xce, 8027 0xce,0xe8,0xcf,0x6e,0xf0,0x57,0xba,0xc4 }; 8028 static const BYTE rsaPrivKeyExponent1[] = { 8029 0xa1,0xca,0x03,0xc2,0xbc,0x0c,0x7b,0x61,0x6f,0x4e,0xf3,0xde, 8030 0x81,0xfb,0x44,0xa7,0x70,0xae,0xe8,0xb3,0x61,0x7a,0x86,0xac, 8031 0x7e,0xcd,0xf9,0xbc,0xe9,0x34,0x32,0x2d,0x7d,0x78,0x93,0xe2, 8032 0xac,0x87,0x45,0xe9,0xde,0x35,0x6d,0x8c,0xe0,0x16,0x09,0x9d, 8033 0x54,0xd9,0x49,0x62,0x73,0x5f,0xd7,0x5c,0x9a,0xba,0x80,0xef, 8034 0xbe,0xf5,0xda,0x9a,0x8c,0x03,0x79,0x9b,0xad,0x9e,0xff,0x0a, 8035 0x15,0x39,0x69,0xba,0x22,0x46,0xdd,0xbb,0x09,0xf9,0xa3,0x47, 8036 0x0b,0xae,0xce,0x10,0xac,0x22,0x86,0xb0,0x0a,0xf3,0x26,0x9f, 8037 0x98,0xa5,0x90,0xd4,0x94,0x0b,0xcb,0x76,0xa8,0xbf,0x26,0x76, 8038 0x01,0x5e,0x53,0x03,0x3e,0x30,0x29,0x39,0x67,0x9e,0x9f,0x54, 8039 0x93,0xa0,0xaf,0xe2,0x08,0x02,0xe7,0x86 }; 8040 static const BYTE rsaPrivKeyExponent2[] = { 8041 0x85,0xfd,0x95,0x6b,0xb1,0x67,0x28,0x1d,0xe4,0xf1,0x20,0xbf, 8042 0x64,0x1d,0xf8,0x52,0xa2,0x4a,0x65,0xbd,0x98,0x55,0xf7,0x10, 8043 0x74,0x30,0x95,0x5a,0x7d,0xea,0x0a,0xc4,0xa5,0xf0,0x5a,0x5f, 8044 0xc3,0x50,0xb0,0x6b,0xa2,0x90,0xf6,0x3d,0xe6,0xfa,0xe3,0xc0, 8045 0xcb,0x14,0x6d,0xda,0x2b,0x96,0x86,0x26,0xb8,0xcb,0x2b,0xa6, 8046 0x21,0xbe,0x83,0x6a,0x5e,0xa3,0x15,0xfa,0xa5,0x7c,0xba,0xf5, 8047 0xc2,0xd9,0x51,0x3b,0x61,0x35,0xb0,0x12,0x92,0xaa,0xec,0xe6, 8048 0x52,0xf6,0x53,0xab,0x2c,0x76,0x10,0xfe,0x5d,0xd5,0xd4,0x96, 8049 0x05,0xe2,0xd9,0xae,0x22,0xb0,0x29,0x6a,0x80,0x88,0x17,0x5b, 8050 0x30,0x15,0xe6,0x20,0xab,0x19,0x11,0x48,0x1a,0x0d,0xf6,0x1b, 8051 0x9d,0x35,0x17,0x4f,0xa1,0x4a,0x5b,0x69 }; 8052 static const BYTE rsaPrivKeyCoefficient[] = { 8053 0xf9,0x85,0x26,0x39,0x96,0x35,0x02,0xfb,0xd9,0xd4,0xf0,0xbd, 8054 0xcb,0xd5,0x3d,0xce,0x8b,0xb6,0x8b,0xc5,0x6c,0x11,0x44,0x1e, 8055 0x39,0x88,0x46,0x4a,0x31,0xe6,0xa1,0x3a,0x2b,0xfc,0x2a,0x05, 8056 0xa1,0x68,0x18,0x88,0xa6,0xd0,0xb1,0xc6,0x0b,0xa3,0x3e,0x68, 8057 0xb2,0x4d,0xf1,0xf2,0x1c,0x40,0xdb,0xf8,0x1a,0x44,0xf6,0x84, 8058 0x04,0x96,0xff,0xce,0x3a,0x7c,0x3c,0xd6,0x60,0xbc,0x14,0x14, 8059 0xf7,0xc1,0x9d,0xcd,0x62,0x46,0x8e,0x3e,0x47,0xb6,0x5b,0x91, 8060 0x74,0xb6,0x65,0x66,0x2a,0x13,0xdd,0x63,0x25,0x00,0xae,0x6b, 8061 0x68,0x4e,0x9c,0xc8,0x47,0x7c,0x83,0x52,0x51,0x14,0x8a,0x0f, 8062 0xa2,0x50,0xbd,0x45,0xf0,0x6b,0xbf,0x46,0x20,0xda,0xd7,0x07, 8063 0x1e,0x9a,0xec,0xe1,0x34,0x31,0xb4,0xda }; 8064 static const BYTE rsaPrivKeyPrivateExponent[] = { 8065 0x11,0x90,0xb6,0x9f,0x62,0x9c,0x87,0x7e,0x9c,0x4c,0xbd,0x8c, 8066 0xf0,0xf8,0x2d,0x00,0x01,0x94,0xbc,0x68,0x39,0x13,0x3b,0x74, 8067 0x03,0x66,0xda,0xd2,0xde,0x79,0x96,0x61,0xba,0x6e,0x90,0xdf, 8068 0xed,0x25,0xdd,0x76,0xaa,0xfa,0x1d,0x15,0x65,0x99,0xba,0xf7, 8069 0x18,0xd5,0x15,0x85,0x33,0xf2,0xfd,0x60,0xb1,0x9f,0x66,0x9f, 8070 0x86,0x0c,0x69,0x06,0x5d,0x4c,0x5e,0xd8,0xf5,0x45,0x2d,0xf8, 8071 0x05,0x45,0xde,0xa4,0x71,0x58,0x81,0xce,0xe2,0xbb,0xb3,0x54, 8072 0x12,0xff,0x86,0x2d,0xd4,0xe5,0x03,0x90,0xa9,0x92,0xb9,0xe3, 8073 0x73,0xf2,0x69,0xbf,0xe2,0x75,0xab,0x59,0xfe,0x1b,0x48,0x8a, 8074 0xaf,0xdb,0xb0,0x7f,0x7e,0xb7,0x8c,0xfc,0x95,0x23,0x14,0x20, 8075 0x27,0x3d,0x74,0x4c,0x00,0xeb,0x23,0x20,0xc8,0x9c,0x2f,0x43, 8076 0x68,0x1d,0x97,0x02,0x15,0xcc,0xfc,0xde,0xda,0xe0,0x80,0xfd, 8077 0x95,0xbe,0xba,0xee,0xb3,0xd3,0xdc,0xd0,0xc2,0x63,0x16,0x40, 8078 0x97,0x04,0xa4,0xed,0x61,0x6d,0x37,0x03,0x84,0x00,0xb2,0x44, 8079 0x09,0x8b,0x6f,0xb3,0x44,0xac,0x54,0x66,0xf3,0x26,0x93,0xee, 8080 0xf7,0x91,0x76,0xa5,0x98,0xf8,0x3a,0x07,0x47,0x8b,0xdd,0x69, 8081 0x61,0x1f,0xdd,0x12,0x90,0x2e,0xe3,0xcd,0xc3,0xb7,0xc9,0x6d, 8082 0xfa,0xe8,0xa5,0x96,0x33,0x74,0xc9,0xc0,0x1f,0x3f,0x65,0xda, 8083 0x6f,0x12,0x75,0x17,0x8a,0xdb,0x4f,0x29,0xa2,0xfc,0x47,0x34, 8084 0x02,0xf6,0x86,0xcb,0x6a,0x74,0x9d,0x46,0x93,0x27,0x11,0x8c, 8085 0xef,0xd6,0xc9,0x2c,0x65,0x89,0xd6,0x78,0x98,0x32,0x03,0x69, 8086 0x5b,0xcd,0x03,0x99 }; 8087 8088 static void test_decodeRsaPrivateKey(DWORD dwEncoding) 8089 { 8090 LPBYTE buf = NULL; 8091 DWORD bufSize = 0; 8092 BOOL ret; 8093 8094 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_RSA_PRIVATE_KEY, 8095 rsaPrivKeyDer, sizeof(rsaPrivKeyDer)-10, 8096 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 8097 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD), 8098 "Expected CRYPT_E_ASN1_EOD, got %08x\n", 8099 GetLastError()); 8100 8101 buf = NULL; 8102 bufSize = 0; 8103 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_RSA_PRIVATE_KEY, 8104 rsaPrivKeyDer, sizeof(rsaPrivKeyDer), 8105 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 8106 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 8107 8108 if (ret) 8109 { 8110 BLOBHEADER *hdr = (BLOBHEADER *)buf; 8111 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER)); 8112 static const int bitlen = 2048; 8113 BYTE *modulus = (BYTE*)(rsaPubKey + 1); 8114 BYTE *prime1 = modulus + bitlen/8; 8115 BYTE *prime2 = prime1 + bitlen/16; 8116 BYTE *exponent1 = prime2 + bitlen/16; 8117 BYTE *exponent2 = exponent1 + bitlen/16; 8118 BYTE *coefficient = exponent2 + bitlen/16; 8119 BYTE *privateExponent = coefficient + bitlen/16; 8120 8121 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + 8122 (bitlen * 9 / 16), 8123 "Wrong size %d\n", bufSize); 8124 8125 ok(hdr->bType == PRIVATEKEYBLOB, 8126 "Expected type PRIVATEKEYBLOB (%d), got %d\n", PRIVATEKEYBLOB, 8127 hdr->bType); 8128 ok(hdr->bVersion == CUR_BLOB_VERSION, 8129 "Expected version CUR_BLOB_VERSION (%d), got %d\n", 8130 CUR_BLOB_VERSION, hdr->bVersion); 8131 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n", 8132 hdr->reserved); 8133 ok(hdr->aiKeyAlg == CALG_RSA_KEYX, 8134 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg); 8135 8136 ok(rsaPubKey->magic == 0x32415352, 8137 "Expected magic 0x32415352, got 0x%x\n", rsaPubKey->magic); 8138 ok(rsaPubKey->bitlen == bitlen, 8139 "Expected bitlen %d, got %d\n", bitlen, rsaPubKey->bitlen); 8140 ok(rsaPubKey->pubexp == 65537, 8141 "Expected pubexp 65537, got %d\n", rsaPubKey->pubexp); 8142 8143 ok(!memcmp(modulus, rsaPrivKeyModulus, bitlen/8), 8144 "unexpected modulus\n"); 8145 ok(!memcmp(prime1, rsaPrivKeyPrime1, bitlen/16), 8146 "unexpected prime1\n"); 8147 ok(!memcmp(prime2, rsaPrivKeyPrime2, bitlen/16), 8148 "unexpected prime2\n"); 8149 ok(!memcmp(exponent1, rsaPrivKeyExponent1, bitlen/16), 8150 "unexpected exponent1\n"); 8151 ok(!memcmp(exponent2, rsaPrivKeyExponent2, bitlen/16), 8152 "unexpected exponent2\n"); 8153 ok(!memcmp(coefficient, rsaPrivKeyCoefficient, bitlen/16), 8154 "unexpected coefficient\n"); 8155 ok(!memcmp(privateExponent, rsaPrivKeyPrivateExponent, bitlen/8), 8156 "unexpected privateExponent\n"); 8157 8158 LocalFree(buf); 8159 } 8160 } 8161 8162 /* Free *pInfo with HeapFree */ 8163 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo) 8164 { 8165 BOOL ret; 8166 DWORD size = 0; 8167 HCRYPTKEY key; 8168 8169 /* This crashes 8170 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL); 8171 */ 8172 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size); 8173 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 8174 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); 8175 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL, 8176 &size); 8177 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 8178 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); 8179 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL, 8180 NULL, &size); 8181 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 8182 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); 8183 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL, 8184 0, NULL, NULL, &size); 8185 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 8186 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); 8187 /* Test with no key */ 8188 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL, 8189 0, NULL, NULL, &size); 8190 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n", 8191 GetLastError()); 8192 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key); 8193 ok(ret, "CryptGenKey failed: %08x\n", GetLastError()); 8194 if (ret) 8195 { 8196 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, 8197 NULL, 0, NULL, NULL, &size); 8198 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError()); 8199 *pInfo = HeapAlloc(GetProcessHeap(), 0, size); 8200 if (*pInfo) 8201 { 8202 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, 8203 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size); 8204 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", 8205 GetLastError()); 8206 if (ret) 8207 { 8208 /* By default (we passed NULL as the OID) the OID is 8209 * szOID_RSA_RSA. 8210 */ 8211 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA), 8212 "Expected %s, got %s\n", szOID_RSA_RSA, 8213 (*pInfo)->Algorithm.pszObjId); 8214 } 8215 } 8216 } 8217 CryptDestroyKey(key); 8218 } 8219 8220 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2, 8221 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6, 8222 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06, 8223 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30, 8224 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40, 8225 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 8226 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30, 8227 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30, 8228 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30, 8229 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40, 8230 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 8231 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 8232 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 8233 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29, 8234 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e, 8235 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5, 8236 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a, 8237 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b, 8238 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 8239 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0, 8240 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3, 8241 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31, 8242 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70, 8243 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef, 8244 0x49, 0xe5, 0xf9, 0x65, 0xf3 }; 8245 8246 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info) 8247 { 8248 BOOL ret; 8249 HCRYPTKEY key; 8250 PCCERT_CONTEXT context; 8251 DWORD dwSize; 8252 ALG_ID ai; 8253 8254 /* These crash 8255 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL); 8256 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key); 8257 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL); 8258 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL, 8259 NULL); 8260 */ 8261 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key); 8262 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 8263 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); 8264 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key); 8265 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 8266 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); 8267 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL, 8268 &key); 8269 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 8270 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); 8271 8272 /* Export key with standard algorithm (CALG_RSA_KEYX) */ 8273 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL, 8274 &key); 8275 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError()); 8276 8277 dwSize = sizeof(ai); 8278 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0); 8279 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError()); 8280 if(ret) 8281 { 8282 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize); 8283 ok(ai == CALG_RSA_KEYX, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai); 8284 } 8285 8286 CryptDestroyKey(key); 8287 8288 /* Repeat with forced algorithm */ 8289 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, CALG_RSA_SIGN, 0, NULL, 8290 &key); 8291 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError()); 8292 8293 dwSize = sizeof(ai); 8294 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0); 8295 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError()); 8296 if(ret) 8297 { 8298 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize); 8299 ok(ai == CALG_RSA_SIGN, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai); 8300 } 8301 8302 CryptDestroyKey(key); 8303 8304 /* Test importing a public key from a certificate context */ 8305 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert, 8306 sizeof(expiredCert)); 8307 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n", 8308 GetLastError()); 8309 if (context) 8310 { 8311 ok(!strcmp(szOID_RSA_RSA, 8312 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId), 8313 "Expected %s, got %s\n", szOID_RSA_RSA, 8314 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId); 8315 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, 8316 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key); 8317 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError()); 8318 CryptDestroyKey(key); 8319 CertFreeCertificateContext(context); 8320 } 8321 } 8322 8323 static const char cspName[] = "WineCryptTemp"; 8324 8325 static void testPortPublicKeyInfo(void) 8326 { 8327 HCRYPTPROV csp; 8328 BOOL ret; 8329 PCERT_PUBLIC_KEY_INFO info = NULL; 8330 8331 /* Just in case a previous run failed, delete this thing */ 8332 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV_A, PROV_RSA_FULL, 8333 CRYPT_DELETEKEYSET); 8334 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV_A, PROV_RSA_FULL, 8335 CRYPT_NEWKEYSET); 8336 ok(ret,"CryptAcquireContextA failed\n"); 8337 8338 testExportPublicKey(csp, &info); 8339 testImportPublicKey(csp, info); 8340 8341 HeapFree(GetProcessHeap(), 0, info); 8342 CryptReleaseContext(csp, 0); 8343 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV_A, PROV_RSA_FULL, 8344 CRYPT_DELETEKEYSET); 8345 ok(ret,"CryptAcquireContextA failed\n"); 8346 } 8347 8348 START_TEST(encode) 8349 { 8350 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING, 8351 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING }; 8352 HMODULE hCrypt32; 8353 DWORD i; 8354 8355 hCrypt32 = GetModuleHandleA("crypt32.dll"); 8356 pCryptDecodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptDecodeObjectEx"); 8357 pCryptEncodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptEncodeObjectEx"); 8358 if (!pCryptDecodeObjectEx || !pCryptEncodeObjectEx) 8359 { 8360 win_skip("CryptDecodeObjectEx() is not available\n"); 8361 return; 8362 } 8363 8364 for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++) 8365 { 8366 test_encodeInt(encodings[i]); 8367 test_decodeInt(encodings[i]); 8368 test_encodeEnumerated(encodings[i]); 8369 test_decodeEnumerated(encodings[i]); 8370 test_encodeFiletime(encodings[i]); 8371 test_decodeFiletime(encodings[i]); 8372 test_encodeName(encodings[i]); 8373 test_decodeName(encodings[i]); 8374 test_encodeUnicodeName(encodings[i]); 8375 test_decodeUnicodeName(encodings[i]); 8376 test_encodeNameValue(encodings[i]); 8377 test_decodeNameValue(encodings[i]); 8378 test_encodeUnicodeNameValue(encodings[i]); 8379 test_decodeUnicodeNameValue(encodings[i]); 8380 test_encodeAltName(encodings[i]); 8381 test_decodeAltName(encodings[i]); 8382 test_encodeOctets(encodings[i]); 8383 test_decodeOctets(encodings[i]); 8384 test_encodeBits(encodings[i]); 8385 test_decodeBits(encodings[i]); 8386 test_encodeBasicConstraints(encodings[i]); 8387 test_decodeBasicConstraints(encodings[i]); 8388 test_encodeRsaPublicKey(encodings[i]); 8389 test_decodeRsaPublicKey(encodings[i]); 8390 test_encodeSequenceOfAny(encodings[i]); 8391 test_decodeSequenceOfAny(encodings[i]); 8392 test_encodeExtensions(encodings[i]); 8393 test_decodeExtensions(encodings[i]); 8394 test_encodePublicKeyInfo(encodings[i]); 8395 test_decodePublicKeyInfo(encodings[i]); 8396 test_encodeCertToBeSigned(encodings[i]); 8397 test_decodeCertToBeSigned(encodings[i]); 8398 test_encodeCert(encodings[i]); 8399 test_decodeCert(encodings[i]); 8400 test_encodeCRLDistPoints(encodings[i]); 8401 test_decodeCRLDistPoints(encodings[i]); 8402 test_encodeCRLIssuingDistPoint(encodings[i]); 8403 test_decodeCRLIssuingDistPoint(encodings[i]); 8404 test_encodeCRLToBeSigned(encodings[i]); 8405 test_decodeCRLToBeSigned(encodings[i]); 8406 test_encodeEnhancedKeyUsage(encodings[i]); 8407 test_decodeEnhancedKeyUsage(encodings[i]); 8408 test_encodeAuthorityKeyId(encodings[i]); 8409 test_decodeAuthorityKeyId(encodings[i]); 8410 test_encodeAuthorityKeyId2(encodings[i]); 8411 test_decodeAuthorityKeyId2(encodings[i]); 8412 test_encodeAuthorityInfoAccess(encodings[i]); 8413 test_decodeAuthorityInfoAccess(encodings[i]); 8414 test_encodeCTL(encodings[i]); 8415 test_decodeCTL(encodings[i]); 8416 test_encodePKCSContentInfo(encodings[i]); 8417 test_decodePKCSContentInfo(encodings[i]); 8418 test_encodePKCSAttribute(encodings[i]); 8419 test_decodePKCSAttribute(encodings[i]); 8420 test_encodePKCSAttributes(encodings[i]); 8421 test_decodePKCSAttributes(encodings[i]); 8422 test_encodePKCSSMimeCapabilities(encodings[i]); 8423 test_decodePKCSSMimeCapabilities(encodings[i]); 8424 test_encodePKCSSignerInfo(encodings[i]); 8425 test_decodePKCSSignerInfo(encodings[i]); 8426 test_encodeCMSSignerInfo(encodings[i]); 8427 test_decodeCMSSignerInfo(encodings[i]); 8428 test_encodeNameConstraints(encodings[i]); 8429 test_decodeNameConstraints(encodings[i]); 8430 test_encodePolicyQualifierUserNotice(encodings[i]); 8431 test_decodePolicyQualifierUserNotice(encodings[i]); 8432 test_encodeCertPolicies(encodings[i]); 8433 test_decodeCertPolicies(encodings[i]); 8434 test_encodeCertPolicyMappings(encodings[i]); 8435 test_decodeCertPolicyMappings(encodings[i]); 8436 test_encodeCertPolicyConstraints(encodings[i]); 8437 test_decodeCertPolicyConstraints(encodings[i]); 8438 test_decodeRsaPrivateKey(encodings[i]); 8439 } 8440 testPortPublicKeyInfo(); 8441 } 8442