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 #include <stdio.h> 21 #include <stdarg.h> 22 #include <windef.h> 23 #include <winbase.h> 24 #include <winerror.h> 25 #include <wincrypt.h> 26 #include <snmp.h> 27 28 #include "wine/test.h" 29 30 31 static BOOL (WINAPI *pCryptDecodeObjectEx)(DWORD,LPCSTR,const BYTE*,DWORD,DWORD,PCRYPT_DECODE_PARA,void*,DWORD*); 32 static BOOL (WINAPI *pCryptEncodeObjectEx)(DWORD,LPCSTR,const void*,DWORD,PCRYPT_ENCODE_PARA,void*,DWORD*); 33 34 struct encodedInt 35 { 36 int val; 37 const BYTE *encoded; 38 }; 39 40 static const BYTE bin1[] = {0x02,0x01,0x01}; 41 static const BYTE bin2[] = {0x02,0x01,0x7f}; 42 static const BYTE bin3[] = {0x02,0x02,0x00,0x80}; 43 static const BYTE bin4[] = {0x02,0x02,0x01,0x00}; 44 static const BYTE bin5[] = {0x02,0x01,0x80}; 45 static const BYTE bin6[] = {0x02,0x02,0xff,0x7f}; 46 static const BYTE bin7[] = {0x02,0x04,0xba,0xdd,0xf0,0x0d}; 47 48 static const struct encodedInt ints[] = { 49 { 1, bin1 }, 50 { 127, bin2 }, 51 { 128, bin3 }, 52 { 256, bin4 }, 53 { -128, bin5 }, 54 { -129, bin6 }, 55 { 0xbaddf00d, bin7 }, 56 }; 57 58 struct encodedBigInt 59 { 60 const BYTE *val; 61 const BYTE *encoded; 62 const BYTE *decoded; 63 }; 64 65 static const BYTE bin8[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0}; 66 static const BYTE bin9[] = {0x02,0x0a,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0}; 67 static const BYTE bin10[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0}; 68 69 static const BYTE bin11[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0xff,0}; 70 static const BYTE bin12[] = {0x02,0x09,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0}; 71 static const BYTE bin13[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0}; 72 73 static const struct encodedBigInt bigInts[] = { 74 { bin8, bin9, bin10 }, 75 { bin11, bin12, bin13 }, 76 }; 77 78 static const BYTE bin14[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0}; 79 static const BYTE bin15[] = {0x02,0x0a,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0}; 80 static const BYTE bin16[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0xff,0}; 81 static const BYTE bin17[] = {0x02,0x0c,0x00,0xff,0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0}; 82 83 /* Decoded is the same as original, so don't bother storing a separate copy */ 84 static const struct encodedBigInt bigUInts[] = { 85 { bin14, bin15, NULL }, 86 { bin16, bin17, NULL }, 87 }; 88 89 static void test_encodeInt(DWORD dwEncoding) 90 { 91 DWORD bufSize = 0; 92 int i; 93 BOOL ret; 94 CRYPT_INTEGER_BLOB blob; 95 BYTE *buf = NULL; 96 97 /* CryptEncodeObjectEx with NULL bufSize crashes.. 98 ret = pCryptEncodeObjectEx(3, X509_INTEGER, &ints[0].val, 0, NULL, NULL, 99 NULL); 100 */ 101 /* check bogus encoding */ 102 ret = pCryptEncodeObjectEx(0, X509_INTEGER, &ints[0].val, 0, NULL, NULL, 103 &bufSize); 104 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 105 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError()); 106 if (0) 107 { 108 /* check with NULL integer buffer. Windows XP incorrectly returns an 109 * NTSTATUS (crashes on win9x). 110 */ 111 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, NULL, 0, NULL, NULL, 112 &bufSize); 113 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 114 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError()); 115 } 116 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++) 117 { 118 /* encode as normal integer */ 119 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, &ints[i].val, 0, 120 NULL, NULL, &bufSize); 121 ok(ret, "Expected success, got %d\n", GetLastError()); 122 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, &ints[i].val, 123 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 124 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError()); 125 if (ret) 126 { 127 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n", 128 buf[0]); 129 ok(buf[1] == ints[i].encoded[1], "Got length %d, expected %d\n", 130 buf[1], ints[i].encoded[1]); 131 ok(!memcmp(buf + 1, ints[i].encoded + 1, ints[i].encoded[1] + 1), 132 "Encoded value of 0x%08x didn't match expected\n", ints[i].val); 133 LocalFree(buf); 134 } 135 /* encode as multibyte integer */ 136 blob.cbData = sizeof(ints[i].val); 137 blob.pbData = (BYTE *)&ints[i].val; 138 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob, 139 0, NULL, NULL, &bufSize); 140 ok(ret, "Expected success, got %d\n", GetLastError()); 141 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob, 142 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 143 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError()); 144 if (ret) 145 { 146 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n", 147 buf[0]); 148 ok(buf[1] == ints[i].encoded[1], "Got length %d, expected %d\n", 149 buf[1], ints[i].encoded[1]); 150 ok(!memcmp(buf + 1, ints[i].encoded + 1, ints[i].encoded[1] + 1), 151 "Encoded value of 0x%08x didn't match expected\n", ints[i].val); 152 LocalFree(buf); 153 } 154 } 155 /* encode a couple bigger ints, just to show it's little-endian and leading 156 * sign bytes are dropped 157 */ 158 for (i = 0; i < sizeof(bigInts) / sizeof(bigInts[0]); i++) 159 { 160 blob.cbData = strlen((const char*)bigInts[i].val); 161 blob.pbData = (BYTE *)bigInts[i].val; 162 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob, 163 0, NULL, NULL, &bufSize); 164 ok(ret, "Expected success, got %d\n", GetLastError()); 165 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob, 166 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 167 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError()); 168 if (ret) 169 { 170 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n", 171 buf[0]); 172 ok(buf[1] == bigInts[i].encoded[1], "Got length %d, expected %d\n", 173 buf[1], bigInts[i].encoded[1]); 174 ok(!memcmp(buf + 1, bigInts[i].encoded + 1, 175 bigInts[i].encoded[1] + 1), 176 "Encoded value didn't match expected\n"); 177 LocalFree(buf); 178 } 179 } 180 /* and, encode some uints */ 181 for (i = 0; i < sizeof(bigUInts) / sizeof(bigUInts[0]); i++) 182 { 183 blob.cbData = strlen((const char*)bigUInts[i].val); 184 blob.pbData = (BYTE*)bigUInts[i].val; 185 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, &blob, 186 0, NULL, NULL, &bufSize); 187 ok(ret, "Expected success, got %d\n", GetLastError()); 188 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, &blob, 189 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 190 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError()); 191 if (ret) 192 { 193 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n", 194 buf[0]); 195 ok(buf[1] == bigUInts[i].encoded[1], "Got length %d, expected %d\n", 196 buf[1], bigUInts[i].encoded[1]); 197 ok(!memcmp(buf + 1, bigUInts[i].encoded + 1, 198 bigUInts[i].encoded[1] + 1), 199 "Encoded value didn't match expected\n"); 200 LocalFree(buf); 201 } 202 } 203 } 204 205 static void test_decodeInt(DWORD dwEncoding) 206 { 207 static const BYTE bigInt[] = { 2, 5, 0xff, 0xfe, 0xff, 0xfe, 0xff }; 208 static const BYTE testStr[] = { 0x16, 4, 't', 'e', 's', 't' }; 209 static const BYTE longForm[] = { 2, 0x81, 0x01, 0x01 }; 210 static const BYTE bigBogus[] = { 0x02, 0x84, 0x01, 0xff, 0xff, 0xf9 }; 211 static const BYTE extraBytes[] = { 2, 1, 1, 0, 0, 0, 0 }; 212 BYTE *buf = NULL; 213 DWORD bufSize = 0; 214 int i; 215 BOOL ret; 216 217 /* CryptDecodeObjectEx with NULL bufSize crashes.. 218 ret = pCryptDecodeObjectEx(3, X509_INTEGER, &ints[0].encoded, 219 ints[0].encoded[1] + 2, 0, NULL, NULL, NULL); 220 */ 221 /* check bogus encoding */ 222 ret = pCryptDecodeObjectEx(3, X509_INTEGER, (BYTE *)&ints[0].encoded, 223 ints[0].encoded[1] + 2, 0, NULL, NULL, &bufSize); 224 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 225 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError()); 226 /* check with NULL integer buffer */ 227 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, NULL, 0, 0, NULL, NULL, 228 &bufSize); 229 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD || 230 GetLastError() == OSS_BAD_ARG /* Win9x */), 231 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError()); 232 /* check with a valid, but too large, integer */ 233 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, bigInt, bigInt[1] + 2, 234 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 235 ok((!ret && GetLastError() == CRYPT_E_ASN1_LARGE) || 236 broken(ret) /* Win9x */, 237 "Expected CRYPT_E_ASN1_LARGE, got %d\n", GetLastError()); 238 /* check with a DER-encoded string */ 239 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, testStr, testStr[1] + 2, 240 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 241 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || 242 GetLastError() == OSS_PDU_MISMATCH /* Win9x */ ), 243 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %08x\n", 244 GetLastError()); 245 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++) 246 { 247 /* When the output buffer is NULL, this always succeeds */ 248 SetLastError(0xdeadbeef); 249 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, 250 ints[i].encoded, ints[i].encoded[1] + 2, 0, NULL, NULL, 251 &bufSize); 252 ok(ret && GetLastError() == NOERROR, 253 "Expected success and NOERROR, got %d\n", GetLastError()); 254 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, 255 ints[i].encoded, ints[i].encoded[1] + 2, 256 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 257 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError()); 258 ok(bufSize == sizeof(int), "Wrong size %d\n", bufSize); 259 ok(buf != NULL, "Expected allocated buffer\n"); 260 if (ret) 261 { 262 ok(!memcmp(buf, &ints[i].val, bufSize), "Expected %d, got %d\n", 263 ints[i].val, *(int *)buf); 264 LocalFree(buf); 265 } 266 } 267 for (i = 0; i < sizeof(bigInts) / sizeof(bigInts[0]); i++) 268 { 269 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, 270 bigInts[i].encoded, bigInts[i].encoded[1] + 2, 0, NULL, NULL, 271 &bufSize); 272 ok(ret && GetLastError() == NOERROR, 273 "Expected success and NOERROR, got %d\n", GetLastError()); 274 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, 275 bigInts[i].encoded, bigInts[i].encoded[1] + 2, 276 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 277 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError()); 278 ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %d\n", bufSize); 279 ok(buf != NULL, "Expected allocated buffer\n"); 280 if (ret) 281 { 282 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf; 283 284 ok(blob->cbData == strlen((const char*)bigInts[i].decoded), 285 "Expected len %d, got %d\n", lstrlenA((const char*)bigInts[i].decoded), 286 blob->cbData); 287 ok(!memcmp(blob->pbData, bigInts[i].decoded, blob->cbData), 288 "Unexpected value\n"); 289 LocalFree(buf); 290 } 291 } 292 for (i = 0; i < sizeof(bigUInts) / sizeof(bigUInts[0]); i++) 293 { 294 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, 295 bigUInts[i].encoded, bigUInts[i].encoded[1] + 2, 0, NULL, NULL, 296 &bufSize); 297 ok(ret && GetLastError() == NOERROR, 298 "Expected success and NOERROR, got %d\n", GetLastError()); 299 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, 300 bigUInts[i].encoded, bigUInts[i].encoded[1] + 2, 301 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 302 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError()); 303 ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %d\n", bufSize); 304 ok(buf != NULL, "Expected allocated buffer\n"); 305 if (ret) 306 { 307 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf; 308 309 ok(blob->cbData == strlen((const char*)bigUInts[i].val), 310 "Expected len %d, got %d\n", lstrlenA((const char*)bigUInts[i].val), 311 blob->cbData); 312 ok(!memcmp(blob->pbData, bigUInts[i].val, blob->cbData), 313 "Unexpected value\n"); 314 LocalFree(buf); 315 } 316 } 317 /* Decode the value 1 with long-form length */ 318 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, longForm, 319 sizeof(longForm), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 320 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 321 if (ret) 322 { 323 ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf); 324 LocalFree(buf); 325 } 326 /* check with extra bytes at the end */ 327 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, extraBytes, 328 sizeof(extraBytes), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 329 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 330 if (ret) 331 { 332 ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf); 333 LocalFree(buf); 334 } 335 /* Try to decode some bogus large items */ 336 /* The buffer size is smaller than the encoded length, so this should fail 337 * with CRYPT_E_ASN1_EOD if it's being decoded. 338 * Under XP it fails with CRYPT_E_ASN1_LARGE, which means there's a limit 339 * on the size decoded, but in ME it fails with CRYPT_E_ASN1_EOD or crashes. 340 * So this test unfortunately isn't useful. 341 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, tooBig, 342 0x7fffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 343 ok(!ret && GetLastError() == CRYPT_E_ASN1_LARGE, 344 "Expected CRYPT_E_ASN1_LARGE, got %08x\n", GetLastError()); 345 */ 346 /* This will try to decode the buffer and overflow it, check that it's 347 * caught. 348 */ 349 if (0) 350 { 351 /* a large buffer isn't guaranteed to crash, it depends on memory allocation order */ 352 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, bigBogus, 353 0x01ffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 354 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 355 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError()); 356 } 357 } 358 359 static const BYTE bin18[] = {0x0a,0x01,0x01}; 360 static const BYTE bin19[] = {0x0a,0x05,0x00,0xff,0xff,0xff,0x80}; 361 362 /* These are always encoded unsigned, and aren't constrained to be any 363 * particular value 364 */ 365 static const struct encodedInt enums[] = { 366 { 1, bin18 }, 367 { -128, bin19 }, 368 }; 369 370 /* X509_CRL_REASON_CODE is also an enumerated type, but it's #defined to 371 * X509_ENUMERATED. 372 */ 373 static const LPCSTR enumeratedTypes[] = { X509_ENUMERATED, 374 szOID_CRL_REASON_CODE }; 375 376 static void test_encodeEnumerated(DWORD dwEncoding) 377 { 378 DWORD i, j; 379 380 for (i = 0; i < sizeof(enumeratedTypes) / sizeof(enumeratedTypes[0]); i++) 381 { 382 for (j = 0; j < sizeof(enums) / sizeof(enums[0]); j++) 383 { 384 BOOL ret; 385 BYTE *buf = NULL; 386 DWORD bufSize = 0; 387 388 ret = pCryptEncodeObjectEx(dwEncoding, enumeratedTypes[i], 389 &enums[j].val, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, 390 &bufSize); 391 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError()); 392 if (ret) 393 { 394 ok(buf[0] == 0xa, 395 "Got unexpected type %d for enumerated (expected 0xa)\n", 396 buf[0]); 397 ok(buf[1] == enums[j].encoded[1], 398 "Got length %d, expected %d\n", buf[1], enums[j].encoded[1]); 399 ok(!memcmp(buf + 1, enums[j].encoded + 1, 400 enums[j].encoded[1] + 1), 401 "Encoded value of 0x%08x didn't match expected\n", 402 enums[j].val); 403 LocalFree(buf); 404 } 405 } 406 } 407 } 408 409 static void test_decodeEnumerated(DWORD dwEncoding) 410 { 411 DWORD i, j; 412 413 for (i = 0; i < sizeof(enumeratedTypes) / sizeof(enumeratedTypes[0]); i++) 414 { 415 for (j = 0; j < sizeof(enums) / sizeof(enums[0]); j++) 416 { 417 BOOL ret; 418 DWORD bufSize = sizeof(int); 419 int val; 420 421 ret = pCryptDecodeObjectEx(dwEncoding, enumeratedTypes[i], 422 enums[j].encoded, enums[j].encoded[1] + 2, 0, NULL, 423 &val, &bufSize); 424 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 425 ok(bufSize == sizeof(int), 426 "Got unexpected size %d for enumerated\n", bufSize); 427 ok(val == enums[j].val, "Unexpected value %d, expected %d\n", 428 val, enums[j].val); 429 } 430 } 431 } 432 433 struct encodedFiletime 434 { 435 SYSTEMTIME sysTime; 436 const BYTE *encodedTime; 437 }; 438 439 static void testTimeEncoding(DWORD dwEncoding, LPCSTR structType, 440 const struct encodedFiletime *time) 441 { 442 FILETIME ft = { 0 }; 443 BYTE *buf = NULL; 444 DWORD bufSize = 0; 445 BOOL ret; 446 447 ret = SystemTimeToFileTime(&time->sysTime, &ft); 448 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError()); 449 ret = pCryptEncodeObjectEx(dwEncoding, structType, &ft, 450 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 451 /* years other than 1950-2050 are not allowed for encodings other than 452 * X509_CHOICE_OF_TIME. 453 */ 454 if (structType == X509_CHOICE_OF_TIME || 455 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050)) 456 { 457 ok(ret, "CryptEncodeObjectEx failed: %d (0x%08x)\n", GetLastError(), 458 GetLastError()); 459 ok(buf != NULL, "Expected an allocated buffer\n"); 460 if (ret) 461 { 462 ok(buf[0] == time->encodedTime[0], 463 "Expected type 0x%02x, got 0x%02x\n", time->encodedTime[0], 464 buf[0]); 465 ok(buf[1] == time->encodedTime[1], "Expected %d bytes, got %d\n", 466 time->encodedTime[1], bufSize); 467 ok(!memcmp(time->encodedTime + 2, buf + 2, time->encodedTime[1]), 468 "Got unexpected value for time encoding\n"); 469 LocalFree(buf); 470 } 471 } 472 else 473 ok((!ret && GetLastError() == CRYPT_E_BAD_ENCODE) || 474 broken(GetLastError() == ERROR_SUCCESS), 475 "Expected CRYPT_E_BAD_ENCODE, got 0x%08x\n", GetLastError()); 476 } 477 478 static const char *printSystemTime(const SYSTEMTIME *st) 479 { 480 static char buf[64]; 481 482 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st->wMonth, st->wDay, 483 st->wYear, st->wHour, st->wMinute, st->wSecond, st->wMilliseconds); 484 return buf; 485 } 486 487 static const char *printFileTime(const FILETIME *ft) 488 { 489 static char buf[64]; 490 SYSTEMTIME st; 491 492 FileTimeToSystemTime(ft, &st); 493 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st.wMonth, st.wDay, 494 st.wYear, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); 495 return buf; 496 } 497 498 static void compareTime(const SYSTEMTIME *expected, const FILETIME *got) 499 { 500 SYSTEMTIME st; 501 502 FileTimeToSystemTime(got, &st); 503 ok((expected->wYear == st.wYear && 504 expected->wMonth == st.wMonth && 505 expected->wDay == st.wDay && 506 expected->wHour == st.wHour && 507 expected->wMinute == st.wMinute && 508 expected->wSecond == st.wSecond && 509 abs(expected->wMilliseconds - st.wMilliseconds) <= 1) || 510 /* Some Windows systems only seem to be accurate in their time decoding to 511 * within about an hour. 512 */ 513 broken(expected->wYear == st.wYear && 514 expected->wMonth == st.wMonth && 515 expected->wDay == st.wDay && 516 abs(expected->wHour - st.wHour) <= 1), 517 "Got unexpected value for time decoding:\nexpected %s, got %s\n", 518 printSystemTime(expected), printFileTime(got)); 519 } 520 521 static void testTimeDecoding(DWORD dwEncoding, LPCSTR structType, 522 const struct encodedFiletime *time) 523 { 524 FILETIME ft = { 0 }; 525 DWORD size = sizeof(ft); 526 BOOL ret; 527 528 ret = pCryptDecodeObjectEx(dwEncoding, structType, time->encodedTime, 529 time->encodedTime[1] + 2, 0, NULL, &ft, &size); 530 /* years other than 1950-2050 are not allowed for encodings other than 531 * X509_CHOICE_OF_TIME. 532 */ 533 if (structType == X509_CHOICE_OF_TIME || 534 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050)) 535 { 536 ok(ret || broken(GetLastError() == OSS_DATA_ERROR), 537 "CryptDecodeObjectEx failed: %d (0x%08x)\n", GetLastError(), 538 GetLastError()); 539 if (ret) 540 compareTime(&time->sysTime, &ft); 541 } 542 else 543 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || 544 GetLastError() == OSS_PDU_MISMATCH /* Win9x */ ), 545 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %08x\n", 546 GetLastError()); 547 } 548 549 static const BYTE bin20[] = { 550 0x17,0x0d,'0','5','0','6','0','6','1','6','1','0','0','0','Z'}; 551 static const BYTE bin21[] = { 552 0x18,0x0f,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','Z'}; 553 static const BYTE bin22[] = { 554 0x18,0x0f,'2','1','4','5','0','6','0','6','1','6','1','0','0','0','Z'}; 555 556 static const struct encodedFiletime times[] = { 557 { { 2005, 6, 1, 6, 16, 10, 0, 0 }, bin20 }, 558 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin21 }, 559 { { 2145, 6, 1, 6, 16, 10, 0, 0 }, bin22 }, 560 }; 561 562 static void test_encodeFiletime(DWORD dwEncoding) 563 { 564 DWORD i; 565 566 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++) 567 { 568 testTimeEncoding(dwEncoding, X509_CHOICE_OF_TIME, ×[i]); 569 testTimeEncoding(dwEncoding, PKCS_UTC_TIME, ×[i]); 570 testTimeEncoding(dwEncoding, szOID_RSA_signingTime, ×[i]); 571 } 572 } 573 574 static const BYTE bin23[] = { 575 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','0','0','0','Z'}; 576 static const BYTE bin24[] = { 577 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','9','9','9','Z'}; 578 static const BYTE bin25[] = { 579 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','+','0','1','0','0'}; 580 static const BYTE bin26[] = { 581 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','0','0'}; 582 static const BYTE bin27[] = { 583 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','1','5'}; 584 static const BYTE bin28[] = { 585 0x18,0x0a,'2','1','4','5','0','6','0','6','1','6'}; 586 static const BYTE bin29[] = { 587 0x17,0x0a,'4','5','0','6','0','6','1','6','1','0'}; 588 static const BYTE bin30[] = { 589 0x17,0x0b,'4','5','0','6','0','6','1','6','1','0','Z'}; 590 static const BYTE bin31[] = { 591 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','+','0','1'}; 592 static const BYTE bin32[] = { 593 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','-','0','1'}; 594 static const BYTE bin33[] = { 595 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','+','0','1','0','0'}; 596 static const BYTE bin34[] = { 597 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','-','0','1','0','0'}; 598 static const BYTE bin35[] = { 599 0x17,0x08, '4','5','0','6','0','6','1','6'}; 600 static const BYTE bin36[] = { 601 0x18,0x0f, 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','Z'}; 602 static const BYTE bin37[] = { 603 0x18,0x04, '2','1','4','5'}; 604 static const BYTE bin38[] = { 605 0x18,0x08, '2','1','4','5','0','6','0','6'}; 606 607 static void test_decodeFiletime(DWORD dwEncoding) 608 { 609 static const struct encodedFiletime otherTimes[] = { 610 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin23 }, 611 { { 1945, 6, 1, 6, 16, 10, 0, 999 }, bin24 }, 612 { { 1945, 6, 1, 6, 17, 10, 0, 0 }, bin25 }, 613 { { 1945, 6, 1, 6, 15, 10, 0, 0 }, bin26 }, 614 { { 1945, 6, 1, 6, 14, 55, 0, 0 }, bin27 }, 615 { { 2145, 6, 1, 6, 16, 0, 0, 0 }, bin28 }, 616 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin29 }, 617 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin30 }, 618 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin31 }, 619 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin32 }, 620 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin33 }, 621 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin34 }, 622 }; 623 /* An oddball case that succeeds in Windows, but doesn't seem correct 624 { { 2145, 6, 1, 2, 11, 31, 0, 0 }, "\x18" "\x13" "21450606161000-9999" }, 625 */ 626 static const unsigned char *bogusTimes[] = { 627 /* oddly, this succeeds on Windows, with year 2765 628 "\x18" "\x0f" "21r50606161000Z", 629 */ 630 bin35, 631 bin36, 632 bin37, 633 bin38, 634 }; 635 DWORD i, size; 636 FILETIME ft1 = { 0 }, ft2 = { 0 }; 637 BOOL ret; 638 639 /* Check bogus length with non-NULL buffer */ 640 ret = SystemTimeToFileTime(×[0].sysTime, &ft1); 641 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError()); 642 size = 1; 643 ret = pCryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME, 644 times[0].encodedTime, times[0].encodedTime[1] + 2, 0, NULL, &ft2, &size); 645 ok(!ret && GetLastError() == ERROR_MORE_DATA, 646 "Expected ERROR_MORE_DATA, got %d\n", GetLastError()); 647 /* Normal tests */ 648 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++) 649 { 650 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, ×[i]); 651 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, ×[i]); 652 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, ×[i]); 653 } 654 for (i = 0; i < sizeof(otherTimes) / sizeof(otherTimes[0]); i++) 655 { 656 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &otherTimes[i]); 657 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &otherTimes[i]); 658 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &otherTimes[i]); 659 } 660 for (i = 0; i < sizeof(bogusTimes) / sizeof(bogusTimes[0]); i++) 661 { 662 size = sizeof(ft1); 663 ret = pCryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME, 664 bogusTimes[i], bogusTimes[i][1] + 2, 0, NULL, &ft1, &size); 665 ok((!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT || 666 GetLastError() == OSS_DATA_ERROR /* Win9x */)) || 667 broken(ret), /* Win9x and NT4 for bin38 */ 668 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n", 669 GetLastError()); 670 } 671 } 672 673 static const char commonName[] = "Juan Lang"; 674 static const char surName[] = "Lang"; 675 676 static const BYTE emptySequence[] = { 0x30, 0 }; 677 static const BYTE emptyRDNs[] = { 0x30, 0x02, 0x31, 0 }; 678 static const BYTE twoRDNs[] = { 679 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04, 680 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03, 681 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0}; 682 static const BYTE encodedTwoRDNs[] = { 683 0x30,0x2e,0x31,0x2c,0x30,0x2a,0x06,0x03,0x55,0x04,0x03,0x30,0x23,0x31,0x21, 684 0x30,0x0c,0x06,0x03,0x55,0x04,0x04,0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30, 685 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61, 686 0x6e,0x67,0x00, 687 }; 688 689 static const BYTE us[] = { 0x55, 0x53 }; 690 static const BYTE minnesota[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x73, 0x6f, 691 0x74, 0x61 }; 692 static const BYTE minneapolis[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x61, 0x70, 693 0x6f, 0x6c, 0x69, 0x73 }; 694 static const BYTE codeweavers[] = { 0x43, 0x6f, 0x64, 0x65, 0x57, 0x65, 0x61, 695 0x76, 0x65, 0x72, 0x73 }; 696 static const BYTE wine[] = { 0x57, 0x69, 0x6e, 0x65, 0x20, 0x44, 0x65, 0x76, 697 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74 }; 698 static const BYTE localhostAttr[] = { 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 699 0x73, 0x74 }; 700 static const BYTE aric[] = { 0x61, 0x72, 0x69, 0x63, 0x40, 0x63, 0x6f, 0x64, 701 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d }; 702 703 #define RDNA(arr) oid_ ## arr, CERT_RDN_PRINTABLE_STRING, { sizeof(arr), (LPBYTE)arr } 704 #define RDNIA5(arr) oid_ ## arr, CERT_RDN_IA5_STRING, { sizeof(arr), (LPBYTE)arr } 705 706 static CHAR oid_us[] = "2.5.4.6", 707 oid_minnesota[] = "2.5.4.8", 708 oid_minneapolis[] = "2.5.4.7", 709 oid_codeweavers[] = "2.5.4.10", 710 oid_wine[] = "2.5.4.11", 711 oid_localhostAttr[] = "2.5.4.3", 712 oid_aric[] = "1.2.840.113549.1.9.1"; 713 static CERT_RDN_ATTR rdnAttrs[] = { { RDNA(us) }, 714 { RDNA(minnesota) }, 715 { RDNA(minneapolis) }, 716 { RDNA(codeweavers) }, 717 { RDNA(wine) }, 718 { RDNA(localhostAttr) }, 719 { RDNIA5(aric) } }; 720 static CERT_RDN_ATTR decodedRdnAttrs[] = { { RDNA(us) }, 721 { RDNA(localhostAttr) }, 722 { RDNA(minnesota) }, 723 { RDNA(minneapolis) }, 724 { RDNA(codeweavers) }, 725 { RDNA(wine) }, 726 { RDNIA5(aric) } }; 727 728 #undef RDNIA5 729 #undef RDNA 730 731 static const BYTE encodedRDNAttrs[] = { 732 0x30,0x81,0x96,0x31,0x81,0x93,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55, 733 0x53,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x68, 734 0x6f,0x73,0x74,0x30,0x10,0x06,0x03,0x55,0x04,0x08,0x13,0x09,0x4d,0x69,0x6e,0x6e, 735 0x65,0x73,0x6f,0x74,0x61,0x30,0x12,0x06,0x03,0x55,0x04,0x07,0x13,0x0b,0x4d,0x69, 736 0x6e,0x6e,0x65,0x61,0x70,0x6f,0x6c,0x69,0x73,0x30,0x12,0x06,0x03,0x55,0x04,0x0a, 737 0x13,0x0b,0x43,0x6f,0x64,0x65,0x57,0x65,0x61,0x76,0x65,0x72,0x73,0x30,0x17,0x06, 738 0x03,0x55,0x04,0x0b,0x13,0x10,0x57,0x69,0x6e,0x65,0x20,0x44,0x65,0x76,0x65,0x6c, 739 0x6f,0x70,0x6d,0x65,0x6e,0x74,0x30,0x21,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d, 740 0x01,0x09,0x01,0x16,0x14,0x61,0x72,0x69,0x63,0x40,0x63,0x6f,0x64,0x65,0x77,0x65, 741 0x61,0x76,0x65,0x72,0x73,0x2e,0x63,0x6f,0x6d 742 }; 743 744 static void test_encodeName(DWORD dwEncoding) 745 { 746 CERT_RDN_ATTR attrs[2]; 747 CERT_RDN rdn; 748 CERT_NAME_INFO info; 749 static CHAR oid_common_name[] = szOID_COMMON_NAME, 750 oid_sur_name[] = szOID_SUR_NAME; 751 BYTE *buf = NULL; 752 DWORD size = 0; 753 BOOL ret; 754 755 if (0) 756 { 757 /* Test with NULL pvStructInfo (crashes on win9x) */ 758 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, NULL, 759 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 760 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 761 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError()); 762 } 763 /* Test with empty CERT_NAME_INFO */ 764 info.cRDN = 0; 765 info.rgRDN = NULL; 766 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info, 767 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 768 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 769 if (ret) 770 { 771 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)), 772 "Got unexpected encoding for empty name\n"); 773 LocalFree(buf); 774 } 775 if (0) 776 { 777 /* Test with bogus CERT_RDN (crashes on win9x) */ 778 info.cRDN = 1; 779 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info, 780 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 781 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 782 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError()); 783 } 784 /* Test with empty CERT_RDN */ 785 rdn.cRDNAttr = 0; 786 rdn.rgRDNAttr = NULL; 787 info.cRDN = 1; 788 info.rgRDN = &rdn; 789 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info, 790 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 791 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 792 if (ret) 793 { 794 ok(!memcmp(buf, emptyRDNs, sizeof(emptyRDNs)), 795 "Got unexpected encoding for empty RDN array\n"); 796 LocalFree(buf); 797 } 798 if (0) 799 { 800 /* Test with bogus attr array (crashes on win9x) */ 801 rdn.cRDNAttr = 1; 802 rdn.rgRDNAttr = NULL; 803 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info, 804 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 805 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 806 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError()); 807 } 808 /* oddly, a bogus OID is accepted by Windows XP; not testing. 809 attrs[0].pszObjId = "bogus"; 810 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING; 811 attrs[0].Value.cbData = sizeof(commonName); 812 attrs[0].Value.pbData = commonName; 813 rdn.cRDNAttr = 1; 814 rdn.rgRDNAttr = attrs; 815 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info, 816 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 817 ok(!ret, "Expected failure, got success\n"); 818 */ 819 /* Check with two CERT_RDN_ATTRs. Note DER encoding forces the order of 820 * the encoded attributes to be swapped. 821 */ 822 attrs[0].pszObjId = oid_common_name; 823 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING; 824 attrs[0].Value.cbData = sizeof(commonName); 825 attrs[0].Value.pbData = (BYTE *)commonName; 826 attrs[1].pszObjId = oid_sur_name; 827 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING; 828 attrs[1].Value.cbData = sizeof(surName); 829 attrs[1].Value.pbData = (BYTE *)surName; 830 rdn.cRDNAttr = 2; 831 rdn.rgRDNAttr = attrs; 832 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info, 833 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 834 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 835 if (ret) 836 { 837 ok(!memcmp(buf, twoRDNs, sizeof(twoRDNs)), 838 "Got unexpected encoding for two RDN array\n"); 839 LocalFree(buf); 840 } 841 /* A name can be "encoded" with previously encoded RDN attrs. */ 842 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB; 843 attrs[0].Value.pbData = (LPBYTE)twoRDNs; 844 attrs[0].Value.cbData = sizeof(twoRDNs); 845 rdn.cRDNAttr = 1; 846 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info, 847 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 848 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 849 if (ret) 850 { 851 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size); 852 ok(!memcmp(buf, encodedTwoRDNs, size), 853 "Unexpected value for re-encoded two RDN array\n"); 854 LocalFree(buf); 855 } 856 /* CERT_RDN_ANY_TYPE is too vague for X509_NAMEs, check the return */ 857 rdn.cRDNAttr = 1; 858 attrs[0].dwValueType = CERT_RDN_ANY_TYPE; 859 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info, 860 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 861 ok(!ret && GetLastError() == E_INVALIDARG, 862 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 863 /* Test a more complex name */ 864 rdn.cRDNAttr = sizeof(rdnAttrs) / sizeof(rdnAttrs[0]); 865 rdn.rgRDNAttr = rdnAttrs; 866 info.cRDN = 1; 867 info.rgRDN = &rdn; 868 buf = NULL; 869 size = 0; 870 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, X509_NAME, &info, 871 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 872 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 873 if (ret) 874 { 875 ok(size == sizeof(encodedRDNAttrs), "Wrong size %d\n", size); 876 ok(!memcmp(buf, encodedRDNAttrs, size), "Unexpected value\n"); 877 LocalFree(buf); 878 } 879 } 880 881 static WCHAR commonNameW[] = { 'J','u','a','n',' ','L','a','n','g',0 }; 882 static WCHAR surNameW[] = { 'L','a','n','g',0 }; 883 884 static const BYTE twoRDNsNoNull[] = { 885 0x30,0x21,0x31,0x1f,0x30,0x0b,0x06,0x03,0x55,0x04,0x04,0x13,0x04,0x4c,0x61, 886 0x6e,0x67,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e, 887 0x20,0x4c,0x61,0x6e,0x67 }; 888 static const BYTE anyType[] = { 889 0x30,0x2f,0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x1e,0x24,0x23,0x30, 890 0x21,0x31,0x0c,0x30,0x03,0x06,0x04,0x55,0x13,0x04,0x4c,0x05,0x6e,0x61,0x00, 891 0x67,0x11,0x30,0x03,0x06,0x04,0x55,0x13,0x03,0x4a,0x0a,0x61,0x75,0x20,0x6e, 892 0x61,0x4c,0x67,0x6e }; 893 894 static void test_encodeUnicodeName(DWORD dwEncoding) 895 { 896 CERT_RDN_ATTR attrs[2]; 897 CERT_RDN rdn; 898 CERT_NAME_INFO info; 899 static CHAR oid_common_name[] = szOID_COMMON_NAME, 900 oid_sur_name[] = szOID_SUR_NAME; 901 BYTE *buf = NULL; 902 DWORD size = 0; 903 BOOL ret; 904 905 if (0) 906 { 907 /* Test with NULL pvStructInfo (crashes on win9x) */ 908 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, NULL, 909 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 910 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 911 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError()); 912 } 913 /* Test with empty CERT_NAME_INFO */ 914 info.cRDN = 0; 915 info.rgRDN = NULL; 916 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info, 917 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 918 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 919 if (ret) 920 { 921 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)), 922 "Got unexpected encoding for empty name\n"); 923 LocalFree(buf); 924 } 925 /* Check with one CERT_RDN_ATTR, that has an invalid character for the 926 * encoding (the NULL). 927 */ 928 attrs[0].pszObjId = oid_common_name; 929 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING; 930 attrs[0].Value.cbData = sizeof(commonNameW); 931 attrs[0].Value.pbData = (BYTE *)commonNameW; 932 rdn.cRDNAttr = 1; 933 rdn.rgRDNAttr = attrs; 934 info.cRDN = 1; 935 info.rgRDN = &rdn; 936 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info, 937 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 938 ok(!ret && GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING, 939 "Expected CRYPT_E_INVALID_PRINTABLE_STRING, got %08x\n", GetLastError()); 940 ok(size == 9, "Unexpected error index %08x\n", size); 941 /* Check with two NULL-terminated CERT_RDN_ATTRs. Note DER encoding 942 * forces the order of the encoded attributes to be swapped. 943 */ 944 attrs[0].pszObjId = oid_common_name; 945 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING; 946 attrs[0].Value.cbData = 0; 947 attrs[0].Value.pbData = (BYTE *)commonNameW; 948 attrs[1].pszObjId = oid_sur_name; 949 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING; 950 attrs[1].Value.cbData = 0; 951 attrs[1].Value.pbData = (BYTE *)surNameW; 952 rdn.cRDNAttr = 2; 953 rdn.rgRDNAttr = attrs; 954 info.cRDN = 1; 955 info.rgRDN = &rdn; 956 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info, 957 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 958 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 959 if (ret) 960 { 961 ok(!memcmp(buf, twoRDNsNoNull, sizeof(twoRDNsNoNull)), 962 "Got unexpected encoding for two RDN array\n"); 963 LocalFree(buf); 964 } 965 /* A name can be "encoded" with previously encoded RDN attrs. */ 966 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB; 967 attrs[0].Value.pbData = (LPBYTE)twoRDNs; 968 attrs[0].Value.cbData = sizeof(twoRDNs); 969 rdn.cRDNAttr = 1; 970 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info, 971 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 972 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 973 if (ret) 974 { 975 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size); 976 ok(!memcmp(buf, encodedTwoRDNs, size), 977 "Unexpected value for re-encoded two RDN array\n"); 978 LocalFree(buf); 979 } 980 /* Unicode names infer the type for CERT_RDN_ANY_TYPE */ 981 rdn.cRDNAttr = 1; 982 attrs[0].dwValueType = CERT_RDN_ANY_TYPE; 983 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info, 984 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 985 todo_wine ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 986 if (ret) 987 { 988 ok(size == sizeof(anyType), "Unexpected size %d\n", size); 989 ok(!memcmp(buf, anyType, size), "Unexpected value\n"); 990 LocalFree(buf); 991 } 992 } 993 994 static void compareNameValues(const CERT_NAME_VALUE *expected, 995 const CERT_NAME_VALUE *got) 996 { 997 if (expected->dwValueType == CERT_RDN_UTF8_STRING && 998 got->dwValueType == CERT_RDN_ENCODED_BLOB) 999 { 1000 win_skip("Can't handle CERT_RDN_UTF8_STRING\n"); 1001 return; 1002 } 1003 1004 ok(got->dwValueType == expected->dwValueType, 1005 "Expected string type %d, got %d\n", expected->dwValueType, 1006 got->dwValueType); 1007 ok(got->Value.cbData == expected->Value.cbData || 1008 got->Value.cbData == expected->Value.cbData - sizeof(WCHAR) /* Win8 */, 1009 "String type %d: unexpected data size, got %d, expected %d\n", 1010 expected->dwValueType, got->Value.cbData, expected->Value.cbData); 1011 if (got->Value.cbData && got->Value.pbData) 1012 ok(!memcmp(got->Value.pbData, expected->Value.pbData, 1013 min(got->Value.cbData, expected->Value.cbData)), 1014 "String type %d: unexpected value\n", expected->dwValueType); 1015 } 1016 1017 static void compareRDNAttrs(const CERT_RDN_ATTR *expected, 1018 const CERT_RDN_ATTR *got) 1019 { 1020 if (expected->pszObjId && strlen(expected->pszObjId)) 1021 { 1022 ok(got->pszObjId != NULL, "Expected OID %s, got NULL\n", 1023 expected->pszObjId); 1024 if (got->pszObjId) 1025 { 1026 ok(!strcmp(got->pszObjId, expected->pszObjId), 1027 "Got unexpected OID %s, expected %s\n", got->pszObjId, 1028 expected->pszObjId); 1029 } 1030 } 1031 compareNameValues((const CERT_NAME_VALUE *)&expected->dwValueType, 1032 (const CERT_NAME_VALUE *)&got->dwValueType); 1033 } 1034 1035 static void compareRDNs(const CERT_RDN *expected, const CERT_RDN *got) 1036 { 1037 ok(got->cRDNAttr == expected->cRDNAttr, 1038 "Expected %d RDN attrs, got %d\n", expected->cRDNAttr, got->cRDNAttr); 1039 if (got->cRDNAttr) 1040 { 1041 DWORD i; 1042 1043 for (i = 0; i < got->cRDNAttr; i++) 1044 compareRDNAttrs(&expected->rgRDNAttr[i], &got->rgRDNAttr[i]); 1045 } 1046 } 1047 1048 static void compareNames(const CERT_NAME_INFO *expected, 1049 const CERT_NAME_INFO *got) 1050 { 1051 ok(got->cRDN == expected->cRDN, "Expected %d RDNs, got %d\n", 1052 expected->cRDN, got->cRDN); 1053 if (got->cRDN) 1054 { 1055 DWORD i; 1056 1057 for (i = 0; i < got->cRDN; i++) 1058 compareRDNs(&expected->rgRDN[i], &got->rgRDN[i]); 1059 } 1060 } 1061 1062 static const BYTE emptyIndefiniteSequence[] = { 0x30,0x80,0x00,0x00 }; 1063 static const BYTE twoRDNsExtraBytes[] = { 1064 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04, 1065 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03, 1066 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0,0,0,0,0,0}; 1067 1068 static void test_decodeName(DWORD dwEncoding) 1069 { 1070 BYTE *buf = NULL; 1071 DWORD bufSize = 0; 1072 BOOL ret; 1073 CERT_RDN rdn; 1074 CERT_NAME_INFO info = { 1, &rdn }; 1075 1076 /* test empty name */ 1077 bufSize = 0; 1078 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptySequence, 1079 emptySequence[1] + 2, 1080 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL, 1081 &buf, &bufSize); 1082 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1083 /* Interestingly, in Windows, if cRDN is 0, rgRGN may not be NULL. My 1084 * decoder works the same way, so only test the count. 1085 */ 1086 if (ret) 1087 { 1088 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize); 1089 ok(((CERT_NAME_INFO *)buf)->cRDN == 0, 1090 "Expected 0 RDNs in empty info, got %d\n", 1091 ((CERT_NAME_INFO *)buf)->cRDN); 1092 LocalFree(buf); 1093 } 1094 /* test empty name with indefinite-length encoding */ 1095 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyIndefiniteSequence, 1096 sizeof(emptyIndefiniteSequence), CRYPT_DECODE_ALLOC_FLAG, NULL, 1097 &buf, &bufSize); 1098 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1099 if (ret) 1100 { 1101 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize); 1102 ok(((CERT_NAME_INFO *)buf)->cRDN == 0, 1103 "Expected 0 RDNs in empty info, got %d\n", 1104 ((CERT_NAME_INFO *)buf)->cRDN); 1105 LocalFree(buf); 1106 } 1107 /* test empty RDN */ 1108 bufSize = 0; 1109 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyRDNs, 1110 emptyRDNs[1] + 2, 1111 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL, 1112 &buf, &bufSize); 1113 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1114 if (ret) 1115 { 1116 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf; 1117 1118 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) && 1119 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0, 1120 "Got unexpected value for empty RDN\n"); 1121 LocalFree(buf); 1122 } 1123 /* test two RDN attrs */ 1124 bufSize = 0; 1125 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNs, 1126 twoRDNs[1] + 2, 1127 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL, 1128 &buf, &bufSize); 1129 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1130 if (ret) 1131 { 1132 static CHAR oid_sur_name[] = szOID_SUR_NAME, 1133 oid_common_name[] = szOID_COMMON_NAME; 1134 1135 CERT_RDN_ATTR attrs[] = { 1136 { oid_sur_name, CERT_RDN_PRINTABLE_STRING, { sizeof(surName), 1137 (BYTE *)surName } }, 1138 { oid_common_name, CERT_RDN_PRINTABLE_STRING, { sizeof(commonName), 1139 (BYTE *)commonName } }, 1140 }; 1141 1142 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]); 1143 rdn.rgRDNAttr = attrs; 1144 compareNames(&info, (CERT_NAME_INFO *)buf); 1145 LocalFree(buf); 1146 } 1147 /* test that two RDN attrs with extra bytes succeeds */ 1148 bufSize = 0; 1149 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNsExtraBytes, 1150 sizeof(twoRDNsExtraBytes), 0, NULL, NULL, &bufSize); 1151 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1152 /* And, a slightly more complicated name */ 1153 buf = NULL; 1154 bufSize = 0; 1155 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME, encodedRDNAttrs, 1156 sizeof(encodedRDNAttrs), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 1157 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1158 if (ret) 1159 { 1160 rdn.cRDNAttr = sizeof(decodedRdnAttrs) / sizeof(decodedRdnAttrs[0]); 1161 rdn.rgRDNAttr = decodedRdnAttrs; 1162 compareNames(&info, (CERT_NAME_INFO *)buf); 1163 LocalFree(buf); 1164 } 1165 } 1166 1167 static void test_decodeUnicodeName(DWORD dwEncoding) 1168 { 1169 BYTE *buf = NULL; 1170 DWORD bufSize = 0; 1171 BOOL ret; 1172 CERT_RDN rdn; 1173 CERT_NAME_INFO info = { 1, &rdn }; 1174 1175 /* test empty name */ 1176 bufSize = 0; 1177 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptySequence, 1178 emptySequence[1] + 2, 1179 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL, 1180 &buf, &bufSize); 1181 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1182 if (ret) 1183 { 1184 ok(bufSize == sizeof(CERT_NAME_INFO), 1185 "Got wrong bufSize %d\n", bufSize); 1186 ok(((CERT_NAME_INFO *)buf)->cRDN == 0, 1187 "Expected 0 RDNs in empty info, got %d\n", 1188 ((CERT_NAME_INFO *)buf)->cRDN); 1189 LocalFree(buf); 1190 } 1191 /* test empty RDN */ 1192 bufSize = 0; 1193 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptyRDNs, 1194 emptyRDNs[1] + 2, 1195 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL, 1196 &buf, &bufSize); 1197 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1198 if (ret) 1199 { 1200 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf; 1201 1202 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) && 1203 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0, 1204 "Got unexpected value for empty RDN\n"); 1205 LocalFree(buf); 1206 } 1207 /* test two RDN attrs */ 1208 bufSize = 0; 1209 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, twoRDNsNoNull, 1210 sizeof(twoRDNsNoNull), 1211 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL, 1212 &buf, &bufSize); 1213 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1214 if (ret) 1215 { 1216 static CHAR oid_sur_name[] = szOID_SUR_NAME, 1217 oid_common_name[] = szOID_COMMON_NAME; 1218 1219 CERT_RDN_ATTR attrs[] = { 1220 { oid_sur_name, CERT_RDN_PRINTABLE_STRING, 1221 { lstrlenW(surNameW) * sizeof(WCHAR), (BYTE *)surNameW } }, 1222 { oid_common_name, CERT_RDN_PRINTABLE_STRING, 1223 { lstrlenW(commonNameW) * sizeof(WCHAR), (BYTE *)commonNameW } }, 1224 }; 1225 1226 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]); 1227 rdn.rgRDNAttr = attrs; 1228 compareNames(&info, (CERT_NAME_INFO *)buf); 1229 LocalFree(buf); 1230 } 1231 } 1232 1233 struct EncodedNameValue 1234 { 1235 CERT_NAME_VALUE value; 1236 const BYTE *encoded; 1237 DWORD encodedSize; 1238 }; 1239 1240 static const char bogusIA5[] = "\x80"; 1241 static const char bogusPrintable[] = "~"; 1242 static const char bogusNumeric[] = "A"; 1243 static const BYTE bin42[] = { 0x16,0x02,0x80,0x00 }; 1244 static const BYTE bin43[] = { 0x13,0x02,0x7e,0x00 }; 1245 static const BYTE bin44[] = { 0x12,0x02,0x41,0x00 }; 1246 static BYTE octetCommonNameValue[] = { 1247 0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 }; 1248 static BYTE numericCommonNameValue[] = { 1249 0x12,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 }; 1250 static BYTE printableCommonNameValue[] = { 1251 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 }; 1252 static BYTE t61CommonNameValue[] = { 1253 0x14,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 }; 1254 static BYTE videotexCommonNameValue[] = { 1255 0x15,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 }; 1256 static BYTE ia5CommonNameValue[] = { 1257 0x16,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 }; 1258 static BYTE graphicCommonNameValue[] = { 1259 0x19,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 }; 1260 static BYTE visibleCommonNameValue[] = { 1261 0x1a,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 }; 1262 static BYTE generalCommonNameValue[] = { 1263 0x1b,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 }; 1264 static BYTE bmpCommonNameValue[] = { 1265 0x1e,0x14,0x00,0x4a,0x00,0x75,0x00,0x61,0x00,0x6e,0x00,0x20,0x00,0x4c,0x00, 1266 0x61,0x00,0x6e,0x00,0x67,0x00,0x00 }; 1267 static BYTE utf8CommonNameValue[] = { 1268 0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 }; 1269 static char embedded_null[] = "foo\0com"; 1270 static BYTE ia5EmbeddedNull[] = { 1271 0x16,0x07,0x66,0x6f,0x6f,0x00,0x63,0x6f,0x6d }; 1272 1273 static struct EncodedNameValue nameValues[] = { 1274 { { CERT_RDN_OCTET_STRING, { sizeof(commonName), (BYTE *)commonName } }, 1275 octetCommonNameValue, sizeof(octetCommonNameValue) }, 1276 { { CERT_RDN_NUMERIC_STRING, { sizeof(commonName), (BYTE *)commonName } }, 1277 numericCommonNameValue, sizeof(numericCommonNameValue) }, 1278 { { CERT_RDN_PRINTABLE_STRING, { sizeof(commonName), (BYTE *)commonName } }, 1279 printableCommonNameValue, sizeof(printableCommonNameValue) }, 1280 { { CERT_RDN_T61_STRING, { sizeof(commonName), (BYTE *)commonName } }, 1281 t61CommonNameValue, sizeof(t61CommonNameValue) }, 1282 { { CERT_RDN_VIDEOTEX_STRING, { sizeof(commonName), (BYTE *)commonName } }, 1283 videotexCommonNameValue, sizeof(videotexCommonNameValue) }, 1284 { { CERT_RDN_IA5_STRING, { sizeof(commonName), (BYTE *)commonName } }, 1285 ia5CommonNameValue, sizeof(ia5CommonNameValue) }, 1286 { { CERT_RDN_GRAPHIC_STRING, { sizeof(commonName), (BYTE *)commonName } }, 1287 graphicCommonNameValue, sizeof(graphicCommonNameValue) }, 1288 { { CERT_RDN_VISIBLE_STRING, { sizeof(commonName), (BYTE *)commonName } }, 1289 visibleCommonNameValue, sizeof(visibleCommonNameValue) }, 1290 { { CERT_RDN_GENERAL_STRING, { sizeof(commonName), (BYTE *)commonName } }, 1291 generalCommonNameValue, sizeof(generalCommonNameValue) }, 1292 { { CERT_RDN_BMP_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } }, 1293 bmpCommonNameValue, sizeof(bmpCommonNameValue) }, 1294 { { CERT_RDN_UTF8_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } }, 1295 utf8CommonNameValue, sizeof(utf8CommonNameValue) }, 1296 /* The following tests succeed under Windows, but really should fail, 1297 * they contain characters that are illegal for the encoding. I'm 1298 * including them to justify my lazy encoding. 1299 */ 1300 { { CERT_RDN_IA5_STRING, { sizeof(bogusIA5), (BYTE *)bogusIA5 } }, bin42, 1301 sizeof(bin42) }, 1302 { { CERT_RDN_PRINTABLE_STRING, { sizeof(bogusPrintable), 1303 (BYTE *)bogusPrintable } }, bin43, sizeof(bin43) }, 1304 { { CERT_RDN_NUMERIC_STRING, { sizeof(bogusNumeric), (BYTE *)bogusNumeric } }, 1305 bin44, sizeof(bin44) }, 1306 }; 1307 /* This is kept separate, because the decoding doesn't return to the original 1308 * value. 1309 */ 1310 static struct EncodedNameValue embeddedNullNameValue = { 1311 { CERT_RDN_IA5_STRING, { sizeof(embedded_null) - 1, (BYTE *)embedded_null } }, 1312 ia5EmbeddedNull, sizeof(ia5EmbeddedNull) }; 1313 1314 static void test_encodeNameValue(DWORD dwEncoding) 1315 { 1316 BYTE *buf = NULL; 1317 DWORD size = 0, i; 1318 BOOL ret; 1319 CERT_NAME_VALUE value = { 0, { 0, NULL } }; 1320 1321 value.dwValueType = CERT_RDN_ENCODED_BLOB; 1322 value.Value.pbData = printableCommonNameValue; 1323 value.Value.cbData = sizeof(printableCommonNameValue); 1324 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, &value, 1325 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1326 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 1327 if (ret) 1328 { 1329 ok(size == sizeof(printableCommonNameValue), "Unexpected size %d\n", 1330 size); 1331 ok(!memcmp(buf, printableCommonNameValue, size), 1332 "Unexpected encoding\n"); 1333 LocalFree(buf); 1334 } 1335 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++) 1336 { 1337 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, 1338 &nameValues[i].value, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1339 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH) /* NT4/Win9x */, 1340 "Type %d: CryptEncodeObjectEx failed: %08x\n", 1341 nameValues[i].value.dwValueType, GetLastError()); 1342 if (ret) 1343 { 1344 ok(size == nameValues[i].encodedSize, 1345 "Expected size %d, got %d\n", nameValues[i].encodedSize, size); 1346 ok(!memcmp(buf, nameValues[i].encoded, size), 1347 "Got unexpected encoding\n"); 1348 LocalFree(buf); 1349 } 1350 } 1351 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, 1352 &embeddedNullNameValue.value, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1353 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH) /* NT4/Win9x */, 1354 "Type %d: CryptEncodeObjectEx failed: %08x\n", 1355 embeddedNullNameValue.value.dwValueType, GetLastError()); 1356 if (ret) 1357 { 1358 ok(size == embeddedNullNameValue.encodedSize, 1359 "Expected size %d, got %d\n", embeddedNullNameValue.encodedSize, size); 1360 ok(!memcmp(buf, embeddedNullNameValue.encoded, size), 1361 "Got unexpected encoding\n"); 1362 LocalFree(buf); 1363 } 1364 } 1365 1366 static void test_decodeNameValue(DWORD dwEncoding) 1367 { 1368 int i; 1369 BYTE *buf = NULL; 1370 DWORD bufSize = 0; 1371 BOOL ret; 1372 1373 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++) 1374 { 1375 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE, 1376 nameValues[i].encoded, nameValues[i].encoded[1] + 2, 1377 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL, 1378 &buf, &bufSize); 1379 ok(ret, "Value type %d: CryptDecodeObjectEx failed: %08x\n", 1380 nameValues[i].value.dwValueType, GetLastError()); 1381 if (ret) 1382 { 1383 compareNameValues(&nameValues[i].value, 1384 (const CERT_NAME_VALUE *)buf); 1385 LocalFree(buf); 1386 } 1387 } 1388 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE, 1389 embeddedNullNameValue.encoded, embeddedNullNameValue.encodedSize, 1390 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL, 1391 &buf, &bufSize); 1392 /* Some Windows versions disallow name values with embedded NULLs, so 1393 * either success or failure is acceptable. 1394 */ 1395 if (ret) 1396 { 1397 CERT_NAME_VALUE rdnEncodedValue = { CERT_RDN_ENCODED_BLOB, 1398 { sizeof(ia5EmbeddedNull), ia5EmbeddedNull } }; 1399 CERT_NAME_VALUE embeddedNullValue = { CERT_RDN_IA5_STRING, 1400 { sizeof(embedded_null) - 1, (BYTE *)embedded_null } }; 1401 const CERT_NAME_VALUE *got = (const CERT_NAME_VALUE *)buf, 1402 *expected = NULL; 1403 1404 /* Some Windows versions decode name values with embedded NULLs, 1405 * others leave them encoded, even with the same version of crypt32. 1406 * Accept either. 1407 */ 1408 ok(got->dwValueType == CERT_RDN_ENCODED_BLOB || 1409 got->dwValueType == CERT_RDN_IA5_STRING, 1410 "Expected CERT_RDN_ENCODED_BLOB or CERT_RDN_IA5_STRING, got %d\n", 1411 got->dwValueType); 1412 if (got->dwValueType == CERT_RDN_ENCODED_BLOB) 1413 expected = &rdnEncodedValue; 1414 else if (got->dwValueType == CERT_RDN_IA5_STRING) 1415 expected = &embeddedNullValue; 1416 if (expected) 1417 { 1418 ok(got->Value.cbData == expected->Value.cbData, 1419 "String type %d: unexpected data size, got %d, expected %d\n", 1420 got->dwValueType, got->Value.cbData, expected->Value.cbData); 1421 if (got->Value.cbData && got->Value.pbData) 1422 ok(!memcmp(got->Value.pbData, expected->Value.pbData, 1423 min(got->Value.cbData, expected->Value.cbData)), 1424 "String type %d: unexpected value\n", expected->dwValueType); 1425 } 1426 LocalFree(buf); 1427 } 1428 } 1429 1430 static const BYTE emptyURL[] = { 0x30, 0x02, 0x86, 0x00 }; 1431 static const BYTE emptyURLExtraBytes[] = { 0x30, 0x02, 0x86, 0x00, 0, 0, 0 }; 1432 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e', 1433 'h','q','.','o','r','g',0 }; 1434 static const BYTE encodedURL[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74, 1435 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 1436 0x6f, 0x72, 0x67 }; 1437 static const WCHAR nihongoURL[] = { 'h','t','t','p',':','/','/',0x226f, 1438 0x575b, 0 }; 1439 static const WCHAR dnsName[] = { 'w','i','n','e','h','q','.','o','r','g',0 }; 1440 static const BYTE encodedDnsName[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69, 1441 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 }; 1442 static const BYTE localhost[] = { 127, 0, 0, 1 }; 1443 static const BYTE encodedIPAddr[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00, 1444 0x01 }; 1445 static const unsigned char encodedCommonName[] = { 1446 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0}; 1447 static const BYTE encodedOidName[] = { 0x30,0x04,0x88,0x02,0x2a,0x03 }; 1448 static const BYTE encodedDirectoryName[] = { 1449 0x30,0x19,0xa4,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03, 1450 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 }; 1451 1452 static void test_encodeAltName(DWORD dwEncoding) 1453 { 1454 CERT_ALT_NAME_INFO info = { 0 }; 1455 CERT_ALT_NAME_ENTRY entry = { 0 }; 1456 BYTE *buf = NULL; 1457 DWORD size = 0; 1458 BOOL ret; 1459 char oid[] = "1.2.3"; 1460 1461 /* Test with empty info */ 1462 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, 1463 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1464 if (ret) 1465 { 1466 ok(size == sizeof(emptySequence), "Wrong size %d\n", size); 1467 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n"); 1468 LocalFree(buf); 1469 } 1470 /* Test with an empty entry */ 1471 info.cAltEntry = 1; 1472 info.rgAltEntry = &entry; 1473 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, 1474 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1475 ok(!ret && GetLastError() == E_INVALIDARG, 1476 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 1477 /* Test with an empty pointer */ 1478 entry.dwAltNameChoice = CERT_ALT_NAME_URL; 1479 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, 1480 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1481 if (ret) 1482 { 1483 ok(size == sizeof(emptyURL), "Wrong size %d\n", size); 1484 ok(!memcmp(buf, emptyURL, size), "Unexpected value\n"); 1485 LocalFree(buf); 1486 } 1487 /* Test with a real URL */ 1488 U(entry).pwszURL = (LPWSTR)url; 1489 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, 1490 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1491 if (ret) 1492 { 1493 ok(size == sizeof(encodedURL), "Wrong size %d\n", size); 1494 ok(!memcmp(buf, encodedURL, size), "Unexpected value\n"); 1495 LocalFree(buf); 1496 } 1497 /* Now with the URL containing an invalid IA5 char */ 1498 U(entry).pwszURL = (LPWSTR)nihongoURL; 1499 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, 1500 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1501 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING, 1502 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError()); 1503 /* The first invalid character is at index 7 */ 1504 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7, 1505 "Expected invalid char at index 7, got %d\n", 1506 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size)); 1507 /* Now with the URL missing a scheme */ 1508 U(entry).pwszURL = (LPWSTR)dnsName; 1509 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, 1510 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1511 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 1512 if (ret) 1513 { 1514 /* This succeeds, but it shouldn't, so don't worry about conforming */ 1515 LocalFree(buf); 1516 } 1517 /* Now with a DNS name */ 1518 entry.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME; 1519 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, 1520 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1521 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 1522 if (ret) 1523 { 1524 ok(size == sizeof(encodedDnsName), "Wrong size %d\n", size); 1525 ok(!memcmp(buf, encodedDnsName, size), "Unexpected value\n"); 1526 LocalFree(buf); 1527 } 1528 /* Test with an IP address */ 1529 entry.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS; 1530 U(entry).IPAddress.cbData = sizeof(localhost); 1531 U(entry).IPAddress.pbData = (LPBYTE)localhost; 1532 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, 1533 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1534 if (ret) 1535 { 1536 ok(size == sizeof(encodedIPAddr), "Wrong size %d\n", size); 1537 ok(!memcmp(buf, encodedIPAddr, size), "Unexpected value\n"); 1538 LocalFree(buf); 1539 } 1540 /* Test with OID */ 1541 entry.dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID; 1542 U(entry).pszRegisteredID = oid; 1543 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, 1544 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1545 if (ret) 1546 { 1547 ok(size == sizeof(encodedOidName), "Wrong size %d\n", size); 1548 ok(!memcmp(buf, encodedOidName, size), "Unexpected value\n"); 1549 LocalFree(buf); 1550 } 1551 /* Test with directory name */ 1552 entry.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME; 1553 U(entry).DirectoryName.cbData = sizeof(encodedCommonName); 1554 U(entry).DirectoryName.pbData = (LPBYTE)encodedCommonName; 1555 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, 1556 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1557 if (ret) 1558 { 1559 ok(size == sizeof(encodedDirectoryName), "Wrong size %d\n", size); 1560 ok(!memcmp(buf, encodedDirectoryName, size), "Unexpected value\n"); 1561 LocalFree(buf); 1562 } 1563 } 1564 1565 static void test_decodeAltName(DWORD dwEncoding) 1566 { 1567 static const BYTE unimplementedType[] = { 0x30, 0x06, 0x85, 0x04, 0x7f, 1568 0x00, 0x00, 0x01 }; 1569 static const BYTE bogusType[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00, 1570 0x01 }; 1571 static const BYTE dns_embedded_null[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f, 1572 0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 }; 1573 static const BYTE dns_embedded_bell[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f, 1574 0x6f,0x2e,0x63,0x6f,0x6d,0x07,0x62,0x61,0x64,0x64,0x69,0x65 }; 1575 static const BYTE url_embedded_null[] = { 0x30,0x10,0x86,0x0e,0x66,0x6f, 1576 0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 }; 1577 BOOL ret; 1578 BYTE *buf = NULL; 1579 DWORD bufSize = 0; 1580 CERT_ALT_NAME_INFO *info; 1581 1582 /* Test some bogus ones first */ 1583 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, 1584 unimplementedType, sizeof(unimplementedType), CRYPT_DECODE_ALLOC_FLAG, 1585 NULL, &buf, &bufSize); 1586 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || 1587 GetLastError() == OSS_DATA_ERROR /* Win9x */), 1588 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n", 1589 GetLastError()); 1590 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, 1591 bogusType, sizeof(bogusType), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, 1592 &bufSize); 1593 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT || 1594 GetLastError() == OSS_DATA_ERROR /* Win9x */), 1595 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n", 1596 GetLastError()); 1597 /* Now expected cases */ 1598 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptySequence, 1599 emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 1600 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1601 if (ret) 1602 { 1603 info = (CERT_ALT_NAME_INFO *)buf; 1604 1605 ok(info->cAltEntry == 0, "Expected 0 entries, got %d\n", 1606 info->cAltEntry); 1607 LocalFree(buf); 1608 } 1609 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptyURL, 1610 emptyURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 1611 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1612 if (ret) 1613 { 1614 info = (CERT_ALT_NAME_INFO *)buf; 1615 1616 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n", 1617 info->cAltEntry); 1618 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL, 1619 "Expected CERT_ALT_NAME_URL, got %d\n", 1620 info->rgAltEntry[0].dwAltNameChoice); 1621 ok(U(info->rgAltEntry[0]).pwszURL == NULL || !*U(info->rgAltEntry[0]).pwszURL, 1622 "Expected empty URL\n"); 1623 LocalFree(buf); 1624 } 1625 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, 1626 emptyURLExtraBytes, sizeof(emptyURLExtraBytes), 0, NULL, NULL, &bufSize); 1627 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1628 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedURL, 1629 encodedURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 1630 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1631 if (ret) 1632 { 1633 info = (CERT_ALT_NAME_INFO *)buf; 1634 1635 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n", 1636 info->cAltEntry); 1637 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL, 1638 "Expected CERT_ALT_NAME_URL, got %d\n", 1639 info->rgAltEntry[0].dwAltNameChoice); 1640 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszURL, url), "Unexpected URL\n"); 1641 LocalFree(buf); 1642 } 1643 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedDnsName, 1644 encodedDnsName[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 1645 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1646 if (ret) 1647 { 1648 info = (CERT_ALT_NAME_INFO *)buf; 1649 1650 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n", 1651 info->cAltEntry); 1652 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME, 1653 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n", 1654 info->rgAltEntry[0].dwAltNameChoice); 1655 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszDNSName, dnsName), 1656 "Unexpected DNS name\n"); 1657 LocalFree(buf); 1658 } 1659 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedIPAddr, 1660 encodedIPAddr[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 1661 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1662 if (ret) 1663 { 1664 info = (CERT_ALT_NAME_INFO *)buf; 1665 1666 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n", 1667 info->cAltEntry); 1668 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS, 1669 "Expected CERT_ALT_NAME_IP_ADDRESS, got %d\n", 1670 info->rgAltEntry[0].dwAltNameChoice); 1671 ok(U(info->rgAltEntry[0]).IPAddress.cbData == sizeof(localhost), 1672 "Unexpected IP address length %d\n", 1673 U(info->rgAltEntry[0]).IPAddress.cbData); 1674 ok(!memcmp(U(info->rgAltEntry[0]).IPAddress.pbData, localhost, 1675 sizeof(localhost)), "Unexpected IP address value\n"); 1676 LocalFree(buf); 1677 } 1678 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedOidName, 1679 sizeof(encodedOidName), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 1680 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1681 if (ret) 1682 { 1683 info = (CERT_ALT_NAME_INFO *)buf; 1684 1685 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n", 1686 info->cAltEntry); 1687 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_REGISTERED_ID, 1688 "Expected CERT_ALT_NAME_REGISTERED_ID, got %d\n", 1689 info->rgAltEntry[0].dwAltNameChoice); 1690 ok(!strcmp(U(info->rgAltEntry[0]).pszRegisteredID, "1.2.3"), 1691 "Expected OID 1.2.3, got %s\n", U(info->rgAltEntry[0]).pszRegisteredID); 1692 LocalFree(buf); 1693 } 1694 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, 1695 encodedDirectoryName, sizeof(encodedDirectoryName), 1696 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 1697 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1698 if (ret) 1699 { 1700 info = (CERT_ALT_NAME_INFO *)buf; 1701 1702 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n", 1703 info->cAltEntry); 1704 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME, 1705 "Expected CERT_ALT_NAME_DIRECTORY_NAME, got %d\n", 1706 info->rgAltEntry[0].dwAltNameChoice); 1707 ok(U(info->rgAltEntry[0]).DirectoryName.cbData == 1708 sizeof(encodedCommonName), "Unexpected directory name length %d\n", 1709 U(info->rgAltEntry[0]).DirectoryName.cbData); 1710 ok(!memcmp(U(info->rgAltEntry[0]).DirectoryName.pbData, 1711 encodedCommonName, sizeof(encodedCommonName)), 1712 "Unexpected directory name value\n"); 1713 LocalFree(buf); 1714 } 1715 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, 1716 dns_embedded_null, sizeof(dns_embedded_null), CRYPT_DECODE_ALLOC_FLAG, 1717 NULL, &buf, &bufSize); 1718 /* Fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned about the 1719 * particular failure, just that it doesn't decode. 1720 * It succeeds on (broken) Windows versions that haven't addressed 1721 * embedded NULLs in alternate names. 1722 */ 1723 ok(!ret || broken(ret), "expected failure\n"); 1724 /* An embedded bell character is allowed, however. */ 1725 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, 1726 dns_embedded_bell, sizeof(dns_embedded_bell), CRYPT_DECODE_ALLOC_FLAG, 1727 NULL, &buf, &bufSize); 1728 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1729 if (ret) 1730 { 1731 info = (CERT_ALT_NAME_INFO *)buf; 1732 1733 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n", 1734 info->cAltEntry); 1735 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME, 1736 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n", 1737 info->rgAltEntry[0].dwAltNameChoice); 1738 LocalFree(buf); 1739 } 1740 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, 1741 url_embedded_null, sizeof(dns_embedded_null), CRYPT_DECODE_ALLOC_FLAG, 1742 NULL, &buf, &bufSize); 1743 /* Again, fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned 1744 * about the particular failure, just that it doesn't decode. 1745 * It succeeds on (broken) Windows versions that haven't addressed 1746 * embedded NULLs in alternate names. 1747 */ 1748 ok(!ret || broken(ret), "expected failure\n"); 1749 } 1750 1751 struct UnicodeExpectedError 1752 { 1753 DWORD valueType; 1754 LPCWSTR str; 1755 DWORD errorIndex; 1756 DWORD error; 1757 }; 1758 1759 static const WCHAR oneW[] = { '1',0 }; 1760 static const WCHAR aW[] = { 'a',0 }; 1761 static const WCHAR quoteW[] = { '"', 0 }; 1762 1763 static struct UnicodeExpectedError unicodeErrors[] = { 1764 { CERT_RDN_ANY_TYPE, oneW, 0, CRYPT_E_NOT_CHAR_STRING }, 1765 { CERT_RDN_ENCODED_BLOB, oneW, 0, CRYPT_E_NOT_CHAR_STRING }, 1766 { CERT_RDN_OCTET_STRING, oneW, 0, CRYPT_E_NOT_CHAR_STRING }, 1767 { CERT_RDN_NUMERIC_STRING, aW, 0, CRYPT_E_INVALID_NUMERIC_STRING }, 1768 { CERT_RDN_PRINTABLE_STRING, quoteW, 0, CRYPT_E_INVALID_PRINTABLE_STRING }, 1769 { CERT_RDN_IA5_STRING, nihongoURL, 7, CRYPT_E_INVALID_IA5_STRING }, 1770 }; 1771 1772 struct UnicodeExpectedResult 1773 { 1774 DWORD valueType; 1775 LPCWSTR str; 1776 CRYPT_DATA_BLOB encoded; 1777 }; 1778 1779 static BYTE oneNumeric[] = { 0x12, 0x01, 0x31 }; 1780 static BYTE onePrintable[] = { 0x13, 0x01, 0x31 }; 1781 static BYTE oneTeletex[] = { 0x14, 0x01, 0x31 }; 1782 static BYTE oneVideotex[] = { 0x15, 0x01, 0x31 }; 1783 static BYTE oneIA5[] = { 0x16, 0x01, 0x31 }; 1784 static BYTE oneGraphic[] = { 0x19, 0x01, 0x31 }; 1785 static BYTE oneVisible[] = { 0x1a, 0x01, 0x31 }; 1786 static BYTE oneUniversal[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 }; 1787 static BYTE oneGeneral[] = { 0x1b, 0x01, 0x31 }; 1788 static BYTE oneBMP[] = { 0x1e, 0x02, 0x00, 0x31 }; 1789 static BYTE oneUTF8[] = { 0x0c, 0x01, 0x31 }; 1790 static BYTE nihongoT61[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f, 1791 0x5b }; 1792 static BYTE nihongoGeneral[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, 1793 0x6f,0x5b }; 1794 static BYTE nihongoBMP[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70, 1795 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b }; 1796 static BYTE nihongoUTF8[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, 1797 0xe2,0x89,0xaf,0xe5,0x9d,0x9b }; 1798 1799 static struct UnicodeExpectedResult unicodeResults[] = { 1800 { CERT_RDN_NUMERIC_STRING, oneW, { sizeof(oneNumeric), oneNumeric } }, 1801 { CERT_RDN_PRINTABLE_STRING, oneW, { sizeof(onePrintable), onePrintable } }, 1802 { CERT_RDN_TELETEX_STRING, oneW, { sizeof(oneTeletex), oneTeletex } }, 1803 { CERT_RDN_VIDEOTEX_STRING, oneW, { sizeof(oneVideotex), oneVideotex } }, 1804 { CERT_RDN_IA5_STRING, oneW, { sizeof(oneIA5), oneIA5 } }, 1805 { CERT_RDN_GRAPHIC_STRING, oneW, { sizeof(oneGraphic), oneGraphic } }, 1806 { CERT_RDN_VISIBLE_STRING, oneW, { sizeof(oneVisible), oneVisible } }, 1807 { CERT_RDN_UNIVERSAL_STRING, oneW, { sizeof(oneUniversal), oneUniversal } }, 1808 { CERT_RDN_GENERAL_STRING, oneW, { sizeof(oneGeneral), oneGeneral } }, 1809 { CERT_RDN_BMP_STRING, oneW, { sizeof(oneBMP), oneBMP } }, 1810 { CERT_RDN_UTF8_STRING, oneW, { sizeof(oneUTF8), oneUTF8 } }, 1811 { CERT_RDN_BMP_STRING, nihongoURL, { sizeof(nihongoBMP), nihongoBMP } }, 1812 { CERT_RDN_UTF8_STRING, nihongoURL, { sizeof(nihongoUTF8), nihongoUTF8 } }, 1813 }; 1814 1815 static struct UnicodeExpectedResult unicodeWeirdness[] = { 1816 { CERT_RDN_TELETEX_STRING, nihongoURL, { sizeof(nihongoT61), nihongoT61 } }, 1817 { CERT_RDN_GENERAL_STRING, nihongoURL, { sizeof(nihongoGeneral), nihongoGeneral } }, 1818 }; 1819 1820 static void test_encodeUnicodeNameValue(DWORD dwEncoding) 1821 { 1822 BYTE *buf = NULL; 1823 DWORD size = 0, i; 1824 BOOL ret; 1825 CERT_NAME_VALUE value; 1826 1827 if (0) 1828 { 1829 /* Crashes on win9x */ 1830 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, NULL, 1831 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1832 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 1833 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError()); 1834 } 1835 /* Have to have a string of some sort */ 1836 value.dwValueType = 0; /* aka CERT_RDN_ANY_TYPE */ 1837 value.Value.pbData = NULL; 1838 value.Value.cbData = 0; 1839 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value, 1840 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1841 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING, 1842 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError()); 1843 value.dwValueType = CERT_RDN_ENCODED_BLOB; 1844 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value, 1845 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1846 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING, 1847 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError()); 1848 value.dwValueType = CERT_RDN_ANY_TYPE; 1849 value.Value.pbData = (LPBYTE)oneW; 1850 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value, 1851 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1852 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING, 1853 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError()); 1854 value.Value.cbData = sizeof(oneW); 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 /* An encoded string with specified length isn't good enough either */ 1860 value.dwValueType = CERT_RDN_ENCODED_BLOB; 1861 value.Value.pbData = oneUniversal; 1862 value.Value.cbData = sizeof(oneUniversal); 1863 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value, 1864 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1865 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING, 1866 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError()); 1867 /* More failure checking */ 1868 value.Value.cbData = 0; 1869 for (i = 0; i < sizeof(unicodeErrors) / sizeof(unicodeErrors[0]); i++) 1870 { 1871 value.Value.pbData = (LPBYTE)unicodeErrors[i].str; 1872 value.dwValueType = unicodeErrors[i].valueType; 1873 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value, 1874 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1875 ok(!ret && GetLastError() == unicodeErrors[i].error, 1876 "Value type %d: expected %08x, got %08x\n", value.dwValueType, 1877 unicodeErrors[i].error, GetLastError()); 1878 ok(size == unicodeErrors[i].errorIndex, 1879 "Expected error index %d, got %d\n", unicodeErrors[i].errorIndex, 1880 size); 1881 } 1882 /* cbData can be zero if the string is NULL-terminated */ 1883 value.Value.cbData = 0; 1884 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++) 1885 { 1886 value.Value.pbData = (LPBYTE)unicodeResults[i].str; 1887 value.dwValueType = unicodeResults[i].valueType; 1888 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value, 1889 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1890 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH /* Win9x */), 1891 "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 1892 if (ret) 1893 { 1894 ok(size == unicodeResults[i].encoded.cbData, 1895 "Value type %d: expected size %d, got %d\n", 1896 value.dwValueType, unicodeResults[i].encoded.cbData, size); 1897 ok(!memcmp(unicodeResults[i].encoded.pbData, buf, size), 1898 "Value type %d: unexpected value\n", value.dwValueType); 1899 LocalFree(buf); 1900 } 1901 } 1902 /* These "encode," but they do so by truncating each unicode character 1903 * rather than properly encoding it. Kept separate from the proper results, 1904 * because the encoded forms won't decode to their original strings. 1905 */ 1906 for (i = 0; i < sizeof(unicodeWeirdness) / sizeof(unicodeWeirdness[0]); i++) 1907 { 1908 value.Value.pbData = (LPBYTE)unicodeWeirdness[i].str; 1909 value.dwValueType = unicodeWeirdness[i].valueType; 1910 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value, 1911 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 1912 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 1913 if (ret) 1914 { 1915 ok(size == unicodeWeirdness[i].encoded.cbData, 1916 "Value type %d: expected size %d, got %d\n", 1917 value.dwValueType, unicodeWeirdness[i].encoded.cbData, size); 1918 ok(!memcmp(unicodeWeirdness[i].encoded.pbData, buf, size), 1919 "Value type %d: unexpected value\n", value.dwValueType); 1920 LocalFree(buf); 1921 } 1922 } 1923 } 1924 1925 static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n ) 1926 { 1927 if (n <= 0) return 0; 1928 while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; } 1929 return *str1 - *str2; 1930 } 1931 1932 static void test_decodeUnicodeNameValue(DWORD dwEncoding) 1933 { 1934 DWORD i; 1935 1936 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++) 1937 { 1938 BYTE *buf = NULL; 1939 BOOL ret; 1940 DWORD size = 0; 1941 1942 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, 1943 unicodeResults[i].encoded.pbData, unicodeResults[i].encoded.cbData, 1944 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 1945 ok(ret || broken(GetLastError() == CRYPT_E_NOT_CHAR_STRING /* Win9x */), 1946 "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 1947 if (ret && buf) 1948 { 1949 PCERT_NAME_VALUE value = (PCERT_NAME_VALUE)buf; 1950 1951 ok(value->dwValueType == unicodeResults[i].valueType, 1952 "Expected value type %d, got %d\n", unicodeResults[i].valueType, 1953 value->dwValueType); 1954 ok(!strncmpW((LPWSTR)value->Value.pbData, unicodeResults[i].str, 1955 value->Value.cbData / sizeof(WCHAR)), 1956 "Unexpected decoded value for index %d (value type %d)\n", i, 1957 unicodeResults[i].valueType); 1958 LocalFree(buf); 1959 } 1960 } 1961 } 1962 1963 static const unsigned char decoded_hi_octet[] = { 'h','i' }; 1964 static const unsigned char encoded_hi_octet[] = { ASN_OCTETSTRING,2,'h','i' }; 1965 static const unsigned char decoded_something_long_octet[] = { 1966 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g' }; 1967 static const unsigned char encoded_something_long_octet[] = { 1968 ASN_OCTETSTRING,15,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g' }; 1969 static const unsigned char encoded_empty_octet[] = { ASN_OCTETSTRING,0 }; 1970 1971 static void test_encodeOctets(DWORD dwEncoding) 1972 { 1973 CRYPT_DATA_BLOB blob; 1974 DWORD i; 1975 1976 static const struct { 1977 const BYTE *decoded; 1978 UINT decoded_size; 1979 const BYTE *encoded; 1980 UINT encoded_size; 1981 } tests[] = { 1982 { 1983 decoded_hi_octet, sizeof(decoded_hi_octet), 1984 encoded_hi_octet, sizeof(encoded_hi_octet) 1985 },{ 1986 decoded_something_long_octet, sizeof(decoded_something_long_octet), 1987 encoded_something_long_octet, sizeof(encoded_something_long_octet) 1988 },{ 1989 encoded_empty_octet, 0, 1990 encoded_empty_octet, sizeof(encoded_empty_octet) 1991 } 1992 }; 1993 1994 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) 1995 { 1996 BYTE *buf = NULL; 1997 BOOL ret; 1998 DWORD bufSize = 0; 1999 2000 blob.cbData = tests[i].decoded_size; 2001 blob.pbData = (BYTE*)tests[i].decoded; 2002 ret = pCryptEncodeObjectEx(dwEncoding, X509_OCTET_STRING, &blob, 2003 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2004 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError()); 2005 if (ret) 2006 { 2007 ok(bufSize == tests[i].encoded_size, "[%u] buf size %u expected %u\n", 2008 i, bufSize, tests[i].encoded_size); 2009 ok(buf[0] == 4, "Got unexpected type %d for octet string (expected 4)\n", buf[0]); 2010 ok(buf[1] == tests[i].decoded_size, "[%u] Got length %d, expected %d\n", 2011 i, buf[1], tests[i].decoded_size); 2012 ok(!memcmp(buf, tests[i].encoded, tests[i].encoded_size), "[%u] Got unexpected value\n", i); 2013 LocalFree(buf); 2014 } 2015 } 2016 } 2017 2018 static const unsigned char encoded_constructed_hi_octet[] = 2019 { ASN_CONSTRUCTOR|ASN_OCTETSTRING,0x80, ASN_OCTETSTRING,2,'h','i', 0,0 }; 2020 static const unsigned char encoded_constructed_hi_octet2[] = 2021 { ASN_CONSTRUCTOR|ASN_OCTETSTRING,4, ASN_OCTETSTRING,2,'h','i', 1,2,3 }; 2022 static const unsigned char encoded_constructed_hi_octet3[] = 2023 { ASN_CONSTRUCTOR|ASN_OCTETSTRING,8, ASN_CONSTRUCTOR|ASN_OCTETSTRING,0x80, ASN_OCTETSTRING,2,'h','i', 0,0, 0,0 }; 2024 static const unsigned char encoded_constructed_hi_octet_invalid_end[] = 2025 { ASN_CONSTRUCTOR|ASN_OCTETSTRING,0x80, ASN_OCTETSTRING,2,'h','i', 0,1 }; 2026 2027 static void test_decodeOctets(DWORD dwEncoding) 2028 { 2029 DWORD i; 2030 2031 static const struct { 2032 const BYTE *encoded; 2033 UINT encoded_size; 2034 const BYTE *decoded; 2035 UINT decoded_size; 2036 DWORD error; 2037 } tests[] = { 2038 { 2039 encoded_hi_octet, sizeof(encoded_hi_octet), 2040 decoded_hi_octet, sizeof(decoded_hi_octet) 2041 },{ 2042 encoded_something_long_octet, sizeof(encoded_something_long_octet), 2043 decoded_something_long_octet, sizeof(decoded_something_long_octet) 2044 },{ 2045 encoded_constructed_hi_octet, sizeof(encoded_constructed_hi_octet), 2046 decoded_hi_octet, sizeof(decoded_hi_octet) 2047 },{ 2048 encoded_constructed_hi_octet2, sizeof(encoded_constructed_hi_octet2), 2049 decoded_hi_octet, sizeof(decoded_hi_octet) 2050 },{ 2051 encoded_constructed_hi_octet3, sizeof(encoded_constructed_hi_octet3), 2052 decoded_hi_octet, sizeof(decoded_hi_octet) 2053 },{ 2054 encoded_empty_octet, sizeof(encoded_empty_octet), 2055 encoded_empty_octet, 0 2056 },{ 2057 encoded_hi_octet, sizeof(encoded_hi_octet) - 1, 2058 NULL, 0, CRYPT_E_ASN1_EOD 2059 },{ 2060 encoded_constructed_hi_octet, sizeof(encoded_constructed_hi_octet) - 1, 2061 NULL, 0, CRYPT_E_ASN1_EOD 2062 },{ 2063 encoded_constructed_hi_octet_invalid_end, sizeof(encoded_constructed_hi_octet_invalid_end), 2064 NULL, 0, CRYPT_E_ASN1_CORRUPT 2065 } 2066 }; 2067 2068 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) 2069 { 2070 BYTE *buf = NULL; 2071 BOOL ret; 2072 DWORD bufSize = 0; 2073 2074 ret = pCryptDecodeObjectEx(dwEncoding, X509_OCTET_STRING, 2075 tests[i].encoded, tests[i].encoded_size, 2076 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2077 if (tests[i].error) 2078 { 2079 ok(!ret && GetLastError() == tests[i].error, 2080 "[%u] CryptDecodeObjectEx returned %x(%x)\n", i, ret, GetLastError()); 2081 continue; 2082 } 2083 ok(ret, "[%u] CryptDecodeObjectEx failed: %08x\n", i, GetLastError()); 2084 ok(bufSize >= sizeof(CRYPT_DATA_BLOB) + tests[i].decoded_size, 2085 "[%u] Expected size >= %d, got %d\n", i, 2086 (int)sizeof(CRYPT_DATA_BLOB) + tests[i].decoded_size, bufSize); 2087 ok(buf != NULL, "Expected allocated buffer\n"); 2088 if (ret) 2089 { 2090 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)buf; 2091 2092 ok (blob->cbData == tests[i].decoded_size, "[%u] cbData = %u\n", i, blob->cbData); 2093 if (blob->cbData) 2094 ok(!memcmp(blob->pbData, tests[i].decoded, blob->cbData), 2095 "Unexpected value\n"); 2096 LocalFree(buf); 2097 } 2098 } 2099 } 2100 2101 static const BYTE bytesToEncode[] = { 0xff, 0xff }; 2102 2103 struct encodedBits 2104 { 2105 DWORD cUnusedBits; 2106 const BYTE *encoded; 2107 DWORD cbDecoded; 2108 const BYTE *decoded; 2109 }; 2110 2111 static const unsigned char bin52[] = { 0x03,0x03,0x00,0xff,0xff }; 2112 static const unsigned char bin53[] = { 0xff,0xff }; 2113 static const unsigned char bin54[] = { 0x03,0x03,0x01,0xff,0xfe }; 2114 static const unsigned char bin55[] = { 0xff,0xfe }; 2115 static const unsigned char bin56[] = { 0x03,0x02,0x01,0xfe }; 2116 static const unsigned char bin57[] = { 0xfe }; 2117 2118 static const struct encodedBits bits[] = { 2119 /* normal test cases */ 2120 { 0, bin52, 2, bin53 }, 2121 { 1, bin54, 2, bin55 }, 2122 /* strange test case, showing cUnusedBits >= 8 is allowed */ 2123 { 9, bin56, 1, bin57 }, 2124 }; 2125 2126 static void test_encodeBits(DWORD dwEncoding) 2127 { 2128 DWORD i; 2129 2130 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++) 2131 { 2132 CRYPT_BIT_BLOB blob; 2133 BOOL ret; 2134 BYTE *buf = NULL; 2135 DWORD bufSize = 0; 2136 2137 blob.cbData = sizeof(bytesToEncode); 2138 blob.pbData = (BYTE *)bytesToEncode; 2139 blob.cUnusedBits = bits[i].cUnusedBits; 2140 ret = pCryptEncodeObjectEx(dwEncoding, X509_BITS, &blob, 2141 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2142 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 2143 if (ret) 2144 { 2145 ok(bufSize == bits[i].encoded[1] + 2, 2146 "%d: Got unexpected size %d, expected %d\n", i, bufSize, 2147 bits[i].encoded[1] + 2); 2148 ok(!memcmp(buf, bits[i].encoded, bits[i].encoded[1] + 2), 2149 "%d: Unexpected value\n", i); 2150 LocalFree(buf); 2151 } 2152 } 2153 } 2154 2155 static void test_decodeBits(DWORD dwEncoding) 2156 { 2157 static const BYTE ber[] = "\x03\x02\x01\xff"; 2158 static const BYTE berDecoded = 0xfe; 2159 DWORD i; 2160 BOOL ret; 2161 BYTE *buf = NULL; 2162 DWORD bufSize = 0; 2163 2164 /* normal cases */ 2165 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++) 2166 { 2167 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, bits[i].encoded, 2168 bits[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, 2169 &bufSize); 2170 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 2171 if (ret) 2172 { 2173 CRYPT_BIT_BLOB *blob; 2174 2175 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + bits[i].cbDecoded, 2176 "Got unexpected size %d\n", bufSize); 2177 blob = (CRYPT_BIT_BLOB *)buf; 2178 ok(blob->cbData == bits[i].cbDecoded, 2179 "Got unexpected length %d, expected %d\n", blob->cbData, 2180 bits[i].cbDecoded); 2181 if (blob->cbData && bits[i].cbDecoded) 2182 ok(!memcmp(blob->pbData, bits[i].decoded, bits[i].cbDecoded), 2183 "Unexpected value\n"); 2184 LocalFree(buf); 2185 } 2186 } 2187 /* special case: check that something that's valid in BER but not in DER 2188 * decodes successfully 2189 */ 2190 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, ber, ber[1] + 2, 2191 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2192 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 2193 if (ret) 2194 { 2195 CRYPT_BIT_BLOB *blob; 2196 2197 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + sizeof(berDecoded), 2198 "Got unexpected size %d\n", bufSize); 2199 blob = (CRYPT_BIT_BLOB *)buf; 2200 ok(blob->cbData == sizeof(berDecoded), 2201 "Got unexpected length %d\n", blob->cbData); 2202 if (blob->cbData) 2203 ok(*blob->pbData == berDecoded, "Unexpected value\n"); 2204 LocalFree(buf); 2205 } 2206 } 2207 2208 struct Constraints2 2209 { 2210 CERT_BASIC_CONSTRAINTS2_INFO info; 2211 const BYTE *encoded; 2212 }; 2213 2214 static const unsigned char bin59[] = { 0x30,0x00 }; 2215 static const unsigned char bin60[] = { 0x30,0x03,0x01,0x01,0xff }; 2216 static const unsigned char bin61[] = { 0x30,0x03,0x02,0x01,0x00 }; 2217 static const unsigned char bin62[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 }; 2218 static const struct Constraints2 constraints2[] = { 2219 /* empty constraints */ 2220 { { FALSE, FALSE, 0}, bin59 }, 2221 /* can be a CA */ 2222 { { TRUE, FALSE, 0}, bin60 }, 2223 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well, 2224 * but that's not the case 2225 */ 2226 { { FALSE, TRUE, 0}, bin61 }, 2227 /* can be a CA and has path length constraints set */ 2228 { { TRUE, TRUE, 1}, bin62 }, 2229 }; 2230 2231 static const BYTE emptyConstraint[] = { 0x30, 0x03, 0x03, 0x01, 0x00 }; 2232 static const BYTE encodedDomainName[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 2233 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 2234 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 2235 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 }; 2236 static const BYTE constraintWithDomainName[] = { 0x30, 0x32, 0x03, 0x01, 0x00, 2237 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26, 2238 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30, 2239 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 2240 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 }; 2241 2242 static void test_encodeBasicConstraints(DWORD dwEncoding) 2243 { 2244 DWORD i, bufSize = 0; 2245 CERT_BASIC_CONSTRAINTS_INFO info = { { 0 } }; 2246 CERT_NAME_BLOB nameBlob = { sizeof(encodedDomainName), 2247 (LPBYTE)encodedDomainName }; 2248 BOOL ret; 2249 BYTE *buf = NULL; 2250 2251 /* First test with the simpler info2 */ 2252 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++) 2253 { 2254 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2, 2255 &constraints2[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, 2256 &bufSize); 2257 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 2258 if (ret) 2259 { 2260 ok(bufSize == constraints2[i].encoded[1] + 2, 2261 "Expected %d bytes, got %d\n", constraints2[i].encoded[1] + 2, 2262 bufSize); 2263 ok(!memcmp(buf, constraints2[i].encoded, 2264 constraints2[i].encoded[1] + 2), "Unexpected value\n"); 2265 LocalFree(buf); 2266 } 2267 } 2268 /* Now test with more complex basic constraints */ 2269 info.SubjectType.cbData = 0; 2270 info.fPathLenConstraint = FALSE; 2271 info.cSubtreesConstraint = 0; 2272 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info, 2273 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2274 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */, 2275 "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 2276 if (ret) 2277 { 2278 ok(bufSize == sizeof(emptyConstraint), "Wrong size %d\n", bufSize); 2279 ok(!memcmp(buf, emptyConstraint, sizeof(emptyConstraint)), 2280 "Unexpected value\n"); 2281 LocalFree(buf); 2282 } 2283 /* None of the certs I examined had any subtree constraint, but I test one 2284 * anyway just in case. 2285 */ 2286 info.cSubtreesConstraint = 1; 2287 info.rgSubtreesConstraint = &nameBlob; 2288 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info, 2289 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2290 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */, 2291 "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 2292 if (ret) 2293 { 2294 ok(bufSize == sizeof(constraintWithDomainName), "Wrong size %d\n", bufSize); 2295 ok(!memcmp(buf, constraintWithDomainName, 2296 sizeof(constraintWithDomainName)), "Unexpected value\n"); 2297 LocalFree(buf); 2298 } 2299 /* FIXME: test encoding with subject type. */ 2300 } 2301 2302 static const unsigned char bin63[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 }; 2303 2304 static void test_decodeBasicConstraints(DWORD dwEncoding) 2305 { 2306 static const BYTE inverted[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01, 2307 0xff }; 2308 static const struct Constraints2 badBool = { { TRUE, TRUE, 1 }, bin63 }; 2309 DWORD i; 2310 BOOL ret; 2311 BYTE *buf = NULL; 2312 DWORD bufSize = 0; 2313 2314 /* First test with simpler info2 */ 2315 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++) 2316 { 2317 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2, 2318 constraints2[i].encoded, constraints2[i].encoded[1] + 2, 2319 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2320 ok(ret, "CryptDecodeObjectEx failed for item %d: %08x\n", i, 2321 GetLastError()); 2322 if (ret) 2323 { 2324 CERT_BASIC_CONSTRAINTS2_INFO *info = 2325 (CERT_BASIC_CONSTRAINTS2_INFO *)buf; 2326 2327 ok(!memcmp(info, &constraints2[i].info, sizeof(*info)), 2328 "Unexpected value for item %d\n", i); 2329 LocalFree(buf); 2330 } 2331 } 2332 /* Check with the order of encoded elements inverted */ 2333 buf = (PBYTE)1; 2334 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2, 2335 inverted, inverted[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, 2336 &bufSize); 2337 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT || 2338 GetLastError() == OSS_DATA_ERROR /* Win9x */), 2339 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n", 2340 GetLastError()); 2341 ok(!buf, "Expected buf to be set to NULL\n"); 2342 /* Check with a non-DER bool */ 2343 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2, 2344 badBool.encoded, badBool.encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, 2345 &buf, &bufSize); 2346 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 2347 if (ret) 2348 { 2349 CERT_BASIC_CONSTRAINTS2_INFO *info = 2350 (CERT_BASIC_CONSTRAINTS2_INFO *)buf; 2351 2352 ok(!memcmp(info, &badBool.info, sizeof(*info)), "Unexpected value\n"); 2353 LocalFree(buf); 2354 } 2355 /* Check with a non-basic constraints value */ 2356 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2, 2357 encodedCommonName, encodedCommonName[1] + 2, 2358 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2359 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT || 2360 GetLastError() == OSS_DATA_ERROR /* Win9x */), 2361 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n", 2362 GetLastError()); 2363 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */ 2364 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, 2365 emptyConstraint, sizeof(emptyConstraint), CRYPT_DECODE_ALLOC_FLAG, NULL, 2366 &buf, &bufSize); 2367 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 2368 if (ret) 2369 { 2370 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf; 2371 2372 ok(info->SubjectType.cbData == 0, "Expected no subject type\n"); 2373 ok(!info->fPathLenConstraint, "Expected no path length constraint\n"); 2374 ok(info->cSubtreesConstraint == 0, "Expected no subtree constraints\n"); 2375 LocalFree(buf); 2376 } 2377 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, 2378 constraintWithDomainName, sizeof(constraintWithDomainName), 2379 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2380 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 2381 if (ret) 2382 { 2383 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf; 2384 2385 ok(info->SubjectType.cbData == 0, "Expected no subject type\n"); 2386 ok(!info->fPathLenConstraint, "Expected no path length constraint\n"); 2387 ok(info->cSubtreesConstraint == 1, "Expected a subtree constraint\n"); 2388 if (info->cSubtreesConstraint && info->rgSubtreesConstraint) 2389 { 2390 ok(info->rgSubtreesConstraint[0].cbData == 2391 sizeof(encodedDomainName), "Wrong size %d\n", 2392 info->rgSubtreesConstraint[0].cbData); 2393 ok(!memcmp(info->rgSubtreesConstraint[0].pbData, encodedDomainName, 2394 sizeof(encodedDomainName)), "Unexpected value\n"); 2395 } 2396 LocalFree(buf); 2397 } 2398 } 2399 2400 /* These are terrible public keys of course, I'm just testing encoding */ 2401 static const BYTE modulus1[] = { 0,0,0,1,1,1,1,1 }; 2402 static const BYTE modulus2[] = { 1,1,1,1,1,0,0,0 }; 2403 static const BYTE modulus3[] = { 0x80,1,1,1,1,0,0,0 }; 2404 static const BYTE modulus4[] = { 1,1,1,1,1,0,0,0x80 }; 2405 static const BYTE mod1_encoded[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 }; 2406 static const BYTE mod2_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 }; 2407 static const BYTE mod3_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 }; 2408 static const BYTE mod4_encoded[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 }; 2409 2410 struct EncodedRSAPubKey 2411 { 2412 const BYTE *modulus; 2413 size_t modulusLen; 2414 const BYTE *encoded; 2415 size_t decodedModulusLen; 2416 }; 2417 2418 static const struct EncodedRSAPubKey rsaPubKeys[] = { 2419 { modulus1, sizeof(modulus1), mod1_encoded, sizeof(modulus1) }, 2420 { modulus2, sizeof(modulus2), mod2_encoded, 5 }, 2421 { modulus3, sizeof(modulus3), mod3_encoded, 5 }, 2422 { modulus4, sizeof(modulus4), mod4_encoded, 8 }, 2423 }; 2424 2425 static void test_encodeRsaPublicKey(DWORD dwEncoding) 2426 { 2427 BYTE toEncode[sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + sizeof(modulus1)]; 2428 BLOBHEADER *hdr = (BLOBHEADER *)toEncode; 2429 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(toEncode + sizeof(BLOBHEADER)); 2430 BOOL ret; 2431 BYTE *buf = NULL; 2432 DWORD bufSize = 0, i; 2433 2434 /* Try with a bogus blob type */ 2435 hdr->bType = 2; 2436 hdr->bVersion = CUR_BLOB_VERSION; 2437 hdr->reserved = 0; 2438 hdr->aiKeyAlg = CALG_RSA_KEYX; 2439 rsaPubKey->magic = 0x31415352; 2440 rsaPubKey->bitlen = sizeof(modulus1) * 8; 2441 rsaPubKey->pubexp = 65537; 2442 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), modulus1, 2443 sizeof(modulus1)); 2444 2445 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB, 2446 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2447 ok(!ret && GetLastError() == E_INVALIDARG, 2448 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 2449 /* Now with a bogus reserved field */ 2450 hdr->bType = PUBLICKEYBLOB; 2451 hdr->reserved = 1; 2452 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB, 2453 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2454 if (ret) 2455 { 2456 ok(bufSize == rsaPubKeys[0].encoded[1] + 2, 2457 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize); 2458 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n"); 2459 LocalFree(buf); 2460 } 2461 /* Now with a bogus blob version */ 2462 hdr->reserved = 0; 2463 hdr->bVersion = 0; 2464 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB, 2465 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2466 if (ret) 2467 { 2468 ok(bufSize == rsaPubKeys[0].encoded[1] + 2, 2469 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize); 2470 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n"); 2471 LocalFree(buf); 2472 } 2473 /* And with a bogus alg ID */ 2474 hdr->bVersion = CUR_BLOB_VERSION; 2475 hdr->aiKeyAlg = CALG_DES; 2476 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB, 2477 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2478 if (ret) 2479 { 2480 ok(bufSize == rsaPubKeys[0].encoded[1] + 2, 2481 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize); 2482 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n"); 2483 LocalFree(buf); 2484 } 2485 /* Check a couple of RSA-related OIDs */ 2486 hdr->aiKeyAlg = CALG_RSA_KEYX; 2487 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_RSA, 2488 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2489 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 2490 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); 2491 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA, 2492 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2493 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 2494 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); 2495 /* Finally, all valid */ 2496 hdr->aiKeyAlg = CALG_RSA_KEYX; 2497 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++) 2498 { 2499 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), 2500 rsaPubKeys[i].modulus, rsaPubKeys[i].modulusLen); 2501 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB, 2502 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2503 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 2504 if (ret) 2505 { 2506 ok(bufSize == rsaPubKeys[i].encoded[1] + 2, 2507 "Expected size %d, got %d\n", rsaPubKeys[i].encoded[1] + 2, 2508 bufSize); 2509 ok(!memcmp(buf, rsaPubKeys[i].encoded, bufSize), 2510 "Unexpected value\n"); 2511 LocalFree(buf); 2512 } 2513 } 2514 } 2515 2516 static void test_decodeRsaPublicKey(DWORD dwEncoding) 2517 { 2518 DWORD i; 2519 LPBYTE buf = NULL; 2520 DWORD bufSize = 0; 2521 BOOL ret; 2522 2523 /* Try with a bad length */ 2524 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB, 2525 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1], 2526 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2527 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD || 2528 GetLastError() == OSS_MORE_INPUT /* Win9x/NT4 */), 2529 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n", 2530 GetLastError()); 2531 /* Try with a couple of RSA-related OIDs */ 2532 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_RSA, 2533 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2, 2534 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2535 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 2536 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); 2537 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA, 2538 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2, 2539 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2540 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 2541 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); 2542 /* Now try success cases */ 2543 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++) 2544 { 2545 bufSize = 0; 2546 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB, 2547 rsaPubKeys[i].encoded, rsaPubKeys[i].encoded[1] + 2, 2548 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2549 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 2550 if (ret) 2551 { 2552 BLOBHEADER *hdr = (BLOBHEADER *)buf; 2553 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER)); 2554 2555 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + 2556 rsaPubKeys[i].decodedModulusLen, 2557 "Wrong size %d\n", bufSize); 2558 ok(hdr->bType == PUBLICKEYBLOB, 2559 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB, 2560 hdr->bType); 2561 ok(hdr->bVersion == CUR_BLOB_VERSION, 2562 "Expected version CUR_BLOB_VERSION (%d), got %d\n", 2563 CUR_BLOB_VERSION, hdr->bVersion); 2564 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n", 2565 hdr->reserved); 2566 ok(hdr->aiKeyAlg == CALG_RSA_KEYX, 2567 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg); 2568 ok(rsaPubKey->magic == 0x31415352, 2569 "Expected magic RSA1, got %08x\n", rsaPubKey->magic); 2570 ok(rsaPubKey->bitlen == rsaPubKeys[i].decodedModulusLen * 8, 2571 "Wrong bit len %d\n", rsaPubKey->bitlen); 2572 ok(rsaPubKey->pubexp == 65537, "Expected pubexp 65537, got %d\n", 2573 rsaPubKey->pubexp); 2574 ok(!memcmp(buf + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), 2575 rsaPubKeys[i].modulus, rsaPubKeys[i].decodedModulusLen), 2576 "Unexpected modulus\n"); 2577 LocalFree(buf); 2578 } 2579 } 2580 } 2581 2582 static const BYTE intSequence[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01, 2583 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 2584 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d }; 2585 2586 static const BYTE mixedSequence[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30, 2587 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f, 2588 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02, 2589 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d }; 2590 2591 static void test_encodeSequenceOfAny(DWORD dwEncoding) 2592 { 2593 CRYPT_DER_BLOB blobs[sizeof(ints) / sizeof(ints[0])]; 2594 CRYPT_SEQUENCE_OF_ANY seq; 2595 DWORD i; 2596 BOOL ret; 2597 BYTE *buf = NULL; 2598 DWORD bufSize = 0; 2599 2600 /* Encode a homogeneous sequence */ 2601 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++) 2602 { 2603 blobs[i].cbData = ints[i].encoded[1] + 2; 2604 blobs[i].pbData = (BYTE *)ints[i].encoded; 2605 } 2606 seq.cValue = sizeof(ints) / sizeof(ints[0]); 2607 seq.rgValue = blobs; 2608 2609 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq, 2610 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2611 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 2612 if (ret) 2613 { 2614 ok(bufSize == sizeof(intSequence), "Wrong size %d\n", bufSize); 2615 ok(!memcmp(buf, intSequence, intSequence[1] + 2), "Unexpected value\n"); 2616 LocalFree(buf); 2617 } 2618 /* Change the type of the first element in the sequence, and give it 2619 * another go 2620 */ 2621 blobs[0].cbData = times[0].encodedTime[1] + 2; 2622 blobs[0].pbData = (BYTE *)times[0].encodedTime; 2623 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq, 2624 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2625 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 2626 if (ret) 2627 { 2628 ok(bufSize == sizeof(mixedSequence), "Wrong size %d\n", bufSize); 2629 ok(!memcmp(buf, mixedSequence, mixedSequence[1] + 2), 2630 "Unexpected value\n"); 2631 LocalFree(buf); 2632 } 2633 } 2634 2635 static void test_decodeSequenceOfAny(DWORD dwEncoding) 2636 { 2637 BOOL ret; 2638 BYTE *buf = NULL; 2639 DWORD bufSize = 0; 2640 2641 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, intSequence, 2642 intSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2643 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 2644 if (ret) 2645 { 2646 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf; 2647 DWORD i; 2648 2649 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]), 2650 "Wrong elements %d\n", seq->cValue); 2651 for (i = 0; i < min(seq->cValue, sizeof(ints) / sizeof(ints[0])); i++) 2652 { 2653 ok(seq->rgValue[i].cbData == ints[i].encoded[1] + 2, 2654 "Expected %d bytes, got %d\n", ints[i].encoded[1] + 2, 2655 seq->rgValue[i].cbData); 2656 ok(!memcmp(seq->rgValue[i].pbData, ints[i].encoded, 2657 ints[i].encoded[1] + 2), "Unexpected value\n"); 2658 } 2659 LocalFree(buf); 2660 } 2661 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, mixedSequence, 2662 mixedSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, 2663 &bufSize); 2664 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 2665 if (ret) 2666 { 2667 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf; 2668 2669 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]), 2670 "Wrong elements %d\n", seq->cValue); 2671 /* Just check the first element since it's all that changed */ 2672 ok(seq->rgValue[0].cbData == times[0].encodedTime[1] + 2, 2673 "Expected %d bytes, got %d\n", times[0].encodedTime[1] + 2, 2674 seq->rgValue[0].cbData); 2675 ok(!memcmp(seq->rgValue[0].pbData, times[0].encodedTime, 2676 times[0].encodedTime[1] + 2), "Unexpected value\n"); 2677 LocalFree(buf); 2678 } 2679 } 2680 2681 struct encodedExtensions 2682 { 2683 CERT_EXTENSIONS exts; 2684 const BYTE *encoded; 2685 }; 2686 2687 static BYTE crit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 }; 2688 static BYTE noncrit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 }; 2689 static CHAR oid_basic_constraints2[] = szOID_BASIC_CONSTRAINTS2; 2690 static CERT_EXTENSION criticalExt = 2691 { oid_basic_constraints2, TRUE, { 8, crit_ext_data } }; 2692 static CERT_EXTENSION nonCriticalExt = 2693 { oid_basic_constraints2, FALSE, { 8, noncrit_ext_data } }; 2694 static CHAR oid_short[] = "1.1"; 2695 static CERT_EXTENSION extWithShortOid = 2696 { oid_short, FALSE, { 0, NULL } }; 2697 2698 static const BYTE ext0[] = { 0x30,0x00 }; 2699 static const BYTE ext1[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01, 2700 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 }; 2701 static const BYTE ext2[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04, 2702 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 }; 2703 static const BYTE ext3[] = { 0x30,0x07,0x30,0x05,0x06,0x01,0x29,0x04,0x00 }; 2704 2705 static const struct encodedExtensions exts[] = { 2706 { { 0, NULL }, ext0 }, 2707 { { 1, &criticalExt }, ext1 }, 2708 { { 1, &nonCriticalExt }, ext2 }, 2709 { { 1, &extWithShortOid }, ext3 } 2710 }; 2711 2712 static void test_encodeExtensions(DWORD dwEncoding) 2713 { 2714 DWORD i; 2715 2716 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++) 2717 { 2718 BOOL ret; 2719 BYTE *buf = NULL; 2720 DWORD bufSize = 0; 2721 2722 ret = pCryptEncodeObjectEx(dwEncoding, X509_EXTENSIONS, &exts[i].exts, 2723 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2724 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 2725 if (ret) 2726 { 2727 ok(bufSize == exts[i].encoded[1] + 2, 2728 "Expected %d bytes, got %d\n", exts[i].encoded[1] + 2, bufSize); 2729 ok(!memcmp(buf, exts[i].encoded, exts[i].encoded[1] + 2), 2730 "Unexpected value\n"); 2731 LocalFree(buf); 2732 } 2733 } 2734 } 2735 2736 static void test_decodeExtensions(DWORD dwEncoding) 2737 { 2738 DWORD i; 2739 2740 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++) 2741 { 2742 BOOL ret; 2743 BYTE *buf = NULL; 2744 DWORD bufSize = 0; 2745 2746 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS, 2747 exts[i].encoded, exts[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, 2748 NULL, &buf, &bufSize); 2749 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 2750 if (ret) 2751 { 2752 CERT_EXTENSIONS *ext = (CERT_EXTENSIONS *)buf; 2753 DWORD j; 2754 2755 ok(ext->cExtension == exts[i].exts.cExtension, 2756 "Expected %d extensions, see %d\n", exts[i].exts.cExtension, 2757 ext->cExtension); 2758 for (j = 0; j < min(ext->cExtension, exts[i].exts.cExtension); j++) 2759 { 2760 ok(!strcmp(ext->rgExtension[j].pszObjId, 2761 exts[i].exts.rgExtension[j].pszObjId), 2762 "Expected OID %s, got %s\n", 2763 exts[i].exts.rgExtension[j].pszObjId, 2764 ext->rgExtension[j].pszObjId); 2765 ok(!memcmp(ext->rgExtension[j].Value.pbData, 2766 exts[i].exts.rgExtension[j].Value.pbData, 2767 exts[i].exts.rgExtension[j].Value.cbData), 2768 "Unexpected value\n"); 2769 } 2770 LocalFree(buf); 2771 } 2772 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS, 2773 exts[i].encoded, exts[i].encoded[1] + 2, 0, NULL, NULL, &bufSize); 2774 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 2775 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bufSize); 2776 if (buf) 2777 { 2778 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS, 2779 exts[i].encoded, exts[i].encoded[1] + 2, 0, NULL, buf, &bufSize); 2780 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 2781 HeapFree(GetProcessHeap(), 0, buf); 2782 } 2783 } 2784 } 2785 2786 /* MS encodes public key info with a NULL if the algorithm identifier's 2787 * parameters are empty. However, when encoding an algorithm in a CERT_INFO, 2788 * it encodes them by omitting the algorithm parameters. It accepts either 2789 * form for decoding. 2790 */ 2791 struct encodedPublicKey 2792 { 2793 CERT_PUBLIC_KEY_INFO info; 2794 const BYTE *encoded; 2795 const BYTE *encodedNoNull; 2796 CERT_PUBLIC_KEY_INFO decoded; 2797 }; 2798 2799 static const BYTE aKey[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 2800 0xe, 0xf }; 2801 static const BYTE params[] = { 0x02, 0x01, 0x01 }; 2802 2803 static const unsigned char bin64[] = { 2804 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00}; 2805 static const unsigned char bin65[] = { 2806 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00}; 2807 static const unsigned char bin66[] = { 2808 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00}; 2809 static const unsigned char bin67[] = { 2810 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00}; 2811 static const unsigned char bin68[] = { 2812 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01, 2813 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; 2814 static const unsigned char bin69[] = { 2815 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01, 2816 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; 2817 static const unsigned char bin70[] = { 2818 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01, 2819 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e, 2820 0x0f}; 2821 static const unsigned char bin71[] = { 2822 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01, 2823 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e, 2824 0x0f}; 2825 static unsigned char bin72[] = { 0x05,0x00}; 2826 2827 static CHAR oid_bogus[] = "1.2.3", 2828 oid_rsa[] = szOID_RSA; 2829 2830 static const struct encodedPublicKey pubKeys[] = { 2831 /* with a bogus OID */ 2832 { { { oid_bogus, { 0, NULL } }, { 0, NULL, 0 } }, 2833 bin64, bin65, 2834 { { oid_bogus, { 2, bin72 } }, { 0, NULL, 0 } } }, 2835 /* some normal keys */ 2836 { { { oid_rsa, { 0, NULL } }, { 0, NULL, 0} }, 2837 bin66, bin67, 2838 { { oid_rsa, { 2, bin72 } }, { 0, NULL, 0 } } }, 2839 { { { oid_rsa, { 0, NULL } }, { sizeof(aKey), (BYTE *)aKey, 0} }, 2840 bin68, bin69, 2841 { { oid_rsa, { 2, bin72 } }, { sizeof(aKey), (BYTE *)aKey, 0} } }, 2842 /* with add'l parameters--note they must be DER-encoded */ 2843 { { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey), 2844 (BYTE *)aKey, 0 } }, 2845 bin70, bin71, 2846 { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey), 2847 (BYTE *)aKey, 0 } } }, 2848 }; 2849 2850 static void test_encodePublicKeyInfo(DWORD dwEncoding) 2851 { 2852 DWORD i; 2853 2854 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++) 2855 { 2856 BOOL ret; 2857 BYTE *buf = NULL; 2858 DWORD bufSize = 0; 2859 2860 ret = pCryptEncodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO, 2861 &pubKeys[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, 2862 &bufSize); 2863 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */, 2864 "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 2865 if (ret) 2866 { 2867 ok(bufSize == pubKeys[i].encoded[1] + 2, 2868 "Expected %d bytes, got %d\n", pubKeys[i].encoded[1] + 2, bufSize); 2869 if (bufSize == pubKeys[i].encoded[1] + 2) 2870 ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2), 2871 "Unexpected value\n"); 2872 LocalFree(buf); 2873 } 2874 } 2875 } 2876 2877 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO *expected, 2878 const CERT_PUBLIC_KEY_INFO *got) 2879 { 2880 ok(!strcmp(expected->Algorithm.pszObjId, got->Algorithm.pszObjId), 2881 "Expected OID %s, got %s\n", expected->Algorithm.pszObjId, 2882 got->Algorithm.pszObjId); 2883 ok(expected->Algorithm.Parameters.cbData == 2884 got->Algorithm.Parameters.cbData, 2885 "Expected parameters of %d bytes, got %d\n", 2886 expected->Algorithm.Parameters.cbData, got->Algorithm.Parameters.cbData); 2887 if (expected->Algorithm.Parameters.cbData) 2888 ok(!memcmp(expected->Algorithm.Parameters.pbData, 2889 got->Algorithm.Parameters.pbData, got->Algorithm.Parameters.cbData), 2890 "Unexpected algorithm parameters\n"); 2891 ok(expected->PublicKey.cbData == got->PublicKey.cbData, 2892 "Expected public key of %d bytes, got %d\n", 2893 expected->PublicKey.cbData, got->PublicKey.cbData); 2894 if (expected->PublicKey.cbData) 2895 ok(!memcmp(expected->PublicKey.pbData, got->PublicKey.pbData, 2896 got->PublicKey.cbData), "Unexpected public key value\n"); 2897 } 2898 2899 static void test_decodePublicKeyInfo(DWORD dwEncoding) 2900 { 2901 static const BYTE bogusPubKeyInfo[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06, 2902 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 2903 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 2904 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; 2905 DWORD i; 2906 BOOL ret; 2907 BYTE *buf = NULL; 2908 DWORD bufSize = 0; 2909 2910 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++) 2911 { 2912 /* The NULL form decodes to the decoded member */ 2913 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO, 2914 pubKeys[i].encoded, pubKeys[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, 2915 NULL, &buf, &bufSize); 2916 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 2917 if (ret) 2918 { 2919 comparePublicKeyInfo(&pubKeys[i].decoded, 2920 (CERT_PUBLIC_KEY_INFO *)buf); 2921 LocalFree(buf); 2922 } 2923 /* The non-NULL form decodes to the original */ 2924 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO, 2925 pubKeys[i].encodedNoNull, pubKeys[i].encodedNoNull[1] + 2, 2926 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 2927 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 2928 if (ret) 2929 { 2930 comparePublicKeyInfo(&pubKeys[i].info, (CERT_PUBLIC_KEY_INFO *)buf); 2931 LocalFree(buf); 2932 } 2933 } 2934 /* Test with bogus (not valid DER) parameters */ 2935 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO, 2936 bogusPubKeyInfo, bogusPubKeyInfo[1] + 2, CRYPT_DECODE_ALLOC_FLAG, 2937 NULL, &buf, &bufSize); 2938 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT || 2939 GetLastError() == OSS_DATA_ERROR /* Win9x */), 2940 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n", 2941 GetLastError()); 2942 } 2943 2944 static const BYTE v1Cert[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00, 2945 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 2946 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 2947 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30, 2948 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 }; 2949 static const BYTE v2Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02, 2950 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 2951 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 2952 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 2953 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 }; 2954 static const BYTE v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 2955 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 2956 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 2957 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 2958 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 }; 2959 static const BYTE v4Cert[] = { 2960 0x30,0x38,0xa0,0x03,0x02,0x01,0x03,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22, 2961 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, 2962 0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30, 2963 0x30,0x30,0x30,0x5a,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00 }; 2964 static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30, 2965 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 2966 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 2967 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 2968 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 2969 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 2970 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 }; 2971 static const BYTE v1CertWithSerial[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30, 2972 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 2973 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 2974 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 2975 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 2976 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 2977 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 }; 2978 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 2979 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 2980 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 2981 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 2982 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 2983 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 2984 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 2985 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 2986 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 2987 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 }; 2988 static const BYTE v1CertWithPubKey[] = { 2989 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30, 2990 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61, 2991 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31, 2992 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, 2993 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11, 2994 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 2995 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 2996 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 2997 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06, 2998 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02, 2999 0x01,0x01 }; 3000 static const BYTE v1CertWithPubKeyNoNull[] = { 3001 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30, 3002 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61, 3003 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31, 3004 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, 3005 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11, 3006 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 3007 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 3008 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09, 3009 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55, 3010 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 }; 3011 static const BYTE v1CertWithSubjectKeyId[] = { 3012 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11, 3013 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 3014 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30, 3015 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30, 3016 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06, 3017 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67, 3018 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30, 3019 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20, 3020 0x4c,0x61,0x6e,0x67,0x00 }; 3021 static const BYTE v1CertWithIssuerUniqueId[] = { 3022 0x30,0x38,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36, 3023 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f, 3024 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a, 3025 0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x81,0x02,0x00,0x01 }; 3026 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueId[] = { 3027 0x30,0x81,0x99,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30, 3028 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61, 3029 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31, 3030 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, 3031 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11, 3032 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 3033 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 3034 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 3035 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30, 3036 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06, 3037 0x01,0x01,0xff,0x02,0x01,0x01 }; 3038 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull[] = { 3039 0x30,0x81,0x97,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30, 3040 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61, 3041 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31, 3042 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, 3043 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11, 3044 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 3045 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 3046 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09, 3047 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,0x14,0x30, 3048 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01, 3049 0xff,0x02,0x01,0x01 }; 3050 3051 static const BYTE serialNum[] = { 0x01 }; 3052 3053 static void test_encodeCertToBeSigned(DWORD dwEncoding) 3054 { 3055 BOOL ret; 3056 BYTE *buf = NULL; 3057 DWORD size = 0; 3058 CERT_INFO info = { 0 }; 3059 static char oid_rsa_rsa[] = szOID_RSA_RSA; 3060 static char oid_subject_key_identifier[] = szOID_SUBJECT_KEY_IDENTIFIER; 3061 CERT_EXTENSION ext; 3062 3063 if (0) 3064 { 3065 /* Test with NULL pvStructInfo (crashes on win9x) */ 3066 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 3067 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3068 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 3069 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError()); 3070 } 3071 /* Test with a V1 cert */ 3072 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, 3073 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3074 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */, 3075 "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3076 if (ret) 3077 { 3078 ok(size == v1Cert[1] + 2, "Expected size %d, got %d\n", 3079 v1Cert[1] + 2, size); 3080 ok(!memcmp(buf, v1Cert, size), "Got unexpected value\n"); 3081 LocalFree(buf); 3082 } 3083 /* Test v2 cert */ 3084 info.dwVersion = CERT_V2; 3085 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, 3086 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3087 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */, 3088 "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3089 if (ret) 3090 { 3091 ok(size == sizeof(v2Cert), "Wrong size %d\n", size); 3092 ok(!memcmp(buf, v2Cert, size), "Got unexpected value\n"); 3093 LocalFree(buf); 3094 } 3095 /* Test v3 cert */ 3096 info.dwVersion = CERT_V3; 3097 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, 3098 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3099 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */, 3100 "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3101 if (ret) 3102 { 3103 ok(size == sizeof(v3Cert), "Wrong size %d\n", size); 3104 ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n"); 3105 LocalFree(buf); 3106 } 3107 /* A v4 cert? */ 3108 info.dwVersion = 3; /* Not a typo, CERT_V3 is 2 */ 3109 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, 3110 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3111 if (ret) 3112 { 3113 ok(size == sizeof(v4Cert), "Wrong size %d\n", size); 3114 ok(!memcmp(buf, v4Cert, size), "Unexpected value\n"); 3115 LocalFree(buf); 3116 } 3117 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but 3118 * API doesn't prevent it) 3119 */ 3120 info.dwVersion = CERT_V1; 3121 info.cExtension = 1; 3122 info.rgExtension = &criticalExt; 3123 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, 3124 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3125 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */, 3126 "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3127 if (ret) 3128 { 3129 ok(size == sizeof(v1CertWithConstraints), "Wrong size %d\n", size); 3130 ok(!memcmp(buf, v1CertWithConstraints, size), "Got unexpected value\n"); 3131 LocalFree(buf); 3132 } 3133 /* test v1 cert with a serial number */ 3134 info.SerialNumber.cbData = sizeof(serialNum); 3135 info.SerialNumber.pbData = (BYTE *)serialNum; 3136 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, 3137 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3138 if (ret) 3139 { 3140 ok(size == sizeof(v1CertWithSerial), "Wrong size %d\n", size); 3141 ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n"); 3142 LocalFree(buf); 3143 } 3144 /* Test v1 cert with an issuer name, serial number, and issuer unique id */ 3145 info.dwVersion = CERT_V1; 3146 info.cExtension = 0; 3147 info.IssuerUniqueId.cbData = sizeof(serialNum); 3148 info.IssuerUniqueId.pbData = (BYTE *)serialNum; 3149 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, 3150 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3151 ok(ret || broken(GetLastError() == OSS_BAD_PTR /* Win98 */), 3152 "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3153 if (ret) 3154 { 3155 ok(size == sizeof(v1CertWithIssuerUniqueId), "Wrong size %d\n", size); 3156 ok(!memcmp(buf, v1CertWithIssuerUniqueId, size), 3157 "Got unexpected value\n"); 3158 LocalFree(buf); 3159 } 3160 /* Test v1 cert with an issuer name, a subject name, and a serial number */ 3161 info.IssuerUniqueId.cbData = 0; 3162 info.IssuerUniqueId.pbData = NULL; 3163 info.cExtension = 1; 3164 info.rgExtension = &criticalExt; 3165 info.Issuer.cbData = sizeof(encodedCommonName); 3166 info.Issuer.pbData = (BYTE *)encodedCommonName; 3167 info.Subject.cbData = sizeof(encodedCommonName); 3168 info.Subject.pbData = (BYTE *)encodedCommonName; 3169 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, 3170 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3171 if (ret) 3172 { 3173 ok(size == sizeof(bigCert), "Wrong size %d\n", size); 3174 ok(!memcmp(buf, bigCert, size), "Got unexpected value\n"); 3175 LocalFree(buf); 3176 } 3177 /* Add a public key */ 3178 info.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa; 3179 info.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey); 3180 info.SubjectPublicKeyInfo.PublicKey.pbData = (LPBYTE)aKey; 3181 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, 3182 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3183 if (ret) 3184 { 3185 ok(size == sizeof(v1CertWithPubKey) || 3186 size == sizeof(v1CertWithPubKeyNoNull), "Wrong size %d\n", size); 3187 if (size == sizeof(v1CertWithPubKey)) 3188 ok(!memcmp(buf, v1CertWithPubKey, size), "Got unexpected value\n"); 3189 else if (size == sizeof(v1CertWithPubKeyNoNull)) 3190 ok(!memcmp(buf, v1CertWithPubKeyNoNull, size), 3191 "Got unexpected value\n"); 3192 LocalFree(buf); 3193 } 3194 /* Again add an issuer unique id */ 3195 info.IssuerUniqueId.cbData = sizeof(serialNum); 3196 info.IssuerUniqueId.pbData = (BYTE *)serialNum; 3197 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, 3198 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3199 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3200 if (ret) 3201 { 3202 ok(size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId) || 3203 size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull), 3204 "Wrong size %d\n", size); 3205 if (size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId)) 3206 ok(!memcmp(buf, v1CertWithSubjectIssuerSerialAndIssuerUniqueId, 3207 size), "unexpected value\n"); 3208 else if (size == 3209 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull)) 3210 ok(!memcmp(buf, 3211 v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull, size), 3212 "unexpected value\n"); 3213 LocalFree(buf); 3214 } 3215 /* Remove the public key, and add a subject key identifier extension */ 3216 info.IssuerUniqueId.cbData = 0; 3217 info.IssuerUniqueId.pbData = NULL; 3218 info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL; 3219 info.SubjectPublicKeyInfo.PublicKey.cbData = 0; 3220 info.SubjectPublicKeyInfo.PublicKey.pbData = NULL; 3221 ext.pszObjId = oid_subject_key_identifier; 3222 ext.fCritical = FALSE; 3223 ext.Value.cbData = sizeof(octetCommonNameValue); 3224 ext.Value.pbData = octetCommonNameValue; 3225 info.cExtension = 1; 3226 info.rgExtension = &ext; 3227 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, 3228 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3229 if (ret) 3230 { 3231 ok(size == sizeof(v1CertWithSubjectKeyId), "Wrong size %d\n", size); 3232 ok(!memcmp(buf, v1CertWithSubjectKeyId, size), "Unexpected value\n"); 3233 LocalFree(buf); 3234 } 3235 } 3236 3237 static void test_decodeCertToBeSigned(DWORD dwEncoding) 3238 { 3239 static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert, v4Cert, 3240 v1CertWithConstraints, v1CertWithSerial, v1CertWithIssuerUniqueId }; 3241 BOOL ret; 3242 BYTE *buf = NULL; 3243 DWORD size = 0, i; 3244 3245 /* Test with NULL pbEncoded */ 3246 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 0, 3247 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 3248 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD || 3249 GetLastError() == OSS_BAD_ARG /* Win9x */), 3250 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError()); 3251 if (0) 3252 { 3253 /* Crashes on win9x */ 3254 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 1, 3255 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 3256 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 3257 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError()); 3258 } 3259 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT or 3260 * CRYPT_E_ASN1_BADTAG, because at a minimum a cert must have a non-zero 3261 * serial number, an issuer, a subject, and a public key. 3262 */ 3263 for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++) 3264 { 3265 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, 3266 corruptCerts[i], corruptCerts[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, 3267 &buf, &size); 3268 ok(!ret, "Expected failure\n"); 3269 } 3270 /* The following succeeds, even though v1 certs are not allowed to have 3271 * extensions. 3272 */ 3273 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, 3274 v1CertWithSubjectKeyId, sizeof(v1CertWithSubjectKeyId), 3275 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 3276 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3277 if (ret) 3278 { 3279 CERT_INFO *info = (CERT_INFO *)buf; 3280 3281 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size); 3282 ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %d\n", 3283 info->dwVersion); 3284 ok(info->cExtension == 1, "expected 1 extension, got %d\n", 3285 info->cExtension); 3286 LocalFree(buf); 3287 } 3288 /* The following also succeeds, even though V1 certs are not allowed to 3289 * have issuer unique ids. 3290 */ 3291 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, 3292 v1CertWithSubjectIssuerSerialAndIssuerUniqueId, 3293 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId), 3294 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 3295 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3296 if (ret) 3297 { 3298 CERT_INFO *info = (CERT_INFO *)buf; 3299 3300 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size); 3301 ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %d\n", 3302 info->dwVersion); 3303 ok(info->IssuerUniqueId.cbData == sizeof(serialNum), 3304 "unexpected issuer unique id size %d\n", info->IssuerUniqueId.cbData); 3305 ok(!memcmp(info->IssuerUniqueId.pbData, serialNum, sizeof(serialNum)), 3306 "unexpected issuer unique id value\n"); 3307 LocalFree(buf); 3308 } 3309 /* Now check with serial number, subject and issuer specified */ 3310 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert, 3311 sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 3312 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3313 if (ret) 3314 { 3315 CERT_INFO *info = (CERT_INFO *)buf; 3316 3317 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size); 3318 ok(info->SerialNumber.cbData == 1, 3319 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData); 3320 ok(*info->SerialNumber.pbData == *serialNum, 3321 "Expected serial number %d, got %d\n", *serialNum, 3322 *info->SerialNumber.pbData); 3323 ok(info->Issuer.cbData == sizeof(encodedCommonName), 3324 "Wrong size %d\n", info->Issuer.cbData); 3325 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData), 3326 "Unexpected issuer\n"); 3327 ok(info->Subject.cbData == sizeof(encodedCommonName), 3328 "Wrong size %d\n", info->Subject.cbData); 3329 ok(!memcmp(info->Subject.pbData, encodedCommonName, 3330 info->Subject.cbData), "Unexpected subject\n"); 3331 LocalFree(buf); 3332 } 3333 /* Check again with pub key specified */ 3334 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, 3335 v1CertWithPubKey, sizeof(v1CertWithPubKey), CRYPT_DECODE_ALLOC_FLAG, NULL, 3336 &buf, &size); 3337 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3338 if (ret) 3339 { 3340 CERT_INFO *info = (CERT_INFO *)buf; 3341 3342 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size); 3343 ok(info->SerialNumber.cbData == 1, 3344 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData); 3345 ok(*info->SerialNumber.pbData == *serialNum, 3346 "Expected serial number %d, got %d\n", *serialNum, 3347 *info->SerialNumber.pbData); 3348 ok(info->Issuer.cbData == sizeof(encodedCommonName), 3349 "Wrong size %d\n", info->Issuer.cbData); 3350 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData), 3351 "Unexpected issuer\n"); 3352 ok(info->Subject.cbData == sizeof(encodedCommonName), 3353 "Wrong size %d\n", info->Subject.cbData); 3354 ok(!memcmp(info->Subject.pbData, encodedCommonName, 3355 info->Subject.cbData), "Unexpected subject\n"); 3356 ok(!strcmp(info->SubjectPublicKeyInfo.Algorithm.pszObjId, 3357 szOID_RSA_RSA), "Expected szOID_RSA_RSA, got %s\n", 3358 info->SubjectPublicKeyInfo.Algorithm.pszObjId); 3359 ok(info->SubjectPublicKeyInfo.PublicKey.cbData == sizeof(aKey), 3360 "Wrong size %d\n", info->SubjectPublicKeyInfo.PublicKey.cbData); 3361 ok(!memcmp(info->SubjectPublicKeyInfo.PublicKey.pbData, aKey, 3362 sizeof(aKey)), "Unexpected public key\n"); 3363 LocalFree(buf); 3364 } 3365 } 3366 3367 static const BYTE hash[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 3368 0xe, 0xf }; 3369 3370 static const BYTE signedBigCert[] = { 3371 ASN_SEQUENCE,0x81,147, 3372 ASN_SEQUENCE,122, 3373 ASN_INTEGER,1, 0x01, 3374 ASN_SEQUENCE,2, 3375 ASN_OBJECTIDENTIFIER,0, 3376 ASN_SEQUENCE,21, 3377 0x31,19, 3378 ASN_SEQUENCE,17, 3379 ASN_OBJECTIDENTIFIER,3, 0x55,0x04,0x03, 3380 0x13,10, 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00, 3381 ASN_SEQUENCE,34, 3382 0x18,15, 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a, 3383 0x18,15, 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a, 3384 ASN_SEQUENCE,21, 3385 0x31,19, 3386 ASN_SEQUENCE,17, 3387 ASN_OBJECTIDENTIFIER,3, 0x55,0x04,0x03, 3388 0x13,10, 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00, 3389 ASN_SEQUENCE,7, 3390 ASN_SEQUENCE,2, 3391 ASN_OBJECTIDENTIFIER,0, 3392 ASN_BITS,1, 0x00, 3393 0xa3,22, 3394 ASN_SEQUENCE,20, 3395 ASN_SEQUENCE,18, 3396 ASN_OBJECTIDENTIFIER,3, 0x55,0x1d,0x13, 3397 0x01,1, 0xff, 3398 ASN_OCTETSTRING,8, 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01, 3399 ASN_SEQUENCE,2, 3400 ASN_OBJECTIDENTIFIER,0, 3401 ASN_BITS,17, 0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08, 3402 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00 3403 }; 3404 3405 static const BYTE signedBigCertWithIndefiniteSeq[] = { 3406 ASN_SEQUENCE,0x81,151, 3407 ASN_SEQUENCE,126, 3408 ASN_INTEGER,1, 0x01, 3409 ASN_SEQUENCE,2, 3410 ASN_OBJECTIDENTIFIER,0, 3411 ASN_SEQUENCE,21, 3412 0x31,19, 3413 ASN_SEQUENCE,17, 3414 ASN_OBJECTIDENTIFIER,3, 0x55,0x04,0x03, 3415 0x13,10, 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00, 3416 ASN_SEQUENCE,0x80, 3417 0x18,15, 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a, 3418 0x18,15, 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a, 3419 0,0, 3420 ASN_SEQUENCE,21, 3421 0x31,19, 3422 ASN_SEQUENCE,17, 3423 ASN_OBJECTIDENTIFIER,3, 0x55,0x04,0x03, 3424 0x13,10, 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00, 3425 ASN_SEQUENCE,0x80, 3426 ASN_SEQUENCE,2, 3427 ASN_OBJECTIDENTIFIER,0, 3428 ASN_BITS,1, 0x00, 3429 0,0, 3430 0xa3,22, 3431 ASN_SEQUENCE,20, 3432 ASN_SEQUENCE,18, 3433 ASN_OBJECTIDENTIFIER,3, 0x55,0x1d,0x13, 3434 0x01,1, 0xff, 3435 ASN_OCTETSTRING,8, 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01, 3436 ASN_SEQUENCE,2, 3437 ASN_OBJECTIDENTIFIER,0, 3438 ASN_BITS,17, 0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08, 3439 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00 3440 }; 3441 3442 static void test_encodeCert(DWORD dwEncoding) 3443 { 3444 /* Note the SignatureAlgorithm must match that in the encoded cert. Note 3445 * also that bigCert is a NULL-terminated string, so don't count its 3446 * last byte (otherwise the signed cert won't decode.) 3447 */ 3448 CERT_SIGNED_CONTENT_INFO info = { { sizeof(bigCert), (BYTE *)bigCert }, 3449 { NULL, { 0, NULL } }, { sizeof(hash), (BYTE *)hash, 0 } }; 3450 BOOL ret; 3451 BYTE *buf = NULL; 3452 DWORD bufSize = 0; 3453 3454 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT, &info, 3455 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); 3456 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3457 if (ret) 3458 { 3459 ok(bufSize == sizeof(signedBigCert), "Wrong size %d\n", bufSize); 3460 ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n"); 3461 LocalFree(buf); 3462 } 3463 } 3464 3465 static void test_decodeCert(DWORD dwEncoding) 3466 { 3467 BOOL ret; 3468 BYTE *buf = NULL; 3469 DWORD size = 0; 3470 3471 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert, 3472 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 3473 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3474 if (ret) 3475 { 3476 CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf; 3477 3478 ok(info->ToBeSigned.cbData == sizeof(bigCert), 3479 "Wrong cert size %d\n", info->ToBeSigned.cbData); 3480 ok(!memcmp(info->ToBeSigned.pbData, bigCert, info->ToBeSigned.cbData), 3481 "Unexpected cert\n"); 3482 ok(info->Signature.cbData == sizeof(hash), 3483 "Wrong signature size %d\n", info->Signature.cbData); 3484 ok(!memcmp(info->Signature.pbData, hash, info->Signature.cbData), 3485 "Unexpected signature\n"); 3486 LocalFree(buf); 3487 } 3488 /* A signed cert decodes as a CERT_INFO too */ 3489 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCert, 3490 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 3491 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3492 if (ret) 3493 { 3494 CERT_INFO *info = (CERT_INFO *)buf; 3495 3496 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size); 3497 ok(info->SerialNumber.cbData == 1, 3498 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData); 3499 ok(*info->SerialNumber.pbData == *serialNum, 3500 "Expected serial number %d, got %d\n", *serialNum, 3501 *info->SerialNumber.pbData); 3502 ok(info->Issuer.cbData == sizeof(encodedCommonName), 3503 "Wrong size %d\n", info->Issuer.cbData); 3504 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData), 3505 "Unexpected issuer\n"); 3506 ok(info->Subject.cbData == sizeof(encodedCommonName), 3507 "Wrong size %d\n", info->Subject.cbData); 3508 ok(!memcmp(info->Subject.pbData, encodedCommonName, 3509 info->Subject.cbData), "Unexpected subject\n"); 3510 LocalFree(buf); 3511 } 3512 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCertWithIndefiniteSeq, 3513 sizeof(signedBigCertWithIndefiniteSeq), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 3514 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3515 if (ret) 3516 { 3517 CERT_INFO *info = (CERT_INFO *)buf; 3518 3519 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size); 3520 ok(info->SerialNumber.cbData == 1, 3521 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData); 3522 ok(*info->SerialNumber.pbData == *serialNum, 3523 "Expected serial number %d, got %d\n", *serialNum, 3524 *info->SerialNumber.pbData); 3525 ok(info->Issuer.cbData == sizeof(encodedCommonName), 3526 "Wrong size %d\n", info->Issuer.cbData); 3527 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData), 3528 "Unexpected issuer\n"); 3529 ok(info->Subject.cbData == sizeof(encodedCommonName), 3530 "Wrong size %d\n", info->Subject.cbData); 3531 ok(!memcmp(info->Subject.pbData, encodedCommonName, 3532 info->Subject.cbData), "Unexpected subject\n"); 3533 LocalFree(buf); 3534 } 3535 } 3536 3537 static const BYTE emptyDistPoint[] = { 0x30, 0x02, 0x30, 0x00 }; 3538 static const BYTE distPointWithUrl[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15, 3539 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 3540 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 }; 3541 static const BYTE distPointWithReason[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02, 3542 0x00, 0x03 }; 3543 static const BYTE distPointWithIssuer[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13, 3544 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 3545 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 }; 3546 static const BYTE distPointWithUrlAndIssuer[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0, 3547 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 3548 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11, 3549 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 3550 0x2e, 0x6f, 0x72, 0x67 }; 3551 static const BYTE crlReason = CRL_REASON_KEY_COMPROMISE | 3552 CRL_REASON_AFFILIATION_CHANGED; 3553 3554 static void test_encodeCRLDistPoints(DWORD dwEncoding) 3555 { 3556 CRL_DIST_POINTS_INFO info = { 0 }; 3557 CRL_DIST_POINT point = { { 0 } }; 3558 CERT_ALT_NAME_ENTRY entry = { 0 }; 3559 BOOL ret; 3560 BYTE *buf = NULL; 3561 DWORD size = 0; 3562 3563 /* Test with an empty info */ 3564 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info, 3565 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3566 ok(!ret && GetLastError() == E_INVALIDARG, 3567 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 3568 /* Test with one empty dist point */ 3569 info.cDistPoint = 1; 3570 info.rgDistPoint = &point; 3571 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info, 3572 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3573 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3574 if (ret) 3575 { 3576 ok(size == sizeof(emptyDistPoint), "Wrong size %d\n", size); 3577 ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n"); 3578 LocalFree(buf); 3579 } 3580 /* A dist point with an invalid name */ 3581 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME; 3582 entry.dwAltNameChoice = CERT_ALT_NAME_URL; 3583 U(entry).pwszURL = (LPWSTR)nihongoURL; 3584 U(point.DistPointName).FullName.cAltEntry = 1; 3585 U(point.DistPointName).FullName.rgAltEntry = &entry; 3586 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info, 3587 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3588 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING, 3589 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError()); 3590 /* The first invalid character is at index 7 */ 3591 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7, 3592 "Expected invalid char at index 7, got %d\n", 3593 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size)); 3594 /* A dist point with (just) a valid name */ 3595 U(entry).pwszURL = (LPWSTR)url; 3596 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info, 3597 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3598 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3599 if (ret) 3600 { 3601 ok(size == sizeof(distPointWithUrl), "Wrong size %d\n", size); 3602 ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n"); 3603 LocalFree(buf); 3604 } 3605 /* A dist point with (just) reason flags */ 3606 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME; 3607 point.ReasonFlags.cbData = sizeof(crlReason); 3608 point.ReasonFlags.pbData = (LPBYTE)&crlReason; 3609 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info, 3610 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3611 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3612 if (ret) 3613 { 3614 ok(size == sizeof(distPointWithReason), "Wrong size %d\n", size); 3615 ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n"); 3616 LocalFree(buf); 3617 } 3618 /* A dist point with just an issuer */ 3619 point.ReasonFlags.cbData = 0; 3620 point.CRLIssuer.cAltEntry = 1; 3621 point.CRLIssuer.rgAltEntry = &entry; 3622 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info, 3623 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3624 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3625 if (ret) 3626 { 3627 ok(size == sizeof(distPointWithIssuer), "Wrong size %d\n", size); 3628 ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n"); 3629 LocalFree(buf); 3630 } 3631 /* A dist point with both a name and an issuer */ 3632 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME; 3633 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info, 3634 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3635 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3636 if (ret) 3637 { 3638 ok(size == sizeof(distPointWithUrlAndIssuer), 3639 "Wrong size %d\n", size); 3640 ok(!memcmp(buf, distPointWithUrlAndIssuer, size), "Unexpected value\n"); 3641 LocalFree(buf); 3642 } 3643 } 3644 3645 static void test_decodeCRLDistPoints(DWORD dwEncoding) 3646 { 3647 BOOL ret; 3648 BYTE *buf = NULL; 3649 DWORD size = 0; 3650 PCRL_DIST_POINTS_INFO info; 3651 PCRL_DIST_POINT point; 3652 PCERT_ALT_NAME_ENTRY entry; 3653 3654 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, 3655 emptyDistPoint, emptyDistPoint[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, 3656 &buf, &size); 3657 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3658 if (ret) 3659 { 3660 info = (PCRL_DIST_POINTS_INFO)buf; 3661 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT), 3662 "Wrong size %d\n", size); 3663 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n", 3664 info->cDistPoint); 3665 point = info->rgDistPoint; 3666 ok(point->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_NO_NAME, 3667 "Expected CRL_DIST_POINT_NO_NAME, got %d\n", 3668 point->DistPointName.dwDistPointNameChoice); 3669 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n"); 3670 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n"); 3671 LocalFree(buf); 3672 } 3673 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, 3674 distPointWithUrl, distPointWithUrl[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, 3675 &buf, &size); 3676 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3677 if (ret) 3678 { 3679 info = (PCRL_DIST_POINTS_INFO)buf; 3680 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT), 3681 "Wrong size %d\n", size); 3682 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n", 3683 info->cDistPoint); 3684 point = info->rgDistPoint; 3685 ok(point->DistPointName.dwDistPointNameChoice == 3686 CRL_DIST_POINT_FULL_NAME, 3687 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n", 3688 point->DistPointName.dwDistPointNameChoice); 3689 ok(U(point->DistPointName).FullName.cAltEntry == 1, 3690 "Expected 1 name entry, got %d\n", 3691 U(point->DistPointName).FullName.cAltEntry); 3692 entry = U(point->DistPointName).FullName.rgAltEntry; 3693 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL, 3694 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice); 3695 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n"); 3696 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n"); 3697 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n"); 3698 LocalFree(buf); 3699 } 3700 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, 3701 distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG, 3702 NULL, &buf, &size); 3703 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3704 if (ret) 3705 { 3706 info = (PCRL_DIST_POINTS_INFO)buf; 3707 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT), 3708 "Wrong size %d\n", size); 3709 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n", 3710 info->cDistPoint); 3711 point = info->rgDistPoint; 3712 ok(point->DistPointName.dwDistPointNameChoice == 3713 CRL_DIST_POINT_NO_NAME, 3714 "Expected CRL_DIST_POINT_NO_NAME, got %d\n", 3715 point->DistPointName.dwDistPointNameChoice); 3716 ok(point->ReasonFlags.cbData == sizeof(crlReason), 3717 "Expected reason length\n"); 3718 ok(!memcmp(point->ReasonFlags.pbData, &crlReason, sizeof(crlReason)), 3719 "Unexpected reason\n"); 3720 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n"); 3721 LocalFree(buf); 3722 } 3723 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, 3724 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2, 3725 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 3726 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3727 if (ret) 3728 { 3729 info = (PCRL_DIST_POINTS_INFO)buf; 3730 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT), 3731 "Wrong size %d\n", size); 3732 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n", 3733 info->cDistPoint); 3734 point = info->rgDistPoint; 3735 ok(point->DistPointName.dwDistPointNameChoice == 3736 CRL_DIST_POINT_FULL_NAME, 3737 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n", 3738 point->DistPointName.dwDistPointNameChoice); 3739 ok(U(point->DistPointName).FullName.cAltEntry == 1, 3740 "Expected 1 name entry, got %d\n", 3741 U(point->DistPointName).FullName.cAltEntry); 3742 entry = U(point->DistPointName).FullName.rgAltEntry; 3743 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL, 3744 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice); 3745 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n"); 3746 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n"); 3747 ok(point->CRLIssuer.cAltEntry == 1, 3748 "Expected 1 issuer entry, got %d\n", point->CRLIssuer.cAltEntry); 3749 entry = point->CRLIssuer.rgAltEntry; 3750 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL, 3751 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice); 3752 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n"); 3753 LocalFree(buf); 3754 } 3755 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, 3756 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2, 0, 3757 NULL, NULL, &size); 3758 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3759 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); 3760 if (buf) 3761 { 3762 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, 3763 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2, 0, 3764 NULL, buf, &size); 3765 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3766 HeapFree(GetProcessHeap(), 0, buf); 3767 } 3768 } 3769 3770 static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff }; 3771 static const BYTE emptyNameIDP[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 }; 3772 static const BYTE urlIDP[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68, 3773 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72, 3774 0x67 }; 3775 3776 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding) 3777 { 3778 BOOL ret; 3779 BYTE *buf = NULL; 3780 DWORD size = 0; 3781 CRL_ISSUING_DIST_POINT point = { { 0 } }; 3782 CERT_ALT_NAME_ENTRY entry; 3783 3784 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, NULL, 3785 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3786 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 3787 { 3788 skip("no X509_ISSUING_DIST_POINT encode support\n"); 3789 return; 3790 } 3791 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 3792 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError()); 3793 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point, 3794 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3795 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3796 if (ret) 3797 { 3798 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size); 3799 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n"); 3800 LocalFree(buf); 3801 } 3802 /* nonsensical flags */ 3803 point.fOnlyContainsUserCerts = TRUE; 3804 point.fOnlyContainsCACerts = TRUE; 3805 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point, 3806 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3807 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3808 if (ret) 3809 { 3810 ok(size == sizeof(badFlagsIDP), "Unexpected size %d\n", size); 3811 ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n"); 3812 LocalFree(buf); 3813 } 3814 /* unimplemented name type */ 3815 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE; 3816 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_ISSUER_RDN_NAME; 3817 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point, 3818 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3819 ok(!ret && GetLastError() == E_INVALIDARG, 3820 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 3821 /* empty name */ 3822 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME; 3823 U(point.DistPointName).FullName.cAltEntry = 0; 3824 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point, 3825 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3826 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3827 if (ret) 3828 { 3829 ok(size == sizeof(emptyNameIDP), "Unexpected size %d\n", size); 3830 ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n"); 3831 LocalFree(buf); 3832 } 3833 /* name with URL entry */ 3834 entry.dwAltNameChoice = CERT_ALT_NAME_URL; 3835 U(entry).pwszURL = (LPWSTR)url; 3836 U(point.DistPointName).FullName.cAltEntry = 1; 3837 U(point.DistPointName).FullName.rgAltEntry = &entry; 3838 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point, 3839 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 3840 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 3841 if (ret) 3842 { 3843 ok(size == sizeof(urlIDP), "Unexpected size %d\n", size); 3844 ok(!memcmp(buf, urlIDP, size), "Unexpected value\n"); 3845 LocalFree(buf); 3846 } 3847 } 3848 3849 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY *expected, 3850 const CERT_ALT_NAME_ENTRY *got) 3851 { 3852 ok(expected->dwAltNameChoice == got->dwAltNameChoice, 3853 "Expected name choice %d, got %d\n", expected->dwAltNameChoice, 3854 got->dwAltNameChoice); 3855 if (expected->dwAltNameChoice == got->dwAltNameChoice) 3856 { 3857 switch (got->dwAltNameChoice) 3858 { 3859 case CERT_ALT_NAME_RFC822_NAME: 3860 case CERT_ALT_NAME_DNS_NAME: 3861 case CERT_ALT_NAME_EDI_PARTY_NAME: 3862 case CERT_ALT_NAME_URL: 3863 case CERT_ALT_NAME_REGISTERED_ID: 3864 ok((!U(*expected).pwszURL && !U(*got).pwszURL) || 3865 (!U(*expected).pwszURL && !lstrlenW(U(*got).pwszURL)) || 3866 (!U(*got).pwszURL && !lstrlenW(U(*expected).pwszURL)) || 3867 !lstrcmpW(U(*expected).pwszURL, U(*got).pwszURL), 3868 "Unexpected name\n"); 3869 break; 3870 case CERT_ALT_NAME_X400_ADDRESS: 3871 case CERT_ALT_NAME_DIRECTORY_NAME: 3872 case CERT_ALT_NAME_IP_ADDRESS: 3873 ok(U(*got).IPAddress.cbData == U(*expected).IPAddress.cbData, 3874 "Unexpected IP address length %d\n", U(*got).IPAddress.cbData); 3875 ok(!memcmp(U(*got).IPAddress.pbData, U(*expected).IPAddress.pbData, 3876 U(*got).IPAddress.cbData), "Unexpected value\n"); 3877 break; 3878 } 3879 } 3880 } 3881 3882 static void compareAltNameInfo(const CERT_ALT_NAME_INFO *expected, 3883 const CERT_ALT_NAME_INFO *got) 3884 { 3885 DWORD i; 3886 3887 ok(expected->cAltEntry == got->cAltEntry, "Expected %d entries, got %d\n", 3888 expected->cAltEntry, got->cAltEntry); 3889 for (i = 0; i < min(expected->cAltEntry, got->cAltEntry); i++) 3890 compareAltNameEntry(&expected->rgAltEntry[i], &got->rgAltEntry[i]); 3891 } 3892 3893 static void compareDistPointName(const CRL_DIST_POINT_NAME *expected, 3894 const CRL_DIST_POINT_NAME *got) 3895 { 3896 ok(got->dwDistPointNameChoice == expected->dwDistPointNameChoice, 3897 "Unexpected name choice %d\n", got->dwDistPointNameChoice); 3898 if (got->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME) 3899 compareAltNameInfo(&(U(*expected).FullName), &(U(*got).FullName)); 3900 } 3901 3902 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT *expected, 3903 const CRL_ISSUING_DIST_POINT *got) 3904 { 3905 compareDistPointName(&expected->DistPointName, &got->DistPointName); 3906 ok(got->fOnlyContainsUserCerts == expected->fOnlyContainsUserCerts, 3907 "Unexpected fOnlyContainsUserCerts\n"); 3908 ok(got->fOnlyContainsCACerts == expected->fOnlyContainsCACerts, 3909 "Unexpected fOnlyContainsCACerts\n"); 3910 ok(got->OnlySomeReasonFlags.cbData == expected->OnlySomeReasonFlags.cbData, 3911 "Unexpected reason flags\n"); 3912 ok(got->fIndirectCRL == expected->fIndirectCRL, 3913 "Unexpected fIndirectCRL\n"); 3914 } 3915 3916 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding) 3917 { 3918 BOOL ret; 3919 BYTE *buf = NULL; 3920 DWORD size = 0; 3921 CRL_ISSUING_DIST_POINT point = { { 0 } }; 3922 3923 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, 3924 emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, 3925 &buf, &size); 3926 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 3927 { 3928 skip("no X509_ISSUING_DIST_POINT decode support\n"); 3929 return; 3930 } 3931 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3932 if (ret) 3933 { 3934 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf); 3935 LocalFree(buf); 3936 } 3937 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, 3938 badFlagsIDP, badFlagsIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, 3939 &buf, &size); 3940 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3941 if (ret) 3942 { 3943 point.fOnlyContainsUserCerts = point.fOnlyContainsCACerts = TRUE; 3944 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf); 3945 LocalFree(buf); 3946 } 3947 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, 3948 emptyNameIDP, emptyNameIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, 3949 &buf, &size); 3950 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3951 if (ret) 3952 { 3953 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE; 3954 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME; 3955 U(point.DistPointName).FullName.cAltEntry = 0; 3956 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf); 3957 LocalFree(buf); 3958 } 3959 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, 3960 urlIDP, urlIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 3961 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 3962 if (ret) 3963 { 3964 CERT_ALT_NAME_ENTRY entry; 3965 3966 entry.dwAltNameChoice = CERT_ALT_NAME_URL; 3967 U(entry).pwszURL = (LPWSTR)url; 3968 U(point.DistPointName).FullName.cAltEntry = 1; 3969 U(point.DistPointName).FullName.rgAltEntry = &entry; 3970 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf); 3971 LocalFree(buf); 3972 } 3973 } 3974 3975 static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f, 3976 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 3977 0x30, 0x5a }; 3978 static const BYTE v2CRL[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 3979 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 3980 0x30, 0x30, 0x30, 0x30, 0x5a }; 3981 static const BYTE v1CRLWithIssuer[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00, 3982 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 3983 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31, 3984 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 3985 0x5a }; 3986 static const BYTE v1CRLWithIssuerAndEmptyEntry[] = { 0x30, 0x43, 0x30, 0x02, 3987 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 3988 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 3989 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 3990 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36, 3991 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a }; 3992 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06, 3993 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 3994 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 3995 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 3996 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36, 3997 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a }; 3998 static const BYTE v1CRLWithEntryExt[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30, 3999 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61, 4000 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, 4001 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01, 4002 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30, 4003 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff, 4004 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 }; 4005 static const BYTE v1CRLWithExt[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15, 4006 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e, 4007 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30, 4008 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01, 4009 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, 4010 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01, 4011 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 }; 4012 static const BYTE v2CRLWithExt[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06, 4013 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a, 4014 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31, 4015 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14, 4016 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30, 4017 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d, 4018 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 }; 4019 4020 static void test_encodeCRLToBeSigned(DWORD dwEncoding) 4021 { 4022 BOOL ret; 4023 BYTE *buf = NULL; 4024 DWORD size = 0; 4025 CRL_INFO info = { 0 }; 4026 CRL_ENTRY entry = { { 0 }, { 0 }, 0, 0 }; 4027 4028 /* Test with a V1 CRL */ 4029 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info, 4030 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 4031 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */), 4032 "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 4033 if (ret) 4034 { 4035 ok(size == sizeof(v1CRL), "Wrong size %d\n", size); 4036 ok(!memcmp(buf, v1CRL, size), "Got unexpected value\n"); 4037 LocalFree(buf); 4038 } 4039 /* Test v2 CRL */ 4040 info.dwVersion = CRL_V2; 4041 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info, 4042 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 4043 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */), 4044 "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 4045 if (ret) 4046 { 4047 ok(size == v2CRL[1] + 2, "Expected size %d, got %d\n", 4048 v2CRL[1] + 2, size); 4049 ok(!memcmp(buf, v2CRL, size), "Got unexpected value\n"); 4050 LocalFree(buf); 4051 } 4052 /* v1 CRL with a name */ 4053 info.dwVersion = CRL_V1; 4054 info.Issuer.cbData = sizeof(encodedCommonName); 4055 info.Issuer.pbData = (BYTE *)encodedCommonName; 4056 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info, 4057 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 4058 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 4059 if (ret) 4060 { 4061 ok(size == sizeof(v1CRLWithIssuer), "Wrong size %d\n", size); 4062 ok(!memcmp(buf, v1CRLWithIssuer, size), "Got unexpected value\n"); 4063 LocalFree(buf); 4064 } 4065 if (0) 4066 { 4067 /* v1 CRL with a name and a NULL entry pointer (crashes on win9x) */ 4068 info.cCRLEntry = 1; 4069 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info, 4070 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 4071 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 4072 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError()); 4073 } 4074 /* now set an empty entry */ 4075 info.cCRLEntry = 1; 4076 info.rgCRLEntry = &entry; 4077 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info, 4078 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 4079 if (ret) 4080 { 4081 ok(size == sizeof(v1CRLWithIssuerAndEmptyEntry), 4082 "Wrong size %d\n", size); 4083 ok(!memcmp(buf, v1CRLWithIssuerAndEmptyEntry, size), 4084 "Got unexpected value\n"); 4085 LocalFree(buf); 4086 } 4087 /* an entry with a serial number */ 4088 entry.SerialNumber.cbData = sizeof(serialNum); 4089 entry.SerialNumber.pbData = (BYTE *)serialNum; 4090 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info, 4091 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 4092 if (ret) 4093 { 4094 ok(size == sizeof(v1CRLWithIssuerAndEntry), 4095 "Wrong size %d\n", size); 4096 ok(!memcmp(buf, v1CRLWithIssuerAndEntry, size), 4097 "Got unexpected value\n"); 4098 LocalFree(buf); 4099 } 4100 /* an entry with an extension */ 4101 entry.cExtension = 1; 4102 entry.rgExtension = &criticalExt; 4103 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info, 4104 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 4105 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 4106 if (ret) 4107 { 4108 ok(size == sizeof(v1CRLWithEntryExt), "Wrong size %d\n", size); 4109 ok(!memcmp(buf, v1CRLWithEntryExt, size), "Got unexpected value\n"); 4110 LocalFree(buf); 4111 } 4112 /* a CRL with an extension */ 4113 entry.cExtension = 0; 4114 info.cExtension = 1; 4115 info.rgExtension = &criticalExt; 4116 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info, 4117 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 4118 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 4119 if (ret) 4120 { 4121 ok(size == sizeof(v1CRLWithExt), "Wrong size %d\n", size); 4122 ok(!memcmp(buf, v1CRLWithExt, size), "Got unexpected value\n"); 4123 LocalFree(buf); 4124 } 4125 /* a v2 CRL with an extension, this time non-critical */ 4126 info.dwVersion = CRL_V2; 4127 info.rgExtension = &nonCriticalExt; 4128 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info, 4129 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 4130 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 4131 if (ret) 4132 { 4133 ok(size == sizeof(v2CRLWithExt), "Wrong size %d\n", size); 4134 ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n"); 4135 LocalFree(buf); 4136 } 4137 } 4138 4139 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01, 4140 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 4141 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06, 4142 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 4143 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 4144 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 4145 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65, 4146 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72, 4147 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 4148 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43, 4149 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30, 4150 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33, 4151 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51, 4152 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99, 4153 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31, 4154 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0, 4155 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30, 4156 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30, 4157 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75, 4158 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33, 4159 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30, 4160 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06, 4161 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06, 4162 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03, 4163 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88, 4164 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd, 4165 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf, 4166 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46, 4167 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f, 4168 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75, 4169 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f, 4170 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82, 4171 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07, 4172 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c, 4173 0xcd }; 4174 static const BYTE verisignCRLWithLotsOfEntries[] = { 4175 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, 4176 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06, 4177 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31, 4178 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53, 4179 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03, 4180 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43, 4181 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77, 4182 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20, 4183 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30, 4184 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35, 4185 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3, 4186 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32, 4187 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10, 4188 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13, 4189 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38, 4190 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16, 4191 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31, 4192 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94, 4193 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32, 4194 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10, 4195 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67, 4196 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30, 4197 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87, 4198 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30, 4199 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f, 4200 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32, 4201 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10, 4202 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac, 4203 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31, 4204 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee, 4205 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31, 4206 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37, 4207 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32, 4208 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10, 4209 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c, 4210 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34, 4211 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11, 4212 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30, 4213 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5, 4214 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32, 4215 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10, 4216 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d, 4217 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39, 4218 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70, 4219 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30, 4220 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5, 4221 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33, 4222 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10, 4223 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39, 4224 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30, 4225 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98, 4226 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32, 4227 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4, 4228 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32, 4229 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10, 4230 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1, 4231 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32, 4232 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05, 4233 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31, 4234 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32, 4235 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32, 4236 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10, 4237 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7, 4238 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31, 4239 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79, 4240 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30, 4241 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4, 4242 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32, 4243 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10, 4244 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a, 4245 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35, 4246 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d, 4247 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31, 4248 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b, 4249 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32, 4250 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10, 4251 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40, 4252 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37, 4253 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6, 4254 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31, 4255 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28, 4256 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32, 4257 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10, 4258 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65, 4259 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39, 4260 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2, 4261 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32, 4262 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f, 4263 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32, 4264 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10, 4265 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21, 4266 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36, 4267 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33, 4268 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30, 4269 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2, 4270 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32, 4271 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10, 4272 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc, 4273 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33, 4274 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8, 4275 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31, 4276 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48, 4277 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32, 4278 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10, 4279 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40, 4280 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34, 4281 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54, 4282 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30, 4283 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6, 4284 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32, 4285 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10, 4286 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd, 4287 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32, 4288 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9, 4289 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31, 4290 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd, 4291 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32, 4292 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10, 4293 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5, 4294 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31, 4295 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb, 4296 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30, 4297 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5, 4298 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32, 4299 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10, 4300 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45, 4301 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32, 4302 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf, 4303 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35, 4304 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88, 4305 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30, 4306 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20, 4307 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92, 4308 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a, 4309 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45, 4310 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33, 4311 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9, 4312 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30, 4313 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22, 4314 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a, 4315 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a, 4316 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e, 4317 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30, 4318 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f, 4319 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30, 4320 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25, 4321 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0, 4322 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a, 4323 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84, 4324 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31, 4325 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec, 4326 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30, 4327 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27, 4328 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16, 4329 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a, 4330 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81, 4331 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31, 4332 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e, 4333 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30, 4334 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29, 4335 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59, 4336 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a, 4337 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9, 4338 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38, 4339 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3, 4340 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30, 4341 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a, 4342 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1, 4343 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a, 4344 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f, 4345 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30, 4346 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71, 4347 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30, 4348 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c, 4349 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85, 4350 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a, 4351 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b, 4352 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33, 4353 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92, 4354 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30, 4355 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d, 4356 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e, 4357 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a, 4358 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13, 4359 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37, 4360 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01, 4361 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30, 4362 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e, 4363 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3, 4364 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a, 4365 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70, 4366 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31, 4367 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20, 4368 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30, 4369 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f, 4370 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c, 4371 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a, 4372 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f, 4373 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33, 4374 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3, 4375 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30, 4376 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30, 4377 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b, 4378 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a, 4379 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0, 4380 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37, 4381 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63, 4382 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30, 4383 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32, 4384 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09, 4385 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a, 4386 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b, 4387 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37, 4388 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61, 4389 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30, 4390 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34, 4391 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe, 4392 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a, 4393 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30, 4394 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31, 4395 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85, 4396 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30, 4397 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37, 4398 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4, 4399 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a, 4400 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55, 4401 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30, 4402 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36, 4403 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30, 4404 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a, 4405 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d, 4406 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a, 4407 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f, 4408 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33, 4409 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97, 4410 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30, 4411 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b, 4412 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4, 4413 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a, 4414 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76, 4415 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30, 4416 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a, 4417 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30, 4418 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c, 4419 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd, 4420 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a, 4421 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae, 4422 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39, 4423 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39, 4424 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31, 4425 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d, 4426 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80, 4427 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a, 4428 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b, 4429 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31, 4430 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd, 4431 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30, 4432 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41, 4433 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e, 4434 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a, 4435 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93, 4436 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32, 4437 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28, 4438 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30, 4439 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42, 4440 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c, 4441 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a, 4442 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74, 4443 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36, 4444 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c, 4445 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30, 4446 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45, 4447 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83, 4448 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a, 4449 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12, 4450 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36, 4451 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98, 4452 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30, 4453 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47, 4454 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75, 4455 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a, 4456 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b, 4457 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34, 4458 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81, 4459 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30, 4460 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49, 4461 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51, 4462 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a, 4463 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53, 4464 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31, 4465 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5, 4466 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30, 4467 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c, 4468 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd, 4469 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a, 4470 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37, 4471 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39, 4472 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9, 4473 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30, 4474 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d, 4475 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32, 4476 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a, 4477 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1, 4478 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30, 4479 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86, 4480 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30, 4481 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50, 4482 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82, 4483 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a, 4484 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03, 4485 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30, 4486 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b, 4487 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30, 4488 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52, 4489 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f, 4490 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a, 4491 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69, 4492 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31, 4493 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c, 4494 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30, 4495 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57, 4496 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a, 4497 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a, 4498 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68, 4499 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34, 4500 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62, 4501 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30, 4502 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58, 4503 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d, 4504 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a, 4505 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25, 4506 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37, 4507 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3, 4508 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30, 4509 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59, 4510 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd, 4511 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a, 4512 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb, 4513 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30, 4514 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9, 4515 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30, 4516 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a, 4517 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d, 4518 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a, 4519 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58, 4520 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37, 4521 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3, 4522 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30, 4523 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b, 4524 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e, 4525 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a, 4526 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd, 4527 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35, 4528 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1, 4529 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31, 4530 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e, 4531 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca, 4532 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a, 4533 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a, 4534 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35, 4535 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd, 4536 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30, 4537 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f, 4538 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2, 4539 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a, 4540 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5, 4541 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36, 4542 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5, 4543 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30, 4544 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60, 4545 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4, 4546 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a, 4547 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09, 4548 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37, 4549 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83, 4550 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30, 4551 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60, 4552 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2, 4553 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a, 4554 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70, 4555 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39, 4556 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17, 4557 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30, 4558 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61, 4559 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97, 4560 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a, 4561 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd, 4562 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38, 4563 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82, 4564 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30, 4565 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62, 4566 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2, 4567 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a, 4568 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee, 4569 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36, 4570 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d, 4571 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30, 4572 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63, 4573 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86, 4574 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a, 4575 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3, 4576 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31, 4577 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22, 4578 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31, 4579 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65, 4580 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7, 4581 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a, 4582 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e, 4583 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37, 4584 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7, 4585 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30, 4586 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67, 4587 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0, 4588 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a, 4589 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0, 4590 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31, 4591 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04, 4592 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30, 4593 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69, 4594 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16, 4595 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a, 4596 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6, 4597 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39, 4598 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9, 4599 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31, 4600 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b, 4601 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53, 4602 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a, 4603 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e, 4604 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34, 4605 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a, 4606 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30, 4607 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d, 4608 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c, 4609 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a, 4610 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16, 4611 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32, 4612 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae, 4613 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30, 4614 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f, 4615 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1, 4616 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a, 4617 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c, 4618 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30, 4619 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5, 4620 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30, 4621 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70, 4622 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48, 4623 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a, 4624 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8, 4625 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39, 4626 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b, 4627 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30, 4628 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72, 4629 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39, 4630 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a, 4631 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39, 4632 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33, 4633 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17, 4634 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30, 4635 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75, 4636 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd, 4637 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a, 4638 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd, 4639 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38, 4640 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde, 4641 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30, 4642 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76, 4643 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03, 4644 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a, 4645 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d, 4646 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31, 4647 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93, 4648 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30, 4649 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78, 4650 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51, 4651 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a, 4652 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10, 4653 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38, 4654 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f, 4655 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30, 4656 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78, 4657 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67, 4658 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a, 4659 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79, 4660 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36, 4661 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02, 4662 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30, 4663 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b, 4664 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea, 4665 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a, 4666 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc, 4667 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30, 4668 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5, 4669 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30, 4670 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f, 4671 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b, 4672 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a, 4673 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00, 4674 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2, 4675 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08, 4676 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84, 4677 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68, 4678 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c, 4679 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f, 4680 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43, 4681 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c, 4682 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 }; 4683 4684 static void test_decodeCRLToBeSigned(DWORD dwEncoding) 4685 { 4686 static const BYTE *corruptCRLs[] = { v1CRL, v2CRL }; 4687 BOOL ret; 4688 BYTE *buf = NULL; 4689 DWORD size = 0, i; 4690 4691 for (i = 0; i < sizeof(corruptCRLs) / sizeof(corruptCRLs[0]); i++) 4692 { 4693 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, 4694 corruptCRLs[i], corruptCRLs[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, 4695 &buf, &size); 4696 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT || 4697 GetLastError() == OSS_DATA_ERROR /* Win9x */), 4698 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n", 4699 GetLastError()); 4700 } 4701 /* at a minimum, a CRL must contain an issuer: */ 4702 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, 4703 v1CRLWithIssuer, v1CRLWithIssuer[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, 4704 &buf, &size); 4705 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 4706 if (ret) 4707 { 4708 CRL_INFO *info = (CRL_INFO *)buf; 4709 4710 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size); 4711 ok(info->cCRLEntry == 0, "Expected 0 CRL entries, got %d\n", 4712 info->cCRLEntry); 4713 ok(info->Issuer.cbData == sizeof(encodedCommonName), 4714 "Wrong issuer size %d\n", info->Issuer.cbData); 4715 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData), 4716 "Unexpected issuer\n"); 4717 LocalFree(buf); 4718 } 4719 /* check decoding with an empty CRL entry */ 4720 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, 4721 v1CRLWithIssuerAndEmptyEntry, v1CRLWithIssuerAndEmptyEntry[1] + 2, 4722 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 4723 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT || 4724 GetLastError() == OSS_DATA_ERROR /* Win9x */ || 4725 GetLastError() == CRYPT_E_BAD_ENCODE /* Win8 */), 4726 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n", 4727 GetLastError()); 4728 /* with a real CRL entry */ 4729 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, 4730 v1CRLWithIssuerAndEntry, v1CRLWithIssuerAndEntry[1] + 2, 4731 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 4732 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 4733 if (ret) 4734 { 4735 CRL_INFO *info = (CRL_INFO *)buf; 4736 CRL_ENTRY *entry; 4737 4738 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size); 4739 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n", 4740 info->cCRLEntry); 4741 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n"); 4742 entry = info->rgCRLEntry; 4743 ok(entry->SerialNumber.cbData == 1, 4744 "Expected serial number size 1, got %d\n", 4745 entry->SerialNumber.cbData); 4746 ok(*entry->SerialNumber.pbData == *serialNum, 4747 "Expected serial number %d, got %d\n", *serialNum, 4748 *entry->SerialNumber.pbData); 4749 ok(info->Issuer.cbData == sizeof(encodedCommonName), 4750 "Wrong issuer size %d\n", info->Issuer.cbData); 4751 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData), 4752 "Unexpected issuer\n"); 4753 LocalFree(buf); 4754 } 4755 /* a real CRL from verisign that has extensions */ 4756 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, 4757 verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG, 4758 NULL, &buf, &size); 4759 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 4760 if (ret) 4761 { 4762 CRL_INFO *info = (CRL_INFO *)buf; 4763 4764 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size); 4765 ok(info->cCRLEntry == 3, "Expected 3 CRL entries, got %d\n", 4766 info->cCRLEntry); 4767 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n"); 4768 ok(info->cExtension == 2, "Expected 2 extensions, got %d\n", 4769 info->cExtension); 4770 LocalFree(buf); 4771 } 4772 /* another real CRL from verisign that has lots of entries */ 4773 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, 4774 verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries), 4775 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 4776 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 4777 if (ret) 4778 { 4779 CRL_INFO *info = (CRL_INFO *)buf; 4780 4781 ok(size >= sizeof(CRL_INFO), "Got size %d\n", size); 4782 ok(info->cCRLEntry == 209, "Expected 209 CRL entries, got %d\n", 4783 info->cCRLEntry); 4784 ok(info->cExtension == 0, "Expected 0 extensions, got %d\n", 4785 info->cExtension); 4786 LocalFree(buf); 4787 } 4788 /* and finally, with an extension */ 4789 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, 4790 v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG, 4791 NULL, &buf, &size); 4792 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 4793 if (ret) 4794 { 4795 CRL_INFO *info = (CRL_INFO *)buf; 4796 CRL_ENTRY *entry; 4797 4798 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size); 4799 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n", 4800 info->cCRLEntry); 4801 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n"); 4802 entry = info->rgCRLEntry; 4803 ok(entry->SerialNumber.cbData == 1, 4804 "Expected serial number size 1, got %d\n", 4805 entry->SerialNumber.cbData); 4806 ok(*entry->SerialNumber.pbData == *serialNum, 4807 "Expected serial number %d, got %d\n", *serialNum, 4808 *entry->SerialNumber.pbData); 4809 ok(info->Issuer.cbData == sizeof(encodedCommonName), 4810 "Wrong issuer size %d\n", info->Issuer.cbData); 4811 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData), 4812 "Unexpected issuer\n"); 4813 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n", 4814 info->cExtension); 4815 LocalFree(buf); 4816 } 4817 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, 4818 v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG, 4819 NULL, &buf, &size); 4820 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 4821 if (ret) 4822 { 4823 CRL_INFO *info = (CRL_INFO *)buf; 4824 4825 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n", 4826 info->cExtension); 4827 LocalFree(buf); 4828 } 4829 } 4830 4831 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING, 4832 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA }; 4833 static const BYTE encodedUsage[] = { 4834 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03, 4835 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09, 4836 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 }; 4837 4838 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding) 4839 { 4840 BOOL ret; 4841 BYTE *buf = NULL; 4842 DWORD size = 0; 4843 CERT_ENHKEY_USAGE usage; 4844 4845 /* Test with empty usage */ 4846 usage.cUsageIdentifier = 0; 4847 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage, 4848 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 4849 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 4850 if (ret) 4851 { 4852 ok(size == sizeof(emptySequence), "Wrong size %d\n", size); 4853 ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n"); 4854 LocalFree(buf); 4855 } 4856 /* Test with a few usages */ 4857 usage.cUsageIdentifier = sizeof(keyUsages) / sizeof(keyUsages[0]); 4858 usage.rgpszUsageIdentifier = (LPSTR *)keyUsages; 4859 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage, 4860 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 4861 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 4862 if (ret) 4863 { 4864 ok(size == sizeof(encodedUsage), "Wrong size %d\n", size); 4865 ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n"); 4866 LocalFree(buf); 4867 } 4868 } 4869 4870 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding) 4871 { 4872 BOOL ret; 4873 LPBYTE buf = NULL; 4874 DWORD size = 0; 4875 4876 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, 4877 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL, 4878 &buf, &size); 4879 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 4880 if (ret) 4881 { 4882 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf; 4883 4884 ok(size >= sizeof(CERT_ENHKEY_USAGE), 4885 "Wrong size %d\n", size); 4886 ok(usage->cUsageIdentifier == 0, "Expected 0 CRL entries, got %d\n", 4887 usage->cUsageIdentifier); 4888 LocalFree(buf); 4889 } 4890 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, 4891 encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL, 4892 &buf, &size); 4893 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 4894 if (ret) 4895 { 4896 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf; 4897 DWORD i; 4898 4899 ok(size >= sizeof(CERT_ENHKEY_USAGE), 4900 "Wrong size %d\n", size); 4901 ok(usage->cUsageIdentifier == sizeof(keyUsages) / sizeof(keyUsages[0]), 4902 "Wrong CRL entries count %d\n", usage->cUsageIdentifier); 4903 for (i = 0; i < usage->cUsageIdentifier; i++) 4904 ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]), 4905 "Expected OID %s, got %s\n", keyUsages[i], 4906 usage->rgpszUsageIdentifier[i]); 4907 LocalFree(buf); 4908 } 4909 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, 4910 encodedUsage, sizeof(encodedUsage), 0, NULL, NULL, &size); 4911 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 4912 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); 4913 if (buf) 4914 { 4915 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, 4916 encodedUsage, sizeof(encodedUsage), 0, NULL, buf, &size); 4917 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 4918 HeapFree(GetProcessHeap(), 0, buf); 4919 } 4920 } 4921 4922 static BYTE keyId[] = { 1,2,3,4 }; 4923 static const BYTE authorityKeyIdWithId[] = { 4924 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 }; 4925 static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15, 4926 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e, 4927 0x20,0x4c,0x61,0x6e,0x67,0x00 }; 4928 static const BYTE authorityKeyIdWithSerial[] = { 0x30,0x03,0x82,0x01,0x01 }; 4929 4930 static void test_encodeAuthorityKeyId(DWORD dwEncoding) 4931 { 4932 CERT_AUTHORITY_KEY_ID_INFO info = { { 0 } }; 4933 BOOL ret; 4934 BYTE *buf = NULL; 4935 DWORD size = 0; 4936 4937 /* Test with empty id */ 4938 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info, 4939 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 4940 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 4941 if (ret) 4942 { 4943 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size); 4944 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n"); 4945 LocalFree(buf); 4946 } 4947 /* With just a key id */ 4948 info.KeyId.cbData = sizeof(keyId); 4949 info.KeyId.pbData = keyId; 4950 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info, 4951 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 4952 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 4953 if (ret) 4954 { 4955 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", size); 4956 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n"); 4957 LocalFree(buf); 4958 } 4959 /* With just an issuer */ 4960 info.KeyId.cbData = 0; 4961 info.CertIssuer.cbData = sizeof(encodedCommonName); 4962 info.CertIssuer.pbData = (BYTE *)encodedCommonName; 4963 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info, 4964 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 4965 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 4966 if (ret) 4967 { 4968 ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %d\n", 4969 size); 4970 ok(!memcmp(buf, authorityKeyIdWithIssuer, size), "Unexpected value\n"); 4971 LocalFree(buf); 4972 } 4973 /* With just a serial number */ 4974 info.CertIssuer.cbData = 0; 4975 info.CertSerialNumber.cbData = sizeof(serialNum); 4976 info.CertSerialNumber.pbData = (BYTE *)serialNum; 4977 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info, 4978 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 4979 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 4980 if (ret) 4981 { 4982 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n", 4983 size); 4984 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n"); 4985 LocalFree(buf); 4986 } 4987 } 4988 4989 static void test_decodeAuthorityKeyId(DWORD dwEncoding) 4990 { 4991 BOOL ret; 4992 LPBYTE buf = NULL; 4993 DWORD size = 0; 4994 4995 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, 4996 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL, 4997 &buf, &size); 4998 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 4999 if (ret) 5000 { 5001 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf; 5002 5003 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n", 5004 size); 5005 ok(info->KeyId.cbData == 0, "Expected no key id\n"); 5006 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n"); 5007 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n"); 5008 LocalFree(buf); 5009 } 5010 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, 5011 authorityKeyIdWithId, sizeof(authorityKeyIdWithId), 5012 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5013 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5014 if (ret) 5015 { 5016 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf; 5017 5018 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n", 5019 size); 5020 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n"); 5021 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)), 5022 "Unexpected key id\n"); 5023 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n"); 5024 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n"); 5025 LocalFree(buf); 5026 } 5027 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, 5028 authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer), 5029 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5030 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5031 if (ret) 5032 { 5033 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf; 5034 5035 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n", 5036 size); 5037 ok(info->KeyId.cbData == 0, "Expected no key id\n"); 5038 ok(info->CertIssuer.cbData == sizeof(encodedCommonName), 5039 "Unexpected issuer len\n"); 5040 ok(!memcmp(info->CertIssuer.pbData, encodedCommonName, 5041 sizeof(encodedCommonName)), "Unexpected issuer\n"); 5042 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n"); 5043 LocalFree(buf); 5044 } 5045 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, 5046 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial), 5047 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5048 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5049 if (ret) 5050 { 5051 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf; 5052 5053 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n", 5054 size); 5055 ok(info->KeyId.cbData == 0, "Expected no key id\n"); 5056 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n"); 5057 ok(info->CertSerialNumber.cbData == sizeof(serialNum), 5058 "Unexpected serial number len\n"); 5059 ok(!memcmp(info->CertSerialNumber.pbData, serialNum, sizeof(serialNum)), 5060 "Unexpected serial number\n"); 5061 LocalFree(buf); 5062 } 5063 } 5064 5065 static const BYTE authorityKeyIdWithIssuerUrl[] = { 0x30,0x15,0xa1,0x13,0x86, 5066 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e, 5067 0x6f,0x72,0x67 }; 5068 5069 static void test_encodeAuthorityKeyId2(DWORD dwEncoding) 5070 { 5071 CERT_AUTHORITY_KEY_ID2_INFO info = { { 0 } }; 5072 CERT_ALT_NAME_ENTRY entry = { 0 }; 5073 BOOL ret; 5074 BYTE *buf = NULL; 5075 DWORD size = 0; 5076 5077 /* Test with empty id */ 5078 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info, 5079 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5080 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5081 if (ret) 5082 { 5083 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size); 5084 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n"); 5085 LocalFree(buf); 5086 } 5087 /* With just a key id */ 5088 info.KeyId.cbData = sizeof(keyId); 5089 info.KeyId.pbData = keyId; 5090 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info, 5091 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5092 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5093 if (ret) 5094 { 5095 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", 5096 size); 5097 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n"); 5098 LocalFree(buf); 5099 } 5100 /* With a bogus issuer name */ 5101 info.KeyId.cbData = 0; 5102 info.AuthorityCertIssuer.cAltEntry = 1; 5103 info.AuthorityCertIssuer.rgAltEntry = &entry; 5104 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info, 5105 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5106 ok(!ret && GetLastError() == E_INVALIDARG, 5107 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 5108 /* With an issuer name */ 5109 entry.dwAltNameChoice = CERT_ALT_NAME_URL; 5110 U(entry).pwszURL = (LPWSTR)url; 5111 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info, 5112 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5113 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5114 if (ret) 5115 { 5116 ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %d\n", 5117 size); 5118 ok(!memcmp(buf, authorityKeyIdWithIssuerUrl, size), 5119 "Unexpected value\n"); 5120 LocalFree(buf); 5121 } 5122 /* With just a serial number */ 5123 info.AuthorityCertIssuer.cAltEntry = 0; 5124 info.AuthorityCertSerialNumber.cbData = sizeof(serialNum); 5125 info.AuthorityCertSerialNumber.pbData = (BYTE *)serialNum; 5126 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info, 5127 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5128 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5129 if (ret) 5130 { 5131 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n", 5132 size); 5133 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n"); 5134 LocalFree(buf); 5135 } 5136 } 5137 5138 static void test_decodeAuthorityKeyId2(DWORD dwEncoding) 5139 { 5140 BOOL ret; 5141 LPBYTE buf = NULL; 5142 DWORD size = 0; 5143 5144 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, 5145 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL, 5146 &buf, &size); 5147 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5148 if (ret) 5149 { 5150 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf; 5151 5152 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n", 5153 size); 5154 ok(info->KeyId.cbData == 0, "Expected no key id\n"); 5155 ok(info->AuthorityCertIssuer.cAltEntry == 0, 5156 "Expected no issuer name entries\n"); 5157 ok(info->AuthorityCertSerialNumber.cbData == 0, 5158 "Expected no serial number\n"); 5159 LocalFree(buf); 5160 } 5161 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, 5162 authorityKeyIdWithId, sizeof(authorityKeyIdWithId), 5163 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5164 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5165 if (ret) 5166 { 5167 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf; 5168 5169 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n", 5170 size); 5171 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n"); 5172 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)), 5173 "Unexpected key id\n"); 5174 ok(info->AuthorityCertIssuer.cAltEntry == 0, 5175 "Expected no issuer name entries\n"); 5176 ok(info->AuthorityCertSerialNumber.cbData == 0, 5177 "Expected no serial number\n"); 5178 LocalFree(buf); 5179 } 5180 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, 5181 authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl), 5182 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5183 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5184 if (ret) 5185 { 5186 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf; 5187 5188 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n", 5189 size); 5190 ok(info->KeyId.cbData == 0, "Expected no key id\n"); 5191 ok(info->AuthorityCertIssuer.cAltEntry == 1, 5192 "Expected 1 issuer entry, got %d\n", 5193 info->AuthorityCertIssuer.cAltEntry); 5194 ok(info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice == 5195 CERT_ALT_NAME_URL, "Expected CERT_ALT_NAME_URL, got %d\n", 5196 info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice); 5197 ok(!lstrcmpW(U(info->AuthorityCertIssuer.rgAltEntry[0]).pwszURL, 5198 url), "Unexpected URL\n"); 5199 ok(info->AuthorityCertSerialNumber.cbData == 0, 5200 "Expected no serial number\n"); 5201 LocalFree(buf); 5202 } 5203 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, 5204 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial), 5205 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5206 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5207 if (ret) 5208 { 5209 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf; 5210 5211 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n", 5212 size); 5213 ok(info->KeyId.cbData == 0, "Expected no key id\n"); 5214 ok(info->AuthorityCertIssuer.cAltEntry == 0, 5215 "Expected no issuer name entries\n"); 5216 ok(info->AuthorityCertSerialNumber.cbData == sizeof(serialNum), 5217 "Unexpected serial number len\n"); 5218 ok(!memcmp(info->AuthorityCertSerialNumber.pbData, serialNum, 5219 sizeof(serialNum)), "Unexpected serial number\n"); 5220 LocalFree(buf); 5221 } 5222 } 5223 5224 static const BYTE authorityInfoAccessWithUrl[] = { 5225 0x30,0x19,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a, 5226 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 }; 5227 static const BYTE authorityInfoAccessWithUrlAndIPAddr[] = { 5228 0x30,0x29,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a, 5229 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x0e,0x06, 5230 0x02,0x2d,0x06,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,0x01 }; 5231 5232 static void test_encodeAuthorityInfoAccess(DWORD dwEncoding) 5233 { 5234 static char oid1[] = "1.2.3"; 5235 static char oid2[] = "1.5.6"; 5236 BOOL ret; 5237 BYTE *buf = NULL; 5238 DWORD size = 0; 5239 CERT_ACCESS_DESCRIPTION accessDescription[2]; 5240 CERT_AUTHORITY_INFO_ACCESS aia; 5241 5242 memset(accessDescription, 0, sizeof(accessDescription)); 5243 aia.cAccDescr = 0; 5244 aia.rgAccDescr = NULL; 5245 /* Having no access descriptions is allowed */ 5246 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia, 5247 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5248 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5249 if (ret) 5250 { 5251 ok(size == sizeof(emptySequence), "unexpected size %d\n", size); 5252 ok(!memcmp(buf, emptySequence, size), "unexpected value\n"); 5253 LocalFree(buf); 5254 buf = NULL; 5255 } 5256 /* It can't have an empty access method */ 5257 aia.cAccDescr = 1; 5258 aia.rgAccDescr = accessDescription; 5259 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia, 5260 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5261 ok(!ret && (GetLastError() == E_INVALIDARG || 5262 GetLastError() == OSS_LIMITED /* Win9x */), 5263 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError()); 5264 /* It can't have an empty location */ 5265 accessDescription[0].pszAccessMethod = oid1; 5266 SetLastError(0xdeadbeef); 5267 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia, 5268 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5269 ok(!ret && GetLastError() == E_INVALIDARG, 5270 "expected E_INVALIDARG, got %08x\n", GetLastError()); 5271 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL; 5272 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url; 5273 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia, 5274 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5275 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5276 if (ret) 5277 { 5278 ok(size == sizeof(authorityInfoAccessWithUrl), "unexpected size %d\n", 5279 size); 5280 ok(!memcmp(buf, authorityInfoAccessWithUrl, size), 5281 "unexpected value\n"); 5282 LocalFree(buf); 5283 buf = NULL; 5284 } 5285 accessDescription[1].pszAccessMethod = oid2; 5286 accessDescription[1].AccessLocation.dwAltNameChoice = 5287 CERT_ALT_NAME_IP_ADDRESS; 5288 U(accessDescription[1].AccessLocation).IPAddress.cbData = 5289 sizeof(encodedIPAddr); 5290 U(accessDescription[1].AccessLocation).IPAddress.pbData = 5291 (LPBYTE)encodedIPAddr; 5292 aia.cAccDescr = 2; 5293 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia, 5294 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5295 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5296 if (ret) 5297 { 5298 ok(size == sizeof(authorityInfoAccessWithUrlAndIPAddr), 5299 "unexpected size %d\n", size); 5300 ok(!memcmp(buf, authorityInfoAccessWithUrlAndIPAddr, size), 5301 "unexpected value\n"); 5302 LocalFree(buf); 5303 buf = NULL; 5304 } 5305 } 5306 5307 static void compareAuthorityInfoAccess(LPCSTR header, 5308 const CERT_AUTHORITY_INFO_ACCESS *expected, 5309 const CERT_AUTHORITY_INFO_ACCESS *got) 5310 { 5311 DWORD i; 5312 5313 ok(expected->cAccDescr == got->cAccDescr, 5314 "%s: expected %d access descriptions, got %d\n", header, 5315 expected->cAccDescr, got->cAccDescr); 5316 for (i = 0; i < expected->cAccDescr; i++) 5317 { 5318 ok(!strcmp(expected->rgAccDescr[i].pszAccessMethod, 5319 got->rgAccDescr[i].pszAccessMethod), "%s[%d]: expected %s, got %s\n", 5320 header, i, expected->rgAccDescr[i].pszAccessMethod, 5321 got->rgAccDescr[i].pszAccessMethod); 5322 compareAltNameEntry(&expected->rgAccDescr[i].AccessLocation, 5323 &got->rgAccDescr[i].AccessLocation); 5324 } 5325 } 5326 5327 static void test_decodeAuthorityInfoAccess(DWORD dwEncoding) 5328 { 5329 static char oid1[] = "1.2.3"; 5330 static char oid2[] = "1.5.6"; 5331 BOOL ret; 5332 LPBYTE buf = NULL; 5333 DWORD size = 0; 5334 5335 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, 5336 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL, 5337 &buf, &size); 5338 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 5339 if (ret) 5340 { 5341 CERT_AUTHORITY_INFO_ACCESS aia = { 0, NULL }; 5342 5343 compareAuthorityInfoAccess("empty AIA", &aia, 5344 (CERT_AUTHORITY_INFO_ACCESS *)buf); 5345 LocalFree(buf); 5346 buf = NULL; 5347 } 5348 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, 5349 authorityInfoAccessWithUrl, sizeof(authorityInfoAccessWithUrl), 5350 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5351 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 5352 if (ret) 5353 { 5354 CERT_ACCESS_DESCRIPTION accessDescription; 5355 CERT_AUTHORITY_INFO_ACCESS aia; 5356 5357 accessDescription.pszAccessMethod = oid1; 5358 accessDescription.AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL; 5359 U(accessDescription.AccessLocation).pwszURL = (LPWSTR)url; 5360 aia.cAccDescr = 1; 5361 aia.rgAccDescr = &accessDescription; 5362 compareAuthorityInfoAccess("AIA with URL", &aia, 5363 (CERT_AUTHORITY_INFO_ACCESS *)buf); 5364 LocalFree(buf); 5365 buf = NULL; 5366 } 5367 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, 5368 authorityInfoAccessWithUrlAndIPAddr, 5369 sizeof(authorityInfoAccessWithUrlAndIPAddr), CRYPT_DECODE_ALLOC_FLAG, 5370 NULL, &buf, &size); 5371 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 5372 if (ret) 5373 { 5374 CERT_ACCESS_DESCRIPTION accessDescription[2]; 5375 CERT_AUTHORITY_INFO_ACCESS aia; 5376 5377 accessDescription[0].pszAccessMethod = oid1; 5378 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL; 5379 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url; 5380 accessDescription[1].pszAccessMethod = oid2; 5381 accessDescription[1].AccessLocation.dwAltNameChoice = 5382 CERT_ALT_NAME_IP_ADDRESS; 5383 U(accessDescription[1].AccessLocation).IPAddress.cbData = 5384 sizeof(encodedIPAddr); 5385 U(accessDescription[1].AccessLocation).IPAddress.pbData = 5386 (LPBYTE)encodedIPAddr; 5387 aia.cAccDescr = 2; 5388 aia.rgAccDescr = accessDescription; 5389 compareAuthorityInfoAccess("AIA with URL and IP addr", &aia, 5390 (CERT_AUTHORITY_INFO_ACCESS *)buf); 5391 LocalFree(buf); 5392 buf = NULL; 5393 } 5394 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, 5395 authorityInfoAccessWithUrlAndIPAddr, 5396 sizeof(authorityInfoAccessWithUrlAndIPAddr), 0, NULL, NULL, &size); 5397 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 5398 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); 5399 if (buf) 5400 { 5401 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, 5402 authorityInfoAccessWithUrlAndIPAddr, 5403 sizeof(authorityInfoAccessWithUrlAndIPAddr), 0, NULL, buf, &size); 5404 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 5405 HeapFree(GetProcessHeap(), 0, buf); 5406 } 5407 } 5408 5409 static const BYTE emptyCTL[] = { 5410 0x30,0x17,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30, 5411 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 }; 5412 static const BYTE emptyCTLWithVersion1[] = { 5413 0x30,0x1a,0x02,0x01,0x01,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, 5414 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 }; 5415 static const BYTE ctlWithUsageIdentifier[] = { 5416 0x30,0x1b,0x30,0x04,0x06,0x02,0x2a,0x03,0x18,0x0f,0x31,0x36,0x30,0x31,0x30, 5417 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 }; 5418 static const BYTE ctlWithListIdentifier[] = { 5419 0x30,0x1a,0x30,0x00,0x04,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, 5420 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 }; 5421 static const BYTE ctlWithSequenceNumber[] = { 5422 0x30,0x1a,0x30,0x00,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, 5423 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 }; 5424 static const BYTE ctlWithThisUpdate[] = { 5425 0x30,0x15,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31, 5426 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 }; 5427 static const BYTE ctlWithThisAndNextUpdate[] = { 5428 0x30,0x24,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31, 5429 0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31, 5430 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 }; 5431 static const BYTE ctlWithAlgId[] = { 5432 0x30,0x1b,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30, 5433 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 }; 5434 static const BYTE ctlWithBogusEntry[] = { 5435 0x30,0x29,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30, 5436 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x10,0x30,0x0e,0x04, 5437 0x01,0x01,0x31,0x09,0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,0x01 }; 5438 static const BYTE ctlWithOneEntry[] = { 5439 0x30,0x2a,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30, 5440 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x11,0x30,0x0f,0x04, 5441 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00 }; 5442 static const BYTE ctlWithTwoEntries[] = { 5443 0x30,0x41,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30, 5444 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x28,0x30,0x0f,0x04, 5445 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00,0x30, 5446 0x15,0x04,0x01,0x01,0x31,0x10,0x30,0x0e,0x06,0x02,0x2d,0x06,0x31,0x08,0x30, 5447 0x06,0x87,0x04,0x7f,0x00,0x00,0x01 }; 5448 5449 static void test_encodeCTL(DWORD dwEncoding) 5450 { 5451 static char oid1[] = "1.2.3"; 5452 static char oid2[] = "1.5.6"; 5453 char *pOid1 = oid1; 5454 BOOL ret; 5455 BYTE *buf = NULL; 5456 DWORD size = 0; 5457 CTL_INFO info; 5458 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 }; 5459 CTL_ENTRY ctlEntry[2]; 5460 CRYPT_ATTRIBUTE attr1, attr2; 5461 CRYPT_ATTR_BLOB value1, value2; 5462 5463 memset(&info, 0, sizeof(info)); 5464 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, 5465 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5466 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5467 if (ret) 5468 { 5469 ok(size == sizeof(emptyCTL), "unexpected size %d\n", size); 5470 ok(!memcmp(buf, emptyCTL, size), "unexpected value\n"); 5471 LocalFree(buf); 5472 buf = NULL; 5473 } 5474 info.dwVersion = 1; 5475 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, 5476 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5477 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5478 if (ret) 5479 { 5480 ok(size == sizeof(emptyCTLWithVersion1), "unexpected size %d\n", size); 5481 ok(!memcmp(buf, emptyCTLWithVersion1, size), "unexpected value\n"); 5482 LocalFree(buf); 5483 buf = NULL; 5484 } 5485 info.dwVersion = 0; 5486 info.SubjectUsage.cUsageIdentifier = 1; 5487 info.SubjectUsage.rgpszUsageIdentifier = &pOid1; 5488 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, 5489 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5490 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5491 if (ret) 5492 { 5493 ok(size == sizeof(ctlWithUsageIdentifier), "unexpected size %d\n", 5494 size); 5495 ok(!memcmp(buf, ctlWithUsageIdentifier, size), "unexpected value\n"); 5496 LocalFree(buf); 5497 buf = NULL; 5498 } 5499 info.SubjectUsage.cUsageIdentifier = 0; 5500 info.ListIdentifier.cbData = sizeof(serialNum); 5501 info.ListIdentifier.pbData = (LPBYTE)serialNum; 5502 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, 5503 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5504 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5505 if (ret) 5506 { 5507 ok(size == sizeof(ctlWithListIdentifier), "unexpected size %d\n", size); 5508 ok(!memcmp(buf, ctlWithListIdentifier, size), "unexpected value\n"); 5509 LocalFree(buf); 5510 buf = NULL; 5511 } 5512 info.ListIdentifier.cbData = 0; 5513 info.SequenceNumber.cbData = sizeof(serialNum); 5514 info.SequenceNumber.pbData = (LPBYTE)serialNum; 5515 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, 5516 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5517 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5518 if (ret) 5519 { 5520 ok(size == sizeof(ctlWithSequenceNumber), "unexpected size %d\n", 5521 size); 5522 ok(!memcmp(buf, ctlWithSequenceNumber, size), "unexpected value\n"); 5523 LocalFree(buf); 5524 buf = NULL; 5525 } 5526 info.SequenceNumber.cbData = 0; 5527 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate); 5528 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, 5529 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5530 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5531 if (ret) 5532 { 5533 ok(size == sizeof(ctlWithThisUpdate), "unexpected size %d\n", size); 5534 ok(!memcmp(buf, ctlWithThisUpdate, size), "unexpected value\n"); 5535 LocalFree(buf); 5536 buf = NULL; 5537 } 5538 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate); 5539 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, 5540 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5541 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5542 if (ret) 5543 { 5544 ok(size == sizeof(ctlWithThisAndNextUpdate), "unexpected size %d\n", 5545 size); 5546 ok(!memcmp(buf, ctlWithThisAndNextUpdate, size), "unexpected value\n"); 5547 LocalFree(buf); 5548 buf = NULL; 5549 } 5550 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0; 5551 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0; 5552 info.SubjectAlgorithm.pszObjId = oid2; 5553 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, 5554 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5555 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5556 if (ret) 5557 { 5558 ok(size == sizeof(ctlWithAlgId), "unexpected size %d\n", size); 5559 ok(!memcmp(buf, ctlWithAlgId, size), "unexpected value\n"); 5560 LocalFree(buf); 5561 buf = NULL; 5562 } 5563 /* The value is supposed to be asn.1 encoded, so this'll fail to decode 5564 * (see tests below) but it'll encode fine. 5565 */ 5566 info.SubjectAlgorithm.pszObjId = NULL; 5567 value1.cbData = sizeof(serialNum); 5568 value1.pbData = (LPBYTE)serialNum; 5569 attr1.pszObjId = oid1; 5570 attr1.cValue = 1; 5571 attr1.rgValue = &value1; 5572 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum); 5573 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum; 5574 ctlEntry[0].cAttribute = 1; 5575 ctlEntry[0].rgAttribute = &attr1; 5576 info.cCTLEntry = 1; 5577 info.rgCTLEntry = ctlEntry; 5578 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, 5579 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5580 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5581 if (ret) 5582 { 5583 ok(size == sizeof(ctlWithBogusEntry), "unexpected size %d\n", size); 5584 ok(!memcmp(buf, ctlWithBogusEntry, size), "unexpected value\n"); 5585 LocalFree(buf); 5586 buf = NULL; 5587 } 5588 value1.cbData = sizeof(emptySequence); 5589 value1.pbData = (LPBYTE)emptySequence; 5590 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, 5591 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5592 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5593 if (ret) 5594 { 5595 ok(size == sizeof(ctlWithOneEntry), "unexpected size %d\n", size); 5596 ok(!memcmp(buf, ctlWithOneEntry, size), "unexpected value\n"); 5597 LocalFree(buf); 5598 buf = NULL; 5599 } 5600 value2.cbData = sizeof(encodedIPAddr); 5601 value2.pbData = (LPBYTE)encodedIPAddr; 5602 attr2.pszObjId = oid2; 5603 attr2.cValue = 1; 5604 attr2.rgValue = &value2; 5605 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum); 5606 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum; 5607 ctlEntry[1].cAttribute = 1; 5608 ctlEntry[1].rgAttribute = &attr2; 5609 info.cCTLEntry = 2; 5610 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, 5611 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5612 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 5613 if (ret) 5614 { 5615 ok(size == sizeof(ctlWithTwoEntries), "unexpected size %d\n", size); 5616 ok(!memcmp(buf, ctlWithTwoEntries, size), "unexpected value\n"); 5617 LocalFree(buf); 5618 buf = NULL; 5619 } 5620 } 5621 5622 static void compareCTLInfo(LPCSTR header, const CTL_INFO *expected, 5623 const CTL_INFO *got) 5624 { 5625 DWORD i, j, k; 5626 5627 ok(expected->dwVersion == got->dwVersion, 5628 "%s: expected version %d, got %d\n", header, expected->dwVersion, 5629 got->dwVersion); 5630 ok(expected->SubjectUsage.cUsageIdentifier == 5631 got->SubjectUsage.cUsageIdentifier, 5632 "%s: expected %d usage identifiers, got %d\n", header, 5633 expected->SubjectUsage.cUsageIdentifier, 5634 got->SubjectUsage.cUsageIdentifier); 5635 for (i = 0; i < expected->SubjectUsage.cUsageIdentifier; i++) 5636 ok(!strcmp(expected->SubjectUsage.rgpszUsageIdentifier[i], 5637 got->SubjectUsage.rgpszUsageIdentifier[i]), 5638 "%s[%d]: expected %s, got %s\n", header, i, 5639 expected->SubjectUsage.rgpszUsageIdentifier[i], 5640 got->SubjectUsage.rgpszUsageIdentifier[i]); 5641 ok(expected->ListIdentifier.cbData == got->ListIdentifier.cbData, 5642 "%s: expected list identifier of %d bytes, got %d\n", header, 5643 expected->ListIdentifier.cbData, got->ListIdentifier.cbData); 5644 if (expected->ListIdentifier.cbData) 5645 ok(!memcmp(expected->ListIdentifier.pbData, got->ListIdentifier.pbData, 5646 expected->ListIdentifier.cbData), 5647 "%s: unexpected list identifier value\n", header); 5648 ok(expected->SequenceNumber.cbData == got->SequenceNumber.cbData, 5649 "%s: expected sequence number of %d bytes, got %d\n", header, 5650 expected->SequenceNumber.cbData, got->SequenceNumber.cbData); 5651 if (expected->SequenceNumber.cbData) 5652 ok(!memcmp(expected->SequenceNumber.pbData, got->SequenceNumber.pbData, 5653 expected->SequenceNumber.cbData), 5654 "%s: unexpected sequence number value\n", header); 5655 ok(!memcmp(&expected->ThisUpdate, &got->ThisUpdate, sizeof(FILETIME)), 5656 "%s: expected this update = (%d, %d), got (%d, %d)\n", header, 5657 expected->ThisUpdate.dwLowDateTime, expected->ThisUpdate.dwHighDateTime, 5658 got->ThisUpdate.dwLowDateTime, got->ThisUpdate.dwHighDateTime); 5659 ok(!memcmp(&expected->NextUpdate, &got->NextUpdate, sizeof(FILETIME)), 5660 "%s: expected next update = (%d, %d), got (%d, %d)\n", header, 5661 expected->NextUpdate.dwLowDateTime, expected->NextUpdate.dwHighDateTime, 5662 got->NextUpdate.dwLowDateTime, got->NextUpdate.dwHighDateTime); 5663 if (expected->SubjectAlgorithm.pszObjId && 5664 *expected->SubjectAlgorithm.pszObjId && !got->SubjectAlgorithm.pszObjId) 5665 ok(0, "%s: expected subject algorithm %s, got NULL\n", header, 5666 expected->SubjectAlgorithm.pszObjId); 5667 if (expected->SubjectAlgorithm.pszObjId && got->SubjectAlgorithm.pszObjId) 5668 ok(!strcmp(expected->SubjectAlgorithm.pszObjId, 5669 got->SubjectAlgorithm.pszObjId), 5670 "%s: expected subject algorithm %s, got %s\n", header, 5671 expected->SubjectAlgorithm.pszObjId, got->SubjectAlgorithm.pszObjId); 5672 ok(expected->SubjectAlgorithm.Parameters.cbData == 5673 got->SubjectAlgorithm.Parameters.cbData, 5674 "%s: expected subject algorithm parameters of %d bytes, got %d\n", header, 5675 expected->SubjectAlgorithm.Parameters.cbData, 5676 got->SubjectAlgorithm.Parameters.cbData); 5677 if (expected->SubjectAlgorithm.Parameters.cbData) 5678 ok(!memcmp(expected->SubjectAlgorithm.Parameters.pbData, 5679 got->SubjectAlgorithm.Parameters.pbData, 5680 expected->SubjectAlgorithm.Parameters.cbData), 5681 "%s: unexpected subject algorithm parameter value\n", header); 5682 ok(expected->cCTLEntry == got->cCTLEntry, 5683 "%s: expected %d CTL entries, got %d\n", header, expected->cCTLEntry, 5684 got->cCTLEntry); 5685 for (i = 0; i < expected->cCTLEntry; i++) 5686 { 5687 ok(expected->rgCTLEntry[i].SubjectIdentifier.cbData == 5688 got->rgCTLEntry[i].SubjectIdentifier.cbData, 5689 "%s[%d]: expected subject identifier of %d bytes, got %d\n", 5690 header, i, expected->rgCTLEntry[i].SubjectIdentifier.cbData, 5691 got->rgCTLEntry[i].SubjectIdentifier.cbData); 5692 if (expected->rgCTLEntry[i].SubjectIdentifier.cbData) 5693 ok(!memcmp(expected->rgCTLEntry[i].SubjectIdentifier.pbData, 5694 got->rgCTLEntry[i].SubjectIdentifier.pbData, 5695 expected->rgCTLEntry[i].SubjectIdentifier.cbData), 5696 "%s[%d]: unexpected subject identifier value\n", 5697 header, i); 5698 for (j = 0; j < expected->rgCTLEntry[i].cAttribute; j++) 5699 { 5700 ok(!strcmp(expected->rgCTLEntry[i].rgAttribute[j].pszObjId, 5701 got->rgCTLEntry[i].rgAttribute[j].pszObjId), 5702 "%s[%d][%d]: expected attribute OID %s, got %s\n", header, i, j, 5703 expected->rgCTLEntry[i].rgAttribute[j].pszObjId, 5704 got->rgCTLEntry[i].rgAttribute[j].pszObjId); 5705 for (k = 0; k < expected->rgCTLEntry[i].rgAttribute[j].cValue; k++) 5706 { 5707 ok(expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData == 5708 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData, 5709 "%s[%d][%d][%d]: expected value of %d bytes, got %d\n", 5710 header, i, j, k, 5711 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData, 5712 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData); 5713 if (expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData) 5714 ok(!memcmp( 5715 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData, 5716 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData, 5717 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData), 5718 "%s[%d][%d][%d]: unexpected value\n", 5719 header, i, j, k); 5720 } 5721 } 5722 } 5723 ok(expected->cExtension == got->cExtension, 5724 "%s: expected %d extensions, got %d\n", header, expected->cExtension, 5725 got->cExtension); 5726 for (i = 0; i < expected->cExtension; i++) 5727 { 5728 ok(!strcmp(expected->rgExtension[i].pszObjId, 5729 got->rgExtension[i].pszObjId), "%s[%d]: expected %s, got %s\n", 5730 header, i, expected->rgExtension[i].pszObjId, 5731 got->rgExtension[i].pszObjId); 5732 ok(expected->rgExtension[i].fCritical == got->rgExtension[i].fCritical, 5733 "%s[%d]: expected fCritical = %d, got %d\n", header, i, 5734 expected->rgExtension[i].fCritical, got->rgExtension[i].fCritical); 5735 ok(expected->rgExtension[i].Value.cbData == 5736 got->rgExtension[i].Value.cbData, 5737 "%s[%d]: expected extension value to have %d bytes, got %d\n", 5738 header, i, expected->rgExtension[i].Value.cbData, 5739 got->rgExtension[i].Value.cbData); 5740 if (expected->rgExtension[i].Value.cbData) 5741 ok(!memcmp(expected->rgExtension[i].Value.pbData, 5742 got->rgExtension[i].Value.pbData, 5743 expected->rgExtension[i].Value.cbData), 5744 "%s[%d]: unexpected extension value\n", header, i); 5745 } 5746 } 5747 5748 static const BYTE signedCTL[] = { 5749 0x30,0x81,0xc7,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0, 5750 0x81,0xb9,0x30,0x81,0xb6,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a, 5751 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x28,0x06,0x09,0x2a,0x86, 5752 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x1b,0x04,0x19,0x30,0x17,0x30,0x00, 5753 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, 5754 0x30,0x5a,0x30,0x02,0x06,0x00,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a, 5755 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75, 5756 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08, 5757 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05, 5758 0x00,0x04,0x40,0xca,0xd8,0x32,0xd1,0xbd,0x97,0x61,0x54,0xd6,0x80,0xcf,0x0d, 5759 0xbd,0xa2,0x42,0xc7,0xca,0x37,0x91,0x7d,0x9d,0xac,0x8c,0xdf,0x05,0x8a,0x39, 5760 0xc6,0x07,0xc1,0x37,0xe6,0xb9,0xd1,0x0d,0x26,0xec,0xa5,0xb0,0x8a,0x51,0x26, 5761 0x2b,0x4f,0x73,0x44,0x86,0x83,0x5e,0x2b,0x6e,0xcc,0xf8,0x1b,0x85,0x53,0xe9, 5762 0x7a,0x80,0x8f,0x6b,0x42,0x19,0x93 }; 5763 static const BYTE signedCTLWithCTLInnerContent[] = { 5764 0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02, 5765 0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06, 5766 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09, 5767 0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00, 5768 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, 5769 0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05, 5770 0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31, 5771 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20, 5772 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48, 5773 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86, 5774 0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04, 5775 0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d, 5776 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9, 5777 0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04, 5778 0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf, 5779 0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1, 5780 0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f, 5781 0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23, 5782 0x57,0x6c,0x0b,0x47,0xb8 }; 5783 5784 static void test_decodeCTL(DWORD dwEncoding) 5785 { 5786 static char oid1[] = "1.2.3"; 5787 static char oid2[] = "1.5.6"; 5788 static BYTE nullData[] = { 5,0 }; 5789 char *pOid1 = oid1; 5790 BOOL ret; 5791 BYTE *buf = NULL; 5792 DWORD size = 0; 5793 CTL_INFO info; 5794 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 }; 5795 CTL_ENTRY ctlEntry[2]; 5796 CRYPT_ATTRIBUTE attr1, attr2; 5797 CRYPT_ATTR_BLOB value1, value2; 5798 5799 memset(&info, 0, sizeof(info)); 5800 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTL, sizeof(emptyCTL), 5801 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5802 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5803 if (ret) 5804 { 5805 compareCTLInfo("empty CTL", &info, (CTL_INFO *)buf); 5806 LocalFree(buf); 5807 buf = NULL; 5808 } 5809 info.dwVersion = 1; 5810 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTLWithVersion1, 5811 sizeof(emptyCTLWithVersion1), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, 5812 &size); 5813 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5814 if (ret) 5815 { 5816 compareCTLInfo("v1 CTL", &info, (CTL_INFO *)buf); 5817 LocalFree(buf); 5818 buf = NULL; 5819 } 5820 info.dwVersion = 0; 5821 info.SubjectUsage.cUsageIdentifier = 1; 5822 info.SubjectUsage.rgpszUsageIdentifier = &pOid1; 5823 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithUsageIdentifier, 5824 sizeof(ctlWithUsageIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL, 5825 &buf, &size); 5826 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5827 if (ret) 5828 { 5829 compareCTLInfo("CTL with usage identifier", &info, (CTL_INFO *)buf); 5830 LocalFree(buf); 5831 buf = NULL; 5832 } 5833 info.SubjectUsage.cUsageIdentifier = 0; 5834 info.ListIdentifier.cbData = sizeof(serialNum); 5835 info.ListIdentifier.pbData = (LPBYTE)serialNum; 5836 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithListIdentifier, 5837 sizeof(ctlWithListIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5838 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5839 if (ret) 5840 { 5841 compareCTLInfo("CTL with list identifier", &info, (CTL_INFO *)buf); 5842 LocalFree(buf); 5843 buf = NULL; 5844 } 5845 info.ListIdentifier.cbData = 0; 5846 info.SequenceNumber.cbData = sizeof(serialNum); 5847 info.SequenceNumber.pbData = (LPBYTE)serialNum; 5848 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithSequenceNumber, 5849 sizeof(ctlWithSequenceNumber), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5850 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5851 if (ret) 5852 { 5853 compareCTLInfo("CTL with sequence number", &info, (CTL_INFO *)buf); 5854 LocalFree(buf); 5855 buf = NULL; 5856 } 5857 info.SequenceNumber.cbData = 0; 5858 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate); 5859 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisUpdate, 5860 sizeof(ctlWithThisUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5861 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5862 if (ret) 5863 { 5864 compareCTLInfo("CTL with this update", &info, (CTL_INFO *)buf); 5865 LocalFree(buf); 5866 buf = NULL; 5867 } 5868 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate); 5869 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisAndNextUpdate, 5870 sizeof(ctlWithThisAndNextUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL, 5871 &buf, &size); 5872 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5873 if (ret) 5874 { 5875 compareCTLInfo("CTL with this and next update", &info, (CTL_INFO *)buf); 5876 LocalFree(buf); 5877 buf = NULL; 5878 } 5879 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0; 5880 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0; 5881 info.SubjectAlgorithm.pszObjId = oid2; 5882 info.SubjectAlgorithm.Parameters.cbData = sizeof(nullData); 5883 info.SubjectAlgorithm.Parameters.pbData = nullData; 5884 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithAlgId, 5885 sizeof(ctlWithAlgId), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5886 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5887 if (ret) 5888 { 5889 compareCTLInfo("CTL with algorithm identifier", &info, (CTL_INFO *)buf); 5890 LocalFree(buf); 5891 buf = NULL; 5892 } 5893 SetLastError(0xdeadbeef); 5894 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithBogusEntry, 5895 sizeof(ctlWithBogusEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5896 ok(!ret && 5897 (GetLastError() == CRYPT_E_ASN1_EOD || 5898 GetLastError() == CRYPT_E_ASN1_CORRUPT || 5899 GetLastError() == OSS_MORE_INPUT), /* Win9x */ 5900 "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n", 5901 GetLastError()); 5902 info.SubjectAlgorithm.Parameters.cbData = 0; 5903 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0; 5904 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0; 5905 info.SubjectAlgorithm.pszObjId = NULL; 5906 value1.cbData = sizeof(emptySequence); 5907 value1.pbData = (LPBYTE)emptySequence; 5908 attr1.pszObjId = oid1; 5909 attr1.cValue = 1; 5910 attr1.rgValue = &value1; 5911 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum); 5912 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum; 5913 ctlEntry[0].cAttribute = 1; 5914 ctlEntry[0].rgAttribute = &attr1; 5915 info.cCTLEntry = 1; 5916 info.rgCTLEntry = ctlEntry; 5917 SetLastError(0xdeadbeef); 5918 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithOneEntry, 5919 sizeof(ctlWithOneEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5920 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5921 if (ret) 5922 { 5923 compareCTLInfo("CTL with one entry", &info, (CTL_INFO *)buf); 5924 LocalFree(buf); 5925 buf = NULL; 5926 } 5927 value2.cbData = sizeof(encodedIPAddr); 5928 value2.pbData = (LPBYTE)encodedIPAddr; 5929 attr2.pszObjId = oid2; 5930 attr2.cValue = 1; 5931 attr2.rgValue = &value2; 5932 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum); 5933 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum; 5934 ctlEntry[1].cAttribute = 1; 5935 ctlEntry[1].rgAttribute = &attr2; 5936 info.cCTLEntry = 2; 5937 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithTwoEntries, 5938 sizeof(ctlWithTwoEntries), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5939 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 5940 if (ret) 5941 { 5942 compareCTLInfo("CTL with two entries", &info, (CTL_INFO *)buf); 5943 LocalFree(buf); 5944 buf = NULL; 5945 } 5946 /* A signed CTL isn't decodable, even if the inner content is a CTL */ 5947 SetLastError(0xdeadbeef); 5948 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, signedCTL, 5949 sizeof(signedCTL), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5950 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || 5951 GetLastError() == OSS_DATA_ERROR /* Win9x */), 5952 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n", 5953 GetLastError()); 5954 SetLastError(0xdeadbeef); 5955 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, 5956 signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent), 5957 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 5958 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || 5959 GetLastError() == OSS_DATA_ERROR /* Win9x */), 5960 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n", 5961 GetLastError()); 5962 } 5963 5964 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 }; 5965 static const BYTE emptyPKCSContentInfoExtraBytes[] = { 0x30,0x04,0x06,0x02,0x2a, 5966 0x03,0,0,0,0,0,0 }; 5967 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03, 5968 0xa0,0x01,0x01 }; 5969 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0, 5970 0x03,0x02,0x01,0x01 }; 5971 static BYTE bogusDER[] = { 1 }; 5972 5973 static void test_encodePKCSContentInfo(DWORD dwEncoding) 5974 { 5975 BOOL ret; 5976 BYTE *buf = NULL; 5977 DWORD size = 0; 5978 CRYPT_CONTENT_INFO info = { 0 }; 5979 char oid1[] = "1.2.3"; 5980 5981 if (0) 5982 { 5983 /* Crashes on win9x */ 5984 SetLastError(0xdeadbeef); 5985 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL, 5986 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5987 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 5988 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError()); 5989 } 5990 SetLastError(0xdeadbeef); 5991 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info, 5992 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5993 ok(!ret && (GetLastError() == E_INVALIDARG || 5994 GetLastError() == OSS_LIMITED /* Win9x */), 5995 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError()); 5996 info.pszObjId = oid1; 5997 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info, 5998 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 5999 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6000 if (ret) 6001 { 6002 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size); 6003 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n"); 6004 LocalFree(buf); 6005 } 6006 info.Content.pbData = bogusDER; 6007 info.Content.cbData = sizeof(bogusDER); 6008 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info, 6009 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6010 ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError()); 6011 if (ret) 6012 { 6013 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size); 6014 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n"); 6015 LocalFree(buf); 6016 } 6017 info.Content.pbData = (BYTE *)ints[0].encoded; 6018 info.Content.cbData = ints[0].encoded[1] + 2; 6019 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info, 6020 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6021 if (ret) 6022 { 6023 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size); 6024 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n"); 6025 LocalFree(buf); 6026 } 6027 } 6028 6029 static const BYTE indefiniteSignedPKCSContent[] = { 6030 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80, 6031 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86, 6032 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7, 6033 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04, 6034 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30, 6035 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11, 6036 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 6037 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30, 6038 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30, 6039 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06, 6040 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67, 6041 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01, 6042 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7, 6043 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21, 6044 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3, 6045 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21, 6046 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79, 6047 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d, 6048 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31, 6049 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06, 6050 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67, 6051 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02, 6052 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad, 6053 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8, 6054 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3, 6055 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d, 6056 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61, 6057 0x00,0x00,0x00,0x00,0x00,0x00 }; 6058 6059 static const BYTE content_abcd[] = { 6060 ASN_SEQUENCE, 0x80, 6061 ASN_OBJECTIDENTIFIER, 2, 42,3, 6062 ASN_CONTEXT|ASN_CONSTRUCTOR, 0x80, 6063 ASN_OCTETSTRING, 4, 'a','b','c','d', 6064 0,0, 6065 0,0, 6066 }; 6067 6068 static const BYTE encoded_abcd[] = { 6069 ASN_OCTETSTRING, 4, 'a','b','c','d', 6070 }; 6071 6072 static const BYTE content_constructed_abcd[] = { 6073 ASN_SEQUENCE, 0x80, 6074 ASN_OBJECTIDENTIFIER, 2, 42,3, 6075 ASN_CONTEXT|ASN_CONSTRUCTOR, 0x80, 6076 ASN_CONSTRUCTOR|ASN_OCTETSTRING,0x80, 6077 ASN_OCTETSTRING, 4, 'a','b','0','0', 6078 0,0, 6079 0,0, 6080 0,0, 6081 1,2,3,4,5,6,7 /* extra garbage */ 6082 }; 6083 6084 static void test_decodePKCSContentInfo(DWORD dwEncoding) 6085 { 6086 BOOL ret; 6087 LPBYTE buf = NULL; 6088 DWORD size = 0, i; 6089 CRYPT_CONTENT_INFO *info; 6090 6091 const struct { 6092 const BYTE *encoded; 6093 UINT encoded_size; 6094 const char *obj_id; 6095 const BYTE *content; 6096 UINT content_size; 6097 } tests[] = { 6098 { emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo), 6099 "1.2.3", NULL, 0 }, 6100 { emptyPKCSContentInfoExtraBytes, sizeof(emptyPKCSContentInfoExtraBytes), 6101 "1.2.3", NULL, 0 }, 6102 { intPKCSContentInfo, sizeof(intPKCSContentInfo), 6103 "1.2.3", ints[0].encoded, ints[0].encoded[1] + 2 }, 6104 { indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent), 6105 "1.2.840.113549.1.7.2", NULL, 392 }, 6106 { content_abcd, sizeof(content_abcd), 6107 "1.2.3", encoded_abcd, 6 }, 6108 { content_constructed_abcd, sizeof(content_constructed_abcd), 6109 "1.2.3", content_constructed_abcd + 8, 10 } 6110 }; 6111 6112 for (i = 0; i < sizeof(tests)/sizeof(*tests); i++) 6113 { 6114 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, tests[i].encoded, 6115 tests[i].encoded_size, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 6116 ok(ret, "[%u] CryptDecodeObjectEx failed: %x\n", i, GetLastError()); 6117 if (!ret) continue; 6118 6119 info = (CRYPT_CONTENT_INFO *)buf; 6120 6121 ok(!strcmp(info->pszObjId, tests[i].obj_id), "[%u] Expected %s, got %s\n", 6122 i, tests[i].obj_id, info->pszObjId); 6123 ok(info->Content.cbData == tests[i].content_size, 6124 "[%u] Unexpected size %d expected %d\n", i, info->Content.cbData, 6125 tests[i].content_size); 6126 if (tests[i].content) 6127 ok(!memcmp(info->Content.pbData, tests[i].content, tests[i].content_size), 6128 "[%u] Unexpected value\n", i); 6129 LocalFree(buf); 6130 } 6131 6132 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, 6133 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo), 6134 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 6135 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as 6136 * I doubt an app depends on that. 6137 */ 6138 ok((!ret && (GetLastError() == CRYPT_E_ASN1_EOD || 6139 GetLastError() == CRYPT_E_ASN1_CORRUPT)) || broken(ret), 6140 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n", 6141 GetLastError()); 6142 } 6143 6144 static const BYTE emptyPKCSAttr[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31, 6145 0x00 }; 6146 static const BYTE bogusPKCSAttr[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01, 6147 0x01 }; 6148 static const BYTE intPKCSAttr[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03, 6149 0x02,0x01,0x01 }; 6150 6151 static void test_encodePKCSAttribute(DWORD dwEncoding) 6152 { 6153 CRYPT_ATTRIBUTE attr = { 0 }; 6154 BOOL ret; 6155 LPBYTE buf = NULL; 6156 DWORD size = 0; 6157 CRYPT_ATTR_BLOB blob; 6158 char oid[] = "1.2.3"; 6159 6160 if (0) 6161 { 6162 /* Crashes on win9x */ 6163 SetLastError(0xdeadbeef); 6164 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, NULL, 6165 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6166 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 6167 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError()); 6168 } 6169 SetLastError(0xdeadbeef); 6170 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr, 6171 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6172 ok(!ret && (GetLastError() == E_INVALIDARG || 6173 GetLastError() == OSS_LIMITED /* Win9x */), 6174 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError()); 6175 attr.pszObjId = oid; 6176 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr, 6177 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6178 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6179 if (ret) 6180 { 6181 ok(size == sizeof(emptyPKCSAttr), "Unexpected size %d\n", size); 6182 ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n"); 6183 LocalFree(buf); 6184 } 6185 blob.cbData = sizeof(bogusDER); 6186 blob.pbData = bogusDER; 6187 attr.cValue = 1; 6188 attr.rgValue = &blob; 6189 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr, 6190 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6191 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6192 if (ret) 6193 { 6194 ok(size == sizeof(bogusPKCSAttr), "Unexpected size %d\n", size); 6195 ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n"); 6196 LocalFree(buf); 6197 } 6198 blob.pbData = (BYTE *)ints[0].encoded; 6199 blob.cbData = ints[0].encoded[1] + 2; 6200 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr, 6201 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6202 if (ret) 6203 { 6204 ok(size == sizeof(intPKCSAttr), "Unexpected size %d\n", size); 6205 ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n"); 6206 LocalFree(buf); 6207 } 6208 } 6209 6210 static void test_decodePKCSAttribute(DWORD dwEncoding) 6211 { 6212 BOOL ret; 6213 LPBYTE buf = NULL; 6214 DWORD size = 0; 6215 CRYPT_ATTRIBUTE *attr; 6216 6217 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, 6218 emptyPKCSAttr, sizeof(emptyPKCSAttr), 6219 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 6220 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 6221 if (ret) 6222 { 6223 attr = (CRYPT_ATTRIBUTE *)buf; 6224 6225 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n", 6226 attr->pszObjId); 6227 ok(attr->cValue == 0, "Expected no value, got %d\n", attr->cValue); 6228 LocalFree(buf); 6229 } 6230 SetLastError(0xdeadbeef); 6231 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, 6232 bogusPKCSAttr, sizeof(bogusPKCSAttr), 6233 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 6234 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as 6235 * I doubt an app depends on that. 6236 */ 6237 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD || 6238 GetLastError() == CRYPT_E_ASN1_CORRUPT || 6239 GetLastError() == OSS_MORE_INPUT /* Win9x */), 6240 "Expected CRYPT_E_ASN1_EOD, CRYPT_E_ASN1_CORRUPT, or OSS_MORE_INPUT, got %x\n", 6241 GetLastError()); 6242 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, 6243 intPKCSAttr, sizeof(intPKCSAttr), 6244 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 6245 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 6246 if (ret) 6247 { 6248 attr = (CRYPT_ATTRIBUTE *)buf; 6249 6250 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n", 6251 attr->pszObjId); 6252 ok(attr->cValue == 1, "Expected 1 value, got %d\n", attr->cValue); 6253 ok(attr->rgValue[0].cbData == ints[0].encoded[1] + 2, 6254 "Unexpected size %d\n", attr->rgValue[0].cbData); 6255 ok(!memcmp(attr->rgValue[0].pbData, ints[0].encoded, 6256 attr->rgValue[0].cbData), "Unexpected value\n"); 6257 LocalFree(buf); 6258 } 6259 } 6260 6261 static const BYTE emptyPKCSAttributes[] = { 0x31,0x00 }; 6262 static const BYTE singlePKCSAttributes[] = { 0x31,0x08,0x30,0x06,0x06,0x02, 6263 0x2a,0x03,0x31,0x00 }; 6264 static const BYTE doublePKCSAttributes[] = { 0x31,0x13,0x30,0x06,0x06,0x02, 6265 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 }; 6266 6267 static void test_encodePKCSAttributes(DWORD dwEncoding) 6268 { 6269 CRYPT_ATTRIBUTES attributes = { 0 }; 6270 CRYPT_ATTRIBUTE attr[2] = { { 0 } }; 6271 CRYPT_ATTR_BLOB blob; 6272 BOOL ret; 6273 LPBYTE buf = NULL; 6274 DWORD size = 0; 6275 char oid1[] = "1.2.3", oid2[] = "1.5.6"; 6276 6277 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes, 6278 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6279 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6280 if (ret) 6281 { 6282 ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %d\n", size); 6283 ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n"); 6284 LocalFree(buf); 6285 } 6286 attributes.cAttr = 1; 6287 attributes.rgAttr = attr; 6288 SetLastError(0xdeadbeef); 6289 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes, 6290 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6291 ok(!ret && (GetLastError() == E_INVALIDARG || 6292 GetLastError() == OSS_LIMITED /* Win9x */), 6293 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError()); 6294 attr[0].pszObjId = oid1; 6295 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes, 6296 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6297 if (ret) 6298 { 6299 ok(size == sizeof(singlePKCSAttributes), "Unexpected size %d\n", size); 6300 ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n"); 6301 LocalFree(buf); 6302 } 6303 attr[1].pszObjId = oid2; 6304 attr[1].cValue = 1; 6305 attr[1].rgValue = &blob; 6306 blob.pbData = (BYTE *)ints[0].encoded; 6307 blob.cbData = ints[0].encoded[1] + 2; 6308 attributes.cAttr = 2; 6309 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes, 6310 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6311 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6312 if (ret) 6313 { 6314 ok(size == sizeof(doublePKCSAttributes), "Unexpected size %d\n", size); 6315 ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n"); 6316 LocalFree(buf); 6317 } 6318 } 6319 6320 static void test_decodePKCSAttributes(DWORD dwEncoding) 6321 { 6322 BOOL ret; 6323 LPBYTE buf = NULL; 6324 DWORD size = 0; 6325 CRYPT_ATTRIBUTES *attributes; 6326 6327 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, 6328 emptyPKCSAttributes, sizeof(emptyPKCSAttributes), 6329 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 6330 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 6331 if (ret) 6332 { 6333 attributes = (CRYPT_ATTRIBUTES *)buf; 6334 ok(attributes->cAttr == 0, "Expected no attributes, got %d\n", 6335 attributes->cAttr); 6336 LocalFree(buf); 6337 } 6338 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, 6339 singlePKCSAttributes, sizeof(singlePKCSAttributes), 6340 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 6341 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 6342 if (ret) 6343 { 6344 attributes = (CRYPT_ATTRIBUTES *)buf; 6345 ok(attributes->cAttr == 1, "Expected 1 attribute, got %d\n", 6346 attributes->cAttr); 6347 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"), 6348 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId); 6349 ok(attributes->rgAttr[0].cValue == 0, 6350 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue); 6351 LocalFree(buf); 6352 } 6353 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, 6354 doublePKCSAttributes, sizeof(doublePKCSAttributes), 6355 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 6356 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 6357 if (ret) 6358 { 6359 attributes = (CRYPT_ATTRIBUTES *)buf; 6360 ok(attributes->cAttr == 2, "Expected 2 attributes, got %d\n", 6361 attributes->cAttr); 6362 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"), 6363 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId); 6364 ok(attributes->rgAttr[0].cValue == 0, 6365 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue); 6366 ok(!strcmp(attributes->rgAttr[1].pszObjId, "1.5.6"), 6367 "Expected 1.5.6, got %s\n", attributes->rgAttr[1].pszObjId); 6368 ok(attributes->rgAttr[1].cValue == 1, 6369 "Expected 1 attribute, got %d\n", attributes->rgAttr[1].cValue); 6370 ok(attributes->rgAttr[1].rgValue[0].cbData == ints[0].encoded[1] + 2, 6371 "Unexpected size %d\n", attributes->rgAttr[1].rgValue[0].cbData); 6372 ok(!memcmp(attributes->rgAttr[1].rgValue[0].pbData, ints[0].encoded, 6373 attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n"); 6374 LocalFree(buf); 6375 } 6376 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, 6377 doublePKCSAttributes, sizeof(doublePKCSAttributes), 0, NULL, NULL, &size); 6378 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 6379 buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); 6380 if (buf) 6381 { 6382 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, 6383 doublePKCSAttributes, sizeof(doublePKCSAttributes), 0, NULL, buf, &size); 6384 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 6385 HeapFree(GetProcessHeap(), 0, buf); 6386 } 6387 } 6388 6389 static const BYTE singleCapability[] = { 6390 0x30,0x06,0x30,0x04,0x06,0x02,0x2d,0x06 }; 6391 static const BYTE twoCapabilities[] = { 6392 0x30,0x0c,0x30,0x04,0x06,0x02,0x2d,0x06,0x30,0x04,0x06,0x02,0x2a,0x03 }; 6393 static const BYTE singleCapabilitywithNULL[] = { 6394 0x30,0x08,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 }; 6395 6396 static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding) 6397 { 6398 static char oid1[] = "1.5.6", oid2[] = "1.2.3"; 6399 BOOL ret; 6400 LPBYTE buf = NULL; 6401 DWORD size = 0; 6402 CRYPT_SMIME_CAPABILITY capability[2]; 6403 CRYPT_SMIME_CAPABILITIES capabilities; 6404 6405 /* An empty capabilities is allowed */ 6406 capabilities.cCapability = 0; 6407 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES, 6408 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6409 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 6410 if (ret) 6411 { 6412 ok(size == sizeof(emptySequence), "unexpected size %d\n", size); 6413 ok(!memcmp(buf, emptySequence, size), "unexpected value\n"); 6414 LocalFree(buf); 6415 } 6416 /* A non-empty capabilities with an empty capability (lacking an OID) is 6417 * not allowed 6418 */ 6419 capability[0].pszObjId = NULL; 6420 capability[0].Parameters.cbData = 0; 6421 capabilities.cCapability = 1; 6422 capabilities.rgCapability = capability; 6423 SetLastError(0xdeadbeef); 6424 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES, 6425 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6426 ok(!ret && (GetLastError() == E_INVALIDARG || 6427 GetLastError() == OSS_LIMITED /* Win9x */), 6428 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError()); 6429 capability[0].pszObjId = oid1; 6430 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES, 6431 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6432 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 6433 if (ret) 6434 { 6435 ok(size == sizeof(singleCapability), "unexpected size %d\n", size); 6436 ok(!memcmp(buf, singleCapability, size), "unexpected value\n"); 6437 LocalFree(buf); 6438 } 6439 capability[1].pszObjId = oid2; 6440 capability[1].Parameters.cbData = 0; 6441 capabilities.cCapability = 2; 6442 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES, 6443 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6444 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 6445 if (ret) 6446 { 6447 ok(size == sizeof(twoCapabilities), "unexpected size %d\n", size); 6448 ok(!memcmp(buf, twoCapabilities, size), "unexpected value\n"); 6449 LocalFree(buf); 6450 } 6451 } 6452 6453 static void compareSMimeCapabilities(LPCSTR header, 6454 const CRYPT_SMIME_CAPABILITIES *expected, const CRYPT_SMIME_CAPABILITIES *got) 6455 { 6456 DWORD i; 6457 6458 ok(got->cCapability == expected->cCapability, 6459 "%s: expected %d capabilities, got %d\n", header, expected->cCapability, 6460 got->cCapability); 6461 for (i = 0; i < expected->cCapability; i++) 6462 { 6463 ok(!strcmp(expected->rgCapability[i].pszObjId, 6464 got->rgCapability[i].pszObjId), "%s[%d]: expected %s, got %s\n", 6465 header, i, expected->rgCapability[i].pszObjId, 6466 got->rgCapability[i].pszObjId); 6467 ok(expected->rgCapability[i].Parameters.cbData == 6468 got->rgCapability[i].Parameters.cbData, 6469 "%s[%d]: expected %d bytes, got %d\n", header, i, 6470 expected->rgCapability[i].Parameters.cbData, 6471 got->rgCapability[i].Parameters.cbData); 6472 if (expected->rgCapability[i].Parameters.cbData) 6473 ok(!memcmp(expected->rgCapability[i].Parameters.pbData, 6474 got->rgCapability[i].Parameters.pbData, 6475 expected->rgCapability[i].Parameters.cbData), 6476 "%s[%d]: unexpected value\n", header, i); 6477 } 6478 } 6479 6480 static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding) 6481 { 6482 static char oid1[] = "1.5.6", oid2[] = "1.2.3"; 6483 BOOL ret; 6484 DWORD size = 0; 6485 CRYPT_SMIME_CAPABILITY capability[2]; 6486 CRYPT_SMIME_CAPABILITIES capabilities, *ptr; 6487 6488 SetLastError(0xdeadbeef); 6489 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES, 6490 emptySequence, sizeof(emptySequence), 6491 CRYPT_DECODE_ALLOC_FLAG, NULL, &ptr, &size); 6492 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 6493 if (ret) 6494 { 6495 capabilities.cCapability = 0; 6496 compareSMimeCapabilities("empty capabilities", &capabilities, ptr); 6497 LocalFree(ptr); 6498 } 6499 SetLastError(0xdeadbeef); 6500 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES, 6501 singleCapability, sizeof(singleCapability), CRYPT_DECODE_ALLOC_FLAG, NULL, 6502 &ptr, &size); 6503 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 6504 if (ret) 6505 { 6506 capability[0].pszObjId = oid1; 6507 capability[0].Parameters.cbData = 0; 6508 capabilities.cCapability = 1; 6509 capabilities.rgCapability = capability; 6510 compareSMimeCapabilities("single capability", &capabilities, ptr); 6511 LocalFree(ptr); 6512 } 6513 SetLastError(0xdeadbeef); 6514 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES, 6515 singleCapabilitywithNULL, sizeof(singleCapabilitywithNULL), 6516 CRYPT_DECODE_ALLOC_FLAG, NULL, &ptr, &size); 6517 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 6518 if (ret) 6519 { 6520 BYTE NULLparam[] = {0x05, 0x00}; 6521 capability[0].pszObjId = oid1; 6522 capability[0].Parameters.cbData = 2; 6523 capability[0].Parameters.pbData = NULLparam; 6524 capabilities.cCapability = 1; 6525 capabilities.rgCapability = capability; 6526 compareSMimeCapabilities("single capability with NULL", &capabilities, 6527 ptr); 6528 LocalFree(ptr); 6529 } 6530 SetLastError(0xdeadbeef); 6531 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES, 6532 twoCapabilities, sizeof(twoCapabilities), CRYPT_DECODE_ALLOC_FLAG, NULL, 6533 &ptr, &size); 6534 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 6535 if (ret) 6536 { 6537 capability[0].Parameters.cbData = 0; 6538 capability[1].pszObjId = oid2; 6539 capability[1].Parameters.cbData = 0; 6540 capabilities.cCapability = 2; 6541 compareSMimeCapabilities("two capabilities", &capabilities, ptr); 6542 LocalFree(ptr); 6543 } 6544 SetLastError(0xdeadbeef); 6545 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES, 6546 twoCapabilities, sizeof(twoCapabilities), 0, NULL, NULL, &size); 6547 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 6548 ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); 6549 if (ptr) 6550 { 6551 SetLastError(0xdeadbeef); 6552 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES, 6553 twoCapabilities, sizeof(twoCapabilities), 0, NULL, ptr, &size); 6554 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 6555 HeapFree(GetProcessHeap(), 0, ptr); 6556 } 6557 } 6558 6559 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10, 6560 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 6561 0x67 }; 6562 static const BYTE minimalPKCSSigner[] = { 6563 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03, 6564 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02, 6565 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 }; 6566 static const BYTE PKCSSignerWithSerial[] = { 6567 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03, 6568 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02, 6569 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04, 6570 0x00 }; 6571 static const BYTE PKCSSignerWithHashAlgo[] = { 6572 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03, 6573 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02, 6574 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05, 6575 0x00,0x04,0x00 }; 6576 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = { 6577 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03, 6578 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02, 6579 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d, 6580 0x06,0x05,0x00,0x04,0x00 }; 6581 static const BYTE PKCSSignerWithHash[] = { 6582 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03, 6583 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02, 6584 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d, 6585 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09, 6586 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f }; 6587 static const BYTE PKCSSignerWithAuthAttr[] = { 6588 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03, 6589 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02, 6590 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06, 6591 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55, 6592 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30, 6593 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05, 6594 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f }; 6595 6596 static void test_encodePKCSSignerInfo(DWORD dwEncoding) 6597 { 6598 static char oid1[] = "1.2.3", oid2[] = "1.5.6"; 6599 BOOL ret; 6600 LPBYTE buf = NULL; 6601 DWORD size = 0; 6602 CMSG_SIGNER_INFO info = { 0 }; 6603 char oid_common_name[] = szOID_COMMON_NAME; 6604 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName), 6605 (LPBYTE)encodedCommonName }; 6606 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName }; 6607 6608 SetLastError(0xdeadbeef); 6609 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info, 6610 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6611 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 6612 { 6613 skip("no PKCS7_SIGNER_INFO encode support\n"); 6614 return; 6615 } 6616 ok(!ret && (GetLastError() == E_INVALIDARG || 6617 GetLastError() == OSS_LIMITED /* Win9x */), 6618 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError()); 6619 /* To be encoded, a signer must have an issuer at least, and the encoding 6620 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded, 6621 * see decoding tests.) 6622 */ 6623 info.Issuer.cbData = sizeof(encodedCommonNameNoNull); 6624 info.Issuer.pbData = encodedCommonNameNoNull; 6625 SetLastError(0xdeadbeef); 6626 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info, 6627 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6628 if (!(dwEncoding & PKCS_7_ASN_ENCODING)) 6629 ok(!ret && GetLastError() == E_INVALIDARG, 6630 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 6631 else 6632 { 6633 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */), 6634 "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6635 if (ret) 6636 { 6637 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size); 6638 if (size == sizeof(minimalPKCSSigner)) 6639 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n"); 6640 else 6641 ok(0, "Unexpected value\n"); 6642 LocalFree(buf); 6643 } 6644 } 6645 info.SerialNumber.cbData = sizeof(serialNum); 6646 info.SerialNumber.pbData = (BYTE *)serialNum; 6647 SetLastError(0xdeadbeef); 6648 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info, 6649 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6650 if (!(dwEncoding & PKCS_7_ASN_ENCODING)) 6651 ok(!ret && GetLastError() == E_INVALIDARG, 6652 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 6653 else 6654 { 6655 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */), 6656 "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6657 if (ret) 6658 { 6659 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n", 6660 size); 6661 if (size == sizeof(PKCSSignerWithSerial)) 6662 ok(!memcmp(buf, PKCSSignerWithSerial, size), 6663 "Unexpected value\n"); 6664 else 6665 ok(0, "Unexpected value\n"); 6666 LocalFree(buf); 6667 } 6668 } 6669 info.HashAlgorithm.pszObjId = oid1; 6670 SetLastError(0xdeadbeef); 6671 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info, 6672 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6673 if (!(dwEncoding & PKCS_7_ASN_ENCODING)) 6674 ok(!ret && GetLastError() == E_INVALIDARG, 6675 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 6676 else 6677 { 6678 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */), 6679 "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6680 if (ret) 6681 { 6682 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n", 6683 size); 6684 if (size == sizeof(PKCSSignerWithHashAlgo)) 6685 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size), 6686 "Unexpected value\n"); 6687 else 6688 ok(0, "Unexpected value\n"); 6689 LocalFree(buf); 6690 } 6691 } 6692 info.HashEncryptionAlgorithm.pszObjId = oid2; 6693 SetLastError(0xdeadbeef); 6694 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info, 6695 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6696 if (!(dwEncoding & PKCS_7_ASN_ENCODING)) 6697 ok(!ret && GetLastError() == E_INVALIDARG, 6698 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 6699 else 6700 { 6701 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6702 if (ret) 6703 { 6704 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo), 6705 "Unexpected size %d\n", size); 6706 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo)) 6707 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size), 6708 "Unexpected value\n"); 6709 else 6710 ok(0, "Unexpected value\n"); 6711 LocalFree(buf); 6712 } 6713 } 6714 info.EncryptedHash.cbData = sizeof(hash); 6715 info.EncryptedHash.pbData = (BYTE *)hash; 6716 SetLastError(0xdeadbeef); 6717 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info, 6718 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6719 if (!(dwEncoding & PKCS_7_ASN_ENCODING)) 6720 ok(!ret && GetLastError() == E_INVALIDARG, 6721 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 6722 else 6723 { 6724 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6725 if (ret) 6726 { 6727 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n", 6728 size); 6729 if (size == sizeof(PKCSSignerWithHash)) 6730 ok(!memcmp(buf, PKCSSignerWithHash, size), 6731 "Unexpected value\n"); 6732 else 6733 ok(0, "Unexpected value\n"); 6734 LocalFree(buf); 6735 } 6736 } 6737 info.AuthAttrs.cAttr = 1; 6738 info.AuthAttrs.rgAttr = &attr; 6739 SetLastError(0xdeadbeef); 6740 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info, 6741 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6742 if (!(dwEncoding & PKCS_7_ASN_ENCODING)) 6743 ok(!ret && GetLastError() == E_INVALIDARG, 6744 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 6745 else 6746 { 6747 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6748 if (ret) 6749 { 6750 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n", 6751 size); 6752 if (size == sizeof(PKCSSignerWithAuthAttr)) 6753 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size), 6754 "Unexpected value\n"); 6755 else 6756 ok(0, "Unexpected value\n"); 6757 LocalFree(buf); 6758 } 6759 } 6760 } 6761 6762 static void test_decodePKCSSignerInfo(DWORD dwEncoding) 6763 { 6764 BOOL ret; 6765 LPBYTE buf = NULL; 6766 DWORD size = 0; 6767 CMSG_SIGNER_INFO *info; 6768 6769 /* A PKCS signer can't be decoded without a serial number. */ 6770 SetLastError(0xdeadbeef); 6771 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, 6772 minimalPKCSSigner, sizeof(minimalPKCSSigner), 6773 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 6774 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT || 6775 GetLastError() == OSS_DATA_ERROR /* Win9x */), 6776 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %x\n", 6777 GetLastError()); 6778 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, 6779 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial), 6780 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 6781 ok(ret || broken(GetLastError() == OSS_DATA_ERROR), 6782 "CryptDecodeObjectEx failed: %x\n", GetLastError()); 6783 if (ret) 6784 { 6785 info = (CMSG_SIGNER_INFO *)buf; 6786 ok(info->dwVersion == 0, "Expected version 0, got %d\n", 6787 info->dwVersion); 6788 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull), 6789 "Unexpected size %d\n", info->Issuer.cbData); 6790 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull, 6791 info->Issuer.cbData), "Unexpected value\n"); 6792 ok(info->SerialNumber.cbData == sizeof(serialNum), 6793 "Unexpected size %d\n", info->SerialNumber.cbData); 6794 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)), 6795 "Unexpected value\n"); 6796 LocalFree(buf); 6797 } 6798 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, 6799 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo), 6800 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 6801 if (ret) 6802 { 6803 info = (CMSG_SIGNER_INFO *)buf; 6804 ok(info->dwVersion == 0, "Expected version 0, got %d\n", 6805 info->dwVersion); 6806 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull), 6807 "Unexpected size %d\n", info->Issuer.cbData); 6808 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull, 6809 info->Issuer.cbData), "Unexpected value\n"); 6810 ok(info->SerialNumber.cbData == sizeof(serialNum), 6811 "Unexpected size %d\n", info->SerialNumber.cbData); 6812 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)), 6813 "Unexpected value\n"); 6814 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"), 6815 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId); 6816 LocalFree(buf); 6817 } 6818 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, 6819 PKCSSignerWithHashAndEncryptionAlgo, 6820 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG, 6821 NULL, &buf, &size); 6822 if (ret) 6823 { 6824 info = (CMSG_SIGNER_INFO *)buf; 6825 ok(info->dwVersion == 0, "Expected version 0, got %d\n", 6826 info->dwVersion); 6827 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull), 6828 "Unexpected size %d\n", info->Issuer.cbData); 6829 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull, 6830 info->Issuer.cbData), "Unexpected value\n"); 6831 ok(info->SerialNumber.cbData == sizeof(serialNum), 6832 "Unexpected size %d\n", info->SerialNumber.cbData); 6833 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)), 6834 "Unexpected value\n"); 6835 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"), 6836 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId); 6837 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"), 6838 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId); 6839 LocalFree(buf); 6840 } 6841 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, 6842 PKCSSignerWithHash, sizeof(PKCSSignerWithHash), 6843 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 6844 if (ret) 6845 { 6846 info = (CMSG_SIGNER_INFO *)buf; 6847 ok(info->dwVersion == 0, "Expected version 0, got %d\n", 6848 info->dwVersion); 6849 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull), 6850 "Unexpected size %d\n", info->Issuer.cbData); 6851 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull, 6852 info->Issuer.cbData), "Unexpected value\n"); 6853 ok(info->SerialNumber.cbData == sizeof(serialNum), 6854 "Unexpected size %d\n", info->SerialNumber.cbData); 6855 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)), 6856 "Unexpected value\n"); 6857 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"), 6858 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId); 6859 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"), 6860 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId); 6861 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n", 6862 info->EncryptedHash.cbData); 6863 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)), 6864 "Unexpected value\n"); 6865 LocalFree(buf); 6866 } 6867 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, 6868 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr), 6869 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 6870 if (ret) 6871 { 6872 info = (CMSG_SIGNER_INFO *)buf; 6873 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n", 6874 info->AuthAttrs.cAttr); 6875 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME), 6876 "Expected %s, got %s\n", szOID_COMMON_NAME, 6877 info->AuthAttrs.rgAttr[0].pszObjId); 6878 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n", 6879 info->AuthAttrs.rgAttr[0].cValue); 6880 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData == 6881 sizeof(encodedCommonName), "Unexpected size %d\n", 6882 info->AuthAttrs.rgAttr[0].rgValue[0].cbData); 6883 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData, 6884 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n"); 6885 LocalFree(buf); 6886 } 6887 } 6888 6889 static const BYTE CMSSignerWithKeyId[] = { 6890 0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30, 6891 0x04,0x06,0x00,0x05,0x00,0x04,0x00 }; 6892 6893 static void test_encodeCMSSignerInfo(DWORD dwEncoding) 6894 { 6895 BOOL ret; 6896 LPBYTE buf = NULL; 6897 DWORD size = 0; 6898 CMSG_CMS_SIGNER_INFO info = { 0 }; 6899 static char oid1[] = "1.2.3", oid2[] = "1.5.6"; 6900 6901 SetLastError(0xdeadbeef); 6902 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, 6903 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6904 ok(!ret, "Expected failure, got %d\n", ret); 6905 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 6906 { 6907 skip("no CMS_SIGNER_INFO encode support\n"); 6908 return; 6909 } 6910 ok(GetLastError() == E_INVALIDARG, 6911 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 6912 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER; 6913 SetLastError(0xdeadbeef); 6914 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, 6915 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6916 ok(!ret, "Expected failure, got %d\n", ret); 6917 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 6918 { 6919 skip("no CMS_SIGNER_INFO encode support\n"); 6920 return; 6921 } 6922 ok(GetLastError() == E_INVALIDARG, 6923 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 6924 /* To be encoded, a signer must have a valid cert ID, where a valid ID may 6925 * be a key id or an issuer serial number with at least the issuer set, and 6926 * the encoding must include PKCS_7_ASN_ENCODING. 6927 * (That isn't enough to be decoded, see decoding tests.) 6928 */ 6929 U(info.SignerId).IssuerSerialNumber.Issuer.cbData = 6930 sizeof(encodedCommonNameNoNull); 6931 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull; 6932 SetLastError(0xdeadbeef); 6933 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, 6934 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6935 if (!(dwEncoding & PKCS_7_ASN_ENCODING)) 6936 ok(!ret && GetLastError() == E_INVALIDARG, 6937 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 6938 else 6939 { 6940 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6941 if (ret) 6942 { 6943 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size); 6944 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n"); 6945 LocalFree(buf); 6946 } 6947 } 6948 U(info.SignerId).IssuerSerialNumber.SerialNumber.cbData = sizeof(serialNum); 6949 U(info.SignerId).IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum; 6950 SetLastError(0xdeadbeef); 6951 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, 6952 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6953 if (!(dwEncoding & PKCS_7_ASN_ENCODING)) 6954 ok(!ret && GetLastError() == E_INVALIDARG, 6955 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 6956 else 6957 { 6958 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6959 if (ret) 6960 { 6961 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n", 6962 size); 6963 ok(!memcmp(buf, PKCSSignerWithSerial, size), "Unexpected value\n"); 6964 LocalFree(buf); 6965 } 6966 } 6967 info.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER; 6968 U(info.SignerId).KeyId.cbData = sizeof(serialNum); 6969 U(info.SignerId).KeyId.pbData = (BYTE *)serialNum; 6970 SetLastError(0xdeadbeef); 6971 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, 6972 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6973 if (!(dwEncoding & PKCS_7_ASN_ENCODING)) 6974 ok(!ret && GetLastError() == E_INVALIDARG, 6975 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 6976 else 6977 { 6978 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 6979 if (ret) 6980 { 6981 ok(size == sizeof(CMSSignerWithKeyId), "Unexpected size %d\n", 6982 size); 6983 ok(!memcmp(buf, CMSSignerWithKeyId, size), "Unexpected value\n"); 6984 LocalFree(buf); 6985 } 6986 } 6987 /* While a CERT_ID can have a hash type, that's not allowed in CMS, where 6988 * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed 6989 * (see RFC 3852, section 5.3.) 6990 */ 6991 info.SignerId.dwIdChoice = CERT_ID_SHA1_HASH; 6992 U(info.SignerId).HashId.cbData = sizeof(hash); 6993 U(info.SignerId).HashId.pbData = (BYTE *)hash; 6994 SetLastError(0xdeadbeef); 6995 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, 6996 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 6997 ok(!ret && GetLastError() == E_INVALIDARG, 6998 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 6999 /* Now with a hash algo */ 7000 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER; 7001 U(info.SignerId).IssuerSerialNumber.Issuer.cbData = 7002 sizeof(encodedCommonNameNoNull); 7003 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull; 7004 info.HashAlgorithm.pszObjId = oid1; 7005 SetLastError(0xdeadbeef); 7006 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, 7007 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7008 if (!(dwEncoding & PKCS_7_ASN_ENCODING)) 7009 ok(!ret && GetLastError() == E_INVALIDARG, 7010 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 7011 else 7012 { 7013 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 7014 if (ret) 7015 { 7016 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n", 7017 size); 7018 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size), 7019 "Unexpected value\n"); 7020 LocalFree(buf); 7021 } 7022 } 7023 info.HashEncryptionAlgorithm.pszObjId = oid2; 7024 SetLastError(0xdeadbeef); 7025 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, 7026 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7027 if (!(dwEncoding & PKCS_7_ASN_ENCODING)) 7028 ok(!ret && GetLastError() == E_INVALIDARG, 7029 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 7030 else 7031 { 7032 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 7033 if (ret) 7034 { 7035 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo), 7036 "Unexpected size %d\n", size); 7037 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size), 7038 "Unexpected value\n"); 7039 LocalFree(buf); 7040 } 7041 } 7042 info.EncryptedHash.cbData = sizeof(hash); 7043 info.EncryptedHash.pbData = (BYTE *)hash; 7044 SetLastError(0xdeadbeef); 7045 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, 7046 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7047 if (!(dwEncoding & PKCS_7_ASN_ENCODING)) 7048 ok(!ret && GetLastError() == E_INVALIDARG, 7049 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 7050 else 7051 { 7052 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); 7053 if (ret) 7054 { 7055 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n", 7056 size); 7057 ok(!memcmp(buf, PKCSSignerWithHash, size), "Unexpected value\n"); 7058 LocalFree(buf); 7059 } 7060 } 7061 } 7062 7063 static void test_decodeCMSSignerInfo(DWORD dwEncoding) 7064 { 7065 BOOL ret; 7066 LPBYTE buf = NULL; 7067 DWORD size = 0; 7068 CMSG_CMS_SIGNER_INFO *info; 7069 static const char oid1[] = "1.2.3", oid2[] = "1.5.6"; 7070 7071 /* A CMS signer can't be decoded without a serial number. */ 7072 SetLastError(0xdeadbeef); 7073 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO, 7074 minimalPKCSSigner, sizeof(minimalPKCSSigner), 7075 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 7076 ok(!ret, "expected failure\n"); 7077 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 7078 { 7079 skip("no CMS_SIGNER_INFO decode support\n"); 7080 return; 7081 } 7082 ok(GetLastError() == CRYPT_E_ASN1_CORRUPT, 7083 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError()); 7084 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO, 7085 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial), 7086 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 7087 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 7088 if (ret) 7089 { 7090 info = (CMSG_CMS_SIGNER_INFO *)buf; 7091 ok(info->dwVersion == 0, "Expected version 0, got %d\n", 7092 info->dwVersion); 7093 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER, 7094 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n", 7095 info->SignerId.dwIdChoice); 7096 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData == 7097 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n", 7098 U(info->SignerId).IssuerSerialNumber.Issuer.cbData); 7099 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData, 7100 encodedCommonNameNoNull, 7101 U(info->SignerId).IssuerSerialNumber.Issuer.cbData), 7102 "Unexpected value\n"); 7103 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData == 7104 sizeof(serialNum), "Unexpected size %d\n", 7105 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData); 7106 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData, 7107 serialNum, sizeof(serialNum)), "Unexpected value\n"); 7108 LocalFree(buf); 7109 } 7110 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO, 7111 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo), 7112 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 7113 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 7114 if (ret) 7115 { 7116 info = (CMSG_CMS_SIGNER_INFO *)buf; 7117 ok(info->dwVersion == 0, "Expected version 0, got %d\n", 7118 info->dwVersion); 7119 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER, 7120 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n", 7121 info->SignerId.dwIdChoice); 7122 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData == 7123 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n", 7124 U(info->SignerId).IssuerSerialNumber.Issuer.cbData); 7125 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData, 7126 encodedCommonNameNoNull, 7127 U(info->SignerId).IssuerSerialNumber.Issuer.cbData), 7128 "Unexpected value\n"); 7129 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData == 7130 sizeof(serialNum), "Unexpected size %d\n", 7131 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData); 7132 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData, 7133 serialNum, sizeof(serialNum)), "Unexpected value\n"); 7134 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1), 7135 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId); 7136 LocalFree(buf); 7137 } 7138 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO, 7139 PKCSSignerWithHashAndEncryptionAlgo, 7140 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG, 7141 NULL, &buf, &size); 7142 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 7143 if (ret) 7144 { 7145 info = (CMSG_CMS_SIGNER_INFO *)buf; 7146 ok(info->dwVersion == 0, "Expected version 0, got %d\n", 7147 info->dwVersion); 7148 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER, 7149 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n", 7150 info->SignerId.dwIdChoice); 7151 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData == 7152 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n", 7153 U(info->SignerId).IssuerSerialNumber.Issuer.cbData); 7154 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData, 7155 encodedCommonNameNoNull, 7156 U(info->SignerId).IssuerSerialNumber.Issuer.cbData), 7157 "Unexpected value\n"); 7158 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData == 7159 sizeof(serialNum), "Unexpected size %d\n", 7160 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData); 7161 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData, 7162 serialNum, sizeof(serialNum)), "Unexpected value\n"); 7163 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1), 7164 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId); 7165 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2), 7166 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId); 7167 LocalFree(buf); 7168 } 7169 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO, 7170 PKCSSignerWithHash, sizeof(PKCSSignerWithHash), 7171 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 7172 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 7173 if (ret) 7174 { 7175 info = (CMSG_CMS_SIGNER_INFO *)buf; 7176 ok(info->dwVersion == 0, "Expected version 0, got %d\n", 7177 info->dwVersion); 7178 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER, 7179 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n", 7180 info->SignerId.dwIdChoice); 7181 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData == 7182 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n", 7183 U(info->SignerId).IssuerSerialNumber.Issuer.cbData); 7184 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData, 7185 encodedCommonNameNoNull, 7186 U(info->SignerId).IssuerSerialNumber.Issuer.cbData), 7187 "Unexpected value\n"); 7188 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData == 7189 sizeof(serialNum), "Unexpected size %d\n", 7190 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData); 7191 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData, 7192 serialNum, sizeof(serialNum)), "Unexpected value\n"); 7193 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1), 7194 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId); 7195 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2), 7196 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId); 7197 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n", 7198 info->EncryptedHash.cbData); 7199 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)), 7200 "Unexpected value\n"); 7201 LocalFree(buf); 7202 } 7203 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO, 7204 CMSSignerWithKeyId, sizeof(CMSSignerWithKeyId), 7205 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); 7206 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); 7207 if (ret) 7208 { 7209 info = (CMSG_CMS_SIGNER_INFO *)buf; 7210 ok(info->dwVersion == 0, "Expected version 0, got %d\n", 7211 info->dwVersion); 7212 ok(info->SignerId.dwIdChoice == CERT_ID_KEY_IDENTIFIER, 7213 "Expected CERT_ID_KEY_IDENTIFIER, got %d\n", 7214 info->SignerId.dwIdChoice); 7215 ok(U(info->SignerId).KeyId.cbData == sizeof(serialNum), 7216 "Unexpected size %d\n", U(info->SignerId).KeyId.cbData); 7217 ok(!memcmp(U(info->SignerId).KeyId.pbData, serialNum, sizeof(serialNum)), 7218 "Unexpected value\n"); 7219 LocalFree(buf); 7220 } 7221 } 7222 7223 static BYTE emptyDNSPermittedConstraints[] = { 7224 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 }; 7225 static BYTE emptyDNSExcludedConstraints[] = { 7226 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 }; 7227 static BYTE DNSExcludedConstraints[] = { 7228 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, 7229 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 }; 7230 static BYTE permittedAndExcludedConstraints[] = { 7231 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00, 7232 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, 7233 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 }; 7234 static BYTE permittedAndExcludedWithMinConstraints[] = { 7235 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00, 7236 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a, 7237 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 }; 7238 static BYTE permittedAndExcludedWithMinMaxConstraints[] = { 7239 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00, 7240 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74, 7241 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 }; 7242 7243 static void test_encodeNameConstraints(DWORD dwEncoding) 7244 { 7245 BOOL ret; 7246 CERT_NAME_CONSTRAINTS_INFO constraints = { 0 }; 7247 CERT_GENERAL_SUBTREE permitted = { { 0 } }; 7248 CERT_GENERAL_SUBTREE excluded = { { 0 } }; 7249 LPBYTE buf; 7250 DWORD size; 7251 7252 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints, 7253 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7254 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 7255 { 7256 skip("no X509_NAME_CONSTRAINTS encode support\n"); 7257 return; 7258 } 7259 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7260 if (ret) 7261 { 7262 ok(size == sizeof(emptySequence), "Unexpected size\n"); 7263 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n"); 7264 LocalFree(buf); 7265 } 7266 constraints.cPermittedSubtree = 1; 7267 constraints.rgPermittedSubtree = &permitted; 7268 SetLastError(0xdeadbeef); 7269 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints, 7270 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7271 ok(!ret && GetLastError() == E_INVALIDARG, 7272 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 7273 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME; 7274 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints, 7275 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7276 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7277 if (ret) 7278 { 7279 ok(size == sizeof(emptyDNSPermittedConstraints), "Unexpected size\n"); 7280 ok(!memcmp(buf, emptyDNSPermittedConstraints, size), 7281 "Unexpected value\n"); 7282 LocalFree(buf); 7283 } 7284 constraints.cPermittedSubtree = 0; 7285 constraints.cExcludedSubtree = 1; 7286 constraints.rgExcludedSubtree = &excluded; 7287 excluded.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME; 7288 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints, 7289 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7290 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7291 if (ret) 7292 { 7293 ok(size == sizeof(emptyDNSExcludedConstraints), "Unexpected size\n"); 7294 ok(!memcmp(buf, emptyDNSExcludedConstraints, size), 7295 "Unexpected value\n"); 7296 LocalFree(buf); 7297 } 7298 U(excluded.Base).pwszURL = (LPWSTR)url; 7299 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints, 7300 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7301 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7302 if (ret) 7303 { 7304 ok(size == sizeof(DNSExcludedConstraints), "Unexpected size\n"); 7305 ok(!memcmp(buf, DNSExcludedConstraints, size), 7306 "Unexpected value\n"); 7307 LocalFree(buf); 7308 } 7309 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS; 7310 U(permitted.Base).IPAddress.cbData = sizeof(encodedIPAddr); 7311 U(permitted.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr; 7312 constraints.cPermittedSubtree = 1; 7313 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints, 7314 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7315 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7316 if (ret) 7317 { 7318 ok(size == sizeof(permittedAndExcludedConstraints), 7319 "Unexpected size\n"); 7320 ok(!memcmp(buf, permittedAndExcludedConstraints, size), 7321 "Unexpected value\n"); 7322 LocalFree(buf); 7323 } 7324 permitted.dwMinimum = 5; 7325 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints, 7326 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7327 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7328 if (ret) 7329 { 7330 ok(size == sizeof(permittedAndExcludedWithMinConstraints), 7331 "Unexpected size\n"); 7332 ok(!memcmp(buf, permittedAndExcludedWithMinConstraints, size), 7333 "Unexpected value\n"); 7334 LocalFree(buf); 7335 } 7336 permitted.fMaximum = TRUE; 7337 permitted.dwMaximum = 3; 7338 SetLastError(0xdeadbeef); 7339 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints, 7340 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7341 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7342 if (ret) 7343 { 7344 ok(size == sizeof(permittedAndExcludedWithMinMaxConstraints), 7345 "Unexpected size\n"); 7346 ok(!memcmp(buf, permittedAndExcludedWithMinMaxConstraints, size), 7347 "Unexpected value\n"); 7348 LocalFree(buf); 7349 } 7350 } 7351 7352 struct EncodedNameConstraints 7353 { 7354 CRYPT_DATA_BLOB encoded; 7355 CERT_NAME_CONSTRAINTS_INFO constraints; 7356 }; 7357 7358 static CERT_GENERAL_SUBTREE emptyDNSSubtree = { 7359 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 }; 7360 static CERT_GENERAL_SUBTREE DNSSubtree = { 7361 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 }; 7362 static CERT_GENERAL_SUBTREE IPAddressSubtree = { 7363 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 0 }; 7364 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree = { 7365 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, 0 }; 7366 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree = { 7367 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, TRUE, 3 }; 7368 7369 static const struct EncodedNameConstraints encodedNameConstraints[] = { 7370 { { sizeof(emptySequence), (LPBYTE)emptySequence }, { 0 } }, 7371 { { sizeof(emptyDNSPermittedConstraints), emptyDNSPermittedConstraints }, 7372 { 1, &emptyDNSSubtree, 0, NULL } }, 7373 { { sizeof(emptyDNSExcludedConstraints), emptyDNSExcludedConstraints }, 7374 { 0, NULL, 1, &emptyDNSSubtree } }, 7375 { { sizeof(DNSExcludedConstraints), DNSExcludedConstraints }, 7376 { 0, NULL, 1, &DNSSubtree } }, 7377 { { sizeof(permittedAndExcludedConstraints), permittedAndExcludedConstraints }, 7378 { 1, &IPAddressSubtree, 1, &DNSSubtree } }, 7379 { { sizeof(permittedAndExcludedWithMinConstraints), 7380 permittedAndExcludedWithMinConstraints }, 7381 { 1, &IPAddressWithMinSubtree, 1, &DNSSubtree } }, 7382 { { sizeof(permittedAndExcludedWithMinMaxConstraints), 7383 permittedAndExcludedWithMinMaxConstraints }, 7384 { 1, &IPAddressWithMinMaxSubtree, 1, &DNSSubtree } }, 7385 }; 7386 7387 static void test_decodeNameConstraints(DWORD dwEncoding) 7388 { 7389 BOOL ret; 7390 DWORD i; 7391 CERT_NAME_CONSTRAINTS_INFO *constraints; 7392 7393 U(DNSSubtree.Base).pwszURL = (LPWSTR)url; 7394 U(IPAddressSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr); 7395 U(IPAddressSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr; 7396 U(IPAddressWithMinSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr); 7397 U(IPAddressWithMinSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr; 7398 U(IPAddressWithMinMaxSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr); 7399 U(IPAddressWithMinMaxSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr; 7400 for (i = 0; 7401 i < sizeof(encodedNameConstraints) / sizeof(encodedNameConstraints[0]); 7402 i++) 7403 { 7404 DWORD size; 7405 7406 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, 7407 encodedNameConstraints[i].encoded.pbData, 7408 encodedNameConstraints[i].encoded.cbData, 7409 CRYPT_DECODE_ALLOC_FLAG, NULL, &constraints, &size); 7410 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 7411 { 7412 skip("no X509_NAME_CONSTRAINTS decode support\n"); 7413 return; 7414 } 7415 ok(ret, "%d: CryptDecodeObjectEx failed: %08x\n", i, GetLastError()); 7416 if (ret) 7417 { 7418 DWORD j; 7419 7420 if (constraints->cPermittedSubtree != 7421 encodedNameConstraints[i].constraints.cPermittedSubtree) 7422 fprintf(stderr, "%d: expected %u permitted, got %u\n", i, 7423 encodedNameConstraints[i].constraints.cPermittedSubtree, 7424 constraints->cPermittedSubtree); 7425 if (constraints->cPermittedSubtree == 7426 encodedNameConstraints[i].constraints.cPermittedSubtree) 7427 { 7428 for (j = 0; j < constraints->cPermittedSubtree; j++) 7429 { 7430 compareAltNameEntry(&constraints->rgPermittedSubtree[j].Base, 7431 &encodedNameConstraints[i].constraints.rgPermittedSubtree[j].Base); 7432 } 7433 } 7434 if (constraints->cExcludedSubtree != 7435 encodedNameConstraints[i].constraints.cExcludedSubtree) 7436 fprintf(stderr, "%d: expected %u excluded, got %u\n", i, 7437 encodedNameConstraints[i].constraints.cExcludedSubtree, 7438 constraints->cExcludedSubtree); 7439 if (constraints->cExcludedSubtree == 7440 encodedNameConstraints[i].constraints.cExcludedSubtree) 7441 { 7442 for (j = 0; j < constraints->cExcludedSubtree; j++) 7443 { 7444 compareAltNameEntry(&constraints->rgExcludedSubtree[j].Base, 7445 &encodedNameConstraints[i].constraints.rgExcludedSubtree[j].Base); 7446 } 7447 } 7448 LocalFree(constraints); 7449 } 7450 } 7451 } 7452 7453 static WCHAR noticeText[] = { 'T','h','i','s',' ','i','s',' ','a',' ', 7454 'n','o','t','i','c','e',0 }; 7455 static const BYTE noticeWithDisplayText[] = { 7456 0x30,0x22,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,0x00, 7457 0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,0x74, 7458 0x00,0x69,0x00,0x63,0x00,0x65 7459 }; 7460 static char org[] = "Wine"; 7461 static int noticeNumbers[] = { 2,3 }; 7462 static BYTE noticeWithReference[] = { 7463 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02, 7464 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20, 7465 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00, 7466 0x74,0x00,0x69,0x00,0x63,0x00,0x65 7467 }; 7468 7469 static void test_encodePolicyQualifierUserNotice(DWORD dwEncoding) 7470 { 7471 BOOL ret; 7472 LPBYTE buf; 7473 DWORD size; 7474 CERT_POLICY_QUALIFIER_USER_NOTICE notice; 7475 CERT_POLICY_QUALIFIER_NOTICE_REFERENCE reference; 7476 7477 memset(¬ice, 0, sizeof(notice)); 7478 ret = pCryptEncodeObjectEx(dwEncoding, 7479 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, ¬ice, CRYPT_ENCODE_ALLOC_FLAG, 7480 NULL, &buf, &size); 7481 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 7482 { 7483 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE encode support\n"); 7484 return; 7485 } 7486 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7487 if (ret) 7488 { 7489 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size); 7490 ok(!memcmp(buf, emptySequence, size), "unexpected value\n"); 7491 LocalFree(buf); 7492 } 7493 notice.pszDisplayText = noticeText; 7494 ret = pCryptEncodeObjectEx(dwEncoding, 7495 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, ¬ice, CRYPT_ENCODE_ALLOC_FLAG, 7496 NULL, &buf, &size); 7497 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7498 if (ret) 7499 { 7500 ok(sizeof(noticeWithDisplayText) == size, "unexpected size %d\n", size); 7501 ok(!memcmp(buf, noticeWithDisplayText, size), "unexpected value\n"); 7502 LocalFree(buf); 7503 } 7504 reference.pszOrganization = org; 7505 reference.cNoticeNumbers = 2; 7506 reference.rgNoticeNumbers = noticeNumbers; 7507 notice.pNoticeReference = &reference; 7508 ret = pCryptEncodeObjectEx(dwEncoding, 7509 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, ¬ice, CRYPT_ENCODE_ALLOC_FLAG, 7510 NULL, &buf, &size); 7511 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7512 if (ret) 7513 { 7514 ok(sizeof(noticeWithReference) == size, "unexpected size %d\n", size); 7515 ok(!memcmp(buf, noticeWithReference, size), "unexpected value\n"); 7516 LocalFree(buf); 7517 } 7518 } 7519 7520 static void test_decodePolicyQualifierUserNotice(DWORD dwEncoding) 7521 { 7522 BOOL ret; 7523 CERT_POLICY_QUALIFIER_USER_NOTICE *notice; 7524 DWORD size; 7525 7526 ret = pCryptDecodeObjectEx(dwEncoding, 7527 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, 7528 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL, 7529 ¬ice, &size); 7530 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 7531 { 7532 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE decode support\n"); 7533 return; 7534 } 7535 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7536 if (ret) 7537 { 7538 ok(notice->pszDisplayText == NULL, "unexpected display text\n"); 7539 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n"); 7540 LocalFree(notice); 7541 } 7542 ret = pCryptDecodeObjectEx(dwEncoding, 7543 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, 7544 noticeWithDisplayText, sizeof(noticeWithDisplayText), 7545 CRYPT_DECODE_ALLOC_FLAG, NULL, ¬ice, &size); 7546 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7547 if (ret) 7548 { 7549 ok(!lstrcmpW(notice->pszDisplayText, noticeText), 7550 "unexpected display text\n"); 7551 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n"); 7552 LocalFree(notice); 7553 } 7554 ret = pCryptDecodeObjectEx(dwEncoding, 7555 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, 7556 noticeWithReference, sizeof(noticeWithReference), 7557 CRYPT_DECODE_ALLOC_FLAG, NULL, ¬ice, &size); 7558 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7559 if (ret) 7560 { 7561 ok(!lstrcmpW(notice->pszDisplayText, noticeText), 7562 "unexpected display text\n"); 7563 ok(notice->pNoticeReference != NULL, "expected a notice reference\n"); 7564 if (notice->pNoticeReference) 7565 { 7566 ok(!strcmp(notice->pNoticeReference->pszOrganization, org), 7567 "unexpected organization %s\n", 7568 notice->pNoticeReference->pszOrganization); 7569 ok(notice->pNoticeReference->cNoticeNumbers == 2, 7570 "expected 2 notice numbers, got %d\n", 7571 notice->pNoticeReference->cNoticeNumbers); 7572 ok(notice->pNoticeReference->rgNoticeNumbers[0] == noticeNumbers[0], 7573 "unexpected notice number %d\n", 7574 notice->pNoticeReference->rgNoticeNumbers[0]); 7575 ok(notice->pNoticeReference->rgNoticeNumbers[1] == noticeNumbers[1], 7576 "unexpected notice number %d\n", 7577 notice->pNoticeReference->rgNoticeNumbers[1]); 7578 } 7579 LocalFree(notice); 7580 } 7581 } 7582 7583 static char oid_any_policy[] = "2.5.29.32.0"; 7584 static const BYTE policiesWithAnyPolicy[] = { 7585 0x30,0x08,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00 7586 }; 7587 static char oid1[] = "1.2.3"; 7588 static char oid_user_notice[] = "1.3.6.1.5.5.7.2.2"; 7589 static const BYTE twoPolicies[] = { 7590 0x30,0x50,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00,0x30,0x46,0x06,0x02,0x2a, 7591 0x03,0x30,0x40,0x30,0x3e,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x02, 7592 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02, 7593 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20, 7594 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00, 7595 0x74,0x00,0x69,0x00,0x63,0x00,0x65 7596 }; 7597 7598 static void test_encodeCertPolicies(DWORD dwEncoding) 7599 { 7600 BOOL ret; 7601 CERT_POLICIES_INFO info; 7602 CERT_POLICY_INFO policy[2]; 7603 CERT_POLICY_QUALIFIER_INFO qualifier; 7604 LPBYTE buf; 7605 DWORD size; 7606 7607 memset(&info, 0, sizeof(info)); 7608 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info, 7609 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7610 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7611 if (ret) 7612 { 7613 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size); 7614 ok(!memcmp(buf, emptySequence, size), "unexpected value\n"); 7615 LocalFree(buf); 7616 } 7617 memset(policy, 0, sizeof(policy)); 7618 info.cPolicyInfo = 1; 7619 info.rgPolicyInfo = policy; 7620 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info, 7621 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7622 ok(!ret && (GetLastError() == E_INVALIDARG || 7623 GetLastError() == OSS_LIMITED /* Win9x/NT4 */), 7624 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError()); 7625 policy[0].pszPolicyIdentifier = oid_any_policy; 7626 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info, 7627 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7628 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7629 if (ret) 7630 { 7631 ok(sizeof(policiesWithAnyPolicy) == size, "unexpected size %d\n", size); 7632 ok(!memcmp(buf, policiesWithAnyPolicy, size), "unexpected value\n"); 7633 LocalFree(buf); 7634 } 7635 policy[1].pszPolicyIdentifier = oid1; 7636 memset(&qualifier, 0, sizeof(qualifier)); 7637 qualifier.pszPolicyQualifierId = oid_user_notice; 7638 qualifier.Qualifier.cbData = sizeof(noticeWithReference); 7639 qualifier.Qualifier.pbData = noticeWithReference; 7640 policy[1].cPolicyQualifier = 1; 7641 policy[1].rgPolicyQualifier = &qualifier; 7642 info.cPolicyInfo = 2; 7643 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info, 7644 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7645 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7646 if (ret) 7647 { 7648 ok(sizeof(twoPolicies) == size, "unexpected size %d\n", size); 7649 ok(!memcmp(buf, twoPolicies, size), "unexpected value\n"); 7650 LocalFree(buf); 7651 } 7652 } 7653 7654 static void test_decodeCertPolicies(DWORD dwEncoding) 7655 { 7656 BOOL ret; 7657 CERT_POLICIES_INFO *info; 7658 DWORD size; 7659 7660 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES, 7661 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL, 7662 &info, &size); 7663 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7664 if (ret) 7665 { 7666 ok(info->cPolicyInfo == 0, "unexpected policy info %d\n", 7667 info->cPolicyInfo); 7668 LocalFree(info); 7669 } 7670 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES, 7671 policiesWithAnyPolicy, sizeof(policiesWithAnyPolicy), 7672 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size); 7673 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7674 if (ret) 7675 { 7676 ok(info->cPolicyInfo == 1, "unexpected policy info %d\n", 7677 info->cPolicyInfo); 7678 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy), 7679 "unexpected policy id %s\n", 7680 info->rgPolicyInfo[0].pszPolicyIdentifier); 7681 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0, 7682 "unexpected policy qualifier count %d\n", 7683 info->rgPolicyInfo[0].cPolicyQualifier); 7684 LocalFree(info); 7685 } 7686 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES, 7687 twoPolicies, sizeof(twoPolicies), 7688 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size); 7689 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7690 if (ret) 7691 { 7692 ok(info->cPolicyInfo == 2, "unexpected policy info %d\n", 7693 info->cPolicyInfo); 7694 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy), 7695 "unexpected policy id %s\n", 7696 info->rgPolicyInfo[0].pszPolicyIdentifier); 7697 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0, 7698 "unexpected policy qualifier count %d\n", 7699 info->rgPolicyInfo[0].cPolicyQualifier); 7700 ok(!strcmp(info->rgPolicyInfo[1].pszPolicyIdentifier, oid1), 7701 "unexpected policy id %s\n", 7702 info->rgPolicyInfo[1].pszPolicyIdentifier); 7703 ok(info->rgPolicyInfo[1].cPolicyQualifier == 1, 7704 "unexpected policy qualifier count %d\n", 7705 info->rgPolicyInfo[1].cPolicyQualifier); 7706 ok(!strcmp( 7707 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId, 7708 oid_user_notice), "unexpected policy qualifier id %s\n", 7709 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId); 7710 ok(info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData == 7711 sizeof(noticeWithReference), "unexpected qualifier size %d\n", 7712 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData); 7713 ok(!memcmp( 7714 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.pbData, 7715 noticeWithReference, sizeof(noticeWithReference)), 7716 "unexpected qualifier value\n"); 7717 LocalFree(info); 7718 } 7719 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES, 7720 twoPolicies, sizeof(twoPolicies), 0, NULL, NULL, &size); 7721 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7722 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); 7723 if (info) 7724 { 7725 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES, 7726 twoPolicies, sizeof(twoPolicies), 0, NULL, info, &size); 7727 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7728 HeapFree(GetProcessHeap(), 0, info); 7729 } 7730 } 7731 7732 static const BYTE policyMappingWithOneMapping[] = { 7733 0x30,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04 }; 7734 static const BYTE policyMappingWithTwoMappings[] = { 7735 0x30,0x14,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04,0x30,0x08,0x06, 7736 0x02,0x2b,0x04,0x06,0x02,0x55,0x06 }; 7737 static const LPCSTR mappingOids[] = { X509_POLICY_MAPPINGS, 7738 szOID_POLICY_MAPPINGS, szOID_LEGACY_POLICY_MAPPINGS }; 7739 7740 static void test_encodeCertPolicyMappings(DWORD dwEncoding) 7741 { 7742 static char oid2[] = "2.3.4"; 7743 static char oid3[] = "1.3.4"; 7744 static char oid4[] = "2.5.6"; 7745 BOOL ret; 7746 CERT_POLICY_MAPPINGS_INFO info = { 0 }; 7747 CERT_POLICY_MAPPING mapping[2]; 7748 LPBYTE buf; 7749 DWORD size, i; 7750 7751 /* Each of the mapping OIDs is equivalent, so check with all of them */ 7752 for (i = 0; i < sizeof(mappingOids) / sizeof(mappingOids[0]); i++) 7753 { 7754 memset(&info, 0, sizeof(info)); 7755 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info, 7756 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7757 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND), 7758 "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7759 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 7760 { 7761 win_skip("no policy mappings support\n"); 7762 return; 7763 } 7764 if (ret) 7765 { 7766 ok(size == sizeof(emptySequence), "unexpected size %d\n", size); 7767 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)), 7768 "unexpected value\n"); 7769 LocalFree(buf); 7770 } 7771 mapping[0].pszIssuerDomainPolicy = NULL; 7772 mapping[0].pszSubjectDomainPolicy = NULL; 7773 info.cPolicyMapping = 1; 7774 info.rgPolicyMapping = mapping; 7775 SetLastError(0xdeadbeef); 7776 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info, 7777 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7778 ok(!ret && GetLastError() == E_INVALIDARG, 7779 "expected E_INVALIDARG, got %08x\n", GetLastError()); 7780 mapping[0].pszIssuerDomainPolicy = oid1; 7781 mapping[0].pszSubjectDomainPolicy = oid2; 7782 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info, 7783 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7784 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7785 if (ret) 7786 { 7787 ok(size == sizeof(policyMappingWithOneMapping), 7788 "unexpected size %d\n", size); 7789 ok(!memcmp(buf, policyMappingWithOneMapping, size), 7790 "unexpected value\n"); 7791 LocalFree(buf); 7792 } 7793 mapping[1].pszIssuerDomainPolicy = oid3; 7794 mapping[1].pszSubjectDomainPolicy = oid4; 7795 info.cPolicyMapping = 2; 7796 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info, 7797 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7798 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7799 if (ret) 7800 { 7801 ok(size == sizeof(policyMappingWithTwoMappings), 7802 "unexpected size %d\n", size); 7803 ok(!memcmp(buf, policyMappingWithTwoMappings, size), 7804 "unexpected value\n"); 7805 LocalFree(buf); 7806 } 7807 } 7808 } 7809 7810 static void test_decodeCertPolicyMappings(DWORD dwEncoding) 7811 { 7812 DWORD size, i; 7813 CERT_POLICY_MAPPINGS_INFO *info; 7814 BOOL ret; 7815 7816 /* Each of the mapping OIDs is equivalent, so check with all of them */ 7817 for (i = 0; i < sizeof(mappingOids) / sizeof(mappingOids[0]); i++) 7818 { 7819 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i], 7820 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL, 7821 &info, &size); 7822 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND), 7823 "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7824 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 7825 { 7826 win_skip("no policy mappings support\n"); 7827 return; 7828 } 7829 if (ret) 7830 { 7831 ok(info->cPolicyMapping == 0, 7832 "expected 0 policy mappings, got %d\n", info->cPolicyMapping); 7833 LocalFree(info); 7834 } 7835 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i], 7836 policyMappingWithOneMapping, sizeof(policyMappingWithOneMapping), 7837 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size); 7838 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7839 if (ret) 7840 { 7841 ok(info->cPolicyMapping == 1, 7842 "expected 1 policy mappings, got %d\n", info->cPolicyMapping); 7843 ok(!strcmp(info->rgPolicyMapping[0].pszIssuerDomainPolicy, "1.2.3"), 7844 "unexpected issuer policy %s\n", 7845 info->rgPolicyMapping[0].pszIssuerDomainPolicy); 7846 ok(!strcmp(info->rgPolicyMapping[0].pszSubjectDomainPolicy, 7847 "2.3.4"), "unexpected subject policy %s\n", 7848 info->rgPolicyMapping[0].pszSubjectDomainPolicy); 7849 LocalFree(info); 7850 } 7851 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i], 7852 policyMappingWithTwoMappings, sizeof(policyMappingWithTwoMappings), 7853 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size); 7854 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7855 if (ret) 7856 { 7857 ok(info->cPolicyMapping == 2, 7858 "expected 2 policy mappings, got %d\n", info->cPolicyMapping); 7859 ok(!strcmp(info->rgPolicyMapping[0].pszIssuerDomainPolicy, "1.2.3"), 7860 "unexpected issuer policy %s\n", 7861 info->rgPolicyMapping[0].pszIssuerDomainPolicy); 7862 ok(!strcmp(info->rgPolicyMapping[0].pszSubjectDomainPolicy, 7863 "2.3.4"), "unexpected subject policy %s\n", 7864 info->rgPolicyMapping[0].pszSubjectDomainPolicy); 7865 ok(!strcmp(info->rgPolicyMapping[1].pszIssuerDomainPolicy, "1.3.4"), 7866 "unexpected issuer policy %s\n", 7867 info->rgPolicyMapping[1].pszIssuerDomainPolicy); 7868 ok(!strcmp(info->rgPolicyMapping[1].pszSubjectDomainPolicy, 7869 "2.5.6"), "unexpected subject policy %s\n", 7870 info->rgPolicyMapping[1].pszSubjectDomainPolicy); 7871 LocalFree(info); 7872 } 7873 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i], 7874 policyMappingWithTwoMappings, sizeof(policyMappingWithTwoMappings), 0, 7875 NULL, NULL, &size); 7876 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7877 info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); 7878 if (info) 7879 { 7880 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i], 7881 policyMappingWithTwoMappings, sizeof(policyMappingWithTwoMappings), 0, 7882 NULL, info, &size); 7883 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7884 HeapFree(GetProcessHeap(), 0, info); 7885 } 7886 } 7887 } 7888 7889 static const BYTE policyConstraintsWithRequireExplicit[] = { 7890 0x30,0x03,0x80,0x01,0x00 }; 7891 static const BYTE policyConstraintsWithInhibitMapping[] = { 7892 0x30,0x03,0x81,0x01,0x01 }; 7893 static const BYTE policyConstraintsWithBoth[] = { 7894 0x30,0x06,0x80,0x01,0x01,0x81,0x01,0x01 }; 7895 7896 static void test_encodeCertPolicyConstraints(DWORD dwEncoding) 7897 { 7898 CERT_POLICY_CONSTRAINTS_INFO info = { 0 }; 7899 LPBYTE buf; 7900 DWORD size; 7901 BOOL ret; 7902 7903 /* Even though RFC 5280 explicitly states CAs must not issue empty 7904 * policy constraints (section 4.2.1.11), the API doesn't prevent it. 7905 */ 7906 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info, 7907 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7908 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND), 7909 "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7910 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 7911 { 7912 win_skip("no policy constraints support\n"); 7913 return; 7914 } 7915 if (ret) 7916 { 7917 ok(size == sizeof(emptySequence), "unexpected size %d\n", size); 7918 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)), 7919 "unexpected value\n"); 7920 LocalFree(buf); 7921 } 7922 /* If fRequireExplicitPolicy is set but dwRequireExplicitPolicySkipCerts 7923 * is not, then a skip of 0 is encoded. 7924 */ 7925 info.fRequireExplicitPolicy = TRUE; 7926 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info, 7927 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7928 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7929 if (ret) 7930 { 7931 ok(size == sizeof(policyConstraintsWithRequireExplicit), 7932 "unexpected size %d\n", size); 7933 ok(!memcmp(buf, policyConstraintsWithRequireExplicit, 7934 sizeof(policyConstraintsWithRequireExplicit)), "unexpected value\n"); 7935 LocalFree(buf); 7936 } 7937 /* With inhibit policy mapping */ 7938 info.fRequireExplicitPolicy = FALSE; 7939 info.dwRequireExplicitPolicySkipCerts = 0; 7940 info.fInhibitPolicyMapping = TRUE; 7941 info.dwInhibitPolicyMappingSkipCerts = 1; 7942 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info, 7943 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7944 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7945 if (ret) 7946 { 7947 ok(size == sizeof(policyConstraintsWithInhibitMapping), 7948 "unexpected size %d\n", size); 7949 ok(!memcmp(buf, policyConstraintsWithInhibitMapping, 7950 sizeof(policyConstraintsWithInhibitMapping)), "unexpected value\n"); 7951 LocalFree(buf); 7952 } 7953 /* And with both */ 7954 info.fRequireExplicitPolicy = TRUE; 7955 info.dwRequireExplicitPolicySkipCerts = 1; 7956 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info, 7957 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); 7958 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); 7959 if (ret) 7960 { 7961 ok(size == sizeof(policyConstraintsWithBoth), "unexpected size %d\n", 7962 size); 7963 ok(!memcmp(buf, policyConstraintsWithBoth, 7964 sizeof(policyConstraintsWithBoth)), "unexpected value\n"); 7965 LocalFree(buf); 7966 } 7967 } 7968 7969 static void test_decodeCertPolicyConstraints(DWORD dwEncoding) 7970 { 7971 CERT_POLICY_CONSTRAINTS_INFO *info; 7972 DWORD size; 7973 BOOL ret; 7974 7975 /* Again, even though CAs must not issue such constraints, they can be 7976 * decoded. 7977 */ 7978 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, 7979 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL, 7980 &info, &size); 7981 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND), 7982 "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 7983 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) 7984 { 7985 win_skip("no policy mappings support\n"); 7986 return; 7987 } 7988 if (ret) 7989 { 7990 ok(!info->fRequireExplicitPolicy, 7991 "expected require explicit = FALSE\n"); 7992 ok(!info->fInhibitPolicyMapping, 7993 "expected implicit mapping = FALSE\n"); 7994 LocalFree(info); 7995 } 7996 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, 7997 policyConstraintsWithRequireExplicit, 7998 sizeof(policyConstraintsWithRequireExplicit), CRYPT_DECODE_ALLOC_FLAG, 7999 NULL, &info, &size); 8000 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 8001 if (ret) 8002 { 8003 ok(info->fRequireExplicitPolicy, 8004 "expected require explicit = TRUE\n"); 8005 ok(info->dwRequireExplicitPolicySkipCerts == 0, "expected 0, got %d\n", 8006 info->dwRequireExplicitPolicySkipCerts); 8007 ok(!info->fInhibitPolicyMapping, 8008 "expected implicit mapping = FALSE\n"); 8009 LocalFree(info); 8010 } 8011 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, 8012 policyConstraintsWithInhibitMapping, 8013 sizeof(policyConstraintsWithInhibitMapping), CRYPT_DECODE_ALLOC_FLAG, 8014 NULL, &info, &size); 8015 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 8016 if (ret) 8017 { 8018 ok(!info->fRequireExplicitPolicy, 8019 "expected require explicit = FALSE\n"); 8020 ok(info->fInhibitPolicyMapping, 8021 "expected implicit mapping = TRUE\n"); 8022 ok(info->dwInhibitPolicyMappingSkipCerts == 1, "expected 1, got %d\n", 8023 info->dwInhibitPolicyMappingSkipCerts); 8024 LocalFree(info); 8025 } 8026 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, 8027 policyConstraintsWithBoth, sizeof(policyConstraintsWithBoth), 8028 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size); 8029 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 8030 if (ret) 8031 { 8032 ok(info->fRequireExplicitPolicy, 8033 "expected require explicit = TRUE\n"); 8034 ok(info->dwRequireExplicitPolicySkipCerts == 1, "expected 1, got %d\n", 8035 info->dwRequireExplicitPolicySkipCerts); 8036 ok(info->fInhibitPolicyMapping, 8037 "expected implicit mapping = TRUE\n"); 8038 ok(info->dwInhibitPolicyMappingSkipCerts == 1, "expected 1, got %d\n", 8039 info->dwInhibitPolicyMappingSkipCerts); 8040 LocalFree(info); 8041 } 8042 } 8043 8044 static const BYTE rsaPrivKeyDer[] = { 8045 0x30,0x82,0x04,0xa5,0x02,0x01,0x00,0x02,0x82,0x01,0x01,0x00, 8046 0xae,0xba,0x3c,0x41,0xeb,0x25,0x41,0xb0,0x1c,0x41,0xd4,0x26, 8047 0xf9,0xf8,0x31,0x64,0x7e,0x97,0x65,0x54,0x9c,0x90,0xdf,0x34, 8048 0x07,0xfb,0xb0,0x69,0x99,0x3b,0x45,0x39,0x06,0xe4,0x3a,0x7a, 8049 0x01,0xe0,0xeb,0x3f,0xe1,0xd5,0x91,0xe0,0x16,0xe0,0xf2,0x35, 8050 0x59,0xdf,0x32,0x2d,0x69,0x3a,0x4a,0xbc,0xd1,0xba,0x1b,0x3b, 8051 0x7a,0x55,0x76,0xba,0x11,0xdd,0x2f,0xc7,0x58,0x66,0xf2,0x6c, 8052 0xd1,0x68,0x27,0x6c,0x85,0x74,0x0b,0xc9,0x7b,0x1a,0xde,0x3c, 8053 0x62,0x73,0xe2,0x9e,0x36,0x3a,0x29,0x3b,0x91,0x85,0x3d,0xd2, 8054 0xe1,0xe5,0x61,0x84,0x1e,0x28,0xfd,0xb7,0x97,0x68,0xc1,0xbb, 8055 0x0f,0x93,0x14,0xc2,0x03,0x60,0x41,0x11,0x7a,0xda,0x76,0x01, 8056 0x65,0x08,0xe6,0x0c,0xf6,0xfc,0x1d,0x64,0x12,0x7b,0x42,0xb0, 8057 0xb8,0xfe,0x61,0xe5,0xe2,0xe5,0x61,0x44,0xcc,0x94,0xe8,0xc0, 8058 0x4f,0x58,0x9a,0xea,0x99,0xaf,0x9c,0xa4,0xf2,0xd7,0x2b,0x31, 8059 0x90,0x3b,0x41,0x2e,0x4a,0x74,0x7c,0x1a,0xfc,0x42,0xa9,0x17, 8060 0xff,0x53,0x20,0x76,0xa7,0xf0,0x2c,0xb9,0xd5,0x1f,0xa9,0x8a, 8061 0x77,0xa8,0x09,0x5c,0x0e,0xd1,0x54,0xc5,0xf2,0x86,0xf1,0x2f, 8062 0x23,0xd6,0x63,0xba,0xe9,0x2b,0x73,0xf9,0xf0,0xdc,0xcb,0xf9, 8063 0xcb,0xe8,0x40,0x62,0x47,0x09,0x85,0xe1,0x9c,0xfd,0xcf,0x75, 8064 0x5a,0x65,0xfd,0x86,0x1c,0x50,0xfa,0x24,0x36,0x0f,0x54,0x5e, 8065 0x81,0xe7,0xf6,0x63,0x2d,0x87,0x0c,0x50,0x03,0x25,0x49,0xe7, 8066 0xc5,0x20,0xaa,0xbc,0x6c,0xf9,0xbe,0x49,0x8f,0x4f,0xb8,0x9a, 8067 0x73,0x9f,0x55,0x43,0x02,0x03,0x01,0x00,0x01,0x02,0x82,0x01, 8068 0x01,0x00,0x99,0x03,0xcd,0x5b,0x69,0x03,0x32,0x98,0x78,0xd6, 8069 0x89,0x65,0x2c,0xc9,0xd6,0xef,0x8c,0x11,0x27,0x93,0x46,0x9d, 8070 0x74,0x6a,0xcb,0x86,0xf6,0x02,0x34,0x47,0xfc,0xa2,0x29,0x4f, 8071 0xdb,0x8a,0x17,0x75,0x12,0x6f,0xda,0x65,0x3f,0x1f,0xc0,0xc9, 8072 0x74,0x33,0x96,0xa5,0xe8,0xfa,0x6d,0xc9,0xb7,0xc3,0xcd,0xe3, 8073 0x2e,0x90,0x12,0xdd,0x1f,0x61,0x69,0xdd,0x8b,0x47,0x07,0x3a, 8074 0xf8,0x98,0xa5,0x76,0x91,0xf7,0xee,0x93,0x26,0xf3,0x66,0x54, 8075 0xac,0x44,0xb3,0x6f,0x8b,0x09,0x44,0xb2,0x00,0x84,0x03,0x37, 8076 0x6d,0x61,0xed,0xa4,0x04,0x97,0x40,0x16,0x63,0xc2,0xd0,0xdc, 8077 0xd3,0xb3,0xee,0xba,0xbe,0x95,0xfd,0x80,0xe0,0xda,0xde,0xfc, 8078 0xcc,0x15,0x02,0x97,0x1d,0x68,0x43,0x2f,0x9c,0xc8,0x20,0x23, 8079 0xeb,0x00,0x4c,0x74,0x3d,0x27,0x20,0x14,0x23,0x95,0xfc,0x8c, 8080 0xb7,0x7e,0x7f,0xb0,0xdb,0xaf,0x8a,0x48,0x1b,0xfe,0x59,0xab, 8081 0x75,0xe2,0xbf,0x69,0xf2,0x73,0xe3,0xb9,0x92,0xa9,0x90,0x03, 8082 0xe5,0xd4,0x2d,0x86,0xff,0x12,0x54,0xb3,0xbb,0xe2,0xce,0x81, 8083 0x58,0x71,0xa4,0xde,0x45,0x05,0xf8,0x2d,0x45,0xf5,0xd8,0x5e, 8084 0x4c,0x5d,0x06,0x69,0x0c,0x86,0x9f,0x66,0x9f,0xb1,0x60,0xfd, 8085 0xf2,0x33,0x85,0x15,0xd5,0x18,0xf7,0xba,0x99,0x65,0x15,0x1d, 8086 0xfa,0xaa,0x76,0xdd,0x25,0xed,0xdf,0x90,0x6e,0xba,0x61,0x96, 8087 0x79,0xde,0xd2,0xda,0x66,0x03,0x74,0x3b,0x13,0x39,0x68,0xbc, 8088 0x94,0x01,0x00,0x2d,0xf8,0xf0,0x8c,0xbd,0x4c,0x9c,0x7e,0x87, 8089 0x9c,0x62,0x9f,0xb6,0x90,0x11,0x02,0x81,0x81,0x00,0xe3,0x5e, 8090 0xfe,0xdd,0xed,0x76,0xb6,0x4e,0xfc,0x5b,0xe0,0x20,0x99,0x7b, 8091 0x48,0x3b,0x1e,0x5f,0x7f,0x9f,0xa4,0x68,0xbe,0xc3,0x7f,0xb8, 8092 0x62,0x98,0xb0,0x95,0x8a,0xfa,0x0d,0xa3,0x79,0x63,0x39,0xf7, 8093 0xdb,0x76,0x3d,0x53,0x4a,0x0a,0x33,0xdf,0xe0,0x47,0x22,0xd5, 8094 0x96,0x80,0xc7,0xcd,0x24,0xef,0xac,0x49,0x46,0x37,0x6c,0x25, 8095 0xcf,0x6c,0x4d,0xe5,0x31,0xf8,0x2f,0xd2,0x59,0x74,0x00,0x38, 8096 0xdb,0xce,0xd1,0x72,0xc3,0xa8,0x30,0x70,0xd8,0x02,0x20,0xe7, 8097 0x56,0xe7,0xca,0xf0,0x3b,0x52,0x5d,0x11,0xbe,0x53,0x4e,0xd0, 8098 0xd9,0x2e,0xa6,0xb8,0xe2,0xd9,0xbf,0xb9,0x77,0xe7,0x3b,0xed, 8099 0x5e,0xd7,0x16,0x4a,0x3a,0xc5,0x86,0xd7,0x74,0x20,0xa7,0x8e, 8100 0xbf,0xb7,0x33,0xdb,0x51,0xe9,0x02,0x81,0x81,0x00,0xc4,0xba, 8101 0x57,0xf0,0x6e,0xcf,0xe8,0xce,0xce,0x9d,0x4a,0xe9,0x0f,0xe1, 8102 0xab,0x91,0x62,0xaa,0x66,0x5d,0x82,0x66,0x1c,0x72,0x18,0x6f, 8103 0x68,0x9c,0x7d,0x5e,0xfc,0xaf,0x4a,0xd6,0x8e,0xc6,0xae,0x40, 8104 0xf2,0x40,0x84,0x93,0xee,0x7c,0x87,0xa9,0xa6,0xcd,0x2b,0xc3, 8105 0xe6,0x29,0x3a,0xe2,0x4a,0xed,0xb0,0x4d,0x9f,0xc0,0xe9,0xd6, 8106 0xa3,0xca,0x97,0xee,0xac,0xab,0xa4,0x32,0x05,0x40,0x4d,0xf2, 8107 0x95,0x99,0xaf,0xa0,0xe1,0xe1,0xe7,0x3a,0x64,0xa4,0x70,0x6b, 8108 0x3d,0x1d,0x7b,0xf1,0x53,0xfa,0xb0,0xe0,0xe2,0x68,0x1a,0x61, 8109 0x2c,0x37,0xa5,0x39,0x7b,0xb2,0xcf,0xe6,0x5f,0x9b,0xc6,0x64, 8110 0xaf,0x48,0x86,0xfb,0xc1,0xf3,0x39,0x97,0x10,0x36,0xf5,0xa9, 8111 0x3d,0x08,0xa5,0x2f,0xe6,0x4b,0x02,0x81,0x81,0x00,0x86,0xe7, 8112 0x02,0x08,0xe2,0xaf,0xa0,0x93,0x54,0x9f,0x9e,0x67,0x39,0x29, 8113 0x30,0x3e,0x03,0x53,0x5e,0x01,0x76,0x26,0xbf,0xa8,0x76,0xcb, 8114 0x0b,0x94,0xd4,0x90,0xa5,0x98,0x9f,0x26,0xf3,0x0a,0xb0,0x86, 8115 0x22,0xac,0x10,0xce,0xae,0x0b,0x47,0xa3,0xf9,0x09,0xbb,0xdd, 8116 0x46,0x22,0xba,0x69,0x39,0x15,0x0a,0xff,0x9e,0xad,0x9b,0x79, 8117 0x03,0x8c,0x9a,0xda,0xf5,0xbe,0xef,0x80,0xba,0x9a,0x5c,0xd7, 8118 0x5f,0x73,0x62,0x49,0xd9,0x54,0x9d,0x09,0x16,0xe0,0x8c,0x6d, 8119 0x35,0xde,0xe9,0x45,0x87,0xac,0xe2,0x93,0x78,0x7d,0x2d,0x32, 8120 0x34,0xe9,0xbc,0xf9,0xcd,0x7e,0xac,0x86,0x7a,0x61,0xb3,0xe8, 8121 0xae,0x70,0xa7,0x44,0xfb,0x81,0xde,0xf3,0x4e,0x6f,0x61,0x7b, 8122 0x0c,0xbc,0xc2,0x03,0xca,0xa1,0x02,0x81,0x80,0x69,0x5b,0x4a, 8123 0xa1,0x4f,0x17,0x35,0x9d,0x1b,0xf6,0x0d,0x1a,0x48,0x11,0x19, 8124 0xab,0x20,0xe6,0x15,0x30,0x5b,0x17,0x88,0x80,0x6a,0x29,0xb0, 8125 0x22,0xae,0xd9,0xe2,0x05,0x96,0xd4,0xd5,0x5d,0xfe,0x10,0x76, 8126 0x2c,0xab,0x53,0xf6,0x52,0xe6,0xec,0xaa,0x92,0x12,0xb0,0x35, 8127 0x61,0x3b,0x51,0xd9,0xc2,0xf5,0xba,0x7c,0xa5,0xfa,0x15,0xa3, 8128 0x5e,0x6a,0x83,0xbe,0x21,0xa6,0x2b,0xcb,0xb8,0x26,0x86,0x96, 8129 0x2b,0xda,0x6d,0x14,0xcb,0xc0,0xe3,0xfa,0xe6,0x3d,0xf6,0x90, 8130 0xa2,0x6b,0xb0,0x50,0xc3,0x5f,0x5a,0xf0,0xa5,0xc4,0x0a,0xea, 8131 0x7d,0x5a,0x95,0x30,0x74,0x10,0xf7,0x55,0x98,0xbd,0x65,0x4a, 8132 0xa2,0x52,0xf8,0x1d,0x64,0xbf,0x20,0xf1,0xe4,0x1d,0x28,0x67, 8133 0xb1,0x6b,0x95,0xfd,0x85,0x02,0x81,0x81,0x00,0xda,0xb4,0x31, 8134 0x34,0xe1,0xec,0x9a,0x1e,0x07,0xd7,0xda,0x20,0x46,0xbf,0x6b, 8135 0xf0,0x45,0xbd,0x50,0xa2,0x0f,0x8a,0x14,0x51,0x52,0x83,0x7c, 8136 0x47,0xc8,0x9c,0x4e,0x68,0x6b,0xae,0x00,0x25,0x63,0xdd,0x13, 8137 0x2a,0x66,0x65,0xb6,0x74,0x91,0x5b,0xb6,0x47,0x3e,0x8e,0x46, 8138 0x62,0xcd,0x9d,0xc1,0xf7,0x14,0x14,0xbc,0x60,0xd6,0x3c,0x7c, 8139 0x3a,0xce,0xff,0x96,0x04,0x84,0xf6,0x44,0x1a,0xf8,0xdb,0x40, 8140 0x1c,0xf2,0xf1,0x4d,0xb2,0x68,0x3e,0xa3,0x0b,0xc6,0xb1,0xd0, 8141 0xa6,0x88,0x18,0x68,0xa1,0x05,0x2a,0xfc,0x2b,0x3a,0xa1,0xe6, 8142 0x31,0x4a,0x46,0x88,0x39,0x1e,0x44,0x11,0x6c,0xc5,0x8b,0xb6, 8143 0x8b,0xce,0x3d,0xd5,0xcb,0xbd,0xf0,0xd4,0xd9,0xfb,0x02,0x35, 8144 0x96,0x39,0x26,0x85,0xf9 }; 8145 static const BYTE rsaPrivKeyModulus[] = { 8146 0x43,0x55,0x9f,0x73,0x9a,0xb8,0x4f,0x8f,0x49,0xbe,0xf9,0x6c, 8147 0xbc,0xaa,0x20,0xc5,0xe7,0x49,0x25,0x03,0x50,0x0c,0x87,0x2d, 8148 0x63,0xf6,0xe7,0x81,0x5e,0x54,0x0f,0x36,0x24,0xfa,0x50,0x1c, 8149 0x86,0xfd,0x65,0x5a,0x75,0xcf,0xfd,0x9c,0xe1,0x85,0x09,0x47, 8150 0x62,0x40,0xe8,0xcb,0xf9,0xcb,0xdc,0xf0,0xf9,0x73,0x2b,0xe9, 8151 0xba,0x63,0xd6,0x23,0x2f,0xf1,0x86,0xf2,0xc5,0x54,0xd1,0x0e, 8152 0x5c,0x09,0xa8,0x77,0x8a,0xa9,0x1f,0xd5,0xb9,0x2c,0xf0,0xa7, 8153 0x76,0x20,0x53,0xff,0x17,0xa9,0x42,0xfc,0x1a,0x7c,0x74,0x4a, 8154 0x2e,0x41,0x3b,0x90,0x31,0x2b,0xd7,0xf2,0xa4,0x9c,0xaf,0x99, 8155 0xea,0x9a,0x58,0x4f,0xc0,0xe8,0x94,0xcc,0x44,0x61,0xe5,0xe2, 8156 0xe5,0x61,0xfe,0xb8,0xb0,0x42,0x7b,0x12,0x64,0x1d,0xfc,0xf6, 8157 0x0c,0xe6,0x08,0x65,0x01,0x76,0xda,0x7a,0x11,0x41,0x60,0x03, 8158 0xc2,0x14,0x93,0x0f,0xbb,0xc1,0x68,0x97,0xb7,0xfd,0x28,0x1e, 8159 0x84,0x61,0xe5,0xe1,0xd2,0x3d,0x85,0x91,0x3b,0x29,0x3a,0x36, 8160 0x9e,0xe2,0x73,0x62,0x3c,0xde,0x1a,0x7b,0xc9,0x0b,0x74,0x85, 8161 0x6c,0x27,0x68,0xd1,0x6c,0xf2,0x66,0x58,0xc7,0x2f,0xdd,0x11, 8162 0xba,0x76,0x55,0x7a,0x3b,0x1b,0xba,0xd1,0xbc,0x4a,0x3a,0x69, 8163 0x2d,0x32,0xdf,0x59,0x35,0xf2,0xe0,0x16,0xe0,0x91,0xd5,0xe1, 8164 0x3f,0xeb,0xe0,0x01,0x7a,0x3a,0xe4,0x06,0x39,0x45,0x3b,0x99, 8165 0x69,0xb0,0xfb,0x07,0x34,0xdf,0x90,0x9c,0x54,0x65,0x97,0x7e, 8166 0x64,0x31,0xf8,0xf9,0x26,0xd4,0x41,0x1c,0xb0,0x41,0x25,0xeb, 8167 0x41,0x3c,0xba,0xae }; 8168 static const BYTE rsaPrivKeyPrime1[] = { 8169 0xe9,0x51,0xdb,0x33,0xb7,0xbf,0x8e,0xa7,0x20,0x74,0xd7,0x86, 8170 0xc5,0x3a,0x4a,0x16,0xd7,0x5e,0xed,0x3b,0xe7,0x77,0xb9,0xbf, 8171 0xd9,0xe2,0xb8,0xa6,0x2e,0xd9,0xd0,0x4e,0x53,0xbe,0x11,0x5d, 8172 0x52,0x3b,0xf0,0xca,0xe7,0x56,0xe7,0x20,0x02,0xd8,0x70,0x30, 8173 0xa8,0xc3,0x72,0xd1,0xce,0xdb,0x38,0x00,0x74,0x59,0xd2,0x2f, 8174 0xf8,0x31,0xe5,0x4d,0x6c,0xcf,0x25,0x6c,0x37,0x46,0x49,0xac, 8175 0xef,0x24,0xcd,0xc7,0x80,0x96,0xd5,0x22,0x47,0xe0,0xdf,0x33, 8176 0x0a,0x4a,0x53,0x3d,0x76,0xdb,0xf7,0x39,0x63,0x79,0xa3,0x0d, 8177 0xfa,0x8a,0x95,0xb0,0x98,0x62,0xb8,0x7f,0xc3,0xbe,0x68,0xa4, 8178 0x9f,0x7f,0x5f,0x1e,0x3b,0x48,0x7b,0x99,0x20,0xe0,0x5b,0xfc, 8179 0x4e,0xb6,0x76,0xed,0xdd,0xfe,0x5e,0xe3 }; 8180 static const BYTE rsaPrivKeyPrime2[] = { 8181 0x4b,0xe6,0x2f,0xa5,0x08,0x3d,0xa9,0xf5,0x36,0x10,0x97,0x39, 8182 0xf3,0xc1,0xfb,0x86,0x48,0xaf,0x64,0xc6,0x9b,0x5f,0xe6,0xcf, 8183 0xb2,0x7b,0x39,0xa5,0x37,0x2c,0x61,0x1a,0x68,0xe2,0xe0,0xb0, 8184 0xfa,0x53,0xf1,0x7b,0x1d,0x3d,0x6b,0x70,0xa4,0x64,0x3a,0xe7, 8185 0xe1,0xe1,0xa0,0xaf,0x99,0x95,0xf2,0x4d,0x40,0x05,0x32,0xa4, 8186 0xab,0xac,0xee,0x97,0xca,0xa3,0xd6,0xe9,0xc0,0x9f,0x4d,0xb0, 8187 0xed,0x4a,0xe2,0x3a,0x29,0xe6,0xc3,0x2b,0xcd,0xa6,0xa9,0x87, 8188 0x7c,0xee,0x93,0x84,0x40,0xf2,0x40,0xae,0xc6,0x8e,0xd6,0x4a, 8189 0xaf,0xfc,0x5e,0x7d,0x9c,0x68,0x6f,0x18,0x72,0x1c,0x66,0x82, 8190 0x5d,0x66,0xaa,0x62,0x91,0xab,0xe1,0x0f,0xe9,0x4a,0x9d,0xce, 8191 0xce,0xe8,0xcf,0x6e,0xf0,0x57,0xba,0xc4 }; 8192 static const BYTE rsaPrivKeyExponent1[] = { 8193 0xa1,0xca,0x03,0xc2,0xbc,0x0c,0x7b,0x61,0x6f,0x4e,0xf3,0xde, 8194 0x81,0xfb,0x44,0xa7,0x70,0xae,0xe8,0xb3,0x61,0x7a,0x86,0xac, 8195 0x7e,0xcd,0xf9,0xbc,0xe9,0x34,0x32,0x2d,0x7d,0x78,0x93,0xe2, 8196 0xac,0x87,0x45,0xe9,0xde,0x35,0x6d,0x8c,0xe0,0x16,0x09,0x9d, 8197 0x54,0xd9,0x49,0x62,0x73,0x5f,0xd7,0x5c,0x9a,0xba,0x80,0xef, 8198 0xbe,0xf5,0xda,0x9a,0x8c,0x03,0x79,0x9b,0xad,0x9e,0xff,0x0a, 8199 0x15,0x39,0x69,0xba,0x22,0x46,0xdd,0xbb,0x09,0xf9,0xa3,0x47, 8200 0x0b,0xae,0xce,0x10,0xac,0x22,0x86,0xb0,0x0a,0xf3,0x26,0x9f, 8201 0x98,0xa5,0x90,0xd4,0x94,0x0b,0xcb,0x76,0xa8,0xbf,0x26,0x76, 8202 0x01,0x5e,0x53,0x03,0x3e,0x30,0x29,0x39,0x67,0x9e,0x9f,0x54, 8203 0x93,0xa0,0xaf,0xe2,0x08,0x02,0xe7,0x86 }; 8204 static const BYTE rsaPrivKeyExponent2[] = { 8205 0x85,0xfd,0x95,0x6b,0xb1,0x67,0x28,0x1d,0xe4,0xf1,0x20,0xbf, 8206 0x64,0x1d,0xf8,0x52,0xa2,0x4a,0x65,0xbd,0x98,0x55,0xf7,0x10, 8207 0x74,0x30,0x95,0x5a,0x7d,0xea,0x0a,0xc4,0xa5,0xf0,0x5a,0x5f, 8208 0xc3,0x50,0xb0,0x6b,0xa2,0x90,0xf6,0x3d,0xe6,0xfa,0xe3,0xc0, 8209 0xcb,0x14,0x6d,0xda,0x2b,0x96,0x86,0x26,0xb8,0xcb,0x2b,0xa6, 8210 0x21,0xbe,0x83,0x6a,0x5e,0xa3,0x15,0xfa,0xa5,0x7c,0xba,0xf5, 8211 0xc2,0xd9,0x51,0x3b,0x61,0x35,0xb0,0x12,0x92,0xaa,0xec,0xe6, 8212 0x52,0xf6,0x53,0xab,0x2c,0x76,0x10,0xfe,0x5d,0xd5,0xd4,0x96, 8213 0x05,0xe2,0xd9,0xae,0x22,0xb0,0x29,0x6a,0x80,0x88,0x17,0x5b, 8214 0x30,0x15,0xe6,0x20,0xab,0x19,0x11,0x48,0x1a,0x0d,0xf6,0x1b, 8215 0x9d,0x35,0x17,0x4f,0xa1,0x4a,0x5b,0x69 }; 8216 static const BYTE rsaPrivKeyCoefficient[] = { 8217 0xf9,0x85,0x26,0x39,0x96,0x35,0x02,0xfb,0xd9,0xd4,0xf0,0xbd, 8218 0xcb,0xd5,0x3d,0xce,0x8b,0xb6,0x8b,0xc5,0x6c,0x11,0x44,0x1e, 8219 0x39,0x88,0x46,0x4a,0x31,0xe6,0xa1,0x3a,0x2b,0xfc,0x2a,0x05, 8220 0xa1,0x68,0x18,0x88,0xa6,0xd0,0xb1,0xc6,0x0b,0xa3,0x3e,0x68, 8221 0xb2,0x4d,0xf1,0xf2,0x1c,0x40,0xdb,0xf8,0x1a,0x44,0xf6,0x84, 8222 0x04,0x96,0xff,0xce,0x3a,0x7c,0x3c,0xd6,0x60,0xbc,0x14,0x14, 8223 0xf7,0xc1,0x9d,0xcd,0x62,0x46,0x8e,0x3e,0x47,0xb6,0x5b,0x91, 8224 0x74,0xb6,0x65,0x66,0x2a,0x13,0xdd,0x63,0x25,0x00,0xae,0x6b, 8225 0x68,0x4e,0x9c,0xc8,0x47,0x7c,0x83,0x52,0x51,0x14,0x8a,0x0f, 8226 0xa2,0x50,0xbd,0x45,0xf0,0x6b,0xbf,0x46,0x20,0xda,0xd7,0x07, 8227 0x1e,0x9a,0xec,0xe1,0x34,0x31,0xb4,0xda }; 8228 static const BYTE rsaPrivKeyPrivateExponent[] = { 8229 0x11,0x90,0xb6,0x9f,0x62,0x9c,0x87,0x7e,0x9c,0x4c,0xbd,0x8c, 8230 0xf0,0xf8,0x2d,0x00,0x01,0x94,0xbc,0x68,0x39,0x13,0x3b,0x74, 8231 0x03,0x66,0xda,0xd2,0xde,0x79,0x96,0x61,0xba,0x6e,0x90,0xdf, 8232 0xed,0x25,0xdd,0x76,0xaa,0xfa,0x1d,0x15,0x65,0x99,0xba,0xf7, 8233 0x18,0xd5,0x15,0x85,0x33,0xf2,0xfd,0x60,0xb1,0x9f,0x66,0x9f, 8234 0x86,0x0c,0x69,0x06,0x5d,0x4c,0x5e,0xd8,0xf5,0x45,0x2d,0xf8, 8235 0x05,0x45,0xde,0xa4,0x71,0x58,0x81,0xce,0xe2,0xbb,0xb3,0x54, 8236 0x12,0xff,0x86,0x2d,0xd4,0xe5,0x03,0x90,0xa9,0x92,0xb9,0xe3, 8237 0x73,0xf2,0x69,0xbf,0xe2,0x75,0xab,0x59,0xfe,0x1b,0x48,0x8a, 8238 0xaf,0xdb,0xb0,0x7f,0x7e,0xb7,0x8c,0xfc,0x95,0x23,0x14,0x20, 8239 0x27,0x3d,0x74,0x4c,0x00,0xeb,0x23,0x20,0xc8,0x9c,0x2f,0x43, 8240 0x68,0x1d,0x97,0x02,0x15,0xcc,0xfc,0xde,0xda,0xe0,0x80,0xfd, 8241 0x95,0xbe,0xba,0xee,0xb3,0xd3,0xdc,0xd0,0xc2,0x63,0x16,0x40, 8242 0x97,0x04,0xa4,0xed,0x61,0x6d,0x37,0x03,0x84,0x00,0xb2,0x44, 8243 0x09,0x8b,0x6f,0xb3,0x44,0xac,0x54,0x66,0xf3,0x26,0x93,0xee, 8244 0xf7,0x91,0x76,0xa5,0x98,0xf8,0x3a,0x07,0x47,0x8b,0xdd,0x69, 8245 0x61,0x1f,0xdd,0x12,0x90,0x2e,0xe3,0xcd,0xc3,0xb7,0xc9,0x6d, 8246 0xfa,0xe8,0xa5,0x96,0x33,0x74,0xc9,0xc0,0x1f,0x3f,0x65,0xda, 8247 0x6f,0x12,0x75,0x17,0x8a,0xdb,0x4f,0x29,0xa2,0xfc,0x47,0x34, 8248 0x02,0xf6,0x86,0xcb,0x6a,0x74,0x9d,0x46,0x93,0x27,0x11,0x8c, 8249 0xef,0xd6,0xc9,0x2c,0x65,0x89,0xd6,0x78,0x98,0x32,0x03,0x69, 8250 0x5b,0xcd,0x03,0x99 }; 8251 8252 static void test_decodeRsaPrivateKey(DWORD dwEncoding) 8253 { 8254 LPBYTE buf = NULL; 8255 DWORD bufSize = 0; 8256 BOOL ret; 8257 8258 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_RSA_PRIVATE_KEY, 8259 rsaPrivKeyDer, sizeof(rsaPrivKeyDer)-10, 8260 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 8261 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD), 8262 "Expected CRYPT_E_ASN1_EOD, got %08x\n", 8263 GetLastError()); 8264 8265 buf = NULL; 8266 bufSize = 0; 8267 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_RSA_PRIVATE_KEY, 8268 rsaPrivKeyDer, sizeof(rsaPrivKeyDer), 8269 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); 8270 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); 8271 8272 if (ret) 8273 { 8274 BLOBHEADER *hdr = (BLOBHEADER *)buf; 8275 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER)); 8276 static const int bitlen = 2048; 8277 BYTE *modulus = (BYTE*)(rsaPubKey + 1); 8278 BYTE *prime1 = modulus + bitlen/8; 8279 BYTE *prime2 = prime1 + bitlen/16; 8280 BYTE *exponent1 = prime2 + bitlen/16; 8281 BYTE *exponent2 = exponent1 + bitlen/16; 8282 BYTE *coefficient = exponent2 + bitlen/16; 8283 BYTE *privateExponent = coefficient + bitlen/16; 8284 8285 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + 8286 (bitlen * 9 / 16), 8287 "Wrong size %d\n", bufSize); 8288 8289 ok(hdr->bType == PRIVATEKEYBLOB, 8290 "Expected type PRIVATEKEYBLOB (%d), got %d\n", PRIVATEKEYBLOB, 8291 hdr->bType); 8292 ok(hdr->bVersion == CUR_BLOB_VERSION, 8293 "Expected version CUR_BLOB_VERSION (%d), got %d\n", 8294 CUR_BLOB_VERSION, hdr->bVersion); 8295 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n", 8296 hdr->reserved); 8297 ok(hdr->aiKeyAlg == CALG_RSA_KEYX, 8298 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg); 8299 8300 ok(rsaPubKey->magic == 0x32415352, 8301 "Expected magic 0x32415352, got 0x%x\n", rsaPubKey->magic); 8302 ok(rsaPubKey->bitlen == bitlen, 8303 "Expected bitlen %d, got %d\n", bitlen, rsaPubKey->bitlen); 8304 ok(rsaPubKey->pubexp == 65537, 8305 "Expected pubexp 65537, got %d\n", rsaPubKey->pubexp); 8306 8307 ok(!memcmp(modulus, rsaPrivKeyModulus, bitlen/8), 8308 "unexpected modulus\n"); 8309 ok(!memcmp(prime1, rsaPrivKeyPrime1, bitlen/16), 8310 "unexpected prime1\n"); 8311 ok(!memcmp(prime2, rsaPrivKeyPrime2, bitlen/16), 8312 "unexpected prime2\n"); 8313 ok(!memcmp(exponent1, rsaPrivKeyExponent1, bitlen/16), 8314 "unexpected exponent1\n"); 8315 ok(!memcmp(exponent2, rsaPrivKeyExponent2, bitlen/16), 8316 "unexpected exponent2\n"); 8317 ok(!memcmp(coefficient, rsaPrivKeyCoefficient, bitlen/16), 8318 "unexpected coefficient\n"); 8319 ok(!memcmp(privateExponent, rsaPrivKeyPrivateExponent, bitlen/8), 8320 "unexpected privateExponent\n"); 8321 8322 LocalFree(buf); 8323 } 8324 } 8325 8326 /* Free *pInfo with HeapFree */ 8327 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo) 8328 { 8329 BOOL ret; 8330 DWORD size = 0; 8331 HCRYPTKEY key; 8332 8333 /* This crashes 8334 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL); 8335 */ 8336 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size); 8337 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 8338 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); 8339 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL, 8340 &size); 8341 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 8342 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); 8343 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL, 8344 NULL, &size); 8345 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 8346 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); 8347 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL, 8348 0, NULL, NULL, &size); 8349 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 8350 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); 8351 /* Test with no key */ 8352 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL, 8353 0, NULL, NULL, &size); 8354 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n", 8355 GetLastError()); 8356 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key); 8357 ok(ret, "CryptGenKey failed: %08x\n", GetLastError()); 8358 if (ret) 8359 { 8360 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, 8361 NULL, 0, NULL, NULL, &size); 8362 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError()); 8363 *pInfo = HeapAlloc(GetProcessHeap(), 0, size); 8364 if (*pInfo) 8365 { 8366 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, 8367 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size); 8368 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", 8369 GetLastError()); 8370 if (ret) 8371 { 8372 /* By default (we passed NULL as the OID) the OID is 8373 * szOID_RSA_RSA. 8374 */ 8375 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA), 8376 "Expected %s, got %s\n", szOID_RSA_RSA, 8377 (*pInfo)->Algorithm.pszObjId); 8378 } 8379 } 8380 } 8381 CryptDestroyKey(key); 8382 } 8383 8384 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2, 8385 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6, 8386 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06, 8387 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30, 8388 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40, 8389 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 8390 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30, 8391 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30, 8392 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30, 8393 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40, 8394 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 8395 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 8396 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 8397 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29, 8398 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e, 8399 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5, 8400 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a, 8401 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b, 8402 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 8403 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0, 8404 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3, 8405 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31, 8406 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70, 8407 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef, 8408 0x49, 0xe5, 0xf9, 0x65, 0xf3 }; 8409 8410 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info) 8411 { 8412 BOOL ret; 8413 HCRYPTKEY key; 8414 PCCERT_CONTEXT context; 8415 DWORD dwSize; 8416 ALG_ID ai; 8417 8418 /* These crash 8419 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL); 8420 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key); 8421 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL); 8422 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL, 8423 NULL); 8424 */ 8425 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key); 8426 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 8427 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); 8428 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key); 8429 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, 8430 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); 8431 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL, 8432 &key); 8433 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 8434 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); 8435 8436 /* Export key with standard algorithm (CALG_RSA_KEYX) */ 8437 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL, 8438 &key); 8439 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError()); 8440 8441 dwSize = sizeof(ai); 8442 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0); 8443 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError()); 8444 if(ret) 8445 { 8446 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize); 8447 ok(ai == CALG_RSA_KEYX, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai); 8448 } 8449 8450 CryptDestroyKey(key); 8451 8452 /* Repeat with forced algorithm */ 8453 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, CALG_RSA_SIGN, 0, NULL, 8454 &key); 8455 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError()); 8456 8457 dwSize = sizeof(ai); 8458 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0); 8459 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError()); 8460 if(ret) 8461 { 8462 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize); 8463 ok(ai == CALG_RSA_SIGN, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai); 8464 } 8465 8466 CryptDestroyKey(key); 8467 8468 /* Test importing a public key from a certificate context */ 8469 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert, 8470 sizeof(expiredCert)); 8471 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n", 8472 GetLastError()); 8473 if (context) 8474 { 8475 ok(!strcmp(szOID_RSA_RSA, 8476 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId), 8477 "Expected %s, got %s\n", szOID_RSA_RSA, 8478 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId); 8479 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, 8480 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key); 8481 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError()); 8482 CryptDestroyKey(key); 8483 CertFreeCertificateContext(context); 8484 } 8485 } 8486 8487 static const char cspName[] = "WineCryptTemp"; 8488 8489 static void testPortPublicKeyInfo(void) 8490 { 8491 HCRYPTPROV csp; 8492 BOOL ret; 8493 PCERT_PUBLIC_KEY_INFO info = NULL; 8494 8495 /* Just in case a previous run failed, delete this thing */ 8496 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV_A, PROV_RSA_FULL, 8497 CRYPT_DELETEKEYSET); 8498 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV_A, PROV_RSA_FULL, 8499 CRYPT_NEWKEYSET); 8500 ok(ret,"CryptAcquireContextA failed\n"); 8501 8502 testExportPublicKey(csp, &info); 8503 testImportPublicKey(csp, info); 8504 8505 HeapFree(GetProcessHeap(), 0, info); 8506 CryptReleaseContext(csp, 0); 8507 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV_A, PROV_RSA_FULL, 8508 CRYPT_DELETEKEYSET); 8509 ok(ret,"CryptAcquireContextA failed\n"); 8510 } 8511 8512 static const BYTE eccCert[] = { 8513 0x30,0x82,0x01,0x46,0x30,0x81,0xec,0x02,0x09,0x00,0xe7,0x6b, 8514 0x26,0x86,0x0a,0x82,0xff,0xe9,0x30,0x0a,0x06,0x08,0x2a,0x86, 8515 0x48,0xce,0x3d,0x04,0x03,0x02,0x30,0x2b,0x31,0x0b,0x30,0x09, 8516 0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x44,0x45,0x31,0x0d,0x30, 8517 0x0b,0x06,0x03,0x55,0x04,0x0a,0x0c,0x04,0x57,0x69,0x6e,0x65, 8518 0x31,0x0d,0x30,0x0b,0x06,0x03,0x55,0x04,0x03,0x0c,0x04,0x57, 8519 0x69,0x6e,0x65,0x30,0x1e,0x17,0x0d,0x31,0x37,0x30,0x39,0x32, 8520 0x37,0x31,0x33,0x34,0x31,0x30,0x34,0x5a,0x17,0x0d,0x32,0x37, 8521 0x30,0x39,0x32,0x35,0x31,0x33,0x34,0x31,0x30,0x34,0x5a,0x30, 8522 0x2b,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02, 8523 0x44,0x45,0x31,0x0d,0x30,0x0b,0x06,0x03,0x55,0x04,0x0a,0x0c, 8524 0x04,0x54,0x65,0x73,0x74,0x31,0x0d,0x30,0x0b,0x06,0x03,0x55, 8525 0x04,0x03,0x0c,0x04,0x54,0x65,0x73,0x74,0x30,0x59,0x30,0x13, 8526 0x06,0x07,0x2a,0x86,0x48,0xce,0x3d,0x02,0x01,0x06,0x08,0x2a, 8527 0x86,0x48,0xce,0x3d,0x03,0x01,0x07,0x03,0x42,0x00,0x04,0xed, 8528 0xfc,0x77,0xd8,0xb9,0xe7,0xf3,0xf8,0xce,0x13,0xb8,0x7f,0x0f, 8529 0x78,0xea,0x73,0x87,0x29,0x10,0xe1,0x6d,0x10,0xce,0x57,0x60, 8530 0x3b,0x3e,0xb4,0x5f,0x0d,0x20,0xc1,0xeb,0x6d,0x74,0xe9,0x7b, 8531 0x11,0x51,0x9a,0x00,0xe8,0xe9,0x12,0x84,0xb9,0x07,0x7e,0x7b, 8532 0x62,0x67,0x12,0x67,0x08,0xe5,0x2e,0x27,0xce,0xa2,0x57,0x15, 8533 0xad,0xc5,0x1f,0x30,0x0a,0x06,0x08,0x2a,0x86,0x48,0xce,0x3d, 8534 0x04,0x03,0x02,0x03,0x49,0x00,0x30,0x46,0x02,0x21,0x00,0xd7, 8535 0x29,0xce,0x5a,0xef,0x74,0x85,0xd1,0x18,0x5f,0x6e,0xf1,0xba, 8536 0x53,0xd4,0xcd,0xdd,0xe0,0x5d,0xf1,0x5e,0x48,0x51,0xea,0x63, 8537 0xc0,0xe8,0xe2,0xf6,0xfa,0x4c,0xaf,0x02,0x21,0x00,0xe3,0x94, 8538 0x15,0x3b,0x6c,0x71,0x6e,0x44,0x22,0xcb,0xa0,0x88,0xcd,0x0a, 8539 0x5a,0x50,0x29,0x7c,0x5c,0xd6,0x6c,0xd2,0xe0,0x7f,0xcd,0x02, 8540 0x92,0x21,0x4c,0x2c,0x92,0xee }; 8541 static const BYTE ecdsaSig[] = { 8542 0x30,0x46,0x02,0x21,0x00,0xd7,0x29,0xce,0x5a,0xef,0x74,0x85, 8543 0xd1,0x18,0x5f,0x6e,0xf1,0xba,0x53,0xd4,0xcd,0xdd,0xe0,0x5d, 8544 0xf1,0x5e,0x48,0x51,0xea,0x63,0xc0,0xe8,0xe2,0xf6,0xfa,0x4c, 8545 0xaf,0x02,0x21,0x00,0xe3,0x94,0x15,0x3b,0x6c,0x71,0x6e,0x44, 8546 0x22,0xcb,0xa0,0x88,0xcd,0x0a,0x5a,0x50,0x29,0x7c,0x5c,0xd6, 8547 0x6c,0xd2,0xe0,0x7f,0xcd,0x02,0x92,0x21,0x4c,0x2c,0x92,0xee }; 8548 static const BYTE eccPubKey[] = { 8549 0x30,0x59,0x30,0x13,0x06,0x07,0x2a,0x86,0x48,0xce,0x3d,0x02, 8550 0x01,0x06,0x08,0x2a,0x86,0x48,0xce,0x3d,0x03,0x01,0x07,0x03, 8551 0x42,0x00,0x04,0xed,0xfc,0x77,0xd8,0xb9,0xe7,0xf3,0xf8,0xce, 8552 0x13,0xb8,0x7f,0x0f,0x78,0xea,0x73,0x87,0x29,0x10,0xe1,0x6d, 8553 0x10,0xce,0x57,0x60,0x3b,0x3e,0xb4,0x5f,0x0d,0x20,0xc1,0xeb, 8554 0x6d,0x74,0xe9,0x7b,0x11,0x51,0x9a,0x00,0xe8,0xe9,0x12,0x84, 8555 0xb9,0x07,0x7e,0x7b,0x62,0x67,0x12,0x67,0x08,0xe5,0x2e,0x27, 8556 0xce,0xa2,0x57,0x15,0xad,0xc5,0x1f }; 8557 8558 static void testECDSACert(void) 8559 { 8560 DWORD decode_flags = CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG; 8561 CERT_SIGNED_CONTENT_INFO *info; 8562 CERT_PUBLIC_KEY_INFO *pubkey; 8563 CERT_ECC_SIGNATURE *ecc_sig; 8564 LPSTR *ecc_curve; 8565 DWORD size; 8566 BOOL ret; 8567 int i; 8568 8569 info = NULL; 8570 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, X509_CERT, eccCert, sizeof(eccCert), decode_flags, 8571 NULL, &info, &size); 8572 ok(ret, "CryptDecodeObjectEx failed with %d\n", GetLastError()); 8573 8574 ok(!strcmp(info->SignatureAlgorithm.pszObjId, szOID_ECDSA_SHA256), 8575 "Expected 1.2.840.10045.4.3.2, got %s\n", info->SignatureAlgorithm.pszObjId); 8576 ok(!info->SignatureAlgorithm.Parameters.cbData, 8577 "Expected no parameter data, got %d bytes\n", info->SignatureAlgorithm.Parameters.cbData); 8578 ok(!info->SignatureAlgorithm.Parameters.pbData, 8579 "Expected no parameter data, got %p pointer\n", info->SignatureAlgorithm.Parameters.pbData); 8580 8581 ok(info->Signature.cbData == sizeof(ecdsaSig), 8582 "Expected %d bytes, got %d\n", (int)sizeof(ecdsaSig), info->Signature.cbData); 8583 ok(info->Signature.pbData != NULL, "Got NULL pointer\n"); 8584 ok(!info->Signature.cUnusedBits, "Expected no unused bytes, got %d\n", info->Signature.cUnusedBits); 8585 for (i = 0; i < info->Signature.cbData; i++) 8586 { 8587 ok(ecdsaSig[i] == info->Signature.pbData[i], "Expected %02x, got %02x at offset %d\n", 8588 ecdsaSig[i], info->Signature.pbData[i], i); 8589 } 8590 8591 ecc_sig = NULL; 8592 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, X509_ECC_SIGNATURE, info->Signature.pbData, 8593 info->Signature.cbData, decode_flags, NULL, &ecc_sig, &size); 8594 ok(ret, "CryptDecodeObjectEx failed with %d\n", GetLastError()); 8595 if (ret) 8596 { 8597 ok(ecc_sig->r.cbData == 32, "Expected 32 bytes, got %d\n", ecc_sig->r.cbData); 8598 ok(ecc_sig->r.pbData != NULL, "Got NULL pointer\n"); 8599 ok(ecc_sig->s.cbData == 32, "Expected 32 bytes, got %d\n", ecc_sig->s.cbData); 8600 ok(ecc_sig->s.pbData != NULL, "Got NULL pointer\n"); 8601 for (i = 0; i < ecc_sig->r.cbData; i++) 8602 { 8603 ok(ecdsaSig[4+32-i] == ecc_sig->r.pbData[i], "Expected %02x, got %02x at offset %d\n", 8604 ecdsaSig[4+32-i], ecc_sig->r.pbData[i], i); 8605 } 8606 for (i = 0; i < ecc_sig->s.cbData; i++) 8607 { 8608 ok(ecdsaSig[4+35+32-i] == ecc_sig->s.pbData[i], "Expected %02x, got %02x at offset %d\n", 8609 ecdsaSig[4+35+32-i], ecc_sig->s.pbData[i], i); 8610 } 8611 LocalFree(ecc_sig); 8612 } 8613 8614 LocalFree(info); 8615 8616 info = NULL; 8617 decode_flags &= ~CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG; 8618 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, X509_CERT, eccCert, sizeof(eccCert), decode_flags, 8619 NULL, &info, &size); 8620 ok(ret, "CryptDecodeObjectEx failed with %d\n", GetLastError()); 8621 8622 ok(info->Signature.cbData == sizeof(ecdsaSig), 8623 "Expected %d bytes, got %d\n", (int)sizeof(ecdsaSig), info->Signature.cbData); 8624 ok(info->Signature.pbData != NULL, "Got NULL pointer\n"); 8625 ok(!info->Signature.cUnusedBits, "Expected no unused bytes, got %d\n", info->Signature.cUnusedBits); 8626 for (i = 0; i < info->Signature.cbData; i++) 8627 { 8628 ok(ecdsaSig[sizeof(ecdsaSig)-i-1] == info->Signature.pbData[i], "Expected %02x, got %02x at offset %d\n", 8629 ecdsaSig[sizeof(ecdsaSig)-i-1], info->Signature.pbData[i], i); 8630 } 8631 8632 LocalFree(info); 8633 8634 pubkey = NULL; 8635 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO, eccPubKey, sizeof(eccPubKey), 8636 decode_flags, NULL, &pubkey, &size); 8637 ok(ret, "CryptDecodeObjectEx failed with %d\n", GetLastError()); 8638 8639 ok(!strcmp(pubkey->Algorithm.pszObjId, szOID_ECC_PUBLIC_KEY), 8640 "Expected 1.2.840.10045.2.1, got %s\n", pubkey->Algorithm.pszObjId); 8641 ok(pubkey->Algorithm.Parameters.cbData == 10, 8642 "Expected 10 bytes parameters, got %d bytes\n", pubkey->Algorithm.Parameters.cbData); 8643 ok(pubkey->Algorithm.Parameters.pbData != NULL, 8644 "Expected pointer to parameters, got NULL\n"); 8645 8646 ecc_curve = NULL; 8647 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, X509_OBJECT_IDENTIFIER, pubkey->Algorithm.Parameters.pbData, 8648 pubkey->Algorithm.Parameters.cbData, decode_flags, NULL, &ecc_curve, &size); 8649 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND /* < Vista */), 8650 "CryptDecodeObjectEx failed with %d\n", GetLastError()); 8651 if (ret) 8652 { 8653 ok(!strcmp(*ecc_curve, szOID_ECC_CURVE_P256), "Expected 1.2.840.10045.3.1.7, got %s\n", *ecc_curve); 8654 LocalFree(ecc_curve); 8655 } 8656 8657 ecc_curve = NULL; 8658 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, szOID_ECC_PUBLIC_KEY, pubkey->Algorithm.Parameters.pbData, 8659 pubkey->Algorithm.Parameters.cbData, decode_flags, NULL, &ecc_curve, &size); 8660 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND /* < Vista */), 8661 "CryptDecodeObjectEx failed with %d\n", GetLastError()); 8662 if (ret) 8663 { 8664 ok(!strcmp(*ecc_curve, szOID_ECC_CURVE_P256), "Expected 1.2.840.10045.3.1.7, got %s\n", *ecc_curve); 8665 LocalFree(ecc_curve); 8666 } 8667 8668 ok(pubkey->PublicKey.cbData == 65, "Expected 32 bytes parameters, got %d bytes\n", pubkey->PublicKey.cbData); 8669 ok(pubkey->PublicKey.pbData != NULL, "Expected pointer to parameters, got NULL\n"); 8670 for (i = 0; i < pubkey->PublicKey.cbData; i++) 8671 { 8672 ok(eccPubKey[26+i] == pubkey->PublicKey.pbData[i], "Expected %02x, got %02x at offset %d\n", 8673 eccPubKey[26+i], pubkey->PublicKey.pbData[i], i); 8674 } 8675 8676 LocalFree(pubkey); 8677 } 8678 8679 START_TEST(encode) 8680 { 8681 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING, 8682 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING }; 8683 HMODULE hCrypt32; 8684 DWORD i; 8685 8686 hCrypt32 = GetModuleHandleA("crypt32.dll"); 8687 pCryptDecodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptDecodeObjectEx"); 8688 pCryptEncodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptEncodeObjectEx"); 8689 if (!pCryptDecodeObjectEx || !pCryptEncodeObjectEx) 8690 { 8691 win_skip("CryptDecodeObjectEx() is not available\n"); 8692 return; 8693 } 8694 8695 for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++) 8696 { 8697 test_encodeInt(encodings[i]); 8698 test_decodeInt(encodings[i]); 8699 test_encodeEnumerated(encodings[i]); 8700 test_decodeEnumerated(encodings[i]); 8701 test_encodeFiletime(encodings[i]); 8702 test_decodeFiletime(encodings[i]); 8703 test_encodeName(encodings[i]); 8704 test_decodeName(encodings[i]); 8705 test_encodeUnicodeName(encodings[i]); 8706 test_decodeUnicodeName(encodings[i]); 8707 test_encodeNameValue(encodings[i]); 8708 test_decodeNameValue(encodings[i]); 8709 test_encodeUnicodeNameValue(encodings[i]); 8710 test_decodeUnicodeNameValue(encodings[i]); 8711 test_encodeAltName(encodings[i]); 8712 test_decodeAltName(encodings[i]); 8713 test_encodeOctets(encodings[i]); 8714 test_decodeOctets(encodings[i]); 8715 test_encodeBits(encodings[i]); 8716 test_decodeBits(encodings[i]); 8717 test_encodeBasicConstraints(encodings[i]); 8718 test_decodeBasicConstraints(encodings[i]); 8719 test_encodeRsaPublicKey(encodings[i]); 8720 test_decodeRsaPublicKey(encodings[i]); 8721 test_encodeSequenceOfAny(encodings[i]); 8722 test_decodeSequenceOfAny(encodings[i]); 8723 test_encodeExtensions(encodings[i]); 8724 test_decodeExtensions(encodings[i]); 8725 test_encodePublicKeyInfo(encodings[i]); 8726 test_decodePublicKeyInfo(encodings[i]); 8727 test_encodeCertToBeSigned(encodings[i]); 8728 test_decodeCertToBeSigned(encodings[i]); 8729 test_encodeCert(encodings[i]); 8730 test_decodeCert(encodings[i]); 8731 test_encodeCRLDistPoints(encodings[i]); 8732 test_decodeCRLDistPoints(encodings[i]); 8733 test_encodeCRLIssuingDistPoint(encodings[i]); 8734 test_decodeCRLIssuingDistPoint(encodings[i]); 8735 test_encodeCRLToBeSigned(encodings[i]); 8736 test_decodeCRLToBeSigned(encodings[i]); 8737 test_encodeEnhancedKeyUsage(encodings[i]); 8738 test_decodeEnhancedKeyUsage(encodings[i]); 8739 test_encodeAuthorityKeyId(encodings[i]); 8740 test_decodeAuthorityKeyId(encodings[i]); 8741 test_encodeAuthorityKeyId2(encodings[i]); 8742 test_decodeAuthorityKeyId2(encodings[i]); 8743 test_encodeAuthorityInfoAccess(encodings[i]); 8744 test_decodeAuthorityInfoAccess(encodings[i]); 8745 test_encodeCTL(encodings[i]); 8746 test_decodeCTL(encodings[i]); 8747 test_encodePKCSContentInfo(encodings[i]); 8748 test_decodePKCSContentInfo(encodings[i]); 8749 test_encodePKCSAttribute(encodings[i]); 8750 test_decodePKCSAttribute(encodings[i]); 8751 test_encodePKCSAttributes(encodings[i]); 8752 test_decodePKCSAttributes(encodings[i]); 8753 test_encodePKCSSMimeCapabilities(encodings[i]); 8754 test_decodePKCSSMimeCapabilities(encodings[i]); 8755 test_encodePKCSSignerInfo(encodings[i]); 8756 test_decodePKCSSignerInfo(encodings[i]); 8757 test_encodeCMSSignerInfo(encodings[i]); 8758 test_decodeCMSSignerInfo(encodings[i]); 8759 test_encodeNameConstraints(encodings[i]); 8760 test_decodeNameConstraints(encodings[i]); 8761 test_encodePolicyQualifierUserNotice(encodings[i]); 8762 test_decodePolicyQualifierUserNotice(encodings[i]); 8763 test_encodeCertPolicies(encodings[i]); 8764 test_decodeCertPolicies(encodings[i]); 8765 test_encodeCertPolicyMappings(encodings[i]); 8766 test_decodeCertPolicyMappings(encodings[i]); 8767 test_encodeCertPolicyConstraints(encodings[i]); 8768 test_decodeCertPolicyConstraints(encodings[i]); 8769 test_decodeRsaPrivateKey(encodings[i]); 8770 } 8771 testPortPublicKeyInfo(); 8772 testECDSACert(); 8773 } 8774