push c03b0bb7c67acf502e715114ece376179b90ac7c
[wine/hacks.git] / dlls / crypt32 / tests / message.c
blob28f9a4eb8ec75bcfb40b9f3e0be6b56cebca9e54
1 /*
2 * Unit test suite for crypt32.dll's Crypt*Message functions
4 * Copyright 2007-2008 Juan Lang
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.
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.
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
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <windef.h>
24 #include <winbase.h>
25 #include <winerror.h>
26 #include <wincrypt.h>
28 #include "wine/test.h"
30 static const BYTE dataEmptyBareContent[] = { 0x04,0x00 };
31 static const BYTE dataEmptyContent[] = {
32 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02,
33 0x04,0x00 };
34 static const BYTE signedEmptyBareContent[] = {
35 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
36 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
37 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
38 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
39 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
40 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
41 static const BYTE signedEmptyContent[] = {
42 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
43 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
44 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
45 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
46 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
47 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
48 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
50 static void test_msg_get_signer_count(void)
52 LONG count;
54 SetLastError(0xdeadbeef);
55 count = CryptGetMessageSignerCount(0, NULL, 0);
56 ok(count == -1, "Expected -1, got %d\n", count);
57 ok(GetLastError() == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n",
58 GetLastError());
59 SetLastError(0xdeadbeef);
60 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING, NULL, 0);
61 ok(count == -1, "Expected -1, got %d\n", count);
62 ok(GetLastError() == CRYPT_E_ASN1_EOD ||
63 GetLastError() == OSS_BAD_ARG, /* win9x */
64 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
65 SetLastError(0xdeadbeef);
66 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
67 dataEmptyBareContent, sizeof(dataEmptyBareContent));
68 ok(count == -1, "Expected -1, got %d\n", count);
69 ok(GetLastError() == CRYPT_E_ASN1_BADTAG ||
70 GetLastError() == OSS_PDU_MISMATCH, /* win9x */
71 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
72 SetLastError(0xdeadbeef);
73 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
74 dataEmptyContent, sizeof(dataEmptyContent));
75 ok(count == -1, "Expected -1, got %d\n", count);
76 ok(GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
77 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
78 SetLastError(0xdeadbeef);
79 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
80 signedEmptyBareContent, sizeof(signedEmptyBareContent));
81 ok(count == -1, "Expected -1, got %d\n", count);
82 ok(GetLastError() == CRYPT_E_ASN1_BADTAG ||
83 GetLastError() == OSS_DATA_ERROR, /* win9x */
84 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
85 count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
86 signedEmptyContent, sizeof(signedEmptyContent));
87 ok(count == 1 ||
88 broken(count == -1), /* win9x */
89 "Expected 1, got %d\n", count);
92 static BYTE detachedHashContent[] = {
93 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
94 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
95 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
96 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
97 0x9d,0x2a,0x8f,0x26,0x2f };
98 static const BYTE msgData[] = { 1, 2, 3, 4 };
100 static void test_verify_detached_message_hash(void)
102 BOOL ret;
103 CRYPT_HASH_MESSAGE_PARA para;
104 DWORD size, hashSize;
105 const BYTE *pMsgData = msgData;
106 BYTE hash[16];
108 if (0)
110 ret = CryptVerifyDetachedMessageHash(NULL, NULL, 0, 0, NULL, NULL, NULL,
111 NULL);
113 memset(&para, 0, sizeof(para));
114 SetLastError(0xdeadbeef);
115 ret = CryptVerifyDetachedMessageHash(&para, NULL, 0, 0, NULL, NULL, NULL,
116 NULL);
117 ok(!ret && GetLastError() == E_INVALIDARG,
118 "expected E_INVALIDARG, got %08x\n", GetLastError());
119 para.cbSize = sizeof(para);
120 SetLastError(0xdeadbeef);
121 ret = CryptVerifyDetachedMessageHash(&para, NULL, 0, 0, NULL, NULL, NULL,
122 NULL);
123 ok(!ret && GetLastError() == E_INVALIDARG,
124 "expected E_INVALIDARG, got %08x\n", GetLastError());
125 para.dwMsgEncodingType = PKCS_7_ASN_ENCODING;
126 SetLastError(0xdeadbeef);
127 ret = CryptVerifyDetachedMessageHash(&para, NULL, 0, 0, NULL, NULL, NULL,
128 NULL);
129 ok(!ret &&
130 (GetLastError() == CRYPT_E_ASN1_EOD ||
131 GetLastError() == OSS_BAD_ARG), /* win9x */
132 "expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
133 para.dwMsgEncodingType = X509_ASN_ENCODING;
134 SetLastError(0xdeadbeef);
135 ret = CryptVerifyDetachedMessageHash(&para, NULL, 0, 0, NULL, NULL, NULL,
136 NULL);
137 ok(!ret && GetLastError() == E_INVALIDARG,
138 "expected E_INVALIDARG, got %08x\n", GetLastError());
139 para.dwMsgEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
140 SetLastError(0xdeadbeef);
141 ret = CryptVerifyDetachedMessageHash(&para, NULL, 0, 0, NULL, NULL, NULL,
142 NULL);
143 ok(!ret &&
144 (GetLastError() == CRYPT_E_ASN1_EOD ||
145 GetLastError() == OSS_BAD_ARG), /* win9x */
146 "expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
147 /* Curiously, passing no data to hash succeeds.. */
148 ret = CryptVerifyDetachedMessageHash(&para, detachedHashContent,
149 sizeof(detachedHashContent), 0, NULL, NULL, NULL, NULL);
150 todo_wine
151 ok(ret, "CryptVerifyDetachedMessageHash failed: %08x\n", GetLastError());
152 /* as does passing the actual content of the message to hash.. */
153 size = sizeof(msgData);
154 pMsgData = msgData;
155 ret = CryptVerifyDetachedMessageHash(&para, detachedHashContent,
156 sizeof(detachedHashContent), 1, &pMsgData, &size, NULL, NULL);
157 ok(ret, "CryptVerifyDetachedMessageHash failed: %08x\n", GetLastError());
158 /* while passing data to hash that isn't the content of the message fails.
160 size = sizeof(detachedHashContent);
161 pMsgData = detachedHashContent;
162 SetLastError(0xdeadbeef);
163 ret = CryptVerifyDetachedMessageHash(&para, detachedHashContent,
164 sizeof(detachedHashContent), 1, &pMsgData, &size, NULL, NULL);
165 ok(!ret && GetLastError() == CRYPT_E_HASH_VALUE,
166 "expected CRYPT_E_HASH_VALUE, got %08x\n", GetLastError());
167 /* Getting the size of the hash while passing no hash data causes the
168 * hash to be checked (and fail.)
170 SetLastError(0xdeadbeef);
171 ret = CryptVerifyDetachedMessageHash(&para, detachedHashContent,
172 sizeof(detachedHashContent), 0, NULL, NULL, NULL, &hashSize);
173 ok(!ret && GetLastError() == CRYPT_E_HASH_VALUE,
174 "expected CRYPT_E_HASH_VALUE, got %08x\n", GetLastError());
175 size = sizeof(msgData);
176 pMsgData = msgData;
177 ret = CryptVerifyDetachedMessageHash(&para, detachedHashContent,
178 sizeof(detachedHashContent), 1, &pMsgData, &size, NULL, &hashSize);
179 ok(ret, "CryptVerifyDetachedMessageHash failed: %08x\n", GetLastError());
180 ok(hashSize == sizeof(hash), "unexpected size %d\n", hashSize);
181 hashSize = 1;
182 SetLastError(0xdeadbeef);
183 ret = CryptVerifyDetachedMessageHash(&para, detachedHashContent,
184 sizeof(detachedHashContent), 1, &pMsgData, &size, hash, &hashSize);
185 ok(!ret && GetLastError() == ERROR_MORE_DATA,
186 "expected ERROR_MORE_DATA, got %08x\n", GetLastError());
187 hashSize = sizeof(hash);
188 ret = CryptVerifyDetachedMessageHash(&para, detachedHashContent,
189 sizeof(detachedHashContent), 1, &pMsgData, &size, hash, &hashSize);
190 ok(ret, "CryptVerifyDetachedMessageHash failed: %08x\n", GetLastError());
193 static BYTE hashContent[] = {
194 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
195 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
196 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
197 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
198 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
200 static void test_verify_message_hash(void)
202 BOOL ret;
203 CRYPT_HASH_MESSAGE_PARA para;
204 DWORD size;
205 BYTE *buf = NULL;
207 memset(&para, 0, sizeof(para));
208 /* Crash */
209 if (0)
210 ret = CryptVerifyMessageHash(NULL, NULL, 0, NULL, NULL, NULL, NULL);
211 SetLastError(0xdeadbeef);
212 ret = CryptVerifyMessageHash(&para, NULL, 0, NULL, NULL, NULL, NULL);
213 ok(!ret && GetLastError() == E_INVALIDARG,
214 "expected E_INVALIDARG, got %08x\n", GetLastError());
215 para.cbSize = sizeof(para);
216 SetLastError(0xdeadbeef);
217 ret = CryptVerifyMessageHash(&para, NULL, 0, NULL, NULL, NULL, NULL);
218 ok(!ret && GetLastError() == E_INVALIDARG,
219 "expected E_INVALIDARG, got %08x\n", GetLastError());
220 para.dwMsgEncodingType = PKCS_7_ASN_ENCODING;
221 SetLastError(0xdeadbeef);
222 ret = CryptVerifyMessageHash(&para, NULL, 0, NULL, NULL, NULL, NULL);
223 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
224 "expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
225 /* Verifying the hash of a detached message succeeds? */
226 ret = CryptVerifyMessageHash(&para, detachedHashContent,
227 sizeof(detachedHashContent), NULL, NULL, NULL, NULL);
228 todo_wine
229 ok(ret, "CryptVerifyMessageHash failed: %08x\n", GetLastError());
230 /* As does verifying the hash of a regular message. */
231 ret = CryptVerifyMessageHash(&para, hashContent, sizeof(hashContent),
232 NULL, NULL, NULL, NULL);
233 ok(ret, "CryptVerifyMessageHash failed: %08x\n", GetLastError());
234 ret = CryptVerifyMessageHash(&para, hashContent, sizeof(hashContent),
235 NULL, &size, NULL, NULL);
236 ok(ret, "CryptVerifyMessageHash failed: %08x\n", GetLastError());
237 if (ret)
238 buf = CryptMemAlloc(size);
239 if (buf)
241 size = 1;
242 ret = CryptVerifyMessageHash(&para, hashContent, sizeof(hashContent),
243 buf, &size, NULL, NULL);
244 ok(!ret && GetLastError() == ERROR_MORE_DATA,
245 "expected ERROR_MORE_DATA, got %08x\n", GetLastError());
246 ret = CryptVerifyMessageHash(&para, hashContent, sizeof(hashContent),
247 buf, &size, NULL, NULL);
248 ok(ret, "CryptVerifyMessageHash failed: %08x\n", GetLastError());
249 ok(size == sizeof(msgData), "unexpected size %d\n", size);
250 ok(!memcmp(buf, msgData, size), "unexpected value\n");
251 CryptMemFree(buf);
255 static const BYTE signedWithCertContent[] = {
256 0x30,0x82,0x01,0x32,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
257 0xa0,0x82,0x01,0x23,0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
258 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
259 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
260 0x02,0x03,0x04,0xa0,0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
261 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
262 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
263 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
264 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
265 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
266 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,
267 0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,
268 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,
269 0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,
270 0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,
271 0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,
272 0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,
273 0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,
274 0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,
275 0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,
276 0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
277 static const BYTE signedContent[] = {
278 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
279 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
280 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
281 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
282 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
283 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
284 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
285 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
286 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
287 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
288 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
289 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
290 0x0d };
291 static const BYTE detachedSignedContent[] = {
292 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
293 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
294 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
295 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
296 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
297 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
298 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
299 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
300 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
301 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
302 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
303 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
304 static const BYTE v1CertWithValidPubKey[] = {
305 0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
306 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
307 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
308 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
309 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
310 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
311 0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
312 0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,
313 0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,
314 0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,
315 0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,
316 0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,
317 0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
318 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
320 static PCCERT_CONTEXT WINAPI msg_get_signer_callback(void *pvArg,
321 DWORD certEncodingType, PCERT_INFO signerId, HCERTSTORE store)
323 return CertCreateCertificateContext(X509_ASN_ENCODING,
324 v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey));
327 static void test_verify_detached_message_signature(void)
329 CRYPT_VERIFY_MESSAGE_PARA para;
330 BOOL ret;
331 const BYTE *pContent;
332 DWORD cbContent;
334 memset(&para, 0, sizeof(para));
335 SetLastError(0xdeadbeef);
336 ret = CryptVerifyDetachedMessageSignature(NULL, 0, NULL, 0, 0, NULL,
337 NULL, NULL);
338 ok(!ret && GetLastError() == E_INVALIDARG,
339 "Expected E_INVALIDARG, got %08x\n", GetLastError());
340 SetLastError(0xdeadbeef);
341 ret = CryptVerifyDetachedMessageSignature(&para, 0, NULL, 0, 0, NULL,
342 NULL, NULL);
343 ok(!ret && GetLastError() == E_INVALIDARG,
344 "Expected E_INVALIDARG, got %08x\n", GetLastError());
345 para.cbSize = sizeof(para);
346 SetLastError(0xdeadbeef);
347 ret = CryptVerifyDetachedMessageSignature(&para, 0, NULL, 0, 0, NULL,
348 NULL, NULL);
349 ok(!ret && GetLastError() == E_INVALIDARG,
350 "Expected E_INVALIDARG, got %08x\n", GetLastError());
351 para.dwMsgAndCertEncodingType = X509_ASN_ENCODING;
352 SetLastError(0xdeadbeef);
353 ret = CryptVerifyDetachedMessageSignature(&para, 0, NULL, 0, 0, NULL,
354 NULL, NULL);
355 ok(!ret && GetLastError() == E_INVALIDARG,
356 "Expected E_INVALIDARG, got %08x\n", GetLastError());
357 para.dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING;
358 SetLastError(0xdeadbeef);
359 ret = CryptVerifyDetachedMessageSignature(&para, 0, NULL, 0, 0, NULL,
360 NULL, NULL);
361 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
362 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
363 /* None of these messages contains a cert in the message itself, so the
364 * default callback isn't able to verify their signature.
366 SetLastError(0xdeadbeef);
367 ret = CryptVerifyDetachedMessageSignature(&para, 0, signedWithCertContent,
368 sizeof(signedWithCertContent), 0, NULL, NULL, NULL);
369 todo_wine
370 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
371 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
372 SetLastError(0xdeadbeef);
373 ret = CryptVerifyDetachedMessageSignature(&para, 0, signedContent,
374 sizeof(signedContent), 0, NULL, NULL, NULL);
375 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
376 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
377 SetLastError(0xdeadbeef);
378 ret = CryptVerifyDetachedMessageSignature(&para, 0, detachedSignedContent,
379 sizeof(detachedSignedContent), 0, NULL, NULL, NULL);
380 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
381 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
382 SetLastError(0xdeadbeef);
383 pContent = msgData;
384 cbContent = sizeof(msgData);
385 ret = CryptVerifyDetachedMessageSignature(&para, 0, detachedSignedContent,
386 sizeof(detachedSignedContent), 1, &pContent, &cbContent, NULL);
387 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
388 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
389 /* Passing the correct callback results in success */
390 para.pfnGetSignerCertificate = msg_get_signer_callback;
391 ret = CryptVerifyDetachedMessageSignature(&para, 0, detachedSignedContent,
392 sizeof(detachedSignedContent), 1, &pContent, &cbContent, NULL);
393 ok(ret, "CryptVerifyDetachedMessageSignature failed: %08x\n",
394 GetLastError());
395 /* Not passing the correct data to be signed results in the signature not
396 * matching.
398 SetLastError(0xdeadbeef);
399 ret = CryptVerifyDetachedMessageSignature(&para, 0, detachedSignedContent,
400 sizeof(detachedSignedContent), 0, NULL, NULL, NULL);
401 ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
402 "expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
405 static const BYTE signedWithCertEmptyContent[] = {
406 0x30,0x81,0xdf,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
407 0x81,0xd1,0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
408 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,
409 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
410 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
411 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
412 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
413 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
414 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
415 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
416 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
417 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
418 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
419 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
420 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
421 0x00 };
422 static const BYTE signedWithCertWithPubKeyContent[] = {
423 0x30,0x81,0xfc,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
424 0x81,0xee,0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
425 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,
426 0x98,0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,
427 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
428 0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
429 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
430 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,
431 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
432 0x6e,0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
433 0x01,0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,
434 0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,
435 0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,
436 0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
437 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
438 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
439 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
441 static void test_verify_message_signature(void)
443 BOOL ret;
444 CRYPT_VERIFY_MESSAGE_PARA para = { 0 };
445 PCCERT_CONTEXT cert;
446 DWORD cbDecoded;
448 SetLastError(0xdeadbeef);
449 ret = CryptVerifyMessageSignature(NULL, 0, NULL, 0, NULL, 0, NULL);
450 ok(!ret && GetLastError() == E_INVALIDARG,
451 "Expected E_INVALIDARG, got %08x\n", GetLastError());
452 SetLastError(0xdeadbeef);
453 ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, 0, NULL);
454 ok(!ret && GetLastError() == E_INVALIDARG,
455 "Expected E_INVALIDARG, got %08x\n", GetLastError());
456 para.cbSize = sizeof(para);
457 SetLastError(0xdeadbeef);
458 ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, 0, NULL);
459 ok(!ret && GetLastError() == E_INVALIDARG,
460 "Expected E_INVALIDARG, got %08x\n", GetLastError());
461 para.cbSize = 0;
462 para.dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING;
463 SetLastError(0xdeadbeef);
464 ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, 0, NULL);
465 ok(!ret && GetLastError() == E_INVALIDARG,
466 "Expected E_INVALIDARG, got %08x\n", GetLastError());
467 para.cbSize = sizeof(para);
468 SetLastError(0xdeadbeef);
469 ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, 0, NULL);
470 ok(!ret &&
471 (GetLastError() == CRYPT_E_ASN1_EOD ||
472 GetLastError() == OSS_BAD_ARG), /* win9x */
473 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
474 /* Check whether cert is set on error */
475 cert = (PCCERT_CONTEXT)0xdeadbeef;
476 ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, 0, &cert);
477 ok(cert == NULL, "Expected NULL cert\n");
478 /* Check whether cbDecoded is set on error */
479 cbDecoded = 0xdeadbeef;
480 ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, &cbDecoded,
481 NULL);
482 ok(!cbDecoded, "Expected 0\n");
483 SetLastError(0xdeadbeef);
484 ret = CryptVerifyMessageSignature(&para, 0, dataEmptyBareContent,
485 sizeof(dataEmptyBareContent), NULL, 0, NULL);
486 ok(GetLastError() == CRYPT_E_ASN1_BADTAG ||
487 GetLastError() == OSS_PDU_MISMATCH, /* win9x */
488 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
489 SetLastError(0xdeadbeef);
490 ret = CryptVerifyMessageSignature(&para, 0, dataEmptyContent,
491 sizeof(dataEmptyContent), NULL, 0, NULL);
492 ok(!ret && GetLastError() == CRYPT_E_UNEXPECTED_MSG_TYPE,
493 "Expected CRYPT_E_UNEXPECTED_MSG_TYPE, got %08x\n", GetLastError());
494 SetLastError(0xdeadbeef);
495 ret = CryptVerifyMessageSignature(&para, 0, signedEmptyBareContent,
496 sizeof(signedEmptyBareContent), NULL, 0, NULL);
497 ok(!ret &&
498 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
499 GetLastError() == OSS_DATA_ERROR), /* win9x */
500 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
501 SetLastError(0xdeadbeef);
502 ret = CryptVerifyMessageSignature(&para, 0, signedEmptyContent,
503 sizeof(signedEmptyContent), NULL, 0, NULL);
504 ok(!ret &&
505 (GetLastError() == CRYPT_E_NOT_FOUND ||
506 GetLastError() == OSS_DATA_ERROR), /* win9x */
507 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
508 SetLastError(0xdeadbeef);
509 ret = CryptVerifyMessageSignature(&para, 0, signedContent,
510 sizeof(signedContent), NULL, 0, NULL);
511 ok(!ret &&
512 (GetLastError() == CRYPT_E_NOT_FOUND ||
513 GetLastError() == OSS_DATA_ERROR), /* win9x */
514 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
515 /* FIXME: Windows fails with CRYPT_E_NOT_FOUND for these messages, but
516 * their signer certs have invalid public keys that fail to decode. In
517 * Wine therefore the failure is an ASN error. Need some messages with
518 * valid public keys and invalid signatures to check against.
520 ret = CryptVerifyMessageSignature(&para, 0, signedWithCertEmptyContent,
521 sizeof(signedWithCertEmptyContent), NULL, 0, NULL);
522 ok(!ret, "Expected failure\n");
523 ret = CryptVerifyMessageSignature(&para, 0, signedWithCertContent,
524 sizeof(signedWithCertContent), NULL, 0, NULL);
525 ok(!ret, "Expected failure\n");
526 ret = CryptVerifyMessageSignature(&para, 0, signedWithCertWithPubKeyContent,
527 sizeof(signedWithCertWithPubKeyContent), NULL, 0, NULL);
528 ok(!ret, "Expected failure\n");
531 static const BYTE detachedHashBlob[] = {
532 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
533 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
534 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
535 0x07,0x01,0x04,0x10,0x2d,0x1b,0xbc,0x1f,0xc7,0xab,0x36,0x8d,0xdb,0x95,0xe6,
536 0x24,0xb9,0x66,0x7c,0x21 };
537 static const BYTE hashBlob[] = {
538 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
539 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
540 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
541 0x07,0x01,0xa0,0x06,0x04,0x04,0xde,0xad,0xbe,0xef,0x04,0x10,0x2f,0x24,0x92,
542 0x30,0xa8,0xe7,0xc2,0xbf,0x60,0x05,0xcc,0xd2,0x67,0x92,0x59,0xec };
543 static const BYTE hashVal[] = {
544 0x2d,0x1b,0xbc,0x1f,0xc7,0xab,0x36,0x8d,0xdb,0x95,0xe6,0x24,0xb9,0x66,0x7c,
545 0x21 };
547 static void test_hash_message(void)
549 BOOL ret;
550 CRYPT_HASH_MESSAGE_PARA para;
551 static const BYTE blob1[] = { 0xde, 0xad, 0xbe, 0xef };
552 static const BYTE blob2[] = { 0xba, 0xad, 0xf0, 0x0d };
553 const BYTE *toHash[] = { blob1, blob2 };
554 DWORD hashSize[] = { sizeof(blob1), sizeof(blob2) };
555 DWORD hashedBlobSize, computedHashSize;
556 static char oid_rsa_md5[] = szOID_RSA_MD5;
557 LPBYTE hashedBlob, computedHash;
559 /* Crash
560 ret = CryptHashMessage(NULL, FALSE, 0, NULL, 0, NULL, NULL, NULL, NULL);
562 memset(&para, 0, sizeof(para));
563 SetLastError(0xdeadbeef);
564 ret = CryptHashMessage(&para, FALSE, 0, NULL, NULL, NULL, NULL, NULL, NULL);
565 ok(!ret && GetLastError() == E_INVALIDARG,
566 "expected E_INVALIDARG, got 0x%08x\n", GetLastError());
567 para.cbSize = sizeof(para);
568 /* Not quite sure what "success" means in this case, but it does succeed */
569 SetLastError(0xdeadbeef);
570 ret = CryptHashMessage(&para, FALSE, 0, NULL, NULL, NULL, NULL, NULL, NULL);
571 ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError());
572 /* With a bogus encoding type it "succeeds" */
573 para.dwMsgEncodingType = 0xdeadbeef;
574 SetLastError(0xdeadbeef);
575 ret = CryptHashMessage(&para, FALSE, 0, NULL, NULL, NULL, NULL, NULL, NULL);
576 ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError());
577 /* According to MSDN, the third parameter (cToBeHashed) must be 1 if the
578 * second parameter (fDetached) is FALSE, but again it "succeeds."
580 SetLastError(0xdeadbeef);
581 ret = CryptHashMessage(&para, FALSE, 2, NULL, NULL, NULL, NULL, NULL, NULL);
582 ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError());
583 /* Even passing parameters to hash results in "success." */
584 SetLastError(0xdeadbeef);
585 ret = CryptHashMessage(&para, FALSE, 2, toHash, hashSize, NULL, NULL, NULL,
586 NULL);
587 /* Try again with a valid encoding type */
588 para.dwMsgEncodingType = PKCS_7_ASN_ENCODING;
589 SetLastError(0xdeadbeef);
590 ret = CryptHashMessage(&para, FALSE, 2, NULL, NULL, NULL, NULL, NULL, NULL);
591 ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError());
592 /* And with valid data to hash */
593 SetLastError(0xdeadbeef);
594 ret = CryptHashMessage(&para, FALSE, 2, toHash, hashSize, NULL, NULL, NULL,
595 NULL);
596 ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError());
597 /* But requesting the size of the hashed blob and indicating there's data
598 * to hash results in a crash
600 if (0)
602 ret = CryptHashMessage(&para, FALSE, 2, NULL, NULL, NULL,
603 &hashedBlobSize, NULL, NULL);
605 /* Passing a valid pointer for the data to hash fails, as the hash
606 * algorithm is finally checked.
608 SetLastError(0xdeadbeef);
609 ret = CryptHashMessage(&para, FALSE, 2, toHash, hashSize, NULL,
610 &hashedBlobSize, NULL, NULL);
611 ok(!ret &&
612 (GetLastError() == CRYPT_E_UNKNOWN_ALGO ||
613 GetLastError() == CRYPT_E_OID_FORMAT), /* Vista */
614 "expected CRYPT_E_UNKNOWN_ALGO or CRYPT_E_OID_FORMAT, got 0x%08x (%d)\n",
615 GetLastError(), GetLastError());
616 para.HashAlgorithm.pszObjId = oid_rsa_md5;
617 /* With a valid hash algorithm, this succeeds, even though fDetached is
618 * FALSE.
620 SetLastError(0xdeadbeef);
621 ret = CryptHashMessage(&para, FALSE, 2, toHash, hashSize, NULL,
622 &hashedBlobSize, NULL, NULL);
623 todo_wine
624 ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError());
625 if (ret)
627 /* Actually attempting to get the hashed data fails, perhaps because
628 * detached is FALSE.
630 hashedBlob = HeapAlloc(GetProcessHeap(), 0, hashedBlobSize);
631 SetLastError(0xdeadbeef);
632 ret = CryptHashMessage(&para, FALSE, 2, toHash, hashSize, hashedBlob,
633 &hashedBlobSize, NULL, NULL);
634 ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
635 "expected CRYPT_E_MSG_ERROR, got 0x%08x (%d)\n", GetLastError(),
636 GetLastError());
637 HeapFree(GetProcessHeap(), 0, hashedBlob);
639 /* Repeating tests with fDetached = TRUE results in success */
640 SetLastError(0xdeadbeef);
641 ret = CryptHashMessage(&para, TRUE, 2, toHash, hashSize, NULL,
642 &hashedBlobSize, NULL, NULL);
643 ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError());
644 if (ret)
646 hashedBlob = HeapAlloc(GetProcessHeap(), 0, hashedBlobSize);
647 SetLastError(0xdeadbeef);
648 ret = CryptHashMessage(&para, TRUE, 2, toHash, hashSize, hashedBlob,
649 &hashedBlobSize, NULL, NULL);
650 ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError());
651 ok(hashedBlobSize == sizeof(detachedHashBlob),
652 "unexpected size of detached blob %d\n", hashedBlobSize);
653 ok(!memcmp(hashedBlob, detachedHashBlob, hashedBlobSize),
654 "unexpected detached blob value\n");
655 HeapFree(GetProcessHeap(), 0, hashedBlob);
657 /* Hashing a single item with fDetached = FALSE also succeeds */
658 SetLastError(0xdeadbeef);
659 ret = CryptHashMessage(&para, FALSE, 1, toHash, hashSize, NULL,
660 &hashedBlobSize, NULL, NULL);
661 ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError());
662 if (ret)
664 hashedBlob = HeapAlloc(GetProcessHeap(), 0, hashedBlobSize);
665 ret = CryptHashMessage(&para, FALSE, 1, toHash, hashSize, hashedBlob,
666 &hashedBlobSize, NULL, NULL);
667 ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError());
668 ok(hashedBlobSize == sizeof(hashBlob),
669 "unexpected size of detached blob %d\n", hashedBlobSize);
670 ok(!memcmp(hashedBlob, hashBlob, hashedBlobSize),
671 "unexpected detached blob value\n");
672 HeapFree(GetProcessHeap(), 0, hashedBlob);
674 /* Check the computed hash value too. You don't need to get the encoded
675 * blob to get it.
677 computedHashSize = 0xdeadbeef;
678 ret = CryptHashMessage(&para, TRUE, 2, toHash, hashSize, NULL,
679 &hashedBlobSize, NULL, &computedHashSize);
680 ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError());
681 ok(computedHashSize == 16, "expected hash size of 16, got %d\n",
682 computedHashSize);
683 if (ret)
685 computedHash = HeapAlloc(GetProcessHeap(), 0, computedHashSize);
686 SetLastError(0xdeadbeef);
687 ret = CryptHashMessage(&para, TRUE, 2, toHash, hashSize, NULL,
688 &hashedBlobSize, computedHash, &computedHashSize);
689 ok(computedHashSize == sizeof(hashVal),
690 "unexpected size of hash value %d\n", computedHashSize);
691 ok(!memcmp(computedHash, hashVal, computedHashSize),
692 "unexpected value\n");
693 HeapFree(GetProcessHeap(), 0, computedHash);
697 START_TEST(message)
699 test_msg_get_signer_count();
700 test_verify_detached_message_hash();
701 test_verify_message_hash();
702 test_verify_detached_message_signature();
703 test_verify_message_signature();
704 test_hash_message();