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