1 /* 2 * Unit test suite for crypt32.dll's Crypt*Message functions 3 * 4 * Copyright 2007-2008 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 #include <wincrypt.h> 27 28 #include "wine/test.h" 29 30 static BOOL (WINAPI * pCryptAcquireContextA) 31 (HCRYPTPROV *, LPCSTR, LPCSTR, DWORD, DWORD); 32 33 static void init_function_pointers(void) 34 { 35 HMODULE hAdvapi32 = GetModuleHandleA("advapi32.dll"); 36 37 #define GET_PROC(dll, func) \ 38 p ## func = (void *)GetProcAddress(dll, #func); \ 39 if(!p ## func) \ 40 trace("GetProcAddress(%s) failed\n", #func); 41 42 GET_PROC(hAdvapi32, CryptAcquireContextA) 43 44 #undef GET_PROC 45 } 46 47 static const BYTE dataEmptyBareContent[] = { 0x04,0x00 }; 48 static const BYTE dataEmptyContent[] = { 49 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02, 50 0x04,0x00 }; 51 static const BYTE signedEmptyBareContent[] = { 52 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86, 53 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02, 54 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03, 55 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01, 56 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30, 57 0x04,0x06,0x00,0x05,0x00,0x04,0x00 }; 58 static const BYTE signedEmptyContent[] = { 59 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52, 60 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86, 61 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02, 62 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03, 63 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01, 64 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30, 65 0x04,0x06,0x00,0x05,0x00,0x04,0x00 }; 66 67 static void test_msg_get_signer_count(void) 68 { 69 LONG count; 70 71 SetLastError(0xdeadbeef); 72 count = CryptGetMessageSignerCount(0, NULL, 0); 73 ok(count == -1, "Expected -1, got %d\n", count); 74 ok(GetLastError() == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", 75 GetLastError()); 76 SetLastError(0xdeadbeef); 77 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING, NULL, 0); 78 ok(count == -1, "Expected -1, got %d\n", count); 79 ok(GetLastError() == CRYPT_E_ASN1_EOD || 80 GetLastError() == OSS_BAD_ARG, /* win9x */ 81 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError()); 82 SetLastError(0xdeadbeef); 83 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING, 84 dataEmptyBareContent, sizeof(dataEmptyBareContent)); 85 ok(count == -1, "Expected -1, got %d\n", count); 86 ok(GetLastError() == CRYPT_E_ASN1_BADTAG || 87 GetLastError() == OSS_PDU_MISMATCH, /* win9x */ 88 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError()); 89 SetLastError(0xdeadbeef); 90 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING, 91 dataEmptyContent, sizeof(dataEmptyContent)); 92 ok(count == -1, "Expected -1, got %d\n", count); 93 ok(GetLastError() == CRYPT_E_INVALID_MSG_TYPE, 94 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError()); 95 SetLastError(0xdeadbeef); 96 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING, 97 signedEmptyBareContent, sizeof(signedEmptyBareContent)); 98 ok(count == -1, "Expected -1, got %d\n", count); 99 ok(GetLastError() == CRYPT_E_ASN1_BADTAG || 100 GetLastError() == OSS_DATA_ERROR, /* win9x */ 101 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError()); 102 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING, 103 signedEmptyContent, sizeof(signedEmptyContent)); 104 ok(count == 1 || 105 broken(count == -1), /* win9x */ 106 "Expected 1, got %d\n", count); 107 } 108 109 static BYTE detachedHashContent[] = { 110 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32, 111 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, 112 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 113 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb, 114 0x9d,0x2a,0x8f,0x26,0x2f }; 115 static const BYTE msgData[] = { 1, 2, 3, 4 }; 116 117 static void test_verify_detached_message_hash(void) 118 { 119 BOOL ret; 120 CRYPT_HASH_MESSAGE_PARA para; 121 DWORD size, hashSize; 122 const BYTE *pMsgData = msgData; 123 BYTE hash[16]; 124 125 if (0) 126 { 127 CryptVerifyDetachedMessageHash(NULL, NULL, 0, 0, NULL, NULL, NULL, 128 NULL); 129 } 130 memset(¶, 0, sizeof(para)); 131 SetLastError(0xdeadbeef); 132 ret = CryptVerifyDetachedMessageHash(¶, NULL, 0, 0, NULL, NULL, NULL, 133 NULL); 134 ok(!ret && GetLastError() == E_INVALIDARG, 135 "expected E_INVALIDARG, got %08x\n", GetLastError()); 136 para.cbSize = sizeof(para); 137 SetLastError(0xdeadbeef); 138 ret = CryptVerifyDetachedMessageHash(¶, NULL, 0, 0, NULL, NULL, NULL, 139 NULL); 140 ok(!ret && GetLastError() == E_INVALIDARG, 141 "expected E_INVALIDARG, got %08x\n", GetLastError()); 142 para.dwMsgEncodingType = PKCS_7_ASN_ENCODING; 143 SetLastError(0xdeadbeef); 144 ret = CryptVerifyDetachedMessageHash(¶, NULL, 0, 0, NULL, NULL, NULL, 145 NULL); 146 ok(!ret && 147 (GetLastError() == CRYPT_E_ASN1_EOD || 148 GetLastError() == OSS_BAD_ARG), /* win9x */ 149 "expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError()); 150 para.dwMsgEncodingType = X509_ASN_ENCODING; 151 SetLastError(0xdeadbeef); 152 ret = CryptVerifyDetachedMessageHash(¶, NULL, 0, 0, NULL, NULL, NULL, 153 NULL); 154 ok(!ret && GetLastError() == E_INVALIDARG, 155 "expected E_INVALIDARG, got %08x\n", GetLastError()); 156 para.dwMsgEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING; 157 SetLastError(0xdeadbeef); 158 ret = CryptVerifyDetachedMessageHash(¶, NULL, 0, 0, NULL, NULL, NULL, 159 NULL); 160 ok(!ret && 161 (GetLastError() == CRYPT_E_ASN1_EOD || 162 GetLastError() == OSS_BAD_ARG), /* win9x */ 163 "expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError()); 164 /* Curiously, passing no data to hash succeeds.. */ 165 ret = CryptVerifyDetachedMessageHash(¶, detachedHashContent, 166 sizeof(detachedHashContent), 0, NULL, NULL, NULL, NULL); 167 todo_wine 168 ok(ret, "CryptVerifyDetachedMessageHash failed: %08x\n", GetLastError()); 169 /* as does passing the actual content of the message to hash.. */ 170 size = sizeof(msgData); 171 pMsgData = msgData; 172 ret = CryptVerifyDetachedMessageHash(¶, detachedHashContent, 173 sizeof(detachedHashContent), 1, &pMsgData, &size, NULL, NULL); 174 ok(ret, "CryptVerifyDetachedMessageHash failed: %08x\n", GetLastError()); 175 /* while passing data to hash that isn't the content of the message fails. 176 */ 177 size = sizeof(detachedHashContent); 178 pMsgData = detachedHashContent; 179 SetLastError(0xdeadbeef); 180 ret = CryptVerifyDetachedMessageHash(¶, detachedHashContent, 181 sizeof(detachedHashContent), 1, &pMsgData, &size, NULL, NULL); 182 ok(!ret && GetLastError() == CRYPT_E_HASH_VALUE, 183 "expected CRYPT_E_HASH_VALUE, got %08x\n", GetLastError()); 184 /* Getting the size of the hash while passing no hash data causes the 185 * hash to be checked (and fail.) 186 */ 187 SetLastError(0xdeadbeef); 188 ret = CryptVerifyDetachedMessageHash(¶, detachedHashContent, 189 sizeof(detachedHashContent), 0, NULL, NULL, NULL, &hashSize); 190 ok(!ret && GetLastError() == CRYPT_E_HASH_VALUE, 191 "expected CRYPT_E_HASH_VALUE, got %08x\n", GetLastError()); 192 size = sizeof(msgData); 193 pMsgData = msgData; 194 ret = CryptVerifyDetachedMessageHash(¶, detachedHashContent, 195 sizeof(detachedHashContent), 1, &pMsgData, &size, NULL, &hashSize); 196 ok(ret, "CryptVerifyDetachedMessageHash failed: %08x\n", GetLastError()); 197 ok(hashSize == sizeof(hash), "unexpected size %d\n", hashSize); 198 hashSize = 1; 199 SetLastError(0xdeadbeef); 200 ret = CryptVerifyDetachedMessageHash(¶, detachedHashContent, 201 sizeof(detachedHashContent), 1, &pMsgData, &size, hash, &hashSize); 202 ok(!ret && GetLastError() == ERROR_MORE_DATA, 203 "expected ERROR_MORE_DATA, got %08x\n", GetLastError()); 204 hashSize = sizeof(hash); 205 ret = CryptVerifyDetachedMessageHash(¶, detachedHashContent, 206 sizeof(detachedHashContent), 1, &pMsgData, &size, hash, &hashSize); 207 ok(ret, "CryptVerifyDetachedMessageHash failed: %08x\n", GetLastError()); 208 } 209 210 static BYTE hashContent[] = { 211 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a, 212 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, 213 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 214 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0, 215 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f }; 216 217 static void test_verify_message_hash(void) 218 { 219 BOOL ret; 220 CRYPT_HASH_MESSAGE_PARA para; 221 DWORD size; 222 BYTE *buf = NULL; 223 224 memset(¶, 0, sizeof(para)); 225 /* Crash */ 226 if (0) 227 ret = CryptVerifyMessageHash(NULL, NULL, 0, NULL, NULL, NULL, NULL); 228 SetLastError(0xdeadbeef); 229 ret = CryptVerifyMessageHash(¶, NULL, 0, NULL, NULL, NULL, NULL); 230 ok(!ret && GetLastError() == E_INVALIDARG, 231 "expected E_INVALIDARG, got %08x\n", GetLastError()); 232 para.cbSize = sizeof(para); 233 SetLastError(0xdeadbeef); 234 ret = CryptVerifyMessageHash(¶, NULL, 0, NULL, NULL, NULL, NULL); 235 ok(!ret && GetLastError() == E_INVALIDARG, 236 "expected E_INVALIDARG, got %08x\n", GetLastError()); 237 para.dwMsgEncodingType = PKCS_7_ASN_ENCODING; 238 SetLastError(0xdeadbeef); 239 ret = CryptVerifyMessageHash(¶, NULL, 0, NULL, NULL, NULL, NULL); 240 ok(!ret, "Expected 0, got %d\n", ret); 241 ok(GetLastError() == CRYPT_E_ASN1_EOD || 242 GetLastError() == OSS_BAD_ARG, /* win98 */ 243 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError()); 244 /* Verifying the hash of a detached message succeeds? */ 245 ret = CryptVerifyMessageHash(¶, detachedHashContent, 246 sizeof(detachedHashContent), NULL, NULL, NULL, NULL); 247 todo_wine 248 ok(ret, "CryptVerifyMessageHash failed: %08x\n", GetLastError()); 249 /* As does verifying the hash of a regular message. */ 250 ret = CryptVerifyMessageHash(¶, hashContent, sizeof(hashContent), 251 NULL, NULL, NULL, NULL); 252 ok(ret, "CryptVerifyMessageHash failed: %08x\n", GetLastError()); 253 ret = CryptVerifyMessageHash(¶, hashContent, sizeof(hashContent), 254 NULL, &size, NULL, NULL); 255 ok(ret, "CryptVerifyMessageHash failed: %08x\n", GetLastError()); 256 if (ret) 257 buf = CryptMemAlloc(size); 258 if (buf) 259 { 260 size = 1; 261 ret = CryptVerifyMessageHash(¶, hashContent, sizeof(hashContent), 262 buf, &size, NULL, NULL); 263 ok(!ret && GetLastError() == ERROR_MORE_DATA, 264 "expected ERROR_MORE_DATA, got %08x\n", GetLastError()); 265 ret = CryptVerifyMessageHash(¶, hashContent, sizeof(hashContent), 266 buf, &size, NULL, NULL); 267 ok(ret, "CryptVerifyMessageHash failed: %08x\n", GetLastError()); 268 ok(size == sizeof(msgData), "unexpected size %d\n", size); 269 ok(!memcmp(buf, msgData, size), "unexpected value\n"); 270 CryptMemFree(buf); 271 } 272 } 273 274 static const BYTE signedWithCertContent[] = { 275 0x30,0x82,0x01,0x32,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02, 276 0xa0,0x82,0x01,0x23,0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c, 277 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06, 278 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01, 279 0x02,0x03,0x04,0xa0,0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30, 280 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61, 281 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31, 282 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36, 283 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15, 284 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e, 285 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00, 286 0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04, 287 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01, 288 0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13, 289 0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30, 290 0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04, 291 0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1, 292 0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9, 293 0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11, 294 0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19, 295 0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d }; 296 static const BYTE signedContent[] = { 297 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0, 298 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a, 299 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86, 300 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04, 301 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11, 302 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 303 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, 304 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70, 305 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d, 306 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe, 307 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29, 308 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8, 309 0x0d }; 310 static const BYTE detachedSignedContent[] = { 311 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0, 312 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a, 313 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86, 314 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30, 315 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a, 316 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06, 317 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00, 318 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0, 319 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0, 320 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23, 321 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51, 322 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d }; 323 static const BYTE v1CertWithValidPubKey[] = { 324 0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30, 325 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61, 326 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31, 327 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, 328 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11, 329 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 330 0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 331 0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a, 332 0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1, 333 0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde, 334 0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f, 335 0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10, 336 0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55, 337 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 }; 338 339 static PCCERT_CONTEXT WINAPI msg_get_signer_callback(void *pvArg, 340 DWORD certEncodingType, PCERT_INFO signerId, HCERTSTORE store) 341 { 342 return CertCreateCertificateContext(X509_ASN_ENCODING, 343 v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey)); 344 } 345 346 static void test_verify_detached_message_signature(void) 347 { 348 CRYPT_VERIFY_MESSAGE_PARA para; 349 BOOL ret; 350 const BYTE *pContent; 351 DWORD cbContent; 352 353 memset(¶, 0, sizeof(para)); 354 SetLastError(0xdeadbeef); 355 ret = CryptVerifyDetachedMessageSignature(NULL, 0, NULL, 0, 0, NULL, 356 NULL, NULL); 357 ok(!ret && GetLastError() == E_INVALIDARG, 358 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 359 SetLastError(0xdeadbeef); 360 ret = CryptVerifyDetachedMessageSignature(¶, 0, NULL, 0, 0, NULL, 361 NULL, NULL); 362 ok(!ret && GetLastError() == E_INVALIDARG, 363 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 364 para.cbSize = sizeof(para); 365 SetLastError(0xdeadbeef); 366 ret = CryptVerifyDetachedMessageSignature(¶, 0, NULL, 0, 0, NULL, 367 NULL, NULL); 368 ok(!ret && GetLastError() == E_INVALIDARG, 369 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 370 para.dwMsgAndCertEncodingType = X509_ASN_ENCODING; 371 SetLastError(0xdeadbeef); 372 ret = CryptVerifyDetachedMessageSignature(¶, 0, NULL, 0, 0, NULL, 373 NULL, NULL); 374 ok(!ret && GetLastError() == E_INVALIDARG, 375 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 376 para.dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING; 377 SetLastError(0xdeadbeef); 378 ret = CryptVerifyDetachedMessageSignature(¶, 0, NULL, 0, 0, NULL, 379 NULL, NULL); 380 ok(!ret, "Expected 0, got %d\n", ret); 381 ok(GetLastError() == CRYPT_E_ASN1_EOD || 382 GetLastError() == OSS_BAD_ARG, /* win98 */ 383 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError()); 384 /* None of these messages contains a cert in the message itself, so the 385 * default callback isn't able to verify their signature. 386 */ 387 SetLastError(0xdeadbeef); 388 ret = CryptVerifyDetachedMessageSignature(¶, 0, signedWithCertContent, 389 sizeof(signedWithCertContent), 0, NULL, NULL, NULL); 390 ok(!ret, "Expected 0, got %d\n", ret); 391 todo_wine 392 ok(GetLastError() == CRYPT_E_NOT_FOUND || 393 GetLastError() == OSS_DATA_ERROR, /* win98 */ 394 "Expected CRYPT_E_NOT_FOUND or OSS_DATA_ERROR, got %08x\n", GetLastError()); 395 SetLastError(0xdeadbeef); 396 ret = CryptVerifyDetachedMessageSignature(¶, 0, signedContent, 397 sizeof(signedContent), 0, NULL, NULL, NULL); 398 ok(!ret, "Expected 0, got %d\n", ret); 399 ok(GetLastError() == CRYPT_E_NOT_FOUND || 400 GetLastError() == OSS_DATA_ERROR, /* win98 */ 401 "Expected CRYPT_E_NOT_FOUND or OSS_DATA_ERROR, got %08x\n", GetLastError()); 402 SetLastError(0xdeadbeef); 403 ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent, 404 sizeof(detachedSignedContent), 0, NULL, NULL, NULL); 405 ok(!ret, "Expected 0, got %d\n", ret); 406 ok(GetLastError() == CRYPT_E_NOT_FOUND || 407 GetLastError() == OSS_DATA_ERROR, /* win98 */ 408 "Expected CRYPT_E_NOT_FOUND or OSS_DATA_ERROR, got %08x\n", GetLastError()); 409 SetLastError(0xdeadbeef); 410 pContent = msgData; 411 cbContent = sizeof(msgData); 412 ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent, 413 sizeof(detachedSignedContent), 1, &pContent, &cbContent, NULL); 414 ok(!ret, "Expected 0, got %d\n", ret); 415 ok(GetLastError() == CRYPT_E_NOT_FOUND || 416 GetLastError() == OSS_DATA_ERROR, /* win98 */ 417 "Expected CRYPT_E_NOT_FOUND or OSS_DATA_ERROR, got %08x\n", GetLastError()); 418 /* Passing the correct callback results in success */ 419 para.pfnGetSignerCertificate = msg_get_signer_callback; 420 ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent, 421 sizeof(detachedSignedContent), 1, &pContent, &cbContent, NULL); 422 ok(ret || 423 broken(!ret), /* win98 */ 424 "CryptVerifyDetachedMessageSignature failed: %08x\n", 425 GetLastError()); 426 /* Not passing the correct data to be signed results in the signature not 427 * matching. 428 */ 429 SetLastError(0xdeadbeef); 430 ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent, 431 sizeof(detachedSignedContent), 0, NULL, NULL, NULL); 432 ok(!ret, "Expected 0, got %d\n", ret); 433 ok(GetLastError() == NTE_BAD_SIGNATURE || 434 GetLastError() == OSS_DATA_ERROR, /* win98 */ 435 "Expected NTE_BAD_SIGNATURE or OSS_DATA_ERROR, got %08x\n", GetLastError()); 436 } 437 438 static const BYTE signedWithCertEmptyContent[] = { 439 0x30,0x81,0xdf,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0, 440 0x81,0xd1,0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a, 441 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c, 442 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11, 443 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, 444 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30, 445 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30, 446 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06, 447 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67, 448 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30, 449 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01, 450 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15, 451 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e, 452 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86, 453 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04, 454 0x00 }; 455 static const BYTE signedWithCertWithPubKeyContent[] = { 456 0x30,0x81,0xfc,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0, 457 0x81,0xee,0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a, 458 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81, 459 0x98,0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13, 460 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c, 461 0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30, 462 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30, 463 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30, 464 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61, 465 0x6e,0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d, 466 0x01,0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06, 467 0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12, 468 0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff, 469 0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31, 470 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20, 471 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48, 472 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 }; 473 static const BYTE signedWithCertWithValidPubKeyContent[] = { 474 0x30,0x82,0x01,0x89,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02, 475 0xa0,0x82,0x01,0x7a,0x30,0x82,0x01,0x76,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c, 476 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06, 477 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01, 478 0x02,0x03,0x04,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06, 479 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a, 480 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36, 481 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f, 482 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a, 483 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75, 484 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a, 485 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48, 486 0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4, 487 0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb, 488 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc, 489 0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30, 490 0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30, 491 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06, 492 0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a, 493 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75, 494 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08, 495 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05, 496 0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a, 497 0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e, 498 0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64, 499 0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4, 500 0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d }; 501 502 static void test_verify_message_signature(void) 503 { 504 BOOL ret; 505 CRYPT_VERIFY_MESSAGE_PARA para = { 0 }; 506 PCCERT_CONTEXT cert; 507 DWORD cbDecoded; 508 BYTE decoded[sizeof(msgData)]; 509 510 SetLastError(0xdeadbeef); 511 ret = CryptVerifyMessageSignature(NULL, 0, NULL, 0, NULL, 0, NULL); 512 ok(!ret && GetLastError() == E_INVALIDARG, 513 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 514 /* Is cbDecoded set when invalid parameters are passed? */ 515 cbDecoded = 0xdeadbeef; 516 ret = CryptVerifyMessageSignature(NULL, 0, NULL, 0, NULL, &cbDecoded, 517 NULL); 518 ok(!ret && GetLastError() == E_INVALIDARG, 519 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 520 ok(cbDecoded == 0, "expected 0, got %08x\n", cbDecoded); 521 SetLastError(0xdeadbeef); 522 ret = CryptVerifyMessageSignature(¶, 0, NULL, 0, NULL, 0, NULL); 523 ok(!ret && GetLastError() == E_INVALIDARG, 524 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 525 para.cbSize = sizeof(para); 526 SetLastError(0xdeadbeef); 527 ret = CryptVerifyMessageSignature(¶, 0, NULL, 0, NULL, 0, NULL); 528 ok(!ret && GetLastError() == E_INVALIDARG, 529 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 530 para.cbSize = 0; 531 para.dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING; 532 SetLastError(0xdeadbeef); 533 ret = CryptVerifyMessageSignature(¶, 0, NULL, 0, NULL, 0, NULL); 534 ok(!ret && GetLastError() == E_INVALIDARG, 535 "Expected E_INVALIDARG, got %08x\n", GetLastError()); 536 para.cbSize = sizeof(para); 537 SetLastError(0xdeadbeef); 538 ret = CryptVerifyMessageSignature(¶, 0, NULL, 0, NULL, 0, NULL); 539 ok(!ret && 540 (GetLastError() == CRYPT_E_ASN1_EOD || 541 GetLastError() == OSS_BAD_ARG), /* win9x */ 542 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError()); 543 /* Check whether cert is set on error */ 544 cert = (PCCERT_CONTEXT)0xdeadbeef; 545 ret = CryptVerifyMessageSignature(¶, 0, NULL, 0, NULL, 0, &cert); 546 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD || 547 GetLastError() == OSS_BAD_ARG /* NT40 */), 548 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError()); 549 ok(cert == NULL, "Expected NULL cert\n"); 550 /* Check whether cbDecoded is set on error */ 551 cbDecoded = 0xdeadbeef; 552 ret = CryptVerifyMessageSignature(¶, 0, NULL, 0, NULL, &cbDecoded, 553 NULL); 554 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD || 555 GetLastError() == OSS_BAD_ARG /* NT40 */), 556 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError()); 557 ok(!cbDecoded, "Expected 0\n"); 558 SetLastError(0xdeadbeef); 559 ret = CryptVerifyMessageSignature(¶, 0, dataEmptyBareContent, 560 sizeof(dataEmptyBareContent), NULL, 0, NULL); 561 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || 562 GetLastError() == OSS_PDU_MISMATCH /* NT40 */), 563 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError()); 564 ok(GetLastError() == CRYPT_E_ASN1_BADTAG || 565 GetLastError() == OSS_PDU_MISMATCH, /* win9x */ 566 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError()); 567 SetLastError(0xdeadbeef); 568 ret = CryptVerifyMessageSignature(¶, 0, dataEmptyContent, 569 sizeof(dataEmptyContent), NULL, 0, NULL); 570 ok(!ret && GetLastError() == CRYPT_E_UNEXPECTED_MSG_TYPE, 571 "Expected CRYPT_E_UNEXPECTED_MSG_TYPE, got %08x\n", GetLastError()); 572 SetLastError(0xdeadbeef); 573 ret = CryptVerifyMessageSignature(¶, 0, signedEmptyBareContent, 574 sizeof(signedEmptyBareContent), NULL, 0, NULL); 575 ok(!ret && 576 (GetLastError() == CRYPT_E_ASN1_BADTAG || 577 GetLastError() == OSS_DATA_ERROR), /* win9x */ 578 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError()); 579 SetLastError(0xdeadbeef); 580 ret = CryptVerifyMessageSignature(¶, 0, signedEmptyContent, 581 sizeof(signedEmptyContent), NULL, 0, NULL); 582 ok(!ret && 583 (GetLastError() == CRYPT_E_NOT_FOUND || 584 GetLastError() == OSS_DATA_ERROR), /* win9x */ 585 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); 586 SetLastError(0xdeadbeef); 587 ret = CryptVerifyMessageSignature(¶, 0, signedContent, 588 sizeof(signedContent), NULL, 0, NULL); 589 ok(!ret && 590 (GetLastError() == CRYPT_E_NOT_FOUND || 591 GetLastError() == OSS_DATA_ERROR), /* win9x */ 592 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); 593 /* FIXME: Windows fails with CRYPT_E_NOT_FOUND for these messages, but 594 * their signer certs have invalid public keys that fail to decode. In 595 * Wine therefore the failure is an ASN error. Need some messages with 596 * valid public keys and invalid signatures to check against. 597 */ 598 ret = CryptVerifyMessageSignature(¶, 0, signedWithCertEmptyContent, 599 sizeof(signedWithCertEmptyContent), NULL, 0, NULL); 600 ok(!ret, "Expected failure\n"); 601 ret = CryptVerifyMessageSignature(¶, 0, signedWithCertContent, 602 sizeof(signedWithCertContent), NULL, 0, NULL); 603 ok(!ret, "Expected failure\n"); 604 ret = CryptVerifyMessageSignature(¶, 0, signedWithCertWithPubKeyContent, 605 sizeof(signedWithCertWithPubKeyContent), NULL, 0, NULL); 606 ok(!ret, "Expected failure\n"); 607 /* Apparently, an output pcbDecoded parameter is expected. */ 608 ret = CryptVerifyMessageSignature(¶, 0, 609 signedWithCertWithValidPubKeyContent, 610 sizeof(signedWithCertWithValidPubKeyContent), NULL, 0, NULL); 611 todo_wine 612 ok(!ret, "Expected failure\n"); 613 /* Finally, a message signed with a valid public key verifies successfully 614 */ 615 cbDecoded = 0xdeadbeef; 616 ret = CryptVerifyMessageSignature(¶, 0, 617 signedWithCertWithValidPubKeyContent, 618 sizeof(signedWithCertWithValidPubKeyContent), NULL, &cbDecoded, NULL); 619 ok(ret, "CryptVerifyMessageSignature failed: %08x\n", GetLastError()); 620 ok(cbDecoded == sizeof(msgData), "expected 4, got %d\n", cbDecoded); 621 cbDecoded = 0; 622 ret = CryptVerifyMessageSignature(¶, 0, 623 signedWithCertWithValidPubKeyContent, 624 sizeof(signedWithCertWithValidPubKeyContent), NULL, &cbDecoded, NULL); 625 /* Setting cbDecoded to 0 succeeds when a NULL buffer is provided */ 626 ok(ret, "CryptVerifyMessageSignature failed: %08x\n", GetLastError()); 627 ok(cbDecoded == sizeof(msgData), "expected 4, got %d\n", cbDecoded); 628 cbDecoded = 0; 629 ret = CryptVerifyMessageSignature(¶, 0, 630 signedWithCertWithValidPubKeyContent, 631 sizeof(signedWithCertWithValidPubKeyContent), decoded, &cbDecoded, NULL); 632 /* When a non-NULL buffer is provided, cbDecoded must not be too small */ 633 ok(!ret && GetLastError() == ERROR_MORE_DATA, 634 "expected ERROR_MORE_DATA, got %d (%08x)\n", GetLastError(), 635 GetLastError()); 636 } 637 638 static const BYTE detachedHashBlob[] = { 639 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32, 640 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, 641 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 642 0x07,0x01,0x04,0x10,0x2d,0x1b,0xbc,0x1f,0xc7,0xab,0x36,0x8d,0xdb,0x95,0xe6, 643 0x24,0xb9,0x66,0x7c,0x21 }; 644 static const BYTE hashBlob[] = { 645 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a, 646 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, 647 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 648 0x07,0x01,0xa0,0x06,0x04,0x04,0xde,0xad,0xbe,0xef,0x04,0x10,0x2f,0x24,0x92, 649 0x30,0xa8,0xe7,0xc2,0xbf,0x60,0x05,0xcc,0xd2,0x67,0x92,0x59,0xec }; 650 static const BYTE hashVal[] = { 651 0x2d,0x1b,0xbc,0x1f,0xc7,0xab,0x36,0x8d,0xdb,0x95,0xe6,0x24,0xb9,0x66,0x7c, 652 0x21 }; 653 654 static void test_hash_message(void) 655 { 656 BOOL ret; 657 CRYPT_HASH_MESSAGE_PARA para; 658 static const BYTE blob1[] = { 0xde, 0xad, 0xbe, 0xef }; 659 static const BYTE blob2[] = { 0xba, 0xad, 0xf0, 0x0d }; 660 const BYTE *toHash[] = { blob1, blob2 }; 661 DWORD hashSize[] = { sizeof(blob1), sizeof(blob2) }; 662 DWORD hashedBlobSize, computedHashSize; 663 static char oid_rsa_md5[] = szOID_RSA_MD5; 664 LPBYTE hashedBlob, computedHash; 665 666 /* Crash 667 ret = CryptHashMessage(NULL, FALSE, 0, NULL, 0, NULL, NULL, NULL, NULL); 668 */ 669 memset(¶, 0, sizeof(para)); 670 SetLastError(0xdeadbeef); 671 ret = CryptHashMessage(¶, FALSE, 0, NULL, NULL, NULL, NULL, NULL, NULL); 672 ok(!ret && GetLastError() == E_INVALIDARG, 673 "expected E_INVALIDARG, got 0x%08x\n", GetLastError()); 674 para.cbSize = sizeof(para); 675 /* Not quite sure what "success" means in this case, but it does succeed */ 676 SetLastError(0xdeadbeef); 677 ret = CryptHashMessage(¶, FALSE, 0, NULL, NULL, NULL, NULL, NULL, NULL); 678 ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError()); 679 /* With a bogus encoding type it "succeeds" */ 680 para.dwMsgEncodingType = 0xdeadbeef; 681 SetLastError(0xdeadbeef); 682 ret = CryptHashMessage(¶, FALSE, 0, NULL, NULL, NULL, NULL, NULL, NULL); 683 ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError()); 684 /* According to MSDN, the third parameter (cToBeHashed) must be 1 if the 685 * second parameter (fDetached) is FALSE, but again it "succeeds." 686 */ 687 SetLastError(0xdeadbeef); 688 ret = CryptHashMessage(¶, FALSE, 2, NULL, NULL, NULL, NULL, NULL, NULL); 689 ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError()); 690 /* Even passing parameters to hash results in "success." */ 691 SetLastError(0xdeadbeef); 692 ret = CryptHashMessage(¶, FALSE, 2, toHash, hashSize, NULL, NULL, NULL, 693 NULL); 694 ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError()); 695 /* Try again with a valid encoding type */ 696 para.dwMsgEncodingType = PKCS_7_ASN_ENCODING; 697 SetLastError(0xdeadbeef); 698 ret = CryptHashMessage(¶, FALSE, 2, NULL, NULL, NULL, NULL, NULL, NULL); 699 ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError()); 700 /* And with valid data to hash */ 701 SetLastError(0xdeadbeef); 702 ret = CryptHashMessage(¶, FALSE, 2, toHash, hashSize, NULL, NULL, NULL, 703 NULL); 704 ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError()); 705 /* But requesting the size of the hashed blob and indicating there's data 706 * to hash results in a crash 707 */ 708 if (0) 709 { 710 CryptHashMessage(¶, FALSE, 2, NULL, NULL, NULL, 711 &hashedBlobSize, NULL, NULL); 712 } 713 /* Passing a valid pointer for the data to hash fails, as the hash 714 * algorithm is finally checked. 715 */ 716 SetLastError(0xdeadbeef); 717 ret = CryptHashMessage(¶, FALSE, 2, toHash, hashSize, NULL, 718 &hashedBlobSize, NULL, NULL); 719 ok(!ret && 720 (GetLastError() == CRYPT_E_UNKNOWN_ALGO || 721 GetLastError() == CRYPT_E_OID_FORMAT), /* Vista */ 722 "expected CRYPT_E_UNKNOWN_ALGO or CRYPT_E_OID_FORMAT, got 0x%08x (%d)\n", 723 GetLastError(), GetLastError()); 724 para.HashAlgorithm.pszObjId = oid_rsa_md5; 725 /* With a valid hash algorithm, this succeeds, even though fDetached is 726 * FALSE. 727 */ 728 SetLastError(0xdeadbeef); 729 ret = CryptHashMessage(¶, FALSE, 2, toHash, hashSize, NULL, 730 &hashedBlobSize, NULL, NULL); 731 todo_wine 732 ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError()); 733 if (ret) 734 { 735 /* Actually attempting to get the hashed data fails, perhaps because 736 * detached is FALSE. 737 */ 738 hashedBlob = HeapAlloc(GetProcessHeap(), 0, hashedBlobSize); 739 SetLastError(0xdeadbeef); 740 ret = CryptHashMessage(¶, FALSE, 2, toHash, hashSize, hashedBlob, 741 &hashedBlobSize, NULL, NULL); 742 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR, 743 "expected CRYPT_E_MSG_ERROR, got 0x%08x (%d)\n", GetLastError(), 744 GetLastError()); 745 HeapFree(GetProcessHeap(), 0, hashedBlob); 746 } 747 /* Repeating tests with fDetached = TRUE results in success */ 748 SetLastError(0xdeadbeef); 749 ret = CryptHashMessage(¶, TRUE, 2, toHash, hashSize, NULL, 750 &hashedBlobSize, NULL, NULL); 751 ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError()); 752 if (ret) 753 { 754 hashedBlob = HeapAlloc(GetProcessHeap(), 0, hashedBlobSize); 755 SetLastError(0xdeadbeef); 756 ret = CryptHashMessage(¶, TRUE, 2, toHash, hashSize, hashedBlob, 757 &hashedBlobSize, NULL, NULL); 758 ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError()); 759 ok(hashedBlobSize == sizeof(detachedHashBlob), 760 "unexpected size of detached blob %d\n", hashedBlobSize); 761 ok(!memcmp(hashedBlob, detachedHashBlob, hashedBlobSize), 762 "unexpected detached blob value\n"); 763 HeapFree(GetProcessHeap(), 0, hashedBlob); 764 } 765 /* Hashing a single item with fDetached = FALSE also succeeds */ 766 SetLastError(0xdeadbeef); 767 ret = CryptHashMessage(¶, FALSE, 1, toHash, hashSize, NULL, 768 &hashedBlobSize, NULL, NULL); 769 ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError()); 770 if (ret) 771 { 772 hashedBlob = HeapAlloc(GetProcessHeap(), 0, hashedBlobSize); 773 ret = CryptHashMessage(¶, FALSE, 1, toHash, hashSize, hashedBlob, 774 &hashedBlobSize, NULL, NULL); 775 ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError()); 776 ok(hashedBlobSize == sizeof(hashBlob), 777 "unexpected size of detached blob %d\n", hashedBlobSize); 778 ok(!memcmp(hashedBlob, hashBlob, hashedBlobSize), 779 "unexpected detached blob value\n"); 780 HeapFree(GetProcessHeap(), 0, hashedBlob); 781 } 782 /* Check the computed hash value too. You don't need to get the encoded 783 * blob to get it. 784 */ 785 computedHashSize = 0xdeadbeef; 786 ret = CryptHashMessage(¶, TRUE, 2, toHash, hashSize, NULL, 787 &hashedBlobSize, NULL, &computedHashSize); 788 ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError()); 789 ok(computedHashSize == 16, "expected hash size of 16, got %d\n", 790 computedHashSize); 791 if (ret) 792 { 793 computedHash = HeapAlloc(GetProcessHeap(), 0, computedHashSize); 794 SetLastError(0xdeadbeef); 795 ret = CryptHashMessage(¶, TRUE, 2, toHash, hashSize, NULL, 796 &hashedBlobSize, computedHash, &computedHashSize); 797 ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError()); 798 ok(computedHashSize == sizeof(hashVal), 799 "unexpected size of hash value %d\n", computedHashSize); 800 ok(!memcmp(computedHash, hashVal, computedHashSize), 801 "unexpected value\n"); 802 HeapFree(GetProcessHeap(), 0, computedHash); 803 } 804 } 805 806 static const BYTE publicPrivateKeyPair[] = { 807 0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00, 808 0x00,0x01,0x00,0x01,0x00,0x9b,0xd9,0x60,0xd9,0x5b,0x09,0x50,0x9e,0x09,0x94, 809 0x1e,0x6a,0x06,0x1d,0xdd,0x39,0xc5,0x96,0x17,0xe3,0xb9,0x0c,0x71,0x9c,0xf7, 810 0xc1,0x07,0x7b,0xd7,0x4a,0xaa,0x8a,0x3e,0xcd,0x78,0x3c,0x4c,0x95,0x98,0x28, 811 0x29,0x2d,0xe0,0xfc,0xe6,0x4f,0x95,0xca,0x87,0x92,0xdd,0xa3,0x8d,0xf0,0x39, 812 0xf3,0x1b,0x87,0x64,0x82,0x99,0xc0,0xa9,0xe8,0x87,0x86,0x2e,0x72,0x07,0x07, 813 0x8f,0x45,0x54,0x51,0x2f,0x51,0xd0,0x60,0x97,0x48,0x54,0x0e,0x78,0xb5,0x7e, 814 0x2b,0x9d,0xca,0x81,0xa8,0xa8,0x00,0x57,0x69,0xa6,0xf7,0x4d,0x45,0xe0,0xf7, 815 0xfa,0xd2,0xeb,0xaa,0xb8,0x06,0x34,0xce,0xf0,0x9d,0x2b,0x76,0x8a,0x4f,0x70, 816 0x51,0x90,0x33,0x72,0xcb,0x81,0x85,0x7e,0x35,0x2e,0xfb,0x81,0xf0,0xc7,0x85, 817 0xa5,0x75,0xf9,0x2d,0x00,0x71,0x66,0x36,0xfe,0x22,0xd6,0xc9,0x36,0x61,0x9b, 818 0x64,0x92,0xe8,0x25,0x38,0x35,0xeb,0x0c,0x84,0x83,0x76,0x42,0x90,0xf7,0x73, 819 0x91,0xdc,0x43,0x83,0x07,0x77,0xc9,0x1b,0x3f,0x74,0xc0,0xbe,0x18,0x97,0xd6, 820 0x86,0xe5,0xfa,0x28,0x7c,0xf7,0x8d,0x89,0xb1,0x93,0xac,0x48,0x3c,0xa1,0x02, 821 0xfa,0xc6,0x1c,0xa0,0xb5,0xe8,0x4f,0xd7,0xd1,0x33,0x63,0x8b,0x7e,0xf1,0x94, 822 0x56,0x07,0xbc,0x6e,0x0c,0xbd,0xa0,0x15,0xba,0x99,0x5d,0xb7,0x5e,0x09,0xf2, 823 0x1b,0x46,0x85,0x61,0x91,0x6a,0x78,0x31,0xb5,0xf0,0xba,0x20,0xf5,0x7a,0xb4, 824 0x8e,0xd3,0x50,0x87,0xf8,0xf3,0xe4,0xd9,0xab,0x6f,0x0e,0x59,0x42,0xac,0x7d, 825 0xb1,0x8c,0xea,0x33,0x54,0x08,0x38,0xc9,0xcd,0xac,0x10,0x19,0x4a,0xba,0x89, 826 0xdc,0xb6,0x73,0xef,0xec,0x56,0x93,0xd6,0xf2,0x4b,0xba,0x50,0x2d,0x8f,0x15, 827 0xed,0x8b,0xb5,0x67,0xc8,0xfc,0x51,0x5f }; 828 static const BYTE cert1[] = { 829 0x30,0x81,0xd0,0x30,0x81,0xbe,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,0x20,0x42, 830 0x68,0x69,0xe9,0xea,0x61,0x83,0x11,0xdf,0xc0,0x24,0x2f,0x3b,0xad,0x40,0x30, 831 0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x0c,0x31,0x0a,0x30, 832 0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x30,0x20,0x17,0x0d,0x31,0x30, 833 0x30,0x39,0x31,0x34,0x31,0x33,0x31,0x39,0x30,0x39,0x5a,0x18,0x0f,0x33,0x30, 834 0x31,0x30,0x30,0x39,0x31,0x34,0x31,0x33,0x31,0x39,0x30,0x39,0x5a,0x30,0x0c, 835 0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x30,0x5c,0x30, 836 0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03, 837 0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe8,0xa9,0xc0,0x99,0x82,0x64,0x87,0x1b, 838 0xf3,0x39,0xf0,0x8d,0xa3,0xdd,0x92,0x87,0xca,0x95,0x4f,0xe6,0xfc,0xe0,0x2d, 839 0x29,0x28,0x98,0x95,0x4c,0x3c,0x78,0xcd,0x3e,0x8a,0xaa,0x4a,0xd7,0x7b,0x07, 840 0xc1,0xf7,0x9c,0x71,0x0c,0xb9,0xe3,0x17,0x96,0xc5,0x39,0xdd,0x1d,0x06,0x6a, 841 0x1e,0x94,0x09,0x9e,0x50,0x09,0x5b,0xd9,0x60,0xd9,0x9b,0x02,0x03,0x01,0x00, 842 0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x02,0x00, 843 0xc1 }; 844 static const BYTE cert2[] = { 845 0x30,0x82,0x01,0x15,0x30,0x82,0x01,0x02,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, 846 0x1c,0xf2,0x1f,0xec,0x6b,0xdc,0x36,0xbf,0x4a,0xd7,0xe1,0x6c,0x84,0x85,0xcd, 847 0x2e,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x0c,0x31, 848 0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x58,0x30,0x20,0x17,0x0d, 849 0x31,0x30,0x30,0x37,0x31,0x32,0x31,0x31,0x33,0x37,0x35,0x36,0x5a,0x18,0x0f, 850 0x33,0x30,0x31,0x30,0x30,0x37,0x31,0x32,0x31,0x31,0x33,0x37,0x35,0x36,0x5a, 851 0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x58,0x30, 852 0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01, 853 0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xab,0xed, 854 0x6e,0xe0,0x00,0x3c,0xcf,0x2d,0x2b,0xda,0x05,0x88,0x6a,0x7e,0xed,0x60,0x30, 855 0x24,0xef,0x6c,0x6b,0xad,0x28,0x9b,0x14,0x90,0xf6,0xd0,0x96,0x79,0x6d,0xad, 856 0xac,0x46,0x14,0x7b,0x0e,0xfe,0xa9,0x8a,0x05,0x5a,0xc8,0x84,0x38,0x44,0xf9, 857 0xce,0xb2,0xe6,0xde,0x5b,0x80,0x0b,0x15,0xff,0x1b,0x60,0x3f,0xba,0xb2,0xfe, 858 0x6e,0xf5,0xdc,0x54,0x33,0xfc,0xfc,0x79,0x0a,0x10,0xa4,0x23,0x6d,0x67,0xeb, 859 0x16,0xb2,0x92,0xbf,0x63,0x42,0x17,0x0a,0xde,0xe6,0xab,0x8e,0xf7,0x8e,0x41, 860 0x8c,0x04,0xe8,0xe2,0x38,0x73,0xd3,0x82,0xd7,0xd1,0xee,0xd3,0xa6,0x54,0x8c, 861 0xcd,0x0b,0x93,0xda,0x63,0x55,0x0d,0x1f,0x68,0x5c,0x30,0xee,0xad,0x2d,0xd5, 862 0x40,0x56,0xe0,0xd8,0xc7,0xef,0x02,0x03,0x01,0x00,0x01,0x30,0x09,0x06,0x05, 863 0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x02,0x00,0x06 }; 864 static const BYTE crl[] = { 865 0x30,0x81,0xc2,0x30,0x7e,0x02,0x01,0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, 866 0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x30,0x3c,0x31,0x0b,0x30,0x09,0x06, 867 0x03,0x55,0x04,0x06,0x13,0x02,0x52,0x55,0x31,0x0c,0x30,0x0a,0x06,0x03,0x55, 868 0x04,0x08,0x13,0x03,0x53,0x50,0x62,0x31,0x0c,0x30,0x0a,0x06,0x03,0x55,0x04, 869 0x07,0x13,0x03,0x53,0x50,0x62,0x31,0x11,0x30,0x0f,0x06,0x03,0x55,0x04,0x0a, 870 0x13,0x08,0x45,0x74,0x65,0x72,0x73,0x6f,0x66,0x74,0x17,0x0d,0x31,0x30,0x30, 871 0x36,0x32,0x38,0x31,0x32,0x35,0x31,0x32,0x37,0x5a,0x17,0x0d,0x31,0x30,0x30, 872 0x37,0x32,0x38,0x31,0x32,0x35,0x31,0x32,0x37,0x5a,0xa0,0x0e,0x30,0x0c,0x30, 873 0x0a,0x06,0x03,0x55,0x1d,0x14,0x04,0x03,0x02,0x01,0x00,0x30,0x0d,0x06,0x09, 874 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x31,0x00,0x83, 875 0x35,0x9c,0xf5,0x35,0x5c,0xc1,0x20,0x81,0x80,0x5c,0x35,0x56,0xaf,0xb3,0x27, 876 0x15,0xc6,0xdd,0x24,0xe1,0xff,0xb9,0xf9,0x19,0x21,0xed,0x5e,0x1b,0xff,0x72, 877 0xc3,0x33,0xf6,0x9f,0xcb,0xde,0x84,0x0b,0x12,0x84,0xad,0x48,0x90,0x9d,0xdd, 878 0x89,0xbb }; 879 static const BYTE signedHashForEmptyMessage[] = { 880 0x30,0x81,0xbb,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0, 881 0x81,0xad,0x30,0x81,0xaa,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a, 882 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86, 883 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x81,0x87,0x30,0x81,0x84,0x02,0x01, 884 0x01,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13, 885 0x01,0x4e,0x02,0x10,0x20,0x42,0x68,0x69,0xe9,0xea,0x61,0x83,0x11,0xdf,0xc0, 886 0x24,0x2f,0x3b,0xad,0x40,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, 887 0x02,0x05,0x05,0x00,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 888 0x01,0x01,0x05,0x00,0x04,0x40,0xe1,0xee,0xca,0x98,0x16,0x23,0x5a,0x34,0xfd, 889 0x91,0x69,0x97,0x1e,0x16,0xe4,0x57,0x45,0xad,0xc9,0x5d,0x2e,0xda,0x92,0xbf, 890 0xee,0x2f,0xb1,0xaa,0x32,0xfa,0x07,0x4e,0x63,0xfd,0xe1,0x52,0x17,0xd0,0xa4, 891 0x49,0x30,0x54,0x4d,0x12,0xa0,0x6a,0x1c,0x64,0xea,0xc7,0x50,0x49,0xa5,0xca, 892 0xc3,0x71,0xa4,0xf7,0x8c,0x25,0xe4,0x1a,0xca,0x89 }; 893 static const BYTE signedEmptyMessage[] = { 894 0x30,0x81,0xbb,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0, 895 0x81,0xad,0x30,0x81,0xaa,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a, 896 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86, 897 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x81,0x87,0x30,0x81,0x84,0x02,0x01, 898 0x01,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13, 899 0x01,0x4e,0x02,0x10,0x20,0x42,0x68,0x69,0xe9,0xea,0x61,0x83,0x11,0xdf,0xc0, 900 0x24,0x2f,0x3b,0xad,0x40,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, 901 0x02,0x05,0x05,0x00,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 902 0x01,0x01,0x05,0x00,0x04,0x40,0xe1,0xee,0xca,0x98,0x16,0x23,0x5a,0x34,0xfd, 903 0x91,0x69,0x97,0x1e,0x16,0xe4,0x57,0x45,0xad,0xc9,0x5d,0x2e,0xda,0x92,0xbf, 904 0xee,0x2f,0xb1,0xaa,0x32,0xfa,0x07,0x4e,0x63,0xfd,0xe1,0x52,0x17,0xd0,0xa4, 905 0x49,0x30,0x54,0x4d,0x12,0xa0,0x6a,0x1c,0x64,0xea,0xc7,0x50,0x49,0xa5,0xca, 906 0xc3,0x71,0xa4,0xf7,0x8c,0x25,0xe4,0x1a,0xca,0x89 }; 907 static const BYTE signedHash[] = { 908 0x30,0x81,0xbb,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0, 909 0x81,0xad,0x30,0x81,0xaa,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a, 910 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86, 911 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x81,0x87,0x30,0x81,0x84,0x02,0x01, 912 0x01,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13, 913 0x01,0x4e,0x02,0x10,0x20,0x42,0x68,0x69,0xe9,0xea,0x61,0x83,0x11,0xdf,0xc0, 914 0x24,0x2f,0x3b,0xad,0x40,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, 915 0x02,0x05,0x05,0x00,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 916 0x01,0x01,0x05,0x00,0x04,0x40,0x1e,0x04,0xa4,0xe3,0x90,0x54,0xed,0xcb,0x94, 917 0xa2,0xbe,0x81,0x73,0x7e,0x05,0xf2,0x82,0xd3,0x3a,0x26,0x96,0x7a,0x53,0xcd, 918 0x05,0xc3,0x09,0x69,0x3d,0x12,0x6c,0xb1,0xb0,0xab,0x0e,0xa1,0xec,0x1b,0xa1, 919 0xff,0x01,0x9c,0x49,0x9f,0x4b,0x69,0x59,0x74,0x20,0x9f,0xb0,0x19,0x95,0xe7, 920 0xed,0x1e,0x84,0xeb,0xe2,0x53,0x2c,0xa6,0x43,0xdf }; 921 static const BYTE signedHashWithCert[] = { 922 0x30,0x82,0x01,0x93,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02, 923 0xa0,0x82,0x01,0x84,0x30,0x82,0x01,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c, 924 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06, 925 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x81,0xd3,0x30,0x81, 926 0xd0,0x30,0x81,0xbe,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,0x20,0x42,0x68,0x69, 927 0xe9,0xea,0x61,0x83,0x11,0xdf,0xc0,0x24,0x2f,0x3b,0xad,0x40,0x30,0x09,0x06, 928 0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06, 929 0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x30,0x20,0x17,0x0d,0x31,0x30,0x30,0x39, 930 0x31,0x34,0x31,0x33,0x31,0x39,0x30,0x39,0x5a,0x18,0x0f,0x33,0x30,0x31,0x30, 931 0x30,0x39,0x31,0x34,0x31,0x33,0x31,0x39,0x30,0x39,0x5a,0x30,0x0c,0x31,0x0a, 932 0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x30,0x5c,0x30,0x0d,0x06, 933 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00, 934 0x30,0x48,0x02,0x41,0x00,0xe8,0xa9,0xc0,0x99,0x82,0x64,0x87,0x1b,0xf3,0x39, 935 0xf0,0x8d,0xa3,0xdd,0x92,0x87,0xca,0x95,0x4f,0xe6,0xfc,0xe0,0x2d,0x29,0x28, 936 0x98,0x95,0x4c,0x3c,0x78,0xcd,0x3e,0x8a,0xaa,0x4a,0xd7,0x7b,0x07,0xc1,0xf7, 937 0x9c,0x71,0x0c,0xb9,0xe3,0x17,0x96,0xc5,0x39,0xdd,0x1d,0x06,0x6a,0x1e,0x94, 938 0x09,0x9e,0x50,0x09,0x5b,0xd9,0x60,0xd9,0x9b,0x02,0x03,0x01,0x00,0x01,0x30, 939 0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x02,0x00,0xc1,0x31, 940 0x81,0x87,0x30,0x81,0x84,0x02,0x01,0x01,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30, 941 0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,0x20,0x42,0x68,0x69, 942 0xe9,0xea,0x61,0x83,0x11,0xdf,0xc0,0x24,0x2f,0x3b,0xad,0x40,0x30,0x0c,0x06, 943 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0d,0x06,0x09, 944 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x40,0x1e,0x04, 945 0xa4,0xe3,0x90,0x54,0xed,0xcb,0x94,0xa2,0xbe,0x81,0x73,0x7e,0x05,0xf2,0x82, 946 0xd3,0x3a,0x26,0x96,0x7a,0x53,0xcd,0x05,0xc3,0x09,0x69,0x3d,0x12,0x6c,0xb1, 947 0xb0,0xab,0x0e,0xa1,0xec,0x1b,0xa1,0xff,0x01,0x9c,0x49,0x9f,0x4b,0x69,0x59, 948 0x74,0x20,0x9f,0xb0,0x19,0x95,0xe7,0xed,0x1e,0x84,0xeb,0xe2,0x53,0x2c,0xa6, 949 0x43,0xdf }; 950 static const BYTE signedHashWithCRL[] = { 951 0x30,0x82,0x01,0x85,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02, 952 0xa0,0x82,0x01,0x76,0x30,0x82,0x01,0x72,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c, 953 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06, 954 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa1,0x81,0xc5,0x30,0x81, 955 0xc2,0x30,0x7e,0x02,0x01,0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7, 956 0x0d,0x01,0x01,0x05,0x05,0x00,0x30,0x3c,0x31,0x0b,0x30,0x09,0x06,0x03,0x55, 957 0x04,0x06,0x13,0x02,0x52,0x55,0x31,0x0c,0x30,0x0a,0x06,0x03,0x55,0x04,0x08, 958 0x13,0x03,0x53,0x50,0x62,0x31,0x0c,0x30,0x0a,0x06,0x03,0x55,0x04,0x07,0x13, 959 0x03,0x53,0x50,0x62,0x31,0x11,0x30,0x0f,0x06,0x03,0x55,0x04,0x0a,0x13,0x08, 960 0x45,0x74,0x65,0x72,0x73,0x6f,0x66,0x74,0x17,0x0d,0x31,0x30,0x30,0x36,0x32, 961 0x38,0x31,0x32,0x35,0x31,0x32,0x37,0x5a,0x17,0x0d,0x31,0x30,0x30,0x37,0x32, 962 0x38,0x31,0x32,0x35,0x31,0x32,0x37,0x5a,0xa0,0x0e,0x30,0x0c,0x30,0x0a,0x06, 963 0x03,0x55,0x1d,0x14,0x04,0x03,0x02,0x01,0x00,0x30,0x0d,0x06,0x09,0x2a,0x86, 964 0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x31,0x00,0x83,0x35,0x9c, 965 0xf5,0x35,0x5c,0xc1,0x20,0x81,0x80,0x5c,0x35,0x56,0xaf,0xb3,0x27,0x15,0xc6, 966 0xdd,0x24,0xe1,0xff,0xb9,0xf9,0x19,0x21,0xed,0x5e,0x1b,0xff,0x72,0xc3,0x33, 967 0xf6,0x9f,0xcb,0xde,0x84,0x0b,0x12,0x84,0xad,0x48,0x90,0x9d,0xdd,0x89,0xbb, 968 0x31,0x81,0x87,0x30,0x81,0x84,0x02,0x01,0x01,0x30,0x20,0x30,0x0c,0x31,0x0a, 969 0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,0x20,0x42,0x68, 970 0x69,0xe9,0xea,0x61,0x83,0x11,0xdf,0xc0,0x24,0x2f,0x3b,0xad,0x40,0x30,0x0c, 971 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0d,0x06, 972 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x40,0x1e, 973 0x04,0xa4,0xe3,0x90,0x54,0xed,0xcb,0x94,0xa2,0xbe,0x81,0x73,0x7e,0x05,0xf2, 974 0x82,0xd3,0x3a,0x26,0x96,0x7a,0x53,0xcd,0x05,0xc3,0x09,0x69,0x3d,0x12,0x6c, 975 0xb1,0xb0,0xab,0x0e,0xa1,0xec,0x1b,0xa1,0xff,0x01,0x9c,0x49,0x9f,0x4b,0x69, 976 0x59,0x74,0x20,0x9f,0xb0,0x19,0x95,0xe7,0xed,0x1e,0x84,0xeb,0xe2,0x53,0x2c, 977 0xa6,0x43,0xdf }; 978 static const BYTE signedData[] = { 979 0x30,0x81,0xc3,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0, 980 0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a, 981 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86, 982 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04, 983 0x31,0x81,0x87,0x30,0x81,0x84,0x02,0x01,0x01,0x30,0x20,0x30,0x0c,0x31,0x0a, 984 0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,0x20,0x42,0x68, 985 0x69,0xe9,0xea,0x61,0x83,0x11,0xdf,0xc0,0x24,0x2f,0x3b,0xad,0x40,0x30,0x0c, 986 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0d,0x06, 987 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x40,0xe4, 988 0x69,0xf5,0x62,0xfb,0x3a,0x7d,0x1c,0x7b,0x8b,0xcc,0xfc,0x6e,0x8e,0x91,0x85, 989 0xcf,0x3c,0xb8,0xfd,0x8a,0xac,0x81,0x96,0xa0,0x42,0xac,0x88,0xc4,0x48,0xe8, 990 0x43,0x64,0xd1,0x38,0xd2,0x6c,0xc4,0xd4,0x9b,0x9a,0xd4,0x33,0x02,0xef,0x88, 991 0xef,0x98,0x2d,0xac,0xad,0xc1,0x93,0x60,0xc4,0x3a,0xdc,0xa7,0xd6,0x97,0x70, 992 0x01,0xc1,0x84 }; 993 994 static void test_sign_message(void) 995 { 996 BOOL ret; 997 CRYPT_SIGN_MESSAGE_PARA para; 998 static char oid_rsa_md5[] = szOID_RSA_MD5; 999 static const BYTE blob1[] = { 0x01, 0x02, 0x03, 0x04 }; 1000 static const BYTE blob2[] = { 0x11, 0x12, 0x13, 0x14 }; 1001 const BYTE *toSign[] = { blob1, blob2 }; 1002 DWORD signSize[] = { sizeof(blob1), sizeof(blob2) }; 1003 LPBYTE signedBlob; 1004 DWORD signedBlobSize; 1005 PCCRL_CONTEXT crlContext; 1006 CERT_KEY_CONTEXT keyContext; 1007 HCRYPTPROV hCryptProv = 0; 1008 HCRYPTKEY hKey = 0; 1009 1010 memset(¶, 0, sizeof(para)); 1011 SetLastError(0xdeadbeef); 1012 ret = CryptSignMessage(¶, FALSE, 0, NULL, NULL, NULL, &signedBlobSize); 1013 ok(!ret && 1014 (GetLastError() == E_INVALIDARG || 1015 GetLastError() == ERROR_ARITHMETIC_OVERFLOW), /* Win7 */ 1016 "expected E_INVALIDARG or ERROR_ARITHMETIC_OVERFLOW, got %08x\n", 1017 GetLastError()); 1018 para.cbSize = sizeof(para); 1019 para.dwMsgEncodingType = X509_ASN_ENCODING; 1020 SetLastError(0xdeadbeef); 1021 signedBlobSize = 255; 1022 ret = CryptSignMessage(¶, FALSE, 0, NULL, NULL, NULL, &signedBlobSize); 1023 ok(!ret && GetLastError() == E_INVALIDARG, 1024 "expected E_INVALIDARG, got %08x\n", GetLastError()); 1025 ok(!signedBlobSize, "unexpected size %d\n", signedBlobSize); 1026 para.dwMsgEncodingType = PKCS_7_ASN_ENCODING; 1027 SetLastError(0xdeadbeef); 1028 signedBlobSize = 0; 1029 ret = CryptSignMessage(¶, FALSE, 0, NULL, NULL, NULL, &signedBlobSize); 1030 ok(ret, "CryptSignMessage failed: %08x\n", GetLastError()); 1031 todo_wine 1032 ok(signedBlobSize, "bad size\n"); 1033 1034 SetLastError(0xdeadbeef); 1035 ret = pCryptAcquireContextA(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 1036 CRYPT_VERIFYCONTEXT); 1037 ok(ret, "CryptAcquireContextA failed: %08x\n", GetLastError()); 1038 SetLastError(0xdeadbeef); 1039 ret = CryptImportKey(hCryptProv, publicPrivateKeyPair, 1040 sizeof(publicPrivateKeyPair), 0, 0, &hKey); 1041 if (!ret && GetLastError() == NTE_PERM) /* Win9x */ 1042 { 1043 skip("Failed to import a key\n"); 1044 if (hCryptProv) 1045 CryptReleaseContext(hCryptProv, 0); 1046 return; 1047 } 1048 ok(ret, "CryptImportKey failed: %08x\n", GetLastError()); 1049 1050 para.dwMsgEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING; 1051 SetLastError(0xdeadbeef); 1052 para.pSigningCert = CertCreateCertificateContext(X509_ASN_ENCODING | 1053 PKCS_7_ASN_ENCODING, cert1, sizeof(cert1)); 1054 ok(para.pSigningCert != NULL, "CertCreateCertificateContext failed: %08x\n", 1055 GetLastError()); 1056 para.HashAlgorithm.pszObjId = oid_rsa_md5; 1057 1058 memset(&keyContext, 0, sizeof(keyContext)); 1059 keyContext.cbSize = sizeof(keyContext); 1060 keyContext.hCryptProv = hCryptProv; 1061 keyContext.dwKeySpec = AT_SIGNATURE; 1062 SetLastError(0xdeadbeef); 1063 ret = CertSetCertificateContextProperty(para.pSigningCert, 1064 CERT_KEY_CONTEXT_PROP_ID, 0, &keyContext); 1065 ok(ret, "CertSetCertificateContextProperty failed: %08x\n", GetLastError()); 1066 1067 SetLastError(0xdeadbeef); 1068 signedBlobSize = 0; 1069 ret = CryptSignMessage(¶, TRUE, 0, NULL, NULL, NULL, &signedBlobSize); 1070 ok(ret, "CryptSignMessage failed: %08x\n", GetLastError()); 1071 signedBlob = CryptMemAlloc(signedBlobSize); 1072 if (signedBlob) 1073 { 1074 SetLastError(0xdeadbeef); 1075 ret = CryptSignMessage(¶, TRUE, 0, NULL, NULL, signedBlob, 1076 &signedBlobSize); 1077 ok(ret, "CryptSignMessage failed: %08x\n", GetLastError()); 1078 ok(signedBlobSize == sizeof(signedHashForEmptyMessage), 1079 "unexpected size %d\n", signedBlobSize); 1080 ok(!memcmp(signedBlob, signedHashForEmptyMessage, signedBlobSize), 1081 "unexpected value\n"); 1082 CryptMemFree(signedBlob); 1083 } 1084 1085 SetLastError(0xdeadbeef); 1086 signedBlobSize = 0; 1087 ret = CryptSignMessage(¶, FALSE, 0, NULL, NULL, NULL, &signedBlobSize); 1088 ok(ret, "CryptSignMessage failed: %08x\n", GetLastError()); 1089 signedBlob = CryptMemAlloc(signedBlobSize); 1090 if (signedBlob) 1091 { 1092 SetLastError(0xdeadbeef); 1093 ret = CryptSignMessage(¶, FALSE, 0, NULL, NULL, signedBlob, 1094 &signedBlobSize); 1095 ok(ret, "CryptSignMessage failed: %08x\n", GetLastError()); 1096 ok(signedBlobSize == sizeof(signedEmptyMessage), "unexpected size %d\n", 1097 signedBlobSize); 1098 ok(!memcmp(signedBlob, signedEmptyMessage, signedBlobSize), 1099 "unexpected value\n"); 1100 CryptMemFree(signedBlob); 1101 } 1102 1103 SetLastError(0xdeadbeef); 1104 signedBlobSize = 0; 1105 ret = CryptSignMessage(¶, TRUE, 2, toSign, signSize, NULL, 1106 &signedBlobSize); 1107 ok(ret, "CryptSignMessage failed: %08x\n", GetLastError()); 1108 signedBlob = CryptMemAlloc(signedBlobSize); 1109 if (signedBlob) 1110 { 1111 SetLastError(0xdeadbeef); 1112 ret = CryptSignMessage(¶, TRUE, 2, toSign, signSize, signedBlob, 1113 &signedBlobSize); 1114 ok(ret, "CryptSignMessage failed: %08x\n", GetLastError()); 1115 ok(signedBlobSize == sizeof(signedHash), 1116 "unexpected size of signed blob %d\n", signedBlobSize); 1117 ok(!memcmp(signedBlob, signedHash, signedBlobSize), 1118 "unexpected value\n"); 1119 CryptMemFree(signedBlob); 1120 } 1121 1122 para.cMsgCert = 1; 1123 para.rgpMsgCert = ¶.pSigningCert; 1124 1125 SetLastError(0xdeadbeef); 1126 signedBlobSize = 0; 1127 ret = CryptSignMessage(¶, TRUE, 2, toSign, signSize, NULL, 1128 &signedBlobSize); 1129 ok(ret, "CryptSignMessage failed: %08x\n", GetLastError()); 1130 signedBlob = CryptMemAlloc(signedBlobSize); 1131 if (signedBlob) 1132 { 1133 SetLastError(0xdeadbeef); 1134 ret = CryptSignMessage(¶, TRUE, 2, toSign, signSize, signedBlob, 1135 &signedBlobSize); 1136 ok(ret, "CryptSignMessage failed: %08x\n", GetLastError()); 1137 ok(signedBlobSize == sizeof(signedHashWithCert), 1138 "unexpected size of signed blob %d\n", signedBlobSize); 1139 ok(!memcmp(signedBlob, signedHashWithCert, signedBlobSize), 1140 "unexpected value\n"); 1141 CryptMemFree(signedBlob); 1142 } 1143 1144 para.cMsgCert = 0; 1145 para.rgpMsgCert = NULL; 1146 para.cMsgCrl = 1; 1147 SetLastError(0xdeadbeef); 1148 crlContext = CertCreateCRLContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 1149 crl, sizeof(crl)); 1150 ok(crlContext != NULL, "CertCreateCRLContext failed: %08x\n", 1151 GetLastError()); 1152 para.rgpMsgCrl = &crlContext; 1153 1154 SetLastError(0xdeadbeef); 1155 signedBlobSize = 0; 1156 ret = CryptSignMessage(¶, TRUE, 2, toSign, signSize, NULL, 1157 &signedBlobSize); 1158 ok(ret, "CryptSignMessage failed: %08x\n", GetLastError()); 1159 signedBlob = CryptMemAlloc(signedBlobSize); 1160 if (signedBlob) 1161 { 1162 SetLastError(0xdeadbeef); 1163 ret = CryptSignMessage(¶, TRUE, 2, toSign, signSize, signedBlob, 1164 &signedBlobSize); 1165 ok(ret, "CryptSignMessage failed: %08x\n", GetLastError()); 1166 ok(signedBlobSize == sizeof(signedHashWithCRL), 1167 "unexpected size of signed blob %d\n", signedBlobSize); 1168 ok(!memcmp(signedBlob, signedHashWithCRL, signedBlobSize), 1169 "unexpected value\n"); 1170 CryptMemFree(signedBlob); 1171 } 1172 1173 CertFreeCRLContext(crlContext); 1174 para.cMsgCrl = 0; 1175 para.rgpMsgCrl = NULL; 1176 1177 SetLastError(0xdeadbeef); 1178 signedBlobSize = 0; 1179 ret = CryptSignMessage(¶, FALSE, 1, toSign, signSize, NULL, 1180 &signedBlobSize); 1181 ok(ret, "CryptSignMessage failed: %08x\n", GetLastError()); 1182 signedBlob = CryptMemAlloc(signedBlobSize); 1183 if (signedBlob) 1184 { 1185 SetLastError(0xdeadbeef); 1186 ret = CryptSignMessage(¶, FALSE, 1, toSign, signSize, signedBlob, 1187 &signedBlobSize); 1188 ok(ret, "CryptSignMessage failed: %08x\n", GetLastError()); 1189 ok(signedBlobSize == sizeof(signedData), 1190 "unexpected size of signed blob %d\n", signedBlobSize); 1191 ok(!memcmp(signedBlob, signedData, signedBlobSize), 1192 "unexpected value\n"); 1193 CryptMemFree(signedBlob); 1194 } 1195 1196 if (para.pSigningCert) 1197 CertFreeCertificateContext(para.pSigningCert); 1198 if (hKey) 1199 CryptDestroyKey(hKey); 1200 if (hCryptProv) 1201 CryptReleaseContext(hCryptProv, 0); 1202 } 1203 1204 static const BYTE encryptedMessage[] = { 1205 0x30,0x31,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,0x24, 1206 0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86, 1207 0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, 1208 0x03,0x04,0x05,0x00,0x80,0x00 }; 1209 1210 static void test_encrypt_message(void) 1211 { 1212 BOOL ret; 1213 CRYPT_ENCRYPT_MESSAGE_PARA para; 1214 static char oid_rsa_rc4[] = szOID_RSA_RC4; 1215 static const BYTE blob[] = { 0x01, 0x02, 0x03, 0x04 }; 1216 PCCERT_CONTEXT certs[2]; 1217 HCRYPTPROV hCryptProv = 0; 1218 LPBYTE encryptedBlob; 1219 DWORD encryptedBlobSize; 1220 1221 SetLastError(0xdeadbeef); 1222 ret = pCryptAcquireContextA(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 1223 CRYPT_VERIFYCONTEXT); 1224 ok(ret, "CryptAcquireContextA failed: %08x\n", GetLastError()); 1225 1226 SetLastError(0xdeadbeef); 1227 certs[0] = CertCreateCertificateContext(X509_ASN_ENCODING | 1228 PKCS_7_ASN_ENCODING, cert1, sizeof(cert1)); 1229 ok(certs[0] != NULL, "CertCreateCertificateContext failed: %08x\n", 1230 GetLastError()); 1231 SetLastError(0xdeadbeef); 1232 certs[1] = CertCreateCertificateContext(X509_ASN_ENCODING | 1233 PKCS_7_ASN_ENCODING, cert2, sizeof(cert2)); 1234 ok(certs[1] != NULL, "CertCreateCertificateContext failed: %08x\n", 1235 GetLastError()); 1236 1237 memset(¶, 0, sizeof(para)); 1238 SetLastError(0xdeadbeef); 1239 encryptedBlobSize = 255; 1240 ret = CryptEncryptMessage(¶, 0, NULL, NULL, 0, NULL, 1241 &encryptedBlobSize); 1242 ok(!ret && GetLastError() == E_INVALIDARG, 1243 "expected E_INVALIDARG, got %08x\n", GetLastError()); 1244 ok(!encryptedBlobSize, "unexpected size %d\n", encryptedBlobSize); 1245 para.cbSize = sizeof(para); 1246 para.dwMsgEncodingType = X509_ASN_ENCODING; 1247 SetLastError(0xdeadbeef); 1248 encryptedBlobSize = 255; 1249 ret = CryptEncryptMessage(¶, 0, NULL, NULL, 0, NULL, 1250 &encryptedBlobSize); 1251 ok(!ret && GetLastError() == E_INVALIDARG, 1252 "expected E_INVALIDARG, got %08x\n", GetLastError()); 1253 ok(!encryptedBlobSize, "unexpected size %d\n", encryptedBlobSize); 1254 para.dwMsgEncodingType = PKCS_7_ASN_ENCODING; 1255 SetLastError(0xdeadbeef); 1256 encryptedBlobSize = 255; 1257 ret = CryptEncryptMessage(¶, 0, NULL, NULL, 0, NULL, 1258 &encryptedBlobSize); 1259 ok(!ret && 1260 (GetLastError() == CRYPT_E_UNKNOWN_ALGO || 1261 GetLastError() == E_INVALIDARG), /* Win9x */ 1262 "expected CRYPT_E_UNKNOWN_ALGO or E_INVALIDARG, got %08x\n", 1263 GetLastError()); 1264 ok(!encryptedBlobSize, "unexpected size %d\n", encryptedBlobSize); 1265 1266 para.hCryptProv = hCryptProv; 1267 para.ContentEncryptionAlgorithm.pszObjId = oid_rsa_rc4; 1268 1269 SetLastError(0xdeadbeef); 1270 encryptedBlobSize = 0; 1271 ret = CryptEncryptMessage(¶, 0, NULL, NULL, 0, NULL, 1272 &encryptedBlobSize); 1273 ok(ret || 1274 broken(!ret) /* Win9x */, 1275 "CryptEncryptMessage failed: %08x\n", GetLastError()); 1276 if (ret) 1277 { 1278 encryptedBlob = CryptMemAlloc(encryptedBlobSize); 1279 if (encryptedBlob) 1280 { 1281 SetLastError(0xdeadbeef); 1282 ret = CryptEncryptMessage(¶, 0, NULL, NULL, 0, encryptedBlob, 1283 &encryptedBlobSize); 1284 ok(ret, "CryptEncryptMessage failed: %08x\n", GetLastError()); 1285 ok(encryptedBlobSize == sizeof(encryptedMessage), 1286 "unexpected size of encrypted blob %d\n", encryptedBlobSize); 1287 ok(!memcmp(encryptedBlob, encryptedMessage, encryptedBlobSize), 1288 "unexpected value\n"); 1289 CryptMemFree(encryptedBlob); 1290 } 1291 } 1292 1293 SetLastError(0xdeadbeef); 1294 encryptedBlobSize = 0; 1295 ret = CryptEncryptMessage(¶, 2, certs, NULL, 0, NULL, 1296 &encryptedBlobSize); 1297 ok(ret, "CryptEncryptMessage failed: %08x\n", GetLastError()); 1298 if (ret) 1299 { 1300 encryptedBlob = CryptMemAlloc(encryptedBlobSize); 1301 if (encryptedBlob) 1302 { 1303 SetLastError(0xdeadbeef); 1304 ret = CryptEncryptMessage(¶, 2, certs, NULL, 0, encryptedBlob, 1305 &encryptedBlobSize); 1306 ok(ret, "CryptEncryptMessage failed: %08x\n", GetLastError()); 1307 CryptMemFree(encryptedBlob); 1308 } 1309 } 1310 1311 SetLastError(0xdeadbeef); 1312 encryptedBlobSize = 0; 1313 ret = CryptEncryptMessage(¶, 0, NULL, blob, sizeof(blob), NULL, 1314 &encryptedBlobSize); 1315 ok(ret || 1316 broken(!ret) /* Win9x */, 1317 "CryptEncryptMessage failed: %08x\n", GetLastError()); 1318 if (ret) 1319 { 1320 encryptedBlob = CryptMemAlloc(encryptedBlobSize); 1321 if (encryptedBlob) 1322 { 1323 SetLastError(0xdeadbeef); 1324 ret = CryptEncryptMessage(¶, 0, NULL, blob, sizeof(blob), 1325 encryptedBlob, &encryptedBlobSize); 1326 ok(ret || 1327 broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */ 1328 "CryptEncryptMessage failed: %08x\n", GetLastError()); 1329 if (ret) 1330 { 1331 ok(encryptedBlobSize == 55, 1332 "unexpected size of encrypted blob %d\n", encryptedBlobSize); 1333 } 1334 CryptMemFree(encryptedBlob); 1335 } 1336 } 1337 1338 SetLastError(0xdeadbeef); 1339 encryptedBlobSize = 0; 1340 ret = CryptEncryptMessage(¶, 2, certs, blob, sizeof(blob), NULL, 1341 &encryptedBlobSize); 1342 ok(ret, "CryptEncryptMessage failed: %08x\n", GetLastError()); 1343 if (ret) 1344 { 1345 encryptedBlob = CryptMemAlloc(encryptedBlobSize); 1346 if (encryptedBlob) 1347 { 1348 SetLastError(0xdeadbeef); 1349 ret = CryptEncryptMessage(¶, 2, certs, blob, sizeof(blob), 1350 encryptedBlob, &encryptedBlobSize); 1351 ok(ret || 1352 broken(!ret), /* some Win95 and some NT4 */ 1353 "CryptEncryptMessage failed: %08x\n", GetLastError()); 1354 CryptMemFree(encryptedBlob); 1355 } 1356 } 1357 1358 if (certs[0]) 1359 CertFreeCertificateContext(certs[0]); 1360 if (certs[1]) 1361 CertFreeCertificateContext(certs[1]); 1362 if (hCryptProv) 1363 CryptReleaseContext(hCryptProv, 0); 1364 } 1365 1366 START_TEST(message) 1367 { 1368 init_function_pointers(); 1369 1370 test_msg_get_signer_count(); 1371 test_verify_detached_message_hash(); 1372 test_verify_message_hash(); 1373 test_verify_detached_message_signature(); 1374 test_verify_message_signature(); 1375 test_hash_message(); 1376 test_sign_message(); 1377 test_encrypt_message(); 1378 } 1379