1 /* 2 * Unit test suite for crypt32.dll's CryptMsg functions 3 * 4 * Copyright 2007 Juan Lang 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include <stdio.h> 22 #include <stdarg.h> 23 #include <windef.h> 24 #include <winbase.h> 25 #include <winerror.h> 26 #define CMSG_SIGNER_ENCODE_INFO_HAS_CMS_FIELDS 27 #define CMSG_SIGNED_ENCODE_INFO_HAS_CMS_FIELDS 28 #include <wincrypt.h> 29 30 #include "wine/test.h" 31 32 static BOOL have_nt = TRUE; 33 static BOOL old_crypt32 = FALSE; 34 static char oid_rsa_md5[] = szOID_RSA_MD5; 35 36 static BOOL (WINAPI * pCryptAcquireContextA) 37 (HCRYPTPROV *, LPCSTR, LPCSTR, DWORD, DWORD); 38 static BOOL (WINAPI * pCryptAcquireContextW) 39 (HCRYPTPROV *, LPCWSTR, LPCWSTR, DWORD, DWORD); 40 41 static void init_function_pointers(void) 42 { 43 HMODULE hAdvapi32 = GetModuleHandleA("advapi32.dll"); 44 45 #define GET_PROC(dll, func) \ 46 p ## func = (void *)GetProcAddress(dll, #func); \ 47 if(!p ## func) \ 48 trace("GetProcAddress(%s) failed\n", #func); 49 50 GET_PROC(hAdvapi32, CryptAcquireContextA) 51 GET_PROC(hAdvapi32, CryptAcquireContextW) 52 53 #undef GET_PROC 54 } 55 56 static void test_msg_open_to_encode(void) 57 { 58 HCRYPTMSG msg; 59 60 /* Crash 61 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, NULL, 62 NULL, NULL); 63 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, NULL, NULL, 64 NULL); 65 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, NULL, NULL, 66 NULL); 67 */ 68 69 /* Bad encodings */ 70 SetLastError(0xdeadbeef); 71 msg = CryptMsgOpenToEncode(0, 0, 0, NULL, NULL, NULL); 72 ok(!msg && GetLastError() == E_INVALIDARG, 73 "Expected E_INVALIDARG, got %x\n", GetLastError()); 74 SetLastError(0xdeadbeef); 75 msg = CryptMsgOpenToEncode(X509_ASN_ENCODING, 0, 0, NULL, NULL, NULL); 76 ok(!msg && GetLastError() == E_INVALIDARG, 77 "Expected E_INVALIDARG, got %x\n", GetLastError()); 78 79 /* Bad message types */ 80 SetLastError(0xdeadbeef); 81 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, 0, NULL, NULL, NULL); 82 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 83 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError()); 84 SetLastError(0xdeadbeef); 85 msg = CryptMsgOpenToEncode(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, 0, 86 NULL, NULL, NULL); 87 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 88 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError()); 89 SetLastError(0xdeadbeef); 90 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, 91 CMSG_SIGNED_AND_ENVELOPED, NULL, NULL, NULL); 92 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 93 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError()); 94 SetLastError(0xdeadbeef); 95 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, NULL, 96 NULL, NULL); 97 ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 98 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError()); 99 } 100 101 static void test_msg_open_to_decode(void) 102 { 103 HCRYPTMSG msg; 104 CMSG_STREAM_INFO streamInfo = { 0 }; 105 106 SetLastError(0xdeadbeef); 107 msg = CryptMsgOpenToDecode(0, 0, 0, 0, NULL, NULL); 108 ok(!msg && GetLastError() == E_INVALIDARG, 109 "Expected E_INVALIDARG, got %x\n", GetLastError()); 110 111 /* Bad encodings */ 112 SetLastError(0xdeadbeef); 113 msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, 0, 0, NULL, NULL); 114 ok(!msg && GetLastError() == E_INVALIDARG, 115 "Expected E_INVALIDARG, got %x\n", GetLastError()); 116 SetLastError(0xdeadbeef); 117 msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, CMSG_DATA, 0, NULL, NULL); 118 ok(!msg && GetLastError() == E_INVALIDARG, 119 "Expected E_INVALIDARG, got %x\n", GetLastError()); 120 121 /* The message type can be explicit... */ 122 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL, 123 NULL); 124 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError()); 125 CryptMsgClose(msg); 126 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL, 127 NULL); 128 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError()); 129 CryptMsgClose(msg); 130 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL, 131 NULL); 132 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError()); 133 CryptMsgClose(msg); 134 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL, 135 NULL); 136 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError()); 137 CryptMsgClose(msg); 138 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 139 CMSG_SIGNED_AND_ENVELOPED, 0, NULL, NULL); 140 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError()); 141 CryptMsgClose(msg); 142 /* or implicit.. */ 143 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 144 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError()); 145 CryptMsgClose(msg); 146 /* or even invalid. */ 147 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL, 148 NULL); 149 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError()); 150 CryptMsgClose(msg); 151 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL); 152 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError()); 153 CryptMsgClose(msg); 154 155 /* And even though the stream info parameter "must be set to NULL" for 156 * CMSG_HASHED, it's still accepted. 157 */ 158 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL, 159 &streamInfo); 160 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError()); 161 CryptMsgClose(msg); 162 } 163 164 static void test_msg_get_param(void) 165 { 166 BOOL ret; 167 HCRYPTMSG msg; 168 DWORD size, i, value; 169 170 /* Crash 171 ret = CryptMsgGetParam(NULL, 0, 0, NULL, NULL); 172 ret = CryptMsgGetParam(NULL, 0, 0, NULL, &size); 173 ret = CryptMsgGetParam(msg, 0, 0, NULL, NULL); 174 */ 175 176 /* Decoded messages */ 177 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 178 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError()); 179 /* For decoded messages, the type is always available */ 180 size = 0; 181 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size); 182 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError()); 183 size = sizeof(value); 184 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size); 185 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError()); 186 /* For this (empty) message, the type isn't set */ 187 ok(value == 0, "Expected type 0, got %d\n", value); 188 CryptMsgClose(msg); 189 190 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL, 191 NULL); 192 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError()); 193 /* For explicitly typed messages, the type is known. */ 194 size = sizeof(value); 195 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size); 196 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError()); 197 ok(value == CMSG_DATA, "Expected CMSG_DATA, got %d\n", value); 198 for (i = CMSG_CONTENT_PARAM; !old_crypt32 && (i <= CMSG_CMS_SIGNER_INFO_PARAM); i++) 199 { 200 size = 0; 201 ret = CryptMsgGetParam(msg, i, 0, NULL, &size); 202 ok(!ret, "Parameter %d: expected failure\n", i); 203 } 204 CryptMsgClose(msg); 205 206 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL, 207 NULL); 208 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError()); 209 size = sizeof(value); 210 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size); 211 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError()); 212 ok(value == CMSG_ENVELOPED, "Expected CMSG_ENVELOPED, got %d\n", value); 213 for (i = CMSG_CONTENT_PARAM; !old_crypt32 && (i <= CMSG_CMS_SIGNER_INFO_PARAM); i++) 214 { 215 size = 0; 216 ret = CryptMsgGetParam(msg, i, 0, NULL, &size); 217 ok(!ret, "Parameter %d: expected failure\n", i); 218 } 219 CryptMsgClose(msg); 220 221 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL, 222 NULL); 223 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError()); 224 size = sizeof(value); 225 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size); 226 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError()); 227 ok(value == CMSG_HASHED, "Expected CMSG_HASHED, got %d\n", value); 228 for (i = CMSG_CONTENT_PARAM; !old_crypt32 && (i <= CMSG_CMS_SIGNER_INFO_PARAM); i++) 229 { 230 size = 0; 231 ret = CryptMsgGetParam(msg, i, 0, NULL, &size); 232 ok(!ret, "Parameter %d: expected failure\n", i); 233 } 234 CryptMsgClose(msg); 235 236 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL, 237 NULL); 238 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError()); 239 size = sizeof(value); 240 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size); 241 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError()); 242 ok(value == CMSG_SIGNED, "Expected CMSG_SIGNED, got %d\n", value); 243 for (i = CMSG_CONTENT_PARAM; !old_crypt32 && (i <= CMSG_CMS_SIGNER_INFO_PARAM); i++) 244 { 245 size = 0; 246 ret = CryptMsgGetParam(msg, i, 0, NULL, &size); 247 ok(!ret, "Parameter %d: expected failure\n", i); 248 } 249 CryptMsgClose(msg); 250 251 /* Explicitly typed messages get their types set, even if they're invalid */ 252 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL, 253 NULL); 254 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError()); 255 size = sizeof(value); 256 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size); 257 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError()); 258 ok(value == CMSG_ENCRYPTED, "Expected CMSG_ENCRYPTED, got %d\n", value); 259 CryptMsgClose(msg); 260 261 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL); 262 ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError()); 263 size = sizeof(value); 264 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size); 265 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError()); 266 ok(value == 1000, "Expected 1000, got %d\n", value); 267 CryptMsgClose(msg); 268 } 269 270 static void test_msg_close(void) 271 { 272 BOOL ret; 273 HCRYPTMSG msg; 274 275 /* NULL succeeds.. */ 276 ret = CryptMsgClose(NULL); 277 ok(ret, "CryptMsgClose failed: %x\n", GetLastError()); 278 /* but an arbitrary pointer crashes. */ 279 if (0) 280 ret = CryptMsgClose((HCRYPTMSG)1); 281 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL, 282 NULL); 283 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 284 ret = CryptMsgClose(msg); 285 ok(ret, "CryptMsgClose failed: %x\n", GetLastError()); 286 } 287 288 static void check_param(LPCSTR test, HCRYPTMSG msg, DWORD param, 289 const BYTE *expected, DWORD expectedSize) 290 { 291 DWORD size; 292 LPBYTE buf; 293 BOOL ret; 294 295 size = 0xdeadbeef; 296 ret = CryptMsgGetParam(msg, param, 0, NULL, &size); 297 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */ || 298 GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x, for some params */), 299 "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError()); 300 if (!ret) 301 { 302 win_skip("parameter %d not supported, skipping tests\n", param); 303 return; 304 } 305 buf = HeapAlloc(GetProcessHeap(), 0, size); 306 ret = CryptMsgGetParam(msg, param, 0, buf, &size); 307 ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError()); 308 ok(size == expectedSize, "%s: expected size %d, got %d\n", test, 309 expectedSize, size); 310 if (size == expectedSize && size) 311 ok(!memcmp(buf, expected, size), "%s: unexpected data\n", test); 312 HeapFree(GetProcessHeap(), 0, buf); 313 } 314 315 static void test_data_msg_open(void) 316 { 317 HCRYPTMSG msg; 318 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 }; 319 CMSG_STREAM_INFO streamInfo = { 0 }; 320 char oid[] = "1.2.3"; 321 322 /* The data message type takes no additional info */ 323 SetLastError(0xdeadbeef); 324 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, &hashInfo, 325 NULL, NULL); 326 ok(!msg && GetLastError() == E_INVALIDARG, 327 "Expected E_INVALIDARG, got %x\n", GetLastError()); 328 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL, 329 NULL); 330 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 331 CryptMsgClose(msg); 332 333 /* An empty stream info is allowed. */ 334 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL, 335 &streamInfo); 336 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 337 CryptMsgClose(msg); 338 339 /* Passing a bogus inner OID succeeds for a non-streamed message.. */ 340 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid, 341 NULL); 342 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 343 CryptMsgClose(msg); 344 /* and still succeeds when CMSG_DETACHED_FLAG is passed.. */ 345 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 346 CMSG_DATA, NULL, oid, NULL); 347 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 348 CryptMsgClose(msg); 349 /* and when a stream info is given, even though you're not supposed to be 350 * able to use anything but szOID_RSA_data when streaming is being used. 351 */ 352 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 353 CMSG_DATA, NULL, oid, &streamInfo); 354 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 355 CryptMsgClose(msg); 356 } 357 358 static const BYTE msgData[] = { 1, 2, 3, 4 }; 359 360 static BOOL WINAPI nop_stream_output(const void *pvArg, BYTE *pb, DWORD cb, 361 BOOL final) 362 { 363 return TRUE; 364 } 365 366 static const BYTE dataEmptyBareContent[] = { 0x04,0x00 }; 367 368 static void test_data_msg_update(void) 369 { 370 HCRYPTMSG msg; 371 BOOL ret; 372 CMSG_STREAM_INFO streamInfo = { 0 }; 373 374 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL, 375 NULL); 376 /* Can't update a message that wasn't opened detached with final = FALSE */ 377 SetLastError(0xdeadbeef); 378 ret = CryptMsgUpdate(msg, NULL, 0, FALSE); 379 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR, 380 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError()); 381 /* Updating it with final = TRUE succeeds */ 382 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 383 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 384 /* Any subsequent update will fail, as the last was final */ 385 SetLastError(0xdeadbeef); 386 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 387 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR, 388 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError()); 389 CryptMsgClose(msg); 390 391 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL, 392 NULL); 393 /* Starting with Vista, can update a message with no data. */ 394 ret = CryptMsgUpdate(msg, NULL, 0, TRUE); 395 ok(ret || broken(!ret), "CryptMsgUpdate failed: %08x\n", GetLastError()); 396 if (ret) 397 { 398 DWORD size; 399 400 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size); 401 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); 402 if (ret) 403 { 404 LPBYTE buf = CryptMemAlloc(size); 405 406 if (buf) 407 { 408 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, buf, 409 &size); 410 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); 411 if (ret) 412 { 413 ok(size == sizeof(dataEmptyBareContent), 414 "unexpected size %d\n", size); 415 ok(!memcmp(buf, dataEmptyBareContent, size), 416 "unexpected value\n"); 417 } 418 CryptMemFree(buf); 419 } 420 } 421 } 422 CryptMsgClose(msg); 423 424 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 425 CMSG_DATA, NULL, NULL, NULL); 426 if (have_nt) 427 { 428 /* Doesn't appear to be able to update CMSG-DATA with non-final updates. 429 * On Win9x, this sometimes succeeds, sometimes fails with 430 * GetLastError() == 0, so it's not worth checking there. 431 */ 432 SetLastError(0xdeadbeef); 433 ret = CryptMsgUpdate(msg, NULL, 0, FALSE); 434 ok(!ret && 435 (GetLastError() == E_INVALIDARG || 436 broken(GetLastError() == ERROR_SUCCESS)), /* Older NT4 */ 437 "Expected E_INVALIDARG, got %x\n", GetLastError()); 438 SetLastError(0xdeadbeef); 439 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE); 440 ok(!ret && 441 (GetLastError() == E_INVALIDARG || 442 broken(GetLastError() == ERROR_SUCCESS)), /* Older NT4 */ 443 "Expected E_INVALIDARG, got %x\n", GetLastError()); 444 } 445 else 446 skip("not updating CMSG_DATA with a non-final update\n"); 447 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 448 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 449 CryptMsgClose(msg); 450 451 if (!old_crypt32) 452 { 453 /* Calling update after opening with an empty stream info (with a bogus 454 * output function) yields an error: 455 */ 456 /* Crashes on some Win9x */ 457 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL, 458 &streamInfo); 459 SetLastError(0xdeadbeef); 460 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE); 461 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION || 462 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */), 463 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n", 464 GetLastError()); 465 CryptMsgClose(msg); 466 } 467 /* Calling update with a valid output function succeeds, even if the data 468 * exceeds the size specified in the stream info. 469 */ 470 streamInfo.pfnStreamOutput = nop_stream_output; 471 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL, 472 &streamInfo); 473 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE); 474 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 475 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 476 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 477 CryptMsgClose(msg); 478 } 479 480 static void test_data_msg_get_param(void) 481 { 482 HCRYPTMSG msg; 483 DWORD size; 484 BOOL ret; 485 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL }; 486 487 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL, 488 NULL); 489 490 /* Content and bare content are always gettable when not streaming */ 491 size = 0; 492 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size); 493 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); 494 size = 0; 495 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size); 496 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); 497 /* But for this type of message, the signer and hash aren't applicable, 498 * and the type isn't available. 499 */ 500 size = 0; 501 SetLastError(0xdeadbeef); 502 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size); 503 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 504 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError()); 505 SetLastError(0xdeadbeef); 506 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size); 507 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 508 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError()); 509 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size); 510 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 511 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError()); 512 CryptMsgClose(msg); 513 514 /* Can't get content or bare content when streaming */ 515 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, 516 NULL, &streamInfo); 517 SetLastError(0xdeadbeef); 518 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size); 519 ok((!ret && GetLastError() == E_INVALIDARG) || broken(ret /* Win9x */), 520 "Expected E_INVALIDARG, got %x\n", GetLastError()); 521 SetLastError(0xdeadbeef); 522 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size); 523 ok((!ret && GetLastError() == E_INVALIDARG) || broken(ret /* Win9x */), 524 "Expected E_INVALIDARG, got %x\n", GetLastError()); 525 CryptMsgClose(msg); 526 } 527 528 static const BYTE dataEmptyContent[] = { 529 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02, 530 0x04,0x00 }; 531 static const BYTE dataBareContent[] = { 0x04,0x04,0x01,0x02,0x03,0x04 }; 532 static const BYTE dataContent[] = { 533 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06, 534 0x04,0x04,0x01,0x02,0x03,0x04 }; 535 536 struct update_accum 537 { 538 DWORD cUpdates; 539 CRYPT_DATA_BLOB *updates; 540 }; 541 542 static BOOL WINAPI accumulating_stream_output(const void *pvArg, BYTE *pb, 543 DWORD cb, BOOL final) 544 { 545 struct update_accum *accum = (struct update_accum *)pvArg; 546 BOOL ret = FALSE; 547 548 if (accum->cUpdates) 549 accum->updates = CryptMemRealloc(accum->updates, 550 (accum->cUpdates + 1) * sizeof(CRYPT_DATA_BLOB)); 551 else 552 accum->updates = CryptMemAlloc(sizeof(CRYPT_DATA_BLOB)); 553 if (accum->updates) 554 { 555 CRYPT_DATA_BLOB *blob = &accum->updates[accum->cUpdates]; 556 557 blob->pbData = CryptMemAlloc(cb); 558 if (blob->pbData) 559 { 560 memcpy(blob->pbData, pb, cb); 561 blob->cbData = cb; 562 ret = TRUE; 563 } 564 accum->cUpdates++; 565 } 566 return ret; 567 } 568 569 /* The updates of a (bogus) definite-length encoded message */ 570 static BYTE u1[] = { 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 571 0x07,0x01,0xa0,0x02,0x04,0x00 }; 572 static BYTE u2[] = { 0x01,0x02,0x03,0x04 }; 573 static CRYPT_DATA_BLOB b1[] = { 574 { sizeof(u1), u1 }, 575 { sizeof(u2), u2 }, 576 { sizeof(u2), u2 }, 577 }; 578 static const struct update_accum a1 = { ARRAY_SIZE(b1), b1 }; 579 /* The updates of a definite-length encoded message */ 580 static BYTE u3[] = { 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 581 0x07,0x01,0xa0,0x06,0x04,0x04 }; 582 static CRYPT_DATA_BLOB b2[] = { 583 { sizeof(u3), u3 }, 584 { sizeof(u2), u2 }, 585 }; 586 static const struct update_accum a2 = { ARRAY_SIZE(b2), b2 }; 587 /* The updates of an indefinite-length encoded message */ 588 static BYTE u4[] = { 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 589 0x07,0x01,0xa0,0x80,0x24,0x80 }; 590 static BYTE u5[] = { 0x04,0x04 }; 591 static BYTE u6[] = { 0x00,0x00,0x00,0x00,0x00,0x00 }; 592 static CRYPT_DATA_BLOB b3[] = { 593 { sizeof(u4), u4 }, 594 { sizeof(u5), u5 }, 595 { sizeof(u2), u2 }, 596 { sizeof(u5), u5 }, 597 { sizeof(u2), u2 }, 598 { sizeof(u6), u6 }, 599 }; 600 static const struct update_accum a3 = { ARRAY_SIZE(b3), b3 }; 601 602 static void check_updates(LPCSTR header, const struct update_accum *expected, 603 const struct update_accum *got) 604 { 605 DWORD i; 606 607 ok(expected->cUpdates == got->cUpdates, 608 "%s: expected %d updates, got %d\n", header, expected->cUpdates, 609 got->cUpdates); 610 if (expected->cUpdates == got->cUpdates) 611 for (i = 0; i < min(expected->cUpdates, got->cUpdates); i++) 612 { 613 ok(expected->updates[i].cbData == got->updates[i].cbData, 614 "%s, update %d: expected %d bytes, got %d\n", header, i, 615 expected->updates[i].cbData, got->updates[i].cbData); 616 if (expected->updates[i].cbData && expected->updates[i].cbData == 617 got->updates[i].cbData) 618 ok(!memcmp(expected->updates[i].pbData, got->updates[i].pbData, 619 got->updates[i].cbData), "%s, update %d: unexpected value\n", 620 header, i); 621 } 622 } 623 624 /* Frees the updates stored in accum */ 625 static void free_updates(struct update_accum *accum) 626 { 627 DWORD i; 628 629 for (i = 0; i < accum->cUpdates; i++) 630 CryptMemFree(accum->updates[i].pbData); 631 CryptMemFree(accum->updates); 632 accum->updates = NULL; 633 accum->cUpdates = 0; 634 } 635 636 static void test_data_msg_encoding(void) 637 { 638 HCRYPTMSG msg; 639 BOOL ret; 640 static char oid[] = "1.2.3"; 641 struct update_accum accum = { 0, NULL }; 642 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum }; 643 644 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL, 645 NULL); 646 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM, 647 dataEmptyBareContent, sizeof(dataEmptyBareContent)); 648 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent, 649 sizeof(dataEmptyContent)); 650 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 651 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 652 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM, 653 dataBareContent, sizeof(dataBareContent)); 654 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent, 655 sizeof(dataContent)); 656 CryptMsgClose(msg); 657 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */ 658 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG, 659 CMSG_DATA, NULL, NULL, NULL); 660 check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM, 661 dataEmptyBareContent, sizeof(dataEmptyBareContent)); 662 check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent, 663 sizeof(dataEmptyContent)); 664 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 665 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 666 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM, 667 dataBareContent, sizeof(dataBareContent)); 668 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent, 669 sizeof(dataContent)); 670 CryptMsgClose(msg); 671 /* The inner OID is apparently ignored */ 672 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid, 673 NULL); 674 check_param("data bogus oid bare content", msg, CMSG_BARE_CONTENT_PARAM, 675 dataEmptyBareContent, sizeof(dataEmptyBareContent)); 676 check_param("data bogus oid content", msg, CMSG_CONTENT_PARAM, 677 dataEmptyContent, sizeof(dataEmptyContent)); 678 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 679 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 680 check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM, 681 dataBareContent, sizeof(dataBareContent)); 682 check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent, 683 sizeof(dataContent)); 684 CryptMsgClose(msg); 685 /* A streaming message is DER encoded if the length is not 0xffffffff, but 686 * curiously, updates aren't validated to make sure they don't exceed the 687 * stated length. (The resulting output will of course fail to decode.) 688 */ 689 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, 690 NULL, &streamInfo); 691 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE); 692 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 693 CryptMsgClose(msg); 694 check_updates("bogus data message with definite length", &a1, &accum); 695 free_updates(&accum); 696 /* A valid definite-length encoding: */ 697 streamInfo.cbContent = sizeof(msgData); 698 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, 699 NULL, &streamInfo); 700 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 701 CryptMsgClose(msg); 702 check_updates("data message with definite length", &a2, &accum); 703 free_updates(&accum); 704 /* An indefinite-length encoding: */ 705 streamInfo.cbContent = 0xffffffff; 706 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, 707 NULL, &streamInfo); 708 CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE); 709 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 710 CryptMsgClose(msg); 711 check_updates("data message with indefinite length", &a3, &accum); 712 free_updates(&accum); 713 } 714 715 static void test_data_msg(void) 716 { 717 test_data_msg_open(); 718 test_data_msg_update(); 719 test_data_msg_get_param(); 720 test_data_msg_encoding(); 721 } 722 723 static void test_hash_msg_open(void) 724 { 725 HCRYPTMSG msg; 726 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 }; 727 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL }; 728 729 SetLastError(0xdeadbeef); 730 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo, 731 NULL, NULL); 732 ok(!msg && GetLastError() == E_INVALIDARG, 733 "Expected E_INVALIDARG, got %x\n", GetLastError()); 734 hashInfo.cbSize = sizeof(hashInfo); 735 SetLastError(0xdeadbeef); 736 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo, 737 NULL, NULL); 738 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO, 739 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError()); 740 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5; 741 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo, 742 NULL, NULL); 743 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 744 CryptMsgClose(msg); 745 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 746 CMSG_HASHED, &hashInfo, NULL, NULL); 747 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 748 CryptMsgClose(msg); 749 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 750 CMSG_HASHED, &hashInfo, NULL, &streamInfo); 751 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 752 CryptMsgClose(msg); 753 } 754 755 static void test_hash_msg_update(void) 756 { 757 HCRYPTMSG msg; 758 BOOL ret; 759 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0, 760 { oid_rsa_md5, { 0, NULL } }, NULL }; 761 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL }; 762 763 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 764 CMSG_HASHED, &hashInfo, NULL, NULL); 765 /* Detached hashed messages opened in non-streaming mode allow non-final 766 * updates.. 767 */ 768 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE); 769 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 770 /* including non-final updates with no data.. */ 771 ret = CryptMsgUpdate(msg, NULL, 0, FALSE); 772 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 773 /* and final updates with no data. */ 774 ret = CryptMsgUpdate(msg, NULL, 0, TRUE); 775 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 776 /* But no updates are allowed after the final update. */ 777 SetLastError(0xdeadbeef); 778 ret = CryptMsgUpdate(msg, NULL, 0, FALSE); 779 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR, 780 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError()); 781 SetLastError(0xdeadbeef); 782 ret = CryptMsgUpdate(msg, NULL, 0, TRUE); 783 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR, 784 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError()); 785 CryptMsgClose(msg); 786 /* Non-detached messages, in contrast, don't allow non-final updates in 787 * non-streaming mode. 788 */ 789 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo, 790 NULL, NULL); 791 SetLastError(0xdeadbeef); 792 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE); 793 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR, 794 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError()); 795 /* Final updates (including empty ones) are allowed. */ 796 ret = CryptMsgUpdate(msg, NULL, 0, TRUE); 797 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 798 CryptMsgClose(msg); 799 /* And, of course, streaming mode allows non-final updates */ 800 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo, 801 NULL, &streamInfo); 802 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE); 803 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 804 CryptMsgClose(msg); 805 /* Setting pfnStreamOutput to NULL results in no error. (In what appears 806 * to be a bug, it isn't actually used - see encoding tests.) 807 */ 808 streamInfo.pfnStreamOutput = NULL; 809 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo, 810 NULL, &streamInfo); 811 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE); 812 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 813 CryptMsgClose(msg); 814 } 815 816 static const BYTE emptyHashParam[] = { 817 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42, 818 0x7e }; 819 820 static void test_hash_msg_get_param(void) 821 { 822 HCRYPTMSG msg; 823 BOOL ret; 824 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0, 825 { oid_rsa_md5, { 0, NULL } }, NULL }; 826 DWORD size, value; 827 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL }; 828 BYTE buf[16]; 829 830 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo, 831 NULL, NULL); 832 /* Content and bare content are always gettable for non-streamed messages */ 833 size = 0; 834 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size); 835 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */), 836 "CryptMsgGetParam failed: %08x\n", GetLastError()); 837 size = 0; 838 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size); 839 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */), 840 "CryptMsgGetParam failed: %08x\n", GetLastError()); 841 /* For an encoded hash message, the hash data aren't available */ 842 SetLastError(0xdeadbeef); 843 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size); 844 ok(!ret && (GetLastError() == CRYPT_E_INVALID_MSG_TYPE || 845 GetLastError() == OSS_LIMITED /* Win9x */), 846 "Expected CRYPT_E_INVALID_MSG_TYPE or OSS_LIMITED, got %08x\n", 847 GetLastError()); 848 /* The hash is also available. */ 849 size = 0; 850 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size); 851 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); 852 ok(size == sizeof(buf), "Unexpected size %d\n", size); 853 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size); 854 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); 855 ok(size == sizeof(buf), "Unexpected size %d\n", size); 856 if (size == sizeof(buf)) 857 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n"); 858 /* By getting the hash, further updates are not allowed */ 859 SetLastError(0xdeadbeef); 860 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 861 ok(!ret && 862 (GetLastError() == NTE_BAD_HASH_STATE /* NT */ || 863 GetLastError() == NTE_BAD_ALGID /* 9x */ || 864 GetLastError() == CRYPT_E_MSG_ERROR /* Vista */ || 865 broken(GetLastError() == ERROR_SUCCESS) /* Some Win9x */), 866 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError()); 867 868 /* Even after a final update, the hash data aren't available */ 869 SetLastError(0xdeadbeef); 870 ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size); 871 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 872 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError()); 873 /* The version is also available, and should be zero for this message. */ 874 size = 0; 875 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size); 876 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */), 877 "CryptMsgGetParam failed: %08x\n", GetLastError()); 878 size = sizeof(value); 879 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size); 880 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */), 881 "CryptMsgGetParam failed: %08x\n", GetLastError()); 882 if (ret) 883 ok(value == 0, "Expected version 0, got %d\n", value); 884 /* As usual, the type isn't available. */ 885 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size); 886 ok(!ret, "Expected failure\n"); 887 CryptMsgClose(msg); 888 889 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo, 890 NULL, &streamInfo); 891 /* Streamed messages don't allow you to get the content or bare content. */ 892 SetLastError(0xdeadbeef); 893 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size); 894 ok(!ret && (GetLastError() == E_INVALIDARG || 895 GetLastError() == OSS_LIMITED /* Win9x */), 896 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError()); 897 SetLastError(0xdeadbeef); 898 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size); 899 ok(!ret && (GetLastError() == E_INVALIDARG || 900 GetLastError() == OSS_LIMITED /* Win9x */), 901 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError()); 902 /* The hash is still available. */ 903 size = 0; 904 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size); 905 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); 906 ok(size == sizeof(buf), "Unexpected size %d\n", size); 907 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size); 908 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); 909 if (size == sizeof(buf)) 910 ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n"); 911 /* After updating the hash, further updates aren't allowed on streamed 912 * messages either. 913 */ 914 SetLastError(0xdeadbeef); 915 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 916 ok(!ret && 917 (GetLastError() == NTE_BAD_HASH_STATE /* NT */ || 918 GetLastError() == NTE_BAD_ALGID /* 9x */ || 919 GetLastError() == CRYPT_E_MSG_ERROR /* Vista */ || 920 broken(GetLastError() == ERROR_SUCCESS) /* Some Win9x */), 921 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError()); 922 923 CryptMsgClose(msg); 924 } 925 926 static const BYTE hashEmptyBareContent[] = { 927 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, 928 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 }; 929 static const BYTE hashEmptyContent[] = { 930 0x30,0x26,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x19, 931 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, 932 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 }; 933 static const BYTE hashBareContent[] = { 934 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, 935 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 936 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0, 937 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f }; 938 static const BYTE hashContent[] = { 939 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a, 940 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, 941 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 942 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0, 943 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f }; 944 945 static const BYTE detachedHashNonFinalBareContent[] = { 946 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, 947 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 948 0x07,0x01,0x04,0x00 }; 949 static const BYTE detachedHashNonFinalContent[] = { 950 0x30,0x2f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x22, 951 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, 952 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 953 0x07,0x01,0x04,0x00 }; 954 static const BYTE detachedHashBareContent[] = { 955 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, 956 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 957 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb, 958 0x9d,0x2a,0x8f,0x26,0x2f }; 959 static const BYTE detachedHashContent[] = { 960 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32, 961 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, 962 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 963 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb, 964 0x9d,0x2a,0x8f,0x26,0x2f }; 965 966 static void test_hash_msg_encoding(void) 967 { 968 HCRYPTMSG msg; 969 CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0 }; 970 BOOL ret; 971 struct update_accum accum = { 0, NULL }, empty_accum = { 0, NULL }; 972 CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum }; 973 974 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5; 975 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo, 976 NULL, NULL); 977 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM, 978 hashEmptyBareContent, sizeof(hashEmptyBareContent)); 979 check_param("hash empty content", msg, CMSG_CONTENT_PARAM, 980 hashEmptyContent, sizeof(hashEmptyContent)); 981 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 982 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 983 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM, 984 hashBareContent, sizeof(hashBareContent)); 985 check_param("hash content", msg, CMSG_CONTENT_PARAM, 986 hashContent, sizeof(hashContent)); 987 CryptMsgClose(msg); 988 /* Same test, but with CMSG_BARE_CONTENT_FLAG set */ 989 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG, 990 CMSG_HASHED, &hashInfo, NULL, NULL); 991 check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM, 992 hashEmptyBareContent, sizeof(hashEmptyBareContent)); 993 check_param("hash empty content", msg, CMSG_CONTENT_PARAM, 994 hashEmptyContent, sizeof(hashEmptyContent)); 995 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 996 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 997 check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM, 998 hashBareContent, sizeof(hashBareContent)); 999 check_param("hash content", msg, CMSG_CONTENT_PARAM, 1000 hashContent, sizeof(hashContent)); 1001 CryptMsgClose(msg); 1002 /* Same test, but with CMSG_DETACHED_FLAG set */ 1003 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 1004 CMSG_HASHED, &hashInfo, NULL, NULL); 1005 check_param("detached hash empty bare content", msg, 1006 CMSG_BARE_CONTENT_PARAM, hashEmptyBareContent, 1007 sizeof(hashEmptyBareContent)); 1008 check_param("detached hash empty content", msg, CMSG_CONTENT_PARAM, 1009 hashEmptyContent, sizeof(hashEmptyContent)); 1010 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE); 1011 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 1012 check_param("detached hash not final bare content", msg, 1013 CMSG_BARE_CONTENT_PARAM, detachedHashNonFinalBareContent, 1014 sizeof(detachedHashNonFinalBareContent)); 1015 check_param("detached hash not final content", msg, CMSG_CONTENT_PARAM, 1016 detachedHashNonFinalContent, sizeof(detachedHashNonFinalContent)); 1017 ret = CryptMsgUpdate(msg, NULL, 0, TRUE); 1018 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 1019 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM, 1020 detachedHashBareContent, sizeof(detachedHashBareContent)); 1021 check_param("detached hash content", msg, CMSG_CONTENT_PARAM, 1022 detachedHashContent, sizeof(detachedHashContent)); 1023 check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM, 1024 detachedHashBareContent, sizeof(detachedHashBareContent)); 1025 check_param("detached hash content", msg, CMSG_CONTENT_PARAM, 1026 detachedHashContent, sizeof(detachedHashContent)); 1027 CryptMsgClose(msg); 1028 /* In what appears to be a bug, streamed updates to hash messages don't 1029 * call the output function. 1030 */ 1031 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo, 1032 NULL, &streamInfo); 1033 ret = CryptMsgUpdate(msg, NULL, 0, FALSE); 1034 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 1035 ret = CryptMsgUpdate(msg, NULL, 0, TRUE); 1036 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 1037 CryptMsgClose(msg); 1038 check_updates("empty hash message", &empty_accum, &accum); 1039 free_updates(&accum); 1040 1041 streamInfo.cbContent = sizeof(msgData); 1042 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo, 1043 NULL, &streamInfo); 1044 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 1045 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 1046 CryptMsgClose(msg); 1047 check_updates("hash message", &empty_accum, &accum); 1048 free_updates(&accum); 1049 1050 streamInfo.cbContent = sizeof(msgData); 1051 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 1052 CMSG_HASHED, &hashInfo, NULL, &streamInfo); 1053 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 1054 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 1055 CryptMsgClose(msg); 1056 check_updates("detached hash message", &empty_accum, &accum); 1057 free_updates(&accum); 1058 } 1059 1060 static void test_hash_msg(void) 1061 { 1062 test_hash_msg_open(); 1063 test_hash_msg_update(); 1064 test_hash_msg_get_param(); 1065 test_hash_msg_encoding(); 1066 } 1067 1068 static const CHAR cspNameA[] = { 'W','i','n','e','C','r','y','p','t','T','e', 1069 'm','p',0 }; 1070 static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e', 1071 'm','p',0 }; 1072 static BYTE serialNum[] = { 1 }; 1073 static BYTE encodedCommonName[] = { 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03, 1074 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 }; 1075 1076 static void test_signed_msg_open(void) 1077 { 1078 HCRYPTMSG msg; 1079 BOOL ret; 1080 CMSG_SIGNED_ENCODE_INFO signInfo = { 0 }; 1081 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 }; 1082 CERT_INFO certInfo = { 0 }; 1083 1084 SetLastError(0xdeadbeef); 1085 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo, 1086 NULL, NULL); 1087 ok(!msg && GetLastError() == E_INVALIDARG, 1088 "Expected E_INVALIDARG, got %x\n", GetLastError()); 1089 signInfo.cbSize = sizeof(signInfo); 1090 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo, 1091 NULL, NULL); 1092 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 1093 CryptMsgClose(msg); 1094 1095 signInfo.cSigners = 1; 1096 signInfo.rgSigners = &signer; 1097 /* With signer.pCertInfo unset, attempting to open this message this 1098 * crashes. 1099 */ 1100 signer.pCertInfo = &certInfo; 1101 /* The cert info must contain a serial number and an issuer. */ 1102 SetLastError(0xdeadbeef); 1103 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo, 1104 NULL, NULL); 1105 /* NT: E_INVALIDARG, 9x: unchanged or CRYPT_E_UNKNOWN_ALGO */ 1106 ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef 1107 || GetLastError() == CRYPT_E_UNKNOWN_ALGO), 1108 "Expected E_INVALIDARG or 0xdeadbeef or CRYPT_E_UNKNOWN_ALGO, got 0x%x\n", 1109 GetLastError()); 1110 1111 certInfo.SerialNumber.cbData = sizeof(serialNum); 1112 certInfo.SerialNumber.pbData = serialNum; 1113 SetLastError(0xdeadbeef); 1114 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo, 1115 NULL, NULL); 1116 /* NT: E_INVALIDARG, 9x: unchanged or CRYPT_E_UNKNOWN_ALGO */ 1117 ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef 1118 || GetLastError() == CRYPT_E_UNKNOWN_ALGO), 1119 "Expected E_INVALIDARG or 0xdeadbeef or CRYPT_E_UNKNOWN_ALGO, got 0x%x\n", 1120 GetLastError()); 1121 1122 certInfo.Issuer.cbData = sizeof(encodedCommonName); 1123 certInfo.Issuer.pbData = encodedCommonName; 1124 SetLastError(0xdeadbeef); 1125 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo, 1126 NULL, NULL); 1127 ok(!msg && (GetLastError() == E_INVALIDARG || 1128 GetLastError() == CRYPT_E_UNKNOWN_ALGO), 1129 "Expected E_INVALIDARG or CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError()); 1130 1131 /* The signer's hCryptProv must be set to something. Whether it's usable 1132 * or not will be checked after the hash algorithm is checked (see next 1133 * test.) 1134 */ 1135 signer.hCryptProv = 1; 1136 SetLastError(0xdeadbeef); 1137 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo, 1138 NULL, NULL); 1139 ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO, 1140 "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError()); 1141 /* The signer's hash algorithm must also be set. */ 1142 signer.HashAlgorithm.pszObjId = oid_rsa_md5; 1143 SetLastError(0xdeadbeef); 1144 /* Crashes in advapi32 in wine, don't do it */ 1145 if (0) { 1146 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 1147 &signInfo, NULL, NULL); 1148 ok(!msg && GetLastError() == ERROR_INVALID_PARAMETER, 1149 "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError()); 1150 } 1151 /* The signer's hCryptProv must also be valid. */ 1152 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, 1153 PROV_RSA_FULL, CRYPT_NEWKEYSET); 1154 if (!ret && GetLastError() == NTE_EXISTS) { 1155 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, 1156 PROV_RSA_FULL, 0); 1157 } 1158 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError()); 1159 1160 if (ret) { 1161 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo, 1162 NULL, NULL); 1163 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 1164 CryptMsgClose(msg); 1165 } 1166 1167 /* pCertInfo must still be set, but can be empty if the SignerId's issuer 1168 * and serial number are set. 1169 */ 1170 certInfo.Issuer.cbData = 0; 1171 certInfo.SerialNumber.cbData = 0; 1172 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER; 1173 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData = 1174 sizeof(encodedCommonName); 1175 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName; 1176 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData = 1177 sizeof(serialNum); 1178 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum; 1179 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo, 1180 NULL, NULL); 1181 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 1182 CryptMsgClose(msg); 1183 1184 CryptReleaseContext(signer.hCryptProv, 0); 1185 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A, 1186 PROV_RSA_FULL, CRYPT_DELETEKEYSET); 1187 } 1188 1189 static const BYTE privKey[] = { 1190 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00, 1191 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10, 1192 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd, 1193 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde, 1194 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68, 1195 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27, 1196 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b, 1197 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4, 1198 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77, 1199 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca, 1200 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06, 1201 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72, 1202 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e, 1203 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf, 1204 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b, 1205 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd, 1206 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8, 1207 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67, 1208 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40, 1209 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e, 1210 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d, 1211 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda, 1212 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78, 1213 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 }; 1214 static BYTE pubKey[] = { 1215 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59, 1216 0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b, 1217 0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61, 1218 0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61, 1219 0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 }; 1220 1221 static void test_signed_msg_update(void) 1222 { 1223 HCRYPTMSG msg; 1224 BOOL ret; 1225 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 }; 1226 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 }; 1227 CERT_INFO certInfo = { 0 }; 1228 HCRYPTKEY key; 1229 1230 certInfo.SerialNumber.cbData = sizeof(serialNum); 1231 certInfo.SerialNumber.pbData = serialNum; 1232 certInfo.Issuer.cbData = sizeof(encodedCommonName); 1233 certInfo.Issuer.pbData = encodedCommonName; 1234 signer.pCertInfo = &certInfo; 1235 signer.HashAlgorithm.pszObjId = oid_rsa_md5; 1236 signInfo.cSigners = 1; 1237 signInfo.rgSigners = &signer; 1238 1239 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, 1240 PROV_RSA_FULL, CRYPT_NEWKEYSET); 1241 if (!ret && GetLastError() == NTE_EXISTS) { 1242 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, 1243 PROV_RSA_FULL, 0); 1244 } 1245 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError()); 1246 1247 if (!ret) { 1248 skip("No context for tests\n"); 1249 return; 1250 } 1251 1252 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 1253 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL); 1254 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 1255 /* Detached CMSG_SIGNED allows non-final updates. */ 1256 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE); 1257 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 1258 /* Detached CMSG_SIGNED also allows non-final updates with no data. */ 1259 ret = CryptMsgUpdate(msg, NULL, 0, FALSE); 1260 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 1261 /* The final update requires a private key in the hCryptProv, in order to 1262 * generate the signature. 1263 */ 1264 SetLastError(0xdeadbeef); 1265 ret = CryptMsgUpdate(msg, NULL, 0, TRUE); 1266 ok(!ret && 1267 (GetLastError() == NTE_BAD_KEYSET || 1268 GetLastError() == NTE_NO_KEY || 1269 broken(GetLastError() == ERROR_SUCCESS)), /* Some Win9x */ 1270 "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %x\n", GetLastError()); 1271 ret = CryptImportKey(signer.hCryptProv, privKey, sizeof(privKey), 1272 0, 0, &key); 1273 ok(ret, "CryptImportKey failed: %08x\n", GetLastError()); 1274 /* The final update should be able to succeed now that a key exists, but 1275 * the previous (invalid) final update prevents it. 1276 */ 1277 SetLastError(0xdeadbeef); 1278 ret = CryptMsgUpdate(msg, NULL, 0, TRUE); 1279 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR, 1280 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError()); 1281 CryptMsgClose(msg); 1282 1283 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 1284 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL); 1285 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 1286 /* Detached CMSG_SIGNED allows non-final updates. */ 1287 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE); 1288 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 1289 /* Detached CMSG_SIGNED also allows non-final updates with no data. */ 1290 ret = CryptMsgUpdate(msg, NULL, 0, FALSE); 1291 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 1292 /* Now that the private key exists, the final update can succeed (even 1293 * with no data.) 1294 */ 1295 ret = CryptMsgUpdate(msg, NULL, 0, TRUE); 1296 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 1297 /* But no updates are allowed after the final update. */ 1298 SetLastError(0xdeadbeef); 1299 ret = CryptMsgUpdate(msg, NULL, 0, FALSE); 1300 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR, 1301 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError()); 1302 SetLastError(0xdeadbeef); 1303 ret = CryptMsgUpdate(msg, NULL, 0, TRUE); 1304 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR, 1305 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError()); 1306 CryptMsgClose(msg); 1307 1308 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo, 1309 NULL, NULL); 1310 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 1311 /* Non-detached messages don't allow non-final updates.. */ 1312 SetLastError(0xdeadbeef); 1313 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE); 1314 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR, 1315 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError()); 1316 /* but they do allow final ones. */ 1317 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 1318 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 1319 CryptMsgClose(msg); 1320 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo, 1321 NULL, NULL); 1322 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 1323 /* They also allow final updates with no data. */ 1324 ret = CryptMsgUpdate(msg, NULL, 0, TRUE); 1325 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 1326 CryptMsgClose(msg); 1327 1328 CryptDestroyKey(key); 1329 CryptReleaseContext(signer.hCryptProv, 0); 1330 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL, 1331 CRYPT_DELETEKEYSET); 1332 } 1333 1334 static const BYTE signedEmptyBareContent[] = { 1335 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86, 1336 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02, 1337 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03, 1338 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01, 1339 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30, 1340 0x04,0x06,0x00,0x05,0x00,0x04,0x00 }; 1341 static const BYTE signedEmptyContent[] = { 1342 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52, 1343 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86, 1344 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02, 1345 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03, 1346 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01, 1347 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30, 1348 0x04,0x06,0x00,0x05,0x00,0x04,0x00 }; 1349 static const BYTE detachedSignedBareContent[] = { 1350 0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48, 1351 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86, 1352 0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30, 1353 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61, 1354 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a, 1355 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00, 1356 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6, 1357 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee, 1358 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92, 1359 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44, 1360 0xb8,0x0b,0x28,0xf4,0xa8,0x0d }; 1361 static const BYTE detachedSignedContent[] = { 1362 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0, 1363 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a, 1364 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86, 1365 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30, 1366 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a, 1367 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06, 1368 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00, 1369 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0, 1370 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0, 1371 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23, 1372 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51, 1373 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d }; 1374 static const BYTE signedBareContent[] = { 1375 0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48, 1376 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86, 1377 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77, 1378 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03, 1379 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00, 1380 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05, 1381 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef, 1382 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59, 1383 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63, 1384 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf, 1385 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d }; 1386 static const BYTE signedContent[] = { 1387 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0, 1388 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a, 1389 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86, 1390 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04, 1391 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11, 1392 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 1393 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, 1394 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70, 1395 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d, 1396 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe, 1397 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29, 1398 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8, 1399 0x0d }; 1400 static const BYTE signedHash[] = { 1401 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26, 1402 0x2f }; 1403 static const BYTE signedKeyIdEmptyContent[] = { 1404 0x30,0x46,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x39, 1405 0x30,0x37,0x02,0x01,0x03,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86, 1406 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x1e,0x30,0x1c,0x02, 1407 0x01,0x03,0x80,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, 1408 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 }; 1409 static const BYTE signedEncodedSigner[] = { 1410 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03, 1411 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00, 1412 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05, 1413 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef, 1414 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59, 1415 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63, 1416 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf, 1417 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d }; 1418 static const BYTE signedWithAuthAttrsBareContent[] = { 1419 0x30,0x82,0x01,0x00,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86, 1420 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48, 1421 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31, 1422 0x81,0xd5,0x30,0x81,0xd2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30, 1423 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61, 1424 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7, 1425 0x0d,0x02,0x05,0x05,0x00,0xa0,0x5b,0x30,0x18,0x06,0x09,0x2a,0x86,0x48,0x86, 1426 0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d, 1427 0x01,0x07,0x01,0x30,0x1e,0x06,0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31, 1428 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20, 1429 0x4c,0x61,0x6e,0x67,0x00,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d, 1430 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79, 1431 0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f,0x30,0x04,0x06,0x00,0x05,0x00,0x04, 1432 0x40,0xbf,0x65,0xde,0x7a,0x3e,0xa2,0x19,0x59,0xc3,0xc7,0x02,0x53,0xc9,0x72, 1433 0xcd,0x74,0x96,0x70,0x0b,0x3b,0xcf,0x8b,0xd9,0x17,0x5c,0xc5,0xd1,0x83,0x41, 1434 0x32,0x93,0xa6,0xf3,0x52,0x83,0x94,0xa9,0x6b,0x0a,0x92,0xcf,0xaf,0x12,0xfa, 1435 0x40,0x53,0x12,0x84,0x03,0xab,0x10,0xa2,0x3d,0xe6,0x9f,0x5a,0xbf,0xc5,0xb8, 1436 0xff,0xc6,0x33,0x63,0x34 }; 1437 static BYTE cert[] = { 1438 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11, 1439 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 1440 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30, 1441 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30, 1442 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06, 1443 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67, 1444 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30, 1445 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01, 1446 0xff,0x02,0x01,0x01 }; 1447 static BYTE v1CertWithPubKey[] = { 1448 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30, 1449 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61, 1450 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31, 1451 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, 1452 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11, 1453 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 1454 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 1455 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 1456 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06, 1457 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02, 1458 0x01,0x01 }; 1459 static const BYTE signedWithCertEmptyBareContent[] = { 1460 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48, 1461 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a, 1462 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03, 1463 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00, 1464 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30, 1465 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30, 1466 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55, 1467 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30, 1468 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06, 1469 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02, 1470 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13, 1471 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c, 1472 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86, 1473 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 }; 1474 static const BYTE signedWithCertBareContent[] = { 1475 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86, 1476 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48, 1477 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0, 1478 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30, 1479 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61, 1480 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31, 1481 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, 1482 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11, 1483 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 1484 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14, 1485 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01, 1486 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30, 1487 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61, 1488 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a, 1489 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00, 1490 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6, 1491 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee, 1492 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92, 1493 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44, 1494 0xb8,0x0b,0x28,0xf4,0xa8,0x0d }; 1495 static BYTE crl[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30, 1496 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61, 1497 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30, 1498 0x30,0x30,0x30,0x30,0x5a }; 1499 static const BYTE signedWithCrlEmptyBareContent[] = { 1500 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48, 1501 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c, 1502 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03, 1503 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31, 1504 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31, 1505 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06, 1506 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67, 1507 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02, 1508 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 }; 1509 static const BYTE signedWithCrlBareContent[] = { 1510 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48, 1511 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86, 1512 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e, 1513 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55, 1514 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18, 1515 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30, 1516 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30, 1517 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61, 1518 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7, 1519 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6, 1520 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f, 1521 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59, 1522 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57, 1523 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4, 1524 0xa8,0x0d }; 1525 static const BYTE signedWithCertAndCrlEmptyBareContent[] = { 1526 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48, 1527 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a, 1528 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03, 1529 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00, 1530 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30, 1531 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30, 1532 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55, 1533 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30, 1534 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06, 1535 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02, 1536 0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30, 1537 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61, 1538 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30, 1539 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30, 1540 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61, 1541 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a, 1542 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00, 1543 0x04,0x00 }; 1544 static const BYTE signedWithCertAndCrlBareContent[] = { 1545 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86, 1546 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48, 1547 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0, 1548 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30, 1549 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61, 1550 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31, 1551 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, 1552 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11, 1553 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 1554 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14, 1555 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01, 1556 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15, 1557 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e, 1558 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30, 1559 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01, 1560 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a, 1561 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c, 1562 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06, 1563 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b, 1564 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c, 1565 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d, 1566 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39, 1567 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d }; 1568 static const BYTE signedWithCertWithPubKeyBareContent[] = { 1569 0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48, 1570 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,0x98,0x30, 1571 0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11, 1572 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 1573 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30, 1574 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30, 1575 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06, 1576 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67, 1577 0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01, 1578 0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08, 1579 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03, 1580 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01, 1581 0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30, 1582 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61, 1583 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7, 1584 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 }; 1585 static BYTE v1CertWithValidPubKey[] = { 1586 0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30, 1587 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61, 1588 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31, 1589 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, 1590 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11, 1591 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 1592 0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 1593 0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a, 1594 0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1, 1595 0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde, 1596 0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f, 1597 0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10, 1598 0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55, 1599 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 }; 1600 static const BYTE signedWithCertWithValidPubKeyEmptyContent[] = { 1601 0x30,0x82,0x01,0x38,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02, 1602 0xa0,0x82,0x01,0x29,0x30,0x82,0x01,0x25,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c, 1603 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06, 1604 0x00,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30, 1605 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61, 1606 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31, 1607 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36, 1608 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15, 1609 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e, 1610 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, 1611 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41, 1612 0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6, 1613 0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97, 1614 0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17, 1615 0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10, 1616 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30, 1617 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01, 1618 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15, 1619 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e, 1620 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86, 1621 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04, 1622 0x00 }; 1623 static const BYTE signedWithCertWithValidPubKeyContent[] = { 1624 0x30,0x82,0x01,0x89,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02, 1625 0xa0,0x82,0x01,0x7a,0x30,0x82,0x01,0x76,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c, 1626 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06, 1627 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01, 1628 0x02,0x03,0x04,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06, 1629 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a, 1630 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36, 1631 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f, 1632 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a, 1633 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75, 1634 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a, 1635 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48, 1636 0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4, 1637 0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb, 1638 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc, 1639 0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30, 1640 0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30, 1641 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06, 1642 0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a, 1643 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75, 1644 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08, 1645 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05, 1646 0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a, 1647 0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e, 1648 0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64, 1649 0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4, 1650 0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d }; 1651 1652 static void test_signed_msg_encoding(void) 1653 { 1654 HCRYPTMSG msg; 1655 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 }; 1656 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 }; 1657 CERT_INFO certInfo = { 0 }; 1658 CERT_BLOB encodedCert = { sizeof(cert), cert }; 1659 CRL_BLOB encodedCrl = { sizeof(crl), crl }; 1660 char oid_common_name[] = szOID_COMMON_NAME; 1661 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName), 1662 encodedCommonName }; 1663 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName }; 1664 BOOL ret; 1665 HCRYPTKEY key; 1666 DWORD size; 1667 1668 certInfo.SerialNumber.cbData = sizeof(serialNum); 1669 certInfo.SerialNumber.pbData = serialNum; 1670 certInfo.Issuer.cbData = sizeof(encodedCommonName); 1671 certInfo.Issuer.pbData = encodedCommonName; 1672 signer.pCertInfo = &certInfo; 1673 signer.HashAlgorithm.pszObjId = oid_rsa_md5; 1674 signInfo.cSigners = 1; 1675 signInfo.rgSigners = &signer; 1676 1677 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, 1678 PROV_RSA_FULL, CRYPT_NEWKEYSET); 1679 if (!ret && GetLastError() == NTE_EXISTS) { 1680 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, 1681 PROV_RSA_FULL, 0); 1682 } 1683 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError()); 1684 1685 if (!ret) { 1686 skip("No context for tests\n"); 1687 return; 1688 } 1689 1690 ret = CryptImportKey(signer.hCryptProv, privKey, sizeof(privKey), 1691 0, 0, &key); 1692 ok(ret, "CryptImportKey failed: %08x\n", GetLastError()); 1693 1694 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 1695 CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL); 1696 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 1697 1698 check_param("detached signed empty bare content", msg, 1699 CMSG_BARE_CONTENT_PARAM, signedEmptyBareContent, 1700 sizeof(signedEmptyBareContent)); 1701 check_param("detached signed empty content", msg, CMSG_CONTENT_PARAM, 1702 signedEmptyContent, sizeof(signedEmptyContent)); 1703 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 1704 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 1705 check_param("detached signed hash", msg, CMSG_COMPUTED_HASH_PARAM, 1706 signedHash, sizeof(signedHash)); 1707 check_param("detached signed bare content", msg, CMSG_BARE_CONTENT_PARAM, 1708 detachedSignedBareContent, sizeof(detachedSignedBareContent)); 1709 check_param("detached signed content", msg, CMSG_CONTENT_PARAM, 1710 detachedSignedContent, sizeof(detachedSignedContent)); 1711 SetLastError(0xdeadbeef); 1712 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size); 1713 ok(!ret && (GetLastError() == CRYPT_E_INVALID_INDEX || 1714 broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */)), 1715 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError()); 1716 check_param("detached signed encoded signer", msg, CMSG_ENCODED_SIGNER, 1717 signedEncodedSigner, sizeof(signedEncodedSigner)); 1718 1719 CryptMsgClose(msg); 1720 1721 certInfo.SerialNumber.cbData = 0; 1722 certInfo.Issuer.cbData = 0; 1723 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER; 1724 U(signer.SignerId).KeyId.cbData = sizeof(serialNum); 1725 U(signer.SignerId).KeyId.pbData = serialNum; 1726 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo, 1727 NULL, NULL); 1728 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 1729 check_param("signed key id empty content", msg, CMSG_CONTENT_PARAM, 1730 signedKeyIdEmptyContent, sizeof(signedKeyIdEmptyContent)); 1731 CryptMsgClose(msg); 1732 1733 certInfo.SerialNumber.cbData = sizeof(serialNum); 1734 certInfo.SerialNumber.pbData = serialNum; 1735 certInfo.Issuer.cbData = sizeof(encodedCommonName); 1736 certInfo.Issuer.pbData = encodedCommonName; 1737 signer.SignerId.dwIdChoice = 0; 1738 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo, 1739 NULL, NULL); 1740 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 1741 1742 check_param("signed empty bare content", msg, CMSG_BARE_CONTENT_PARAM, 1743 signedEmptyBareContent, sizeof(signedEmptyBareContent)); 1744 check_param("signed empty content", msg, CMSG_CONTENT_PARAM, 1745 signedEmptyContent, sizeof(signedEmptyContent)); 1746 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 1747 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 1748 check_param("signed bare content", msg, CMSG_BARE_CONTENT_PARAM, 1749 signedBareContent, sizeof(signedBareContent)); 1750 check_param("signed content", msg, CMSG_CONTENT_PARAM, 1751 signedContent, sizeof(signedContent)); 1752 1753 CryptMsgClose(msg); 1754 1755 signer.cAuthAttr = 1; 1756 signer.rgAuthAttr = &attr; 1757 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo, 1758 NULL, NULL); 1759 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 1760 1761 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 1762 check_param("signed with auth attrs bare content", msg, 1763 CMSG_BARE_CONTENT_PARAM, signedWithAuthAttrsBareContent, 1764 sizeof(signedWithAuthAttrsBareContent)); 1765 1766 CryptMsgClose(msg); 1767 1768 signer.cAuthAttr = 0; 1769 signInfo.rgCertEncoded = &encodedCert; 1770 signInfo.cCertEncoded = 1; 1771 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo, 1772 NULL, NULL); 1773 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 1774 1775 check_param("signed with cert empty bare content", msg, 1776 CMSG_BARE_CONTENT_PARAM, signedWithCertEmptyBareContent, 1777 sizeof(signedWithCertEmptyBareContent)); 1778 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 1779 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 1780 check_param("signed with cert bare content", msg, CMSG_BARE_CONTENT_PARAM, 1781 signedWithCertBareContent, sizeof(signedWithCertBareContent)); 1782 1783 CryptMsgClose(msg); 1784 1785 signInfo.cCertEncoded = 0; 1786 signInfo.rgCrlEncoded = &encodedCrl; 1787 signInfo.cCrlEncoded = 1; 1788 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo, 1789 NULL, NULL); 1790 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 1791 1792 check_param("signed with crl empty bare content", msg, 1793 CMSG_BARE_CONTENT_PARAM, signedWithCrlEmptyBareContent, 1794 sizeof(signedWithCrlEmptyBareContent)); 1795 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 1796 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 1797 check_param("signed with crl bare content", msg, CMSG_BARE_CONTENT_PARAM, 1798 signedWithCrlBareContent, sizeof(signedWithCrlBareContent)); 1799 1800 CryptMsgClose(msg); 1801 1802 signInfo.cCertEncoded = 1; 1803 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo, 1804 NULL, NULL); 1805 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 1806 1807 check_param("signed with cert and crl empty bare content", msg, 1808 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlEmptyBareContent, 1809 sizeof(signedWithCertAndCrlEmptyBareContent)); 1810 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 1811 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 1812 check_param("signed with cert and crl bare content", msg, 1813 CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlBareContent, 1814 sizeof(signedWithCertAndCrlBareContent)); 1815 1816 CryptMsgClose(msg); 1817 1818 /* Test with a cert with a (bogus) public key */ 1819 signInfo.cCrlEncoded = 0; 1820 encodedCert.cbData = sizeof(v1CertWithPubKey); 1821 encodedCert.pbData = v1CertWithPubKey; 1822 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo, 1823 NULL, NULL); 1824 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 1825 check_param("signedWithCertWithPubKeyBareContent", msg, 1826 CMSG_BARE_CONTENT_PARAM, signedWithCertWithPubKeyBareContent, 1827 sizeof(signedWithCertWithPubKeyBareContent)); 1828 CryptMsgClose(msg); 1829 1830 encodedCert.cbData = sizeof(v1CertWithValidPubKey); 1831 encodedCert.pbData = v1CertWithValidPubKey; 1832 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo, 1833 NULL, NULL); 1834 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 1835 check_param("signedWithCertWithValidPubKeyEmptyContent", msg, 1836 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyEmptyContent, 1837 sizeof(signedWithCertWithValidPubKeyEmptyContent)); 1838 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 1839 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 1840 check_param("signedWithCertWithValidPubKeyContent", msg, 1841 CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyContent, 1842 sizeof(signedWithCertWithValidPubKeyContent)); 1843 CryptMsgClose(msg); 1844 1845 CryptDestroyKey(key); 1846 CryptReleaseContext(signer.hCryptProv, 0); 1847 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL, 1848 CRYPT_DELETEKEYSET); 1849 } 1850 1851 static void test_signed_msg_get_param(void) 1852 { 1853 BOOL ret; 1854 HCRYPTMSG msg; 1855 DWORD size, value = 0; 1856 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 }; 1857 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 }; 1858 CERT_INFO certInfo = { 0 }; 1859 1860 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo, 1861 NULL, NULL); 1862 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 1863 1864 /* Content and bare content are always gettable */ 1865 size = 0; 1866 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size); 1867 ok(ret || broken(!ret /* Win9x */), "CryptMsgGetParam failed: %08x\n", 1868 GetLastError()); 1869 if (!ret) 1870 { 1871 skip("message parameters are broken, skipping tests\n"); 1872 return; 1873 } 1874 size = 0; 1875 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size); 1876 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); 1877 /* For "signed" messages, so is the version. */ 1878 size = 0; 1879 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size); 1880 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); 1881 size = sizeof(value); 1882 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size); 1883 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); 1884 ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %d\n", value); 1885 /* But for this message, with no signers, the hash and signer aren't 1886 * available. 1887 */ 1888 size = 0; 1889 SetLastError(0xdeadbeef); 1890 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size); 1891 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX, 1892 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError()); 1893 SetLastError(0xdeadbeef); 1894 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size); 1895 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX, 1896 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError()); 1897 /* As usual, the type isn't available. */ 1898 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size); 1899 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 1900 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError()); 1901 1902 CryptMsgClose(msg); 1903 1904 certInfo.SerialNumber.cbData = sizeof(serialNum); 1905 certInfo.SerialNumber.pbData = serialNum; 1906 certInfo.Issuer.cbData = sizeof(encodedCommonName); 1907 certInfo.Issuer.pbData = encodedCommonName; 1908 signer.pCertInfo = &certInfo; 1909 signer.HashAlgorithm.pszObjId = oid_rsa_md5; 1910 signInfo.cSigners = 1; 1911 signInfo.rgSigners = &signer; 1912 1913 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, 1914 PROV_RSA_FULL, CRYPT_NEWKEYSET); 1915 if (!ret && GetLastError() == NTE_EXISTS) { 1916 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, 1917 PROV_RSA_FULL, 0); 1918 } 1919 ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError()); 1920 1921 if (!ret) { 1922 skip("No context for tests\n"); 1923 return; 1924 } 1925 1926 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo, 1927 NULL, NULL); 1928 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 1929 1930 /* This message, with one signer, has the hash and signer for index 0 1931 * available, but not for other indexes. 1932 */ 1933 size = 0; 1934 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size); 1935 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError()); 1936 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size); 1937 ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError()); 1938 size = 0; 1939 SetLastError(0xdeadbeef); 1940 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 1, NULL, &size); 1941 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX, 1942 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError()); 1943 SetLastError(0xdeadbeef); 1944 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size); 1945 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX, 1946 "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError()); 1947 /* As usual, the type isn't available. */ 1948 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size); 1949 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 1950 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError()); 1951 1952 CryptMsgClose(msg); 1953 1954 /* Opening the message using the CMS fields.. */ 1955 certInfo.SerialNumber.cbData = 0; 1956 certInfo.Issuer.cbData = 0; 1957 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER; 1958 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData = 1959 sizeof(encodedCommonName); 1960 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName; 1961 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData = 1962 sizeof(serialNum); 1963 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum; 1964 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, 1965 PROV_RSA_FULL, CRYPT_NEWKEYSET); 1966 if (!ret && GetLastError() == NTE_EXISTS) 1967 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, 1968 PROV_RSA_FULL, 0); 1969 ok(ret, "CryptAcquireContextA failed: %x\n", GetLastError()); 1970 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 1971 CMSG_CRYPT_RELEASE_CONTEXT_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL); 1972 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 1973 /* still results in the version being 1 when the issuer and serial number 1974 * are used and no additional CMS fields are used. 1975 */ 1976 size = sizeof(value); 1977 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size); 1978 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE), 1979 "CryptMsgGetParam failed: %08x\n", GetLastError()); 1980 if (ret) 1981 ok(value == CMSG_SIGNED_DATA_V1, "expected version 1, got %d\n", value); 1982 /* Apparently the encoded signer can be retrieved.. */ 1983 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size); 1984 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); 1985 /* but the signer info, CMS signer info, and cert ID can't be. */ 1986 SetLastError(0xdeadbeef); 1987 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size); 1988 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 1989 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError()); 1990 SetLastError(0xdeadbeef); 1991 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size); 1992 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 1993 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError()); 1994 SetLastError(0xdeadbeef); 1995 ret = CryptMsgGetParam(msg, CMSG_SIGNER_CERT_ID_PARAM, 0, NULL, &size); 1996 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 1997 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError()); 1998 CryptMsgClose(msg); 1999 2000 /* Using the KeyId field of the SignerId results in the version becoming 2001 * the CMS version. 2002 */ 2003 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER; 2004 U(signer.SignerId).KeyId.cbData = sizeof(serialNum); 2005 U(signer.SignerId).KeyId.pbData = serialNum; 2006 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, 2007 PROV_RSA_FULL, CRYPT_NEWKEYSET); 2008 if (!ret && GetLastError() == NTE_EXISTS) 2009 ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, 2010 PROV_RSA_FULL, 0); 2011 ok(ret, "CryptAcquireContextA failed: %x\n", GetLastError()); 2012 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 2013 CMSG_CRYPT_RELEASE_CONTEXT_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL); 2014 ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError()); 2015 size = sizeof(value); 2016 ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size); 2017 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); 2018 if (ret) 2019 ok(value == CMSG_SIGNED_DATA_V3, "expected version 3, got %d\n", value); 2020 /* Even for a CMS message, the signer can be retrieved.. */ 2021 ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size); 2022 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); 2023 /* but the signer info, CMS signer info, and cert ID can't be. */ 2024 SetLastError(0xdeadbeef); 2025 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size); 2026 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 2027 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError()); 2028 SetLastError(0xdeadbeef); 2029 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size); 2030 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 2031 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError()); 2032 SetLastError(0xdeadbeef); 2033 ret = CryptMsgGetParam(msg, CMSG_SIGNER_CERT_ID_PARAM, 0, NULL, &size); 2034 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 2035 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError()); 2036 CryptMsgClose(msg); 2037 2038 CryptReleaseContext(signer.hCryptProv, 0); 2039 pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A, 2040 PROV_RSA_FULL, CRYPT_DELETEKEYSET); 2041 } 2042 2043 static void test_signed_msg(void) 2044 { 2045 test_signed_msg_open(); 2046 test_signed_msg_update(); 2047 test_signed_msg_encoding(); 2048 test_signed_msg_get_param(); 2049 } 2050 2051 static char oid_rsa_rc4[] = szOID_RSA_RC4; 2052 2053 static void test_enveloped_msg_open(void) 2054 { 2055 HCRYPTMSG msg; 2056 BOOL ret; 2057 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { 0 }; 2058 PCCERT_CONTEXT context; 2059 2060 SetLastError(0xdeadbeef); 2061 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 2062 &envelopedInfo, NULL, NULL); 2063 ok(!msg && GetLastError() == E_INVALIDARG, 2064 "expected E_INVALIDARG, got %08x\n", GetLastError()); 2065 2066 envelopedInfo.cbSize = sizeof(envelopedInfo); 2067 SetLastError(0xdeadbeef); 2068 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 2069 &envelopedInfo, NULL, NULL); 2070 ok(!msg && 2071 (GetLastError() == CRYPT_E_UNKNOWN_ALGO || 2072 GetLastError() == E_INVALIDARG), /* Win9x */ 2073 "expected CRYPT_E_UNKNOWN_ALGO or E_INVALIDARG, got %08x\n", GetLastError()); 2074 2075 envelopedInfo.ContentEncryptionAlgorithm.pszObjId = oid_rsa_rc4; 2076 SetLastError(0xdeadbeef); 2077 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 2078 &envelopedInfo, NULL, NULL); 2079 ok(msg != NULL || 2080 broken(!msg), /* Win9x */ 2081 "CryptMsgOpenToEncode failed: %08x\n", GetLastError()); 2082 CryptMsgClose(msg); 2083 2084 envelopedInfo.cRecipients = 1; 2085 if (!old_crypt32) 2086 { 2087 SetLastError(0xdeadbeef); 2088 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 2089 &envelopedInfo, NULL, NULL); 2090 ok(!msg && GetLastError() == E_INVALIDARG, 2091 "expected E_INVALIDARG, got %08x\n", GetLastError()); 2092 } 2093 2094 context = CertCreateCertificateContext(X509_ASN_ENCODING, 2095 v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey)); 2096 if (context) 2097 { 2098 envelopedInfo.rgpRecipientCert = (PCERT_INFO *)&context->pCertInfo; 2099 SetLastError(0xdeadbeef); 2100 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 2101 &envelopedInfo, NULL, NULL); 2102 ok(msg != NULL, "CryptMsgOpenToEncode failed: %08x\n", GetLastError()); 2103 CryptMsgClose(msg); 2104 SetLastError(0xdeadbeef); 2105 ret = pCryptAcquireContextA(&envelopedInfo.hCryptProv, NULL, NULL, 2106 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); 2107 ok(ret, "CryptAcquireContextA failed: %08x\n", GetLastError()); 2108 SetLastError(0xdeadbeef); 2109 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 2110 &envelopedInfo, NULL, NULL); 2111 ok(msg != NULL, "CryptMsgOpenToEncode failed: %08x\n", GetLastError()); 2112 CryptMsgClose(msg); 2113 CryptReleaseContext(envelopedInfo.hCryptProv, 0); 2114 CertFreeCertificateContext(context); 2115 } 2116 else 2117 win_skip("failed to create certificate context, skipping tests\n"); 2118 } 2119 2120 static void test_enveloped_msg_update(void) 2121 { 2122 HCRYPTMSG msg; 2123 BOOL ret; 2124 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0, 2125 { oid_rsa_rc4, { 0, NULL } }, NULL }; 2126 CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL }; 2127 2128 SetLastError(0xdeadbeef); 2129 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 2130 &envelopedInfo, NULL, NULL); 2131 ok(msg != NULL || 2132 broken(!msg), /* Win9x */ 2133 "CryptMsgOpenToEncode failed: %08x\n", GetLastError()); 2134 if (msg) 2135 { 2136 SetLastError(0xdeadbeef); 2137 ret = CryptMsgUpdate(msg, NULL, 0, FALSE); 2138 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR, 2139 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError()); 2140 SetLastError(0xdeadbeef); 2141 ret = CryptMsgUpdate(msg, NULL, 0, TRUE); 2142 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 2143 SetLastError(0xdeadbeef); 2144 ret = CryptMsgUpdate(msg, NULL, 0, TRUE); 2145 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR, 2146 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError()); 2147 CryptMsgClose(msg); 2148 } 2149 SetLastError(0xdeadbeef); 2150 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 2151 &envelopedInfo, NULL, NULL); 2152 ok(msg != NULL || 2153 broken(!msg), /* Win9x */ 2154 "CryptMsgOpenToEncode failed: %08x\n", GetLastError()); 2155 if (msg) 2156 { 2157 SetLastError(0xdeadbeef); 2158 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE); 2159 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR, 2160 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError()); 2161 SetLastError(0xdeadbeef); 2162 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 2163 ok(ret || 2164 broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */ 2165 "CryptMsgUpdate failed: %08x\n", GetLastError()); 2166 SetLastError(0xdeadbeef); 2167 ret = CryptMsgUpdate(msg, NULL, 0, TRUE); 2168 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR, 2169 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError()); 2170 CryptMsgClose(msg); 2171 } 2172 SetLastError(0xdeadbeef); 2173 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 2174 CMSG_ENVELOPED, &envelopedInfo, NULL, NULL); 2175 ok(msg != NULL || 2176 broken(!msg), /* Win9x */ 2177 "CryptMsgOpenToEncode failed: %08x\n", GetLastError()); 2178 if (msg) 2179 { 2180 SetLastError(0xdeadbeef); 2181 ret = CryptMsgUpdate(msg, NULL, 0, FALSE); 2182 ok(!ret && GetLastError() == E_INVALIDARG, 2183 "expected E_INVALIDARG, got %08x\n", GetLastError()); 2184 SetLastError(0xdeadbeef); 2185 ret = CryptMsgUpdate(msg, NULL, 0, TRUE); 2186 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 2187 CryptMsgClose(msg); 2188 } 2189 SetLastError(0xdeadbeef); 2190 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 2191 CMSG_ENVELOPED, &envelopedInfo, NULL, NULL); 2192 ok(msg != NULL || 2193 broken(!msg), /* Win9x */ 2194 "CryptMsgOpenToEncode failed: %08x\n", GetLastError()); 2195 if (msg) 2196 { 2197 SetLastError(0xdeadbeef); 2198 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE); 2199 ok(!ret && GetLastError() == E_INVALIDARG, 2200 "expected E_INVALIDARG, got %08x\n", GetLastError()); 2201 SetLastError(0xdeadbeef); 2202 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 2203 ok(ret || 2204 broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */ 2205 "CryptMsgUpdate failed: %08x\n", GetLastError()); 2206 CryptMsgClose(msg); 2207 } 2208 SetLastError(0xdeadbeef); 2209 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 2210 &envelopedInfo, NULL, &streamInfo); 2211 ok(msg != NULL || 2212 broken(!msg), /* Win9x */ 2213 "CryptMsgOpenToEncode failed: %08x\n", GetLastError()); 2214 if (msg) 2215 { 2216 SetLastError(0xdeadbeef); 2217 ret = CryptMsgUpdate(msg, NULL, 0, FALSE); 2218 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 2219 SetLastError(0xdeadbeef); 2220 ret = CryptMsgUpdate(msg, NULL, 0, TRUE); 2221 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 2222 CryptMsgClose(msg); 2223 } 2224 SetLastError(0xdeadbeef); 2225 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 2226 &envelopedInfo, NULL, &streamInfo); 2227 ok(msg != NULL || 2228 broken(!msg), /* Win9x */ 2229 "CryptMsgOpenToEncode failed: %08x\n", GetLastError()); 2230 if (msg) 2231 { 2232 SetLastError(0xdeadbeef); 2233 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE); 2234 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 2235 SetLastError(0xdeadbeef); 2236 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 2237 ok(ret || 2238 broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */ 2239 "CryptMsgUpdate failed: %08x\n", GetLastError()); 2240 CryptMsgClose(msg); 2241 } 2242 } 2243 2244 static const BYTE envelopedEmptyBareContent[] = { 2245 0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86, 2246 0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, 2247 0x03,0x04,0x05,0x00,0x80,0x00 }; 2248 static const BYTE envelopedEmptyContent[] = { 2249 0x30,0x31,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,0x24, 2250 0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86, 2251 0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, 2252 0x03,0x04,0x05,0x00,0x80,0x00 }; 2253 2254 static void test_enveloped_msg_encoding(void) 2255 { 2256 HCRYPTMSG msg; 2257 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0, 2258 { oid_rsa_rc4, { 0, NULL } }, NULL }; 2259 2260 SetLastError(0xdeadbeef); 2261 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 2262 &envelopedInfo, NULL, NULL); 2263 ok(msg != NULL || 2264 broken(!msg), /* Win9x */ 2265 "CryptMsgOpenToEncode failed: %08x\n", GetLastError()); 2266 if (msg) 2267 { 2268 check_param("enveloped empty bare content", msg, 2269 CMSG_BARE_CONTENT_PARAM, envelopedEmptyBareContent, 2270 sizeof(envelopedEmptyBareContent)); 2271 check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM, 2272 envelopedEmptyContent, sizeof(envelopedEmptyContent)); 2273 CryptMsgClose(msg); 2274 } 2275 } 2276 2277 static void test_enveloped_msg(void) 2278 { 2279 test_enveloped_msg_open(); 2280 test_enveloped_msg_update(); 2281 test_enveloped_msg_encoding(); 2282 } 2283 2284 static CRYPT_DATA_BLOB b4 = { 0, NULL }; 2285 static const struct update_accum a4 = { 1, &b4 }; 2286 2287 static const BYTE bogusOIDContent[] = { 2288 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02, 2289 0x04,0x00 }; 2290 static const BYTE bogusHashContent[] = { 2291 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a, 2292 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, 2293 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 2294 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0, 2295 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f }; 2296 static const BYTE envelopedBareContentWithoutData[] = { 2297 0x30,0x81,0xdb,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00, 2298 0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01, 2299 0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01, 2300 0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 2301 0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x87,0x46,0x26,0x56,0xe3,0xf3,0xa5,0x5b, 2302 0xd4,0x2c,0x03,0xcc,0x52,0x7e,0xf7,0x55,0xf1,0x34,0x9f,0x63,0xf6,0x04,0x9f, 2303 0xc5,0x13,0xf1,0xc9,0x57,0x0a,0xbc,0xa9,0x33,0xd2,0xf2,0x93,0xb6,0x5c,0x94, 2304 0xc3,0x49,0xd6,0xd6,0x6d,0xc4,0x91,0x38,0x80,0xdd,0x0d,0x82,0xef,0xe5,0x72, 2305 0x55,0x40,0x0a,0xdd,0x35,0xfe,0xdc,0x87,0x47,0x92,0xb1,0xbd,0x05,0xc9,0x18, 2306 0x0e,0xde,0x4b,0x00,0x70,0x40,0x31,0x1f,0x5d,0x6c,0x8f,0x3a,0xfb,0x9a,0xc3, 2307 0xb3,0x06,0xe7,0x68,0x3f,0x20,0x14,0x1c,0xf9,0x28,0x4b,0x0f,0x01,0x01,0xb6, 2308 0xfe,0x07,0xe5,0xd8,0xf0,0x7c,0x17,0xbc,0xec,0xfb,0xd7,0x73,0x8a,0x71,0x49, 2309 0x79,0x62,0xe4,0xbf,0xb5,0xe3,0x56,0xa6,0xb4,0x49,0x1e,0xdc,0xaf,0xd7,0x0e, 2310 0x30,0x19,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c, 2311 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00 }; 2312 2313 static void test_decode_msg_update(void) 2314 { 2315 HCRYPTMSG msg; 2316 BOOL ret; 2317 CMSG_STREAM_INFO streamInfo = { 0 }; 2318 DWORD i; 2319 struct update_accum accum = { 0, NULL }; 2320 2321 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 2322 /* Update with a full message in a final update */ 2323 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE); 2324 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 2325 /* Can't update after a final update */ 2326 SetLastError(0xdeadbeef); 2327 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE); 2328 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR, 2329 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError()); 2330 CryptMsgClose(msg); 2331 2332 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 2333 /* Can't send a non-final update without streaming */ 2334 SetLastError(0xdeadbeef); 2335 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), 2336 FALSE); 2337 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR, 2338 "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError()); 2339 /* A subsequent final update succeeds */ 2340 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE); 2341 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 2342 CryptMsgClose(msg); 2343 2344 if (!old_crypt32) 2345 { 2346 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo); 2347 /* Updating a message that has a NULL stream callback fails */ 2348 SetLastError(0xdeadbeef); 2349 /* Crashes on some Win9x */ 2350 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), 2351 FALSE); 2352 todo_wine 2353 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION || 2354 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */), 2355 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n", 2356 GetLastError()); 2357 /* Changing the callback pointer after the fact yields the same error (so 2358 * the message must copy the stream info, not just store a pointer to it) 2359 */ 2360 streamInfo.pfnStreamOutput = nop_stream_output; 2361 SetLastError(0xdeadbeef); 2362 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), 2363 FALSE); 2364 todo_wine 2365 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION || 2366 GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */), 2367 "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n", 2368 GetLastError()); 2369 CryptMsgClose(msg); 2370 } 2371 2372 /* Empty non-final updates are allowed when streaming.. */ 2373 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo); 2374 ret = CryptMsgUpdate(msg, NULL, 0, FALSE); 2375 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 2376 /* but final updates aren't when not enough data has been received. */ 2377 SetLastError(0xdeadbeef); 2378 ret = CryptMsgUpdate(msg, NULL, 0, TRUE); 2379 todo_wine 2380 ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA, 2381 "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError()); 2382 CryptMsgClose(msg); 2383 2384 /* Updating the message byte by byte is legal */ 2385 streamInfo.pfnStreamOutput = accumulating_stream_output; 2386 streamInfo.pvArg = &accum; 2387 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo); 2388 for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++) 2389 ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE); 2390 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError()); 2391 ret = CryptMsgUpdate(msg, NULL, 0, TRUE); 2392 ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError()); 2393 CryptMsgClose(msg); 2394 todo_wine 2395 check_updates("byte-by-byte empty content", &a4, &accum); 2396 free_updates(&accum); 2397 2398 /* Decoding bogus content fails in non-streaming mode.. */ 2399 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 2400 SetLastError(0xdeadbeef); 2401 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 2402 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || 2403 GetLastError() == OSS_PDU_MISMATCH /* Win9x */), 2404 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n", 2405 GetLastError()); 2406 CryptMsgClose(msg); 2407 /* and as the final update in streaming mode.. */ 2408 streamInfo.pfnStreamOutput = nop_stream_output; 2409 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo); 2410 SetLastError(0xdeadbeef); 2411 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 2412 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || 2413 GetLastError() == OSS_PDU_MISMATCH /* Win9x */), 2414 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n", 2415 GetLastError()); 2416 CryptMsgClose(msg); 2417 /* and even as a non-final update in streaming mode. */ 2418 streamInfo.pfnStreamOutput = nop_stream_output; 2419 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo); 2420 SetLastError(0xdeadbeef); 2421 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE); 2422 todo_wine 2423 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || 2424 GetLastError() == OSS_PDU_MISMATCH /* Win9x */), 2425 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n", 2426 GetLastError()); 2427 CryptMsgClose(msg); 2428 2429 /* An empty message can be opened with undetermined type.. */ 2430 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 2431 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), 2432 TRUE); 2433 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 2434 CryptMsgClose(msg); 2435 /* but decoding it as an explicitly typed message fails. */ 2436 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL, 2437 NULL); 2438 SetLastError(0xdeadbeef); 2439 ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), 2440 TRUE); 2441 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || 2442 GetLastError() == OSS_PDU_MISMATCH /* Win9x */), 2443 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n", 2444 GetLastError()); 2445 CryptMsgClose(msg); 2446 /* On the other hand, decoding the bare content of an empty message fails 2447 * with unspecified type.. 2448 */ 2449 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 2450 SetLastError(0xdeadbeef); 2451 ret = CryptMsgUpdate(msg, dataEmptyBareContent, 2452 sizeof(dataEmptyBareContent), TRUE); 2453 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || 2454 GetLastError() == OSS_PDU_MISMATCH /* Win9x */), 2455 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n", 2456 GetLastError()); 2457 CryptMsgClose(msg); 2458 /* but succeeds with explicit type. */ 2459 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL, 2460 NULL); 2461 ret = CryptMsgUpdate(msg, dataEmptyBareContent, 2462 sizeof(dataEmptyBareContent), TRUE); 2463 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 2464 CryptMsgClose(msg); 2465 2466 /* Decoding valid content with an unsupported OID fails */ 2467 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 2468 SetLastError(0xdeadbeef); 2469 ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE); 2470 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 2471 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError()); 2472 CryptMsgClose(msg); 2473 2474 /* Similarly, opening an empty hash with unspecified type succeeds.. */ 2475 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 2476 SetLastError(0xdeadbeef); 2477 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE); 2478 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */), 2479 "CryptMsgUpdate failed: %08x\n", GetLastError()); 2480 CryptMsgClose(msg); 2481 /* while with specified type it fails. */ 2482 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL, 2483 NULL); 2484 SetLastError(0xdeadbeef); 2485 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE); 2486 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || 2487 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ || 2488 GetLastError() == OSS_DATA_ERROR /* some Win9x */), 2489 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n", 2490 GetLastError()); 2491 CryptMsgClose(msg); 2492 /* On the other hand, decoding the bare content of an empty hash message 2493 * fails with unspecified type.. 2494 */ 2495 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 2496 SetLastError(0xdeadbeef); 2497 ret = CryptMsgUpdate(msg, hashEmptyBareContent, 2498 sizeof(hashEmptyBareContent), TRUE); 2499 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || 2500 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ || 2501 GetLastError() == OSS_DATA_ERROR /* some Win9x */), 2502 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n", 2503 GetLastError()); 2504 CryptMsgClose(msg); 2505 /* but succeeds with explicit type. */ 2506 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL, 2507 NULL); 2508 ret = CryptMsgUpdate(msg, hashEmptyBareContent, 2509 sizeof(hashEmptyBareContent), TRUE); 2510 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* win9x */), 2511 "CryptMsgUpdate failed: %x\n", GetLastError()); 2512 CryptMsgClose(msg); 2513 2514 /* And again, opening a (non-empty) hash message with unspecified type 2515 * succeeds.. 2516 */ 2517 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 2518 SetLastError(0xdeadbeef); 2519 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE); 2520 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 2521 CryptMsgClose(msg); 2522 /* while with specified type it fails.. */ 2523 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL, 2524 NULL); 2525 SetLastError(0xdeadbeef); 2526 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE); 2527 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || 2528 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ || 2529 GetLastError() == OSS_DATA_ERROR /* some Win9x */), 2530 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n", 2531 GetLastError()); 2532 CryptMsgClose(msg); 2533 /* and decoding the bare content of a non-empty hash message fails with 2534 * unspecified type.. 2535 */ 2536 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 2537 SetLastError(0xdeadbeef); 2538 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE); 2539 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || 2540 GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ || 2541 GetLastError() == OSS_DATA_ERROR /* some Win9x */), 2542 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n", 2543 GetLastError()); 2544 CryptMsgClose(msg); 2545 /* but succeeds with explicit type. */ 2546 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL, 2547 NULL); 2548 ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE); 2549 ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); 2550 CryptMsgClose(msg); 2551 2552 /* Opening a (non-empty) hash message with unspecified type and a bogus 2553 * hash value succeeds.. 2554 */ 2555 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 2556 SetLastError(0xdeadbeef); 2557 ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE); 2558 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 2559 CryptMsgClose(msg); 2560 2561 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 2562 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE); 2563 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 2564 CryptMsgClose(msg); 2565 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 2566 SetLastError(0xdeadbeef); 2567 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent, 2568 sizeof(signedWithCertAndCrlBareContent), TRUE); 2569 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || 2570 GetLastError() == OSS_DATA_ERROR /* Win9x */), 2571 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n", 2572 GetLastError()); 2573 CryptMsgClose(msg); 2574 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL, 2575 NULL); 2576 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent, 2577 sizeof(signedWithCertAndCrlBareContent), TRUE); 2578 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 2579 CryptMsgClose(msg); 2580 2581 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0, 2582 NULL, NULL); 2583 /* The first update succeeds.. */ 2584 ret = CryptMsgUpdate(msg, detachedSignedContent, 2585 sizeof(detachedSignedContent), TRUE); 2586 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 2587 /* as does a second (probably to update the detached portion).. */ 2588 ret = CryptMsgUpdate(msg, detachedSignedContent, 2589 sizeof(detachedSignedContent), TRUE); 2590 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 2591 /* while a third fails. */ 2592 ret = CryptMsgUpdate(msg, detachedSignedContent, 2593 sizeof(detachedSignedContent), TRUE); 2594 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR, 2595 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError()); 2596 CryptMsgClose(msg); 2597 2598 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0, NULL, &streamInfo); 2599 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE); 2600 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 2601 ret = CryptMsgUpdate(msg, NULL, 0, TRUE); 2602 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 2603 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE); 2604 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 2605 ret = CryptMsgUpdate(msg, NULL, 0, TRUE); 2606 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 2607 2608 ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), TRUE); 2609 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR, 2610 "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError()); 2611 CryptMsgClose(msg); 2612 2613 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL, 2614 NULL); 2615 SetLastError(0xdeadbeef); 2616 ret = CryptMsgUpdate(msg, envelopedEmptyBareContent, 2617 sizeof(envelopedEmptyBareContent), TRUE); 2618 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 2619 CryptMsgClose(msg); 2620 2621 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL, 2622 NULL); 2623 SetLastError(0xdeadbeef); 2624 ret = CryptMsgUpdate(msg, envelopedEmptyContent, 2625 sizeof(envelopedEmptyContent), TRUE); 2626 ok(!ret && 2627 (GetLastError() == CRYPT_E_ASN1_BADTAG || 2628 GetLastError() == OSS_DATA_ERROR), /* Win9x */ 2629 "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError()); 2630 CryptMsgClose(msg); 2631 2632 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 2633 SetLastError(0xdeadbeef); 2634 ret = CryptMsgUpdate(msg, envelopedEmptyBareContent, 2635 sizeof(envelopedEmptyBareContent), TRUE); 2636 ok(!ret && 2637 (GetLastError() == CRYPT_E_ASN1_BADTAG || 2638 GetLastError() == OSS_DATA_ERROR), /* Win9x */ 2639 "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError()); 2640 CryptMsgClose(msg); 2641 2642 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 2643 SetLastError(0xdeadbeef); 2644 ret = CryptMsgUpdate(msg, envelopedEmptyContent, 2645 sizeof(envelopedEmptyContent), TRUE); 2646 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 2647 CryptMsgClose(msg); 2648 2649 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL, 2650 NULL); 2651 SetLastError(0xdeadbeef); 2652 ret = CryptMsgUpdate(msg, envelopedBareContentWithoutData, 2653 sizeof(envelopedBareContentWithoutData), TRUE); 2654 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 2655 CryptMsgClose(msg); 2656 } 2657 2658 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1, 2659 0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f }; 2660 2661 static void compare_signer_info(const CMSG_SIGNER_INFO *got, 2662 const CMSG_SIGNER_INFO *expected) 2663 { 2664 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n", 2665 expected->dwVersion, got->dwVersion); 2666 ok(got->Issuer.cbData == expected->Issuer.cbData, 2667 "Expected issuer size %d, got %d\n", expected->Issuer.cbData, 2668 got->Issuer.cbData); 2669 ok(!memcmp(got->Issuer.pbData, expected->Issuer.pbData, got->Issuer.cbData), 2670 "Unexpected issuer\n"); 2671 ok(got->SerialNumber.cbData == expected->SerialNumber.cbData, 2672 "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData, 2673 got->SerialNumber.cbData); 2674 ok(!memcmp(got->SerialNumber.pbData, expected->SerialNumber.pbData, 2675 got->SerialNumber.cbData), "Unexpected serial number\n"); 2676 /* FIXME: check more things */ 2677 } 2678 2679 static void compare_cms_signer_info(const CMSG_CMS_SIGNER_INFO *got, 2680 const CMSG_CMS_SIGNER_INFO *expected) 2681 { 2682 ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n", 2683 expected->dwVersion, got->dwVersion); 2684 ok(got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice, 2685 "Expected id choice %d, got %d\n", expected->SignerId.dwIdChoice, 2686 got->SignerId.dwIdChoice); 2687 if (got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice) 2688 { 2689 if (got->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER) 2690 { 2691 ok(U(got->SignerId).IssuerSerialNumber.Issuer.cbData == 2692 U(expected->SignerId).IssuerSerialNumber.Issuer.cbData, 2693 "Expected issuer size %d, got %d\n", 2694 U(expected->SignerId).IssuerSerialNumber.Issuer.cbData, 2695 U(got->SignerId).IssuerSerialNumber.Issuer.cbData); 2696 ok(!memcmp(U(got->SignerId).IssuerSerialNumber.Issuer.pbData, 2697 U(expected->SignerId).IssuerSerialNumber.Issuer.pbData, 2698 U(got->SignerId).IssuerSerialNumber.Issuer.cbData), 2699 "Unexpected issuer\n"); 2700 ok(U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData == 2701 U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData, 2702 "Expected serial number size %d, got %d\n", 2703 U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData, 2704 U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData); 2705 ok(!memcmp(U(got->SignerId).IssuerSerialNumber.SerialNumber.pbData, 2706 U(expected->SignerId).IssuerSerialNumber.SerialNumber.pbData, 2707 U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData), 2708 "Unexpected serial number\n"); 2709 } 2710 else 2711 { 2712 ok(U(got->SignerId).KeyId.cbData == U(expected->SignerId).KeyId.cbData, 2713 "expected key id size %d, got %d\n", 2714 U(expected->SignerId).KeyId.cbData, U(got->SignerId).KeyId.cbData); 2715 ok(!memcmp(U(expected->SignerId).KeyId.pbData, 2716 U(got->SignerId).KeyId.pbData, U(got->SignerId).KeyId.cbData), 2717 "unexpected key id\n"); 2718 } 2719 } 2720 /* FIXME: check more things */ 2721 } 2722 2723 static const BYTE signedWithCertAndCrlComputedHash[] = { 2724 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26, 2725 0x2f }; 2726 static BYTE keyIdIssuer[] = { 2727 0x30,0x13,0x31,0x11,0x30,0x0f,0x06,0x0a,0x2b,0x06,0x01,0x04,0x01,0x82,0x37, 2728 0x0a,0x07,0x01,0x04,0x01,0x01 }; 2729 static const BYTE publicPrivateKeyPair[] = { 2730 0x07,0x02,0x00,0x00,0x00,0xa4,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x04,0x00, 2731 0x00,0x01,0x00,0x01,0x00,0x21,0x65,0x5d,0x97,0x19,0x3f,0xd0,0xd0,0x76,0x5b, 2732 0xb1,0x10,0x4e,0xcc,0x14,0xb5,0x92,0x0f,0x60,0xad,0xb6,0x74,0x8d,0x94,0x50, 2733 0xfd,0x14,0x5e,0xbc,0xf1,0x93,0xbf,0x24,0x21,0x64,0x9d,0xc7,0x77,0x04,0x54, 2734 0xd1,0xbd,0x3e,0xd8,0x3b,0x2a,0x8b,0x95,0x70,0xdf,0x19,0x20,0xed,0x76,0x39, 2735 0xfa,0x64,0x04,0xc6,0xf7,0x33,0x7b,0xaa,0x94,0x67,0x74,0xbc,0x6b,0xd5,0xa7, 2736 0x69,0x99,0x99,0x47,0x88,0xc0,0x7e,0x36,0xf1,0xc5,0x7d,0xa8,0xd8,0x07,0x48, 2737 0xe6,0x05,0x4f,0xf4,0x1f,0x37,0xd7,0xc7,0xa7,0x00,0x20,0xb3,0xe5,0x40,0x17, 2738 0x86,0x43,0x77,0xe0,0x32,0x39,0x11,0x9c,0xd9,0xd8,0x53,0x9b,0x45,0x42,0x54, 2739 0x65,0xca,0x15,0xbe,0xb2,0x44,0xf1,0xd0,0xf3,0xb6,0x4a,0x19,0xc8,0x3d,0x33, 2740 0x63,0x93,0x4f,0x7c,0x67,0xc6,0x58,0x6d,0xf6,0xb7,0x20,0xd8,0x30,0xcc,0x52, 2741 0xaa,0x68,0x66,0xf6,0x86,0xf8,0xe0,0x3a,0x73,0x0e,0x9d,0xc5,0x03,0x60,0x9e, 2742 0x08,0xe9,0x5e,0xd4,0x5e,0xcc,0xbb,0xc1,0x48,0xad,0x9d,0xbb,0xfb,0x26,0x61, 2743 0xa8,0x0e,0x9c,0xba,0xf1,0xd0,0x0b,0x5f,0x87,0xd4,0xb5,0xd2,0xdf,0x41,0xcb, 2744 0x7a,0xec,0xb5,0x87,0x59,0x6a,0x9d,0xb3,0x6c,0x06,0xee,0x1f,0xc5,0xae,0x02, 2745 0xa8,0x7f,0x33,0x6e,0x30,0x50,0x6d,0x65,0xd0,0x1f,0x00,0x47,0x43,0x25,0x90, 2746 0x4a,0xa8,0x74,0x8c,0x23,0x8b,0x15,0x8a,0x74,0xd2,0x03,0xa6,0x1c,0xc1,0x7e, 2747 0xbb,0xb1,0xa6,0x80,0x05,0x2b,0x62,0xfb,0x89,0xe5,0xba,0xc6,0xcc,0x12,0xce, 2748 0xa8,0xe9,0xc4,0xb5,0x9d,0xd8,0x11,0xdd,0x95,0x90,0x71,0xb0,0xfe,0xaa,0x14, 2749 0xce,0xd5,0xd0,0x5a,0x88,0x47,0xda,0x31,0xda,0x26,0x11,0x66,0xd1,0xd5,0xc5, 2750 0x1b,0x08,0xbe,0xc6,0xf3,0x15,0xbf,0x80,0x78,0xcf,0x55,0xe0,0x61,0xee,0xf5, 2751 0x71,0x1e,0x2f,0x0e,0xb3,0x67,0xf7,0xa1,0x86,0x04,0xcf,0x4b,0xc1,0x2f,0x94, 2752 0x73,0xd1,0x5d,0x0c,0xee,0x10,0x58,0xbb,0x74,0x0c,0x61,0x02,0x15,0x69,0x68, 2753 0xe0,0x21,0x3e,0xa6,0x27,0x22,0x8c,0xc8,0x61,0xbc,0xba,0xa9,0x4b,0x2e,0x71, 2754 0x77,0x74,0xdc,0x63,0x05,0x32,0x7a,0x93,0x4f,0xbf,0xc7,0xa5,0x3a,0xe3,0x25, 2755 0x4d,0x67,0xcf,0x78,0x1b,0x85,0x22,0x6c,0xfe,0x5c,0x34,0x0e,0x27,0x12,0xbc, 2756 0xd5,0x33,0x1a,0x75,0x8a,0x9c,0x40,0x39,0xe8,0xa0,0xc9,0xae,0xf8,0xaf,0x9a, 2757 0xc6,0x62,0x47,0xf3,0x5b,0xdf,0x5e,0xcd,0xc6,0xc0,0x5c,0xd7,0x0e,0x04,0x64, 2758 0x3d,0xdd,0x57,0xef,0xf6,0xcd,0xdf,0xd2,0x7e,0x17,0x6c,0x0a,0x47,0x5e,0x77, 2759 0x4b,0x02,0x49,0x78,0xc0,0xf7,0x09,0x6e,0xdf,0x96,0x04,0x51,0x74,0x3d,0x68, 2760 0x99,0x43,0x8e,0x03,0x16,0x46,0xa4,0x04,0x84,0x01,0x6e,0xd4,0xca,0x5c,0xab, 2761 0xb0,0xd3,0x82,0xf1,0xb9,0xba,0x51,0x99,0x03,0xe9,0x7f,0xdf,0x30,0x3b,0xf9, 2762 0x18,0xbb,0x80,0x7f,0xf0,0x89,0xbb,0x6d,0x98,0x95,0xb7,0xfd,0xd8,0xdf,0xed, 2763 0xf3,0x16,0x6f,0x96,0x4f,0xfd,0x54,0x66,0x6d,0x90,0xba,0xf5,0xcc,0xce,0x01, 2764 0x34,0x34,0x51,0x07,0x66,0x20,0xfb,0x4a,0x3c,0x7e,0x19,0xf8,0x8e,0x35,0x0e, 2765 0x07,0x48,0x74,0x38,0xd2,0x18,0xaa,0x2e,0x90,0x5e,0x0e,0xcc,0x50,0x6e,0x71, 2766 0x6f,0x54,0xdb,0xbf,0x7b,0xb4,0xf4,0x79,0x6a,0x21,0xa3,0x6d,0xdf,0x61,0xc0, 2767 0x8f,0xb3,0xb6,0xe1,0x8a,0x65,0x21,0x6e,0xf6,0x5b,0x80,0xf0,0xfb,0x28,0x87, 2768 0x13,0x06,0xd6,0xbc,0x28,0x5c,0xda,0xc5,0x13,0x13,0x44,0x8d,0xf4,0xa8,0x7b, 2769 0x5c,0x2a,0x7f,0x11,0x16,0x4e,0x52,0x41,0xe9,0xe7,0x8e }; 2770 static const BYTE envelopedMessage[] = { 2771 0x30,0x81,0xf2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0, 2772 0x81,0xe4,0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02, 2773 0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03, 2774 0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5, 2775 0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7, 2776 0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xc2,0x0d,0x59,0x87,0xb3,0x65, 2777 0xd2,0x64,0xcd,0xba,0xe3,0xaf,0x1e,0xa1,0xd3,0xdd,0xb3,0x53,0xfc,0x2f,0xae, 2778 0xdc,0x6d,0x2a,0x81,0x84,0x38,0x6f,0xdf,0x81,0xb1,0x65,0xba,0xac,0x59,0xb1, 2779 0x19,0x12,0x3f,0xde,0x12,0xce,0x77,0x42,0x71,0x67,0xa9,0x78,0x38,0x95,0x51, 2780 0xbb,0x66,0x78,0xbf,0xaf,0x0a,0x98,0x4b,0xba,0xa5,0xf0,0x8b,0x9f,0xef,0xcf, 2781 0x40,0x05,0xa1,0xd6,0x10,0xae,0xbf,0xb9,0xbd,0x4d,0x22,0x39,0x33,0x63,0x2b, 2782 0x0b,0xd3,0x0c,0xb5,0x4b,0xe8,0xfe,0x15,0xa8,0xa5,0x2c,0x86,0x33,0x80,0x6e, 2783 0x4c,0x7a,0x99,0x3c,0x6b,0x4b,0x60,0xfd,0x8e,0xb2,0xf3,0x82,0x2f,0x3e,0x1e, 2784 0xba,0xb9,0x78,0x24,0x32,0xab,0xa4,0x10,0x1a,0x38,0x94,0x10,0x8d,0xf8,0x70, 2785 0x3e,0x4e,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01, 2786 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80, 2787 0x04,0x5f,0x80,0xf2,0x17 }; 2788 static const BYTE envelopedBareMessage[] = { 2789 0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00, 2790 0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01, 2791 0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01, 2792 0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 2793 0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x69,0x79,0x12,0x6b,0xa1,0x2f,0xe9,0x0d, 2794 0x34,0x79,0x77,0xe9,0x15,0xf2,0xff,0x0c,0x9a,0xf2,0x87,0xbd,0x12,0xc4,0x2d, 2795 0x9e,0x81,0xc7,0x3c,0x74,0x05,0xdc,0x13,0xaf,0xe9,0xa2,0xba,0x72,0xe9,0xa5, 2796 0x2b,0x81,0x39,0xd3,0x62,0xaa,0x78,0xc3,0x90,0x4f,0x06,0xf0,0xdb,0x18,0x5e, 2797 0xe1,0x2e,0x19,0xa3,0xc2,0xac,0x1e,0xf1,0xbf,0xe6,0x03,0x00,0x96,0xfa,0xd2, 2798 0x66,0x73,0xd0,0x45,0x55,0x57,0x71,0xff,0x3a,0x0c,0xad,0xce,0xde,0x68,0xd4, 2799 0x45,0x20,0xc8,0x44,0x4d,0x5d,0xa2,0x98,0x79,0xb1,0x81,0x0f,0x8a,0xfc,0x70, 2800 0xa5,0x18,0xd2,0x30,0x65,0x22,0x84,0x02,0x24,0x48,0xf7,0xa4,0xe0,0xa5,0x6c, 2801 0xa8,0xa4,0xd0,0x86,0x4b,0x6e,0x9b,0x18,0xab,0x78,0xfa,0x76,0x12,0xce,0x55, 2802 0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c, 2803 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80,0x04,0x2c, 2804 0x2d,0xa3,0x6e }; 2805 static const BYTE envelopedMessageWith3Recps[] = { 2806 0x30,0x82,0x02,0x69,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03, 2807 0xa0,0x82,0x02,0x5a,0x30,0x82,0x02,0x56,0x02,0x01,0x00,0x31,0x82,0x02,0x2e, 2808 0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06, 2809 0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36, 2810 0xa9,0xba,0x41,0xa5,0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a, 2811 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xa4,0x2e, 2812 0xe5,0x56,0x60,0xc5,0x64,0x07,0x29,0xaf,0x5c,0x38,0x3d,0x4b,0xec,0xbd,0xba, 2813 0x97,0x60,0x17,0xed,0xd7,0x21,0x7b,0x19,0x94,0x95,0xf1,0xb2,0x84,0x06,0x1f, 2814 0xc5,0x83,0xb3,0x5d,0xc8,0x2c,0x1c,0x0f,0xf7,0xfd,0x58,0x8b,0x0f,0x25,0xb5, 2815 0x9f,0x7f,0x43,0x8f,0x5f,0x81,0x16,0x4a,0x62,0xfb,0x47,0xb5,0x36,0x72,0x21, 2816 0x29,0xd4,0x9e,0x27,0x35,0xf4,0xd0,0xd4,0xc0,0xa3,0x7a,0x47,0xbe,0xc9,0xae, 2817 0x08,0x17,0x6a,0xb5,0x63,0x38,0xa1,0xdc,0xf5,0xc1,0x8d,0x97,0x56,0xb4,0xc0, 2818 0x2d,0x2b,0xec,0x3d,0xbd,0xce,0xd1,0x52,0x3e,0x29,0x34,0xe2,0x9a,0x00,0x96, 2819 0x4c,0x85,0xaf,0x0f,0xfb,0x10,0x1d,0xf8,0x08,0x27,0x10,0x04,0x04,0xbf,0xae, 2820 0x36,0xd0,0x6a,0x49,0xe7,0x43,0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30, 2821 0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10, 2822 0xc2,0x8f,0xc4,0x5e,0x8d,0x3b,0x01,0x8c,0x4b,0x23,0xcb,0x93,0x77,0xab,0xb6, 2823 0xe1,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05, 2824 0x00,0x04,0x81,0x80,0x4b,0x22,0x8a,0xfa,0xa6,0xb6,0x01,0xe9,0xb5,0x54,0xcf, 2825 0xa7,0x81,0x54,0xf9,0x08,0x42,0x8a,0x75,0x19,0x9c,0xc9,0x27,0x68,0x08,0xf9, 2826 0x53,0xa7,0x60,0xf8,0xdd,0xba,0xfb,0x4f,0x63,0x8a,0x15,0x6a,0x5b,0xf6,0xe3, 2827 0x4e,0x29,0xa9,0xc8,0x1d,0x63,0x92,0x8f,0x95,0x91,0x95,0x71,0xb5,0x5d,0x02, 2828 0xe5,0xa0,0x07,0x67,0x36,0xe5,0x2d,0x7b,0xcd,0xe1,0xf2,0xa4,0xc6,0x24,0x70, 2829 0xac,0xd7,0xaf,0x63,0xb2,0x04,0x02,0x8d,0xae,0x2f,0xdc,0x7e,0x6c,0x84,0xd3, 2830 0xe3,0x66,0x54,0x3b,0x05,0xd8,0x77,0x40,0xe4,0x6b,0xbd,0xa9,0x8d,0x4d,0x74, 2831 0x15,0xfd,0x74,0xf7,0xd3,0xc0,0xc9,0xf1,0x20,0x0e,0x08,0x13,0xcc,0xb0,0x94, 2832 0x53,0x01,0xd4,0x5f,0x95,0x32,0xeb,0xe8,0x73,0x9f,0x6a,0xd1,0x30,0x81,0xb7, 2833 0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04, 2834 0x03,0x13,0x01,0x58,0x02,0x10,0x1c,0xf2,0x1f,0xec,0x6b,0xdc,0x36,0xbf,0x4a, 2835 0xd7,0xe1,0x6c,0x84,0x85,0xcd,0x2e,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86, 2836 0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x47,0x21,0xf9,0xe7,0x98, 2837 0x7f,0xe7,0x49,0x3f,0x16,0xb8,0x4c,0x8b,0x7d,0x5d,0x56,0xa7,0x31,0xfd,0xa5, 2838 0xcd,0x43,0x70,0x58,0xf1,0x33,0xfb,0xe6,0xc8,0xbb,0x6f,0x0a,0x89,0xa4,0xb9, 2839 0x3e,0x3a,0xc5,0x85,0x46,0x54,0x73,0x37,0xa3,0xbd,0x36,0xc3,0xce,0x40,0xf3, 2840 0xd7,0x92,0x54,0x8e,0x60,0x1f,0xa2,0xa7,0x03,0xc2,0x49,0xa9,0x02,0x28,0xc8, 2841 0xa5,0xa7,0x42,0xcd,0x29,0x85,0x34,0xa7,0xa9,0xe8,0x8c,0x3d,0xb3,0xd0,0xac, 2842 0x7d,0x31,0x5d,0xb4,0xcb,0x7e,0xad,0x62,0xfd,0x04,0x7b,0xa1,0x93,0xb5,0xbc, 2843 0x08,0x4f,0x36,0xd7,0x5a,0x95,0xbc,0xff,0x47,0x0f,0x84,0x21,0x24,0xdf,0xc5, 2844 0xfe,0xc8,0xe5,0x0b,0xc4,0xc4,0x5c,0x1a,0x50,0x31,0x91,0xce,0xf6,0x11,0xf1, 2845 0x0e,0x28,0xce,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07, 2846 0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00, 2847 0x80,0x04,0x4e,0x99,0x9d,0x4c }; 2848 static const BYTE serialNumber[] = { 2849 0x2e,0xcd,0x85,0x84,0x6c,0xe1,0xd7,0x4a,0xbf,0x36,0xdc,0x6b,0xec,0x1f,0xf2, 2850 0x1c }; 2851 static const BYTE issuer[] = { 2852 0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x58 }; 2853 2854 static void test_decode_msg_get_param(void) 2855 { 2856 HCRYPTMSG msg; 2857 HCRYPTPROV hCryptProv; 2858 HCRYPTKEY key = 0; 2859 BOOL ret; 2860 DWORD size = 0, value, req_size; 2861 LPBYTE buf; 2862 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 }; 2863 2864 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 2865 SetLastError(0xdeadbeef); 2866 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size); 2867 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 2868 "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError()); 2869 ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE); 2870 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 2871 check_param("data content", msg, CMSG_CONTENT_PARAM, msgData, 2872 sizeof(msgData)); 2873 CryptMsgClose(msg); 2874 2875 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 2876 ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE); 2877 if (ret) 2878 { 2879 /* Crashes on some Win9x */ 2880 check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0); 2881 check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0); 2882 check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM, 2883 emptyHashParam, sizeof(emptyHashParam)); 2884 } 2885 CryptMsgClose(msg); 2886 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 2887 ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE); 2888 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 2889 check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData, 2890 sizeof(msgData)); 2891 check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam, 2892 sizeof(hashParam)); 2893 check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM, 2894 hashParam, sizeof(hashParam)); 2895 /* Curiously, on NT-like systems, getting the hash of index 1 succeeds, 2896 * even though there's only one hash. 2897 */ 2898 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size); 2899 ok(ret || GetLastError() == OSS_DATA_ERROR /* Win9x */, 2900 "CryptMsgGetParam failed: %08x\n", GetLastError()); 2901 if (ret) 2902 buf = CryptMemAlloc(size); 2903 else 2904 buf = NULL; 2905 if (buf) 2906 { 2907 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size); 2908 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); 2909 ok(size == sizeof(hashParam), "Unexpected size %d\n", size); 2910 ok(!memcmp(buf, hashParam, size), "Unexpected value\n"); 2911 CryptMemFree(buf); 2912 } 2913 check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM, 2914 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1); 2915 value = CMSG_HASHED_DATA_V0; 2916 check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value, 2917 sizeof(value)); 2918 CryptMsgClose(msg); 2919 2920 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 2921 ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE); 2922 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 2923 check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData, 2924 sizeof(msgData)); 2925 check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM, 2926 (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1); 2927 size = sizeof(value); 2928 value = 2112; 2929 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size); 2930 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); 2931 ok(value == 1, "Expected 1 signer, got %d\n", value); 2932 size = 0; 2933 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size); 2934 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */), 2935 "CryptMsgGetParam failed: %08x\n", GetLastError()); 2936 if (ret) 2937 buf = CryptMemAlloc(size); 2938 else 2939 buf = NULL; 2940 if (buf) 2941 { 2942 CMSG_SIGNER_INFO signer = { 0 }; 2943 2944 signer.dwVersion = 1; 2945 signer.Issuer.cbData = sizeof(encodedCommonName); 2946 signer.Issuer.pbData = encodedCommonName; 2947 signer.SerialNumber.cbData = sizeof(serialNum); 2948 signer.SerialNumber.pbData = serialNum; 2949 signer.HashAlgorithm.pszObjId = oid_rsa_md5; 2950 req_size = size; 2951 size += 10; 2952 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size); 2953 ok(size == req_size, "size = %u, expected %u\n", size, req_size); 2954 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer); 2955 CryptMemFree(buf); 2956 } 2957 /* Getting the CMS signer info of a PKCS7 message is possible. */ 2958 size = 0; 2959 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size); 2960 ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */), 2961 "CryptMsgGetParam failed: %08x\n", GetLastError()); 2962 if (ret) 2963 buf = CryptMemAlloc(size); 2964 else 2965 buf = NULL; 2966 if (buf) 2967 { 2968 CMSG_CMS_SIGNER_INFO signer = { 0 }; 2969 2970 signer.dwVersion = 1; 2971 signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER; 2972 U(signer.SignerId).IssuerSerialNumber.Issuer.cbData = 2973 sizeof(encodedCommonName); 2974 U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName; 2975 U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData = 2976 sizeof(serialNum); 2977 U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum; 2978 signer.HashAlgorithm.pszObjId = oid_rsa_md5; 2979 CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size); 2980 compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer); 2981 CryptMemFree(buf); 2982 } 2983 /* index is ignored when getting signer count */ 2984 size = sizeof(value); 2985 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size); 2986 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); 2987 ok(value == 1, "Expected 1 signer, got %d\n", value); 2988 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size); 2989 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); 2990 ok(value == 0, "Expected 0 certs, got %d\n", value); 2991 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size); 2992 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); 2993 ok(value == 0, "Expected 0 CRLs, got %d\n", value); 2994 CryptMsgClose(msg); 2995 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL, 2996 NULL); 2997 ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent, 2998 sizeof(signedWithCertAndCrlBareContent), TRUE); 2999 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 3000 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size); 3001 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); 3002 ok(value == 1, "Expected 1 cert, got %d\n", value); 3003 check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert)); 3004 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size); 3005 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); 3006 ok(value == 1, "Expected 1 CRL, got %d\n", value); 3007 check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl)); 3008 check_param("signed with cert and CRL computed hash", msg, 3009 CMSG_COMPUTED_HASH_PARAM, signedWithCertAndCrlComputedHash, 3010 sizeof(signedWithCertAndCrlComputedHash)); 3011 CryptMsgClose(msg); 3012 3013 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 3014 ret = CryptMsgUpdate(msg, signedKeyIdEmptyContent, 3015 sizeof(signedKeyIdEmptyContent), TRUE); 3016 if (!ret && GetLastError() == OSS_DATA_ERROR) 3017 { 3018 CryptMsgClose(msg); 3019 win_skip("Subsequent tests crash on some Win9x\n"); 3020 return; 3021 } 3022 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 3023 size = sizeof(value); 3024 ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size); 3025 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); 3026 ok(value == 1, "Expected 1 signer, got %d\n", value); 3027 /* Getting the regular (non-CMS) signer info from a CMS message is also 3028 * possible.. 3029 */ 3030 size = 0; 3031 ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size); 3032 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); 3033 if (ret) 3034 buf = CryptMemAlloc(size); 3035 else 3036 buf = NULL; 3037 if (buf) 3038 { 3039 CMSG_SIGNER_INFO signer; 3040 BYTE zero = 0; 3041 3042 /* and here's the little oddity: for a CMS message using the key id 3043 * variant of a SignerId, retrieving the CMSG_SIGNER_INFO param yields 3044 * a signer with a zero (not empty) serial number, and whose issuer is 3045 * an RDN with OID szOID_KEYID_RDN, value type CERT_RDN_OCTET_STRING, 3046 * and value of the key id. 3047 */ 3048 signer.dwVersion = CMSG_SIGNED_DATA_V3; 3049 signer.Issuer.cbData = sizeof(keyIdIssuer); 3050 signer.Issuer.pbData = keyIdIssuer; 3051 signer.SerialNumber.cbData = 1; 3052 signer.SerialNumber.pbData = &zero; 3053 CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size); 3054 compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer); 3055 CryptMemFree(buf); 3056 } 3057 size = 0; 3058 ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size); 3059 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); 3060 if (ret) 3061 buf = CryptMemAlloc(size); 3062 else 3063 buf = NULL; 3064 if (buf) 3065 { 3066 CMSG_CMS_SIGNER_INFO signer = { 0 }; 3067 3068 signer.dwVersion = CMSG_SIGNED_DATA_V3; 3069 signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER; 3070 U(signer.SignerId).KeyId.cbData = sizeof(serialNum); 3071 U(signer.SignerId).KeyId.pbData = serialNum; 3072 signer.HashAlgorithm.pszObjId = oid_rsa_md5; 3073 CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size); 3074 compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer); 3075 CryptMemFree(buf); 3076 } 3077 CryptMsgClose(msg); 3078 3079 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL, 3080 NULL); 3081 CryptMsgUpdate(msg, envelopedEmptyBareContent, 3082 sizeof(envelopedEmptyBareContent), TRUE); 3083 check_param("enveloped empty bare content", msg, CMSG_CONTENT_PARAM, NULL, 3084 0); 3085 CryptMsgClose(msg); 3086 3087 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 3088 CryptMsgUpdate(msg, envelopedEmptyContent, sizeof(envelopedEmptyContent), 3089 TRUE); 3090 check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM, NULL, 0); 3091 CryptMsgClose(msg); 3092 3093 pCryptAcquireContextA(&hCryptProv, NULL, MS_ENHANCED_PROV_A, PROV_RSA_FULL, 3094 CRYPT_VERIFYCONTEXT); 3095 SetLastError(0xdeadbeef); 3096 ret = CryptImportKey(hCryptProv, publicPrivateKeyPair, 3097 sizeof(publicPrivateKeyPair), 0, 0, &key); 3098 ok(ret || 3099 broken(!ret && GetLastError() == NTE_PERM), /* WinME and some NT4 */ 3100 "CryptImportKey failed: %08x\n", GetLastError()); 3101 3102 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 3103 CryptMsgUpdate(msg, envelopedMessage, sizeof(envelopedMessage), TRUE); 3104 check_param("enveloped message before decrypting", msg, CMSG_CONTENT_PARAM, 3105 envelopedMessage + sizeof(envelopedMessage) - 4, 4); 3106 if (key) 3107 { 3108 decryptPara.hCryptProv = hCryptProv; 3109 SetLastError(0xdeadbeef); 3110 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara); 3111 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError()); 3112 decryptPara.hCryptProv = 0; 3113 SetLastError(0xdeadbeef); 3114 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara); 3115 ok(!ret && GetLastError() == CRYPT_E_ALREADY_DECRYPTED, 3116 "expected CRYPT_E_ALREADY_DECRYPTED, got %08x\n", GetLastError()); 3117 check_param("enveloped message", msg, CMSG_CONTENT_PARAM, msgData, 3118 sizeof(msgData)); 3119 } 3120 else 3121 win_skip("failed to import a key, skipping tests\n"); 3122 CryptMsgClose(msg); 3123 3124 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL, 3125 NULL); 3126 CryptMsgUpdate(msg, envelopedBareMessage, sizeof(envelopedBareMessage), 3127 TRUE); 3128 check_param("enveloped bare message before decrypting", msg, 3129 CMSG_CONTENT_PARAM, envelopedBareMessage + 3130 sizeof(envelopedBareMessage) - 4, 4); 3131 if (key) 3132 { 3133 decryptPara.hCryptProv = hCryptProv; 3134 SetLastError(0xdeadbeef); 3135 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara); 3136 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError()); 3137 check_param("enveloped bare message", msg, CMSG_CONTENT_PARAM, msgData, 3138 sizeof(msgData)); 3139 } 3140 else 3141 win_skip("failed to import a key, skipping tests\n"); 3142 CryptMsgClose(msg); 3143 3144 if (key) 3145 CryptDestroyKey(key); 3146 CryptReleaseContext(hCryptProv, 0); 3147 3148 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 3149 CryptMsgUpdate(msg, envelopedMessageWith3Recps, 3150 sizeof(envelopedMessageWith3Recps), TRUE); 3151 value = 3; 3152 check_param("recipient count", msg, CMSG_RECIPIENT_COUNT_PARAM, 3153 (const BYTE *)&value, sizeof(value)); 3154 size = 0; 3155 SetLastError(0xdeadbeef); 3156 ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 3, NULL, &size); 3157 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX, 3158 "expected CRYPT_E_INVALID_INDEX, got %08x\n", GetLastError()); 3159 size = 0; 3160 SetLastError(0xdeadbeef); 3161 ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 2, NULL, &size); 3162 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); 3163 ok(size >= 142, "unexpected size: %u\n", size); 3164 if (ret) 3165 buf = CryptMemAlloc(size); 3166 else 3167 buf = NULL; 3168 if (buf) 3169 { 3170 CERT_INFO *certInfo = (CERT_INFO *)buf; 3171 3172 SetLastError(0xdeadbeef); 3173 ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 2, buf, &size); 3174 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); 3175 ok(certInfo->SerialNumber.cbData == sizeof(serialNumber), 3176 "unexpected serial number size: %u\n", certInfo->SerialNumber.cbData); 3177 ok(!memcmp(certInfo->SerialNumber.pbData, serialNumber, 3178 sizeof(serialNumber)), "unexpected serial number\n"); 3179 ok(certInfo->Issuer.cbData == sizeof(issuer), 3180 "unexpected issuer size: %u\n", certInfo->Issuer.cbData); 3181 ok(!memcmp(certInfo->Issuer.pbData, issuer, sizeof(issuer)), 3182 "unexpected issuer\n"); 3183 CryptMemFree(buf); 3184 } 3185 CryptMsgClose(msg); 3186 } 3187 3188 static void test_decode_msg(void) 3189 { 3190 test_decode_msg_update(); 3191 test_decode_msg_get_param(); 3192 } 3193 3194 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf }; 3195 /* aKey encoded as a X509_PUBLIC_KEY_INFO */ 3196 static BYTE encodedPubKey[] = { 3197 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03, 3198 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c, 3199 0x0d,0x0e,0x0f }; 3200 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */ 3201 static BYTE mod_encoded[] = { 3202 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03, 3203 0x01,0x00,0x01 }; 3204 3205 static void test_msg_control(void) 3206 { 3207 static char oid_rsa_rsa[] = szOID_RSA_RSA; 3208 BOOL ret; 3209 HCRYPTMSG msg; 3210 DWORD i; 3211 CERT_INFO certInfo = { 0 }; 3212 CMSG_HASHED_ENCODE_INFO hashInfo = { 0 }; 3213 CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 }; 3214 CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 }; 3215 3216 /* Crashes 3217 ret = CryptMsgControl(NULL, 0, 0, NULL); 3218 */ 3219 3220 /* Data encode messages don't allow any sort of control.. */ 3221 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL, 3222 NULL); 3223 /* either with no prior update.. */ 3224 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++) 3225 { 3226 SetLastError(0xdeadbeef); 3227 ret = CryptMsgControl(msg, 0, i, NULL); 3228 ok(!ret && GetLastError() == E_INVALIDARG, 3229 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 3230 } 3231 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 3232 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 3233 /* or after an update. */ 3234 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++) 3235 { 3236 SetLastError(0xdeadbeef); 3237 ret = CryptMsgControl(msg, 0, i, NULL); 3238 ok(!ret && GetLastError() == E_INVALIDARG, 3239 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 3240 } 3241 CryptMsgClose(msg); 3242 3243 /* Hash encode messages don't allow any sort of control.. */ 3244 hashInfo.cbSize = sizeof(hashInfo); 3245 hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5; 3246 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo, 3247 NULL, NULL); 3248 /* either with no prior update.. */ 3249 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++) 3250 { 3251 SetLastError(0xdeadbeef); 3252 ret = CryptMsgControl(msg, 0, i, NULL); 3253 ok(!ret && GetLastError() == E_INVALIDARG, 3254 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 3255 } 3256 ret = CryptMsgUpdate(msg, NULL, 0, TRUE); 3257 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 3258 /* or after an update. */ 3259 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++) 3260 { 3261 SetLastError(0xdeadbeef); 3262 ret = CryptMsgControl(msg, 0, i, NULL); 3263 ok(!ret && GetLastError() == E_INVALIDARG, 3264 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 3265 } 3266 CryptMsgClose(msg); 3267 3268 /* Signed encode messages likewise don't allow any sort of control.. */ 3269 signInfo.cbSize = sizeof(signInfo); 3270 msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo, 3271 NULL, NULL); 3272 /* either before an update.. */ 3273 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++) 3274 { 3275 SetLastError(0xdeadbeef); 3276 ret = CryptMsgControl(msg, 0, i, NULL); 3277 ok(!ret && GetLastError() == E_INVALIDARG, 3278 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 3279 } 3280 ret = CryptMsgUpdate(msg, NULL, 0, TRUE); 3281 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 3282 /* or after an update. */ 3283 for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++) 3284 { 3285 SetLastError(0xdeadbeef); 3286 ret = CryptMsgControl(msg, 0, i, NULL); 3287 ok(!ret && GetLastError() == E_INVALIDARG, 3288 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 3289 } 3290 CryptMsgClose(msg); 3291 3292 /* Decode messages behave a bit differently. */ 3293 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 3294 /* Bad control type */ 3295 SetLastError(0xdeadbeef); 3296 ret = CryptMsgControl(msg, 0, 0, NULL); 3297 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE, 3298 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError()); 3299 SetLastError(0xdeadbeef); 3300 ret = CryptMsgControl(msg, 1, 0, NULL); 3301 ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE, 3302 "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError()); 3303 /* Can't verify the hash of an indeterminate-type message */ 3304 SetLastError(0xdeadbeef); 3305 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL); 3306 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 3307 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError()); 3308 /* Crashes 3309 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL); 3310 */ 3311 /* Can't decrypt an indeterminate-type message */ 3312 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara); 3313 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 3314 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError()); 3315 CryptMsgClose(msg); 3316 3317 if (!old_crypt32) 3318 { 3319 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL, 3320 NULL); 3321 /* Can't verify the hash of an empty message */ 3322 SetLastError(0xdeadbeef); 3323 /* Crashes on some Win9x */ 3324 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL); 3325 todo_wine 3326 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, 3327 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError()); 3328 /* Crashes 3329 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL); 3330 */ 3331 /* Can't verify the signature of a hash message */ 3332 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo); 3333 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 3334 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError()); 3335 CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent), 3336 TRUE); 3337 /* Oddly enough, this fails, crashes on some Win9x */ 3338 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL); 3339 ok(!ret, "Expected failure\n"); 3340 CryptMsgClose(msg); 3341 } 3342 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL, 3343 NULL); 3344 CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE); 3345 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL); 3346 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError()); 3347 /* Can't decrypt an indeterminate-type message */ 3348 SetLastError(0xdeadbeef); 3349 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara); 3350 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 3351 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError()); 3352 CryptMsgClose(msg); 3353 3354 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0, 3355 NULL, NULL); 3356 /* Can't verify the hash of a detached message before it's been updated. */ 3357 SetLastError(0xdeadbeef); 3358 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL); 3359 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 3360 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError()); 3361 ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent), 3362 TRUE); 3363 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 3364 /* Still can't verify the hash of a detached message with the content 3365 * of the detached hash given.. 3366 */ 3367 SetLastError(0xdeadbeef); 3368 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL); 3369 ok(!ret && GetLastError() == CRYPT_E_HASH_VALUE, 3370 "Expected CRYPT_E_HASH_VALUE, got %08x\n", GetLastError()); 3371 /* and giving the content of the message after attempting to verify the 3372 * hash fails. 3373 */ 3374 SetLastError(0xdeadbeef); 3375 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 3376 todo_wine 3377 ok(!ret && 3378 (GetLastError() == NTE_BAD_HASH_STATE || 3379 GetLastError() == NTE_BAD_ALGID || /* Win9x */ 3380 GetLastError() == CRYPT_E_MSG_ERROR), /* Vista */ 3381 "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, " 3382 "got %08x\n", GetLastError()); 3383 CryptMsgClose(msg); 3384 3385 /* Finally, verifying the hash of a detached message in the correct order: 3386 * 1. Update with the detached hash message 3387 * 2. Update with the content of the message 3388 * 3. Verifying the hash of the message 3389 * succeeds. 3390 */ 3391 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0, 3392 NULL, NULL); 3393 ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent), 3394 TRUE); 3395 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 3396 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 3397 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 3398 SetLastError(0xdeadbeef); 3399 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL); 3400 ok(ret, "CryptMsgControl failed: %08x\n", GetLastError()); 3401 CryptMsgClose(msg); 3402 3403 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL, 3404 NULL); 3405 /* Can't verify the hash of a signed message */ 3406 SetLastError(0xdeadbeef); 3407 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL); 3408 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 3409 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError()); 3410 /* Can't decrypt a signed message */ 3411 SetLastError(0xdeadbeef); 3412 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara); 3413 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 3414 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError()); 3415 /* Crash 3416 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL); 3417 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo); 3418 */ 3419 CryptMsgUpdate(msg, signedWithCertBareContent, 3420 sizeof(signedWithCertBareContent), TRUE); 3421 /* With an empty cert info, the signer can't be found in the message (and 3422 * the signature can't be verified. 3423 */ 3424 SetLastError(0xdeadbeef); 3425 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo); 3426 ok(!ret && (GetLastError() == CRYPT_E_SIGNER_NOT_FOUND || 3427 GetLastError() == OSS_DATA_ERROR /* Win9x */), 3428 "Expected CRYPT_E_SIGNER_NOT_FOUND or OSS_DATA_ERROR, got %08x\n", 3429 GetLastError()); 3430 /* The cert info is expected to have an issuer, serial number, and public 3431 * key info set. 3432 */ 3433 certInfo.SerialNumber.cbData = sizeof(serialNum); 3434 certInfo.SerialNumber.pbData = serialNum; 3435 certInfo.Issuer.cbData = sizeof(encodedCommonName); 3436 certInfo.Issuer.pbData = encodedCommonName; 3437 SetLastError(0xdeadbeef); 3438 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo); 3439 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD || 3440 GetLastError() == OSS_DATA_ERROR /* Win9x */), 3441 "Expected CRYPT_E_ASN1_EOD or OSS_DATA_ERROR, got %08x\n", GetLastError()); 3442 CryptMsgClose(msg); 3443 /* This cert has a public key, but it's not in a usable form */ 3444 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL, 3445 NULL); 3446 ret = CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent, 3447 sizeof(signedWithCertWithPubKeyBareContent), TRUE); 3448 if (ret) 3449 { 3450 /* Crashes on some Win9x */ 3451 /* Again, cert info needs to have a public key set */ 3452 SetLastError(0xdeadbeef); 3453 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo); 3454 ok(!ret && 3455 (GetLastError() == CRYPT_E_ASN1_EOD || 3456 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */), 3457 "Expected CRYPT_E_ASN1_EOD or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError()); 3458 /* The public key is supposed to be in encoded form.. */ 3459 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa; 3460 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey); 3461 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey; 3462 SetLastError(0xdeadbeef); 3463 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo); 3464 ok(!ret && 3465 (GetLastError() == CRYPT_E_ASN1_BADTAG || 3466 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */), 3467 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError()); 3468 /* but not as a X509_PUBLIC_KEY_INFO.. */ 3469 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL; 3470 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey); 3471 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey; 3472 SetLastError(0xdeadbeef); 3473 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo); 3474 ok(!ret && 3475 (GetLastError() == CRYPT_E_ASN1_BADTAG || 3476 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */), 3477 "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError()); 3478 /* This decodes successfully, but it doesn't match any key in the message */ 3479 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded); 3480 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded; 3481 SetLastError(0xdeadbeef); 3482 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo); 3483 /* In Wine's rsaenh, this fails to decode because the key length is too 3484 * small. Not sure if that's a bug in rsaenh, so leaving todo_wine for 3485 * now. 3486 */ 3487 todo_wine 3488 ok(!ret && 3489 (GetLastError() == NTE_BAD_SIGNATURE || 3490 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */), 3491 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError()); 3492 } 3493 CryptMsgClose(msg); 3494 /* A message with no data doesn't have a valid signature */ 3495 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 3496 ret = CryptMsgUpdate(msg, signedWithCertWithValidPubKeyEmptyContent, 3497 sizeof(signedWithCertWithValidPubKeyEmptyContent), TRUE); 3498 if (ret) 3499 { 3500 certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa; 3501 certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(pubKey); 3502 certInfo.SubjectPublicKeyInfo.PublicKey.pbData = pubKey; 3503 SetLastError(0xdeadbeef); 3504 /* Crashes on some Win9x */ 3505 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo); 3506 ok(!ret && 3507 (GetLastError() == NTE_BAD_SIGNATURE || 3508 GetLastError() == TRUST_E_NOSIGNATURE /* Vista */), 3509 "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError()); 3510 } 3511 CryptMsgClose(msg); 3512 /* Finally, this succeeds */ 3513 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 3514 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent, 3515 sizeof(signedWithCertWithValidPubKeyContent), TRUE); 3516 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo); 3517 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */), 3518 "CryptMsgControl failed: %08x\n", GetLastError()); 3519 CryptMsgClose(msg); 3520 3521 /* Test verifying signature of a detached signed message */ 3522 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0, 3523 NULL, NULL); 3524 ret = CryptMsgUpdate(msg, detachedSignedContent, 3525 sizeof(detachedSignedContent), TRUE); 3526 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 3527 /* Can't verify the sig without having updated the data */ 3528 SetLastError(0xdeadbeef); 3529 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo); 3530 ok(!ret && (GetLastError() == NTE_BAD_SIGNATURE || 3531 GetLastError() == OSS_DATA_ERROR /* Win9x */), 3532 "expected NTE_BAD_SIGNATURE or OSS_DATA_ERROR, got %08x\n", 3533 GetLastError()); 3534 /* Now that the signature's been checked, can't do the final update */ 3535 SetLastError(0xdeadbeef); 3536 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 3537 todo_wine 3538 ok((!ret && 3539 (GetLastError() == NTE_BAD_HASH_STATE || 3540 GetLastError() == NTE_BAD_ALGID || /* Win9x */ 3541 GetLastError() == CRYPT_E_MSG_ERROR)) || /* Vista */ 3542 broken(ret), /* Win9x */ 3543 "expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, " 3544 "got %08x\n", GetLastError()); 3545 CryptMsgClose(msg); 3546 /* Updating with the detached portion of the message and the data of the 3547 * the message allows the sig to be verified. 3548 */ 3549 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0, 3550 NULL, NULL); 3551 ret = CryptMsgUpdate(msg, detachedSignedContent, 3552 sizeof(detachedSignedContent), TRUE); 3553 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 3554 ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 3555 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 3556 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo); 3557 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */), 3558 "CryptMsgControl failed: %08x\n", GetLastError()); 3559 CryptMsgClose(msg); 3560 3561 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL, 3562 NULL); 3563 decryptPara.cbSize = 0; 3564 SetLastError(0xdeadbeef); 3565 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara); 3566 ok(!ret && GetLastError() == E_INVALIDARG, 3567 "expected E_INVALIDARG, got %08x\n", GetLastError()); 3568 decryptPara.cbSize = sizeof(decryptPara); 3569 if (!old_crypt32) 3570 { 3571 SetLastError(0xdeadbeef); 3572 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara); 3573 ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 3574 "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError()); 3575 } 3576 SetLastError(0xdeadbeef); 3577 ret = CryptMsgUpdate(msg, envelopedEmptyBareContent, 3578 sizeof(envelopedEmptyBareContent), TRUE); 3579 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 3580 SetLastError(0xdeadbeef); 3581 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara); 3582 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX, 3583 "expected CRYPT_E_INVALID_INDEX, got %08x\n", GetLastError()); 3584 CryptMsgClose(msg); 3585 3586 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL, 3587 NULL); 3588 SetLastError(0xdeadbeef); 3589 ret = CryptMsgUpdate(msg, envelopedBareMessage, 3590 sizeof(envelopedBareMessage), TRUE); 3591 ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); 3592 SetLastError(0xdeadbeef); 3593 ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara); 3594 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 3595 "expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); 3596 CryptMsgClose(msg); 3597 } 3598 3599 /* win9x has much less parameter checks and will crash on many tests 3600 * this code is from test_signed_msg_update() 3601 */ 3602 static BOOL detect_nt(void) 3603 { 3604 BOOL ret; 3605 CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 }; 3606 CERT_INFO certInfo = { 0 }; 3607 3608 if (!pCryptAcquireContextW) 3609 return FALSE; 3610 3611 certInfo.SerialNumber.cbData = sizeof(serialNum); 3612 certInfo.SerialNumber.pbData = serialNum; 3613 certInfo.Issuer.cbData = sizeof(encodedCommonName); 3614 certInfo.Issuer.pbData = encodedCommonName; 3615 signer.pCertInfo = &certInfo; 3616 signer.HashAlgorithm.pszObjId = oid_rsa_md5; 3617 3618 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, 3619 PROV_RSA_FULL, CRYPT_NEWKEYSET); 3620 if (!ret && GetLastError() == NTE_EXISTS) { 3621 ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, 3622 PROV_RSA_FULL, 0); 3623 } 3624 3625 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) return FALSE; 3626 3627 /* cleanup */ 3628 CryptReleaseContext(signer.hCryptProv, 0); 3629 pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL, 3630 CRYPT_DELETEKEYSET); 3631 3632 return TRUE; 3633 } 3634 3635 static void test_msg_get_and_verify_signer(void) 3636 { 3637 BOOL ret; 3638 HCRYPTMSG msg; 3639 PCCERT_CONTEXT signer; 3640 DWORD signerIndex; 3641 HCERTSTORE store; 3642 3643 /* Crash */ 3644 if (0) 3645 { 3646 CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, NULL); 3647 CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, &signerIndex); 3648 } 3649 3650 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 3651 /* An empty message has no signer */ 3652 SetLastError(0xdeadbeef); 3653 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL); 3654 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER, 3655 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError()); 3656 /* The signer is cleared on error */ 3657 signer = (PCCERT_CONTEXT)0xdeadbeef; 3658 SetLastError(0xdeadbeef); 3659 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL); 3660 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER, 3661 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError()); 3662 ok(!signer, "expected signer to be NULL\n"); 3663 /* The signer index is also cleared on error */ 3664 signerIndex = 0xdeadbeef; 3665 SetLastError(0xdeadbeef); 3666 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex); 3667 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER, 3668 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError()); 3669 ok(!signerIndex, "expected 0, got %d\n", signerIndex); 3670 /* An unsigned message (msgData isn't a signed message at all) 3671 * likewise has no signer. 3672 */ 3673 CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); 3674 SetLastError(0xdeadbeef); 3675 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL); 3676 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER, 3677 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError()); 3678 CryptMsgClose(msg); 3679 3680 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 3681 /* A "signed" message created with no signer cert likewise has no signer */ 3682 ret = CryptMsgUpdate(msg, signedEmptyContent, sizeof(signedEmptyContent), TRUE); 3683 if (ret) 3684 { 3685 /* Crashes on most Win9x */ 3686 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL); 3687 ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER, 3688 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError()); 3689 } 3690 CryptMsgClose(msg); 3691 3692 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); 3693 /* A signed message succeeds, .. */ 3694 CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent, 3695 sizeof(signedWithCertWithValidPubKeyContent), TRUE); 3696 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL); 3697 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */), 3698 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError()); 3699 /* the signer index can be retrieved, .. */ 3700 signerIndex = 0xdeadbeef; 3701 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex); 3702 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */), 3703 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError()); 3704 if (ret) 3705 ok(signerIndex == 0, "expected 0, got %d\n", signerIndex); 3706 /* as can the signer cert. */ 3707 signer = (PCCERT_CONTEXT)0xdeadbeef; 3708 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL); 3709 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */), 3710 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError()); 3711 if (ret) 3712 ok(signer != NULL && signer != (PCCERT_CONTEXT)0xdeadbeef, 3713 "expected a valid signer\n"); 3714 if (signer && signer != (PCCERT_CONTEXT)0xdeadbeef) 3715 CertFreeCertificateContext(signer); 3716 /* Specifying CMSG_USE_SIGNER_INDEX_FLAG and an invalid signer index fails 3717 */ 3718 signerIndex = 0xdeadbeef; 3719 SetLastError(0xdeadbeef); 3720 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_USE_SIGNER_INDEX_FLAG, 3721 NULL, &signerIndex); 3722 ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX, 3723 "expected CRYPT_E_INVALID_INDEX, got 0x%08x\n", GetLastError()); 3724 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and no cert stores causes the 3725 * message signer not to be found. 3726 */ 3727 SetLastError(0xdeadbeef); 3728 ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_TRUSTED_SIGNER_FLAG, 3729 NULL, NULL); 3730 ok(!ret && (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER || 3731 broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)), 3732 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError()); 3733 /* Specifying CMSG_TRUSTED_SIGNER_FLAG and an empty cert store also causes 3734 * the message signer not to be found. 3735 */ 3736 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 3737 CERT_STORE_CREATE_NEW_FLAG, NULL); 3738 SetLastError(0xdeadbeef); 3739 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG, 3740 NULL, NULL); 3741 ok(!ret && (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER || 3742 broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)), 3743 "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError()); 3744 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, 3745 v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey), 3746 CERT_STORE_ADD_ALWAYS, NULL); 3747 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win98 */), 3748 "CertAddEncodedCertificateToStore failed: 0x%08x\n", GetLastError()); 3749 /* Specifying CMSG_TRUSTED_SIGNER_FLAG with a cert store that contains 3750 * the signer succeeds. 3751 */ 3752 SetLastError(0xdeadbeef); 3753 ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG, 3754 NULL, NULL); 3755 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */), 3756 "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError()); 3757 CertCloseStore(store, 0); 3758 CryptMsgClose(msg); 3759 } 3760 3761 START_TEST(msg) 3762 { 3763 init_function_pointers(); 3764 have_nt = detect_nt(); 3765 if (!have_nt) 3766 win_skip("Win9x crashes on some parameter checks\n"); 3767 3768 /* I_CertUpdateStore can be used for verification if crypt32 is new enough */ 3769 if (!GetProcAddress(GetModuleHandleA("crypt32.dll"), "I_CertUpdateStore")) 3770 { 3771 win_skip("Some tests will crash on older crypt32 implementations\n"); 3772 old_crypt32 = TRUE; 3773 } 3774 3775 /* Basic parameter checking tests */ 3776 test_msg_open_to_encode(); 3777 test_msg_open_to_decode(); 3778 test_msg_get_param(); 3779 test_msg_close(); 3780 test_msg_control(); 3781 3782 /* Message-type specific tests */ 3783 test_data_msg(); 3784 test_hash_msg(); 3785 test_signed_msg(); 3786 test_enveloped_msg(); 3787 test_decode_msg(); 3788 3789 test_msg_get_and_verify_signer(); 3790 } 3791