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
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,
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)
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",
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
));
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)
103 CRYPT_HASH_MESSAGE_PARA para
;
104 DWORD size
, hashSize
;
105 const BYTE
*pMsgData
= msgData
;
110 ret
= CryptVerifyDetachedMessageHash(NULL
, NULL
, 0, 0, NULL
, NULL
, NULL
,
113 memset(¶
, 0, sizeof(para
));
114 SetLastError(0xdeadbeef);
115 ret
= CryptVerifyDetachedMessageHash(¶
, NULL
, 0, 0, NULL
, NULL
, 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(¶
, NULL
, 0, 0, NULL
, NULL
, 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(¶
, NULL
, 0, 0, NULL
, NULL
, NULL
,
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(¶
, NULL
, 0, 0, NULL
, NULL
, 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(¶
, NULL
, 0, 0, NULL
, NULL
, NULL
,
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(¶
, detachedHashContent
,
149 sizeof(detachedHashContent
), 0, NULL
, NULL
, NULL
, NULL
);
151 ok(ret
, "CryptVerifyDetachedMessageHash failed: %08x\n", GetLastError());
152 /* as does passing the actual content of the message to hash.. */
153 size
= sizeof(msgData
);
155 ret
= CryptVerifyDetachedMessageHash(¶
, 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(¶
, 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(¶
, 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
);
177 ret
= CryptVerifyDetachedMessageHash(¶
, 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
);
182 SetLastError(0xdeadbeef);
183 ret
= CryptVerifyDetachedMessageHash(¶
, 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(¶
, 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)
203 CRYPT_HASH_MESSAGE_PARA para
;
207 memset(¶
, 0, sizeof(para
));
210 ret
= CryptVerifyMessageHash(NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
211 SetLastError(0xdeadbeef);
212 ret
= CryptVerifyMessageHash(¶
, 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(¶
, 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(¶
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
223 ok(!ret
, "Expected 0, got %d\n", ret
);
224 ok(GetLastError() == CRYPT_E_ASN1_EOD
||
225 GetLastError() == OSS_BAD_ARG
, /* win98 */
226 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
227 /* Verifying the hash of a detached message succeeds? */
228 ret
= CryptVerifyMessageHash(¶
, detachedHashContent
,
229 sizeof(detachedHashContent
), NULL
, NULL
, NULL
, NULL
);
231 ok(ret
, "CryptVerifyMessageHash failed: %08x\n", GetLastError());
232 /* As does verifying the hash of a regular message. */
233 ret
= CryptVerifyMessageHash(¶
, hashContent
, sizeof(hashContent
),
234 NULL
, NULL
, NULL
, NULL
);
235 ok(ret
, "CryptVerifyMessageHash failed: %08x\n", GetLastError());
236 ret
= CryptVerifyMessageHash(¶
, hashContent
, sizeof(hashContent
),
237 NULL
, &size
, NULL
, NULL
);
238 ok(ret
, "CryptVerifyMessageHash failed: %08x\n", GetLastError());
240 buf
= CryptMemAlloc(size
);
244 ret
= CryptVerifyMessageHash(¶
, hashContent
, sizeof(hashContent
),
245 buf
, &size
, NULL
, NULL
);
246 ok(!ret
&& GetLastError() == ERROR_MORE_DATA
,
247 "expected ERROR_MORE_DATA, got %08x\n", GetLastError());
248 ret
= CryptVerifyMessageHash(¶
, hashContent
, sizeof(hashContent
),
249 buf
, &size
, NULL
, NULL
);
250 ok(ret
, "CryptVerifyMessageHash failed: %08x\n", GetLastError());
251 ok(size
== sizeof(msgData
), "unexpected size %d\n", size
);
252 ok(!memcmp(buf
, msgData
, size
), "unexpected value\n");
257 static const BYTE signedWithCertContent
[] = {
258 0x30,0x82,0x01,0x32,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
259 0xa0,0x82,0x01,0x23,0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
260 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
261 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
262 0x02,0x03,0x04,0xa0,0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
263 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
264 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
265 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
266 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
267 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
268 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,
269 0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,
270 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,
271 0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,
272 0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,
273 0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,
274 0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,
275 0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,
276 0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,
277 0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,
278 0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
279 static const BYTE signedContent
[] = {
280 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
281 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
282 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
283 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
284 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
285 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
286 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
287 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
288 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
289 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
290 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
291 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
293 static const BYTE detachedSignedContent
[] = {
294 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
295 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
296 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
297 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
298 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
299 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
300 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
301 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
302 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
303 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
304 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
305 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
306 static const BYTE v1CertWithValidPubKey
[] = {
307 0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
308 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
309 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
310 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
311 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
312 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
313 0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
314 0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,
315 0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,
316 0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,
317 0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,
318 0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,
319 0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
320 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
322 static PCCERT_CONTEXT WINAPI
msg_get_signer_callback(void *pvArg
,
323 DWORD certEncodingType
, PCERT_INFO signerId
, HCERTSTORE store
)
325 return CertCreateCertificateContext(X509_ASN_ENCODING
,
326 v1CertWithValidPubKey
, sizeof(v1CertWithValidPubKey
));
329 static void test_verify_detached_message_signature(void)
331 CRYPT_VERIFY_MESSAGE_PARA para
;
333 const BYTE
*pContent
;
336 memset(¶
, 0, sizeof(para
));
337 SetLastError(0xdeadbeef);
338 ret
= CryptVerifyDetachedMessageSignature(NULL
, 0, NULL
, 0, 0, NULL
,
340 ok(!ret
&& GetLastError() == E_INVALIDARG
,
341 "Expected E_INVALIDARG, got %08x\n", GetLastError());
342 SetLastError(0xdeadbeef);
343 ret
= CryptVerifyDetachedMessageSignature(¶
, 0, NULL
, 0, 0, NULL
,
345 ok(!ret
&& GetLastError() == E_INVALIDARG
,
346 "Expected E_INVALIDARG, got %08x\n", GetLastError());
347 para
.cbSize
= sizeof(para
);
348 SetLastError(0xdeadbeef);
349 ret
= CryptVerifyDetachedMessageSignature(¶
, 0, NULL
, 0, 0, NULL
,
351 ok(!ret
&& GetLastError() == E_INVALIDARG
,
352 "Expected E_INVALIDARG, got %08x\n", GetLastError());
353 para
.dwMsgAndCertEncodingType
= X509_ASN_ENCODING
;
354 SetLastError(0xdeadbeef);
355 ret
= CryptVerifyDetachedMessageSignature(¶
, 0, NULL
, 0, 0, NULL
,
357 ok(!ret
&& GetLastError() == E_INVALIDARG
,
358 "Expected E_INVALIDARG, got %08x\n", GetLastError());
359 para
.dwMsgAndCertEncodingType
= PKCS_7_ASN_ENCODING
;
360 SetLastError(0xdeadbeef);
361 ret
= CryptVerifyDetachedMessageSignature(¶
, 0, NULL
, 0, 0, NULL
,
363 ok(!ret
, "Expected 0, got %d\n", ret
);
364 ok(GetLastError() == CRYPT_E_ASN1_EOD
||
365 GetLastError() == OSS_BAD_ARG
, /* win98 */
366 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
367 /* None of these messages contains a cert in the message itself, so the
368 * default callback isn't able to verify their signature.
370 SetLastError(0xdeadbeef);
371 ret
= CryptVerifyDetachedMessageSignature(¶
, 0, signedWithCertContent
,
372 sizeof(signedWithCertContent
), 0, NULL
, NULL
, NULL
);
373 ok(!ret
, "Expected 0, got %d\n", ret
);
375 ok(GetLastError() == CRYPT_E_NOT_FOUND
||
376 GetLastError() == OSS_DATA_ERROR
, /* win98 */
377 "Expected CRYPT_E_NOT_FOUND or OSS_DATA_ERROR, got %08x\n", GetLastError());
378 SetLastError(0xdeadbeef);
379 ret
= CryptVerifyDetachedMessageSignature(¶
, 0, signedContent
,
380 sizeof(signedContent
), 0, NULL
, NULL
, NULL
);
381 ok(!ret
, "Expected 0, got %d\n", ret
);
382 ok(GetLastError() == CRYPT_E_NOT_FOUND
||
383 GetLastError() == OSS_DATA_ERROR
, /* win98 */
384 "Expected CRYPT_E_NOT_FOUND or OSS_DATA_ERROR, got %08x\n", GetLastError());
385 SetLastError(0xdeadbeef);
386 ret
= CryptVerifyDetachedMessageSignature(¶
, 0, detachedSignedContent
,
387 sizeof(detachedSignedContent
), 0, NULL
, NULL
, NULL
);
388 ok(!ret
, "Expected 0, got %d\n", ret
);
389 ok(GetLastError() == CRYPT_E_NOT_FOUND
||
390 GetLastError() == OSS_DATA_ERROR
, /* win98 */
391 "Expected CRYPT_E_NOT_FOUND or OSS_DATA_ERROR, got %08x\n", GetLastError());
392 SetLastError(0xdeadbeef);
394 cbContent
= sizeof(msgData
);
395 ret
= CryptVerifyDetachedMessageSignature(¶
, 0, detachedSignedContent
,
396 sizeof(detachedSignedContent
), 1, &pContent
, &cbContent
, NULL
);
397 ok(!ret
, "Expected 0, got %d\n", ret
);
398 ok(GetLastError() == CRYPT_E_NOT_FOUND
||
399 GetLastError() == OSS_DATA_ERROR
, /* win98 */
400 "Expected CRYPT_E_NOT_FOUND or OSS_DATA_ERROR, got %08x\n", GetLastError());
401 /* Passing the correct callback results in success */
402 para
.pfnGetSignerCertificate
= msg_get_signer_callback
;
403 ret
= CryptVerifyDetachedMessageSignature(¶
, 0, detachedSignedContent
,
404 sizeof(detachedSignedContent
), 1, &pContent
, &cbContent
, NULL
);
406 broken(!ret
), /* win98 */
407 "CryptVerifyDetachedMessageSignature failed: %08x\n",
409 /* Not passing the correct data to be signed results in the signature not
412 SetLastError(0xdeadbeef);
413 ret
= CryptVerifyDetachedMessageSignature(¶
, 0, detachedSignedContent
,
414 sizeof(detachedSignedContent
), 0, NULL
, NULL
, NULL
);
415 ok(!ret
, "Expected 0, got %d\n", ret
);
416 ok(GetLastError() == NTE_BAD_SIGNATURE
||
417 GetLastError() == OSS_DATA_ERROR
, /* win98 */
418 "Expected NTE_BAD_SIGNATURE or OSS_DATA_ERROR, got %08x\n", GetLastError());
421 static const BYTE signedWithCertEmptyContent
[] = {
422 0x30,0x81,0xdf,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
423 0x81,0xd1,0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
424 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,
425 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
426 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
427 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
428 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
429 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
430 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
431 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
432 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
433 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
434 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
435 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
436 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
438 static const BYTE signedWithCertWithPubKeyContent
[] = {
439 0x30,0x81,0xfc,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
440 0x81,0xee,0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
441 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,
442 0x98,0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,
443 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
444 0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
445 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
446 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,
447 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
448 0x6e,0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
449 0x01,0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,
450 0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,
451 0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,
452 0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
453 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
454 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
455 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
456 static const BYTE signedWithCertWithValidPubKeyContent
[] = {
457 0x30,0x82,0x01,0x89,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
458 0xa0,0x82,0x01,0x7a,0x30,0x82,0x01,0x76,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
459 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
460 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
461 0x02,0x03,0x04,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,
462 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
463 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
464 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
465 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
466 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
467 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,
468 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,
469 0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,
470 0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
471 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,
472 0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,
473 0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,
474 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
475 0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
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,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
478 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
479 0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,
480 0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,
481 0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,
482 0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,
483 0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
485 static void test_verify_message_signature(void)
488 CRYPT_VERIFY_MESSAGE_PARA para
= { 0 };
491 BYTE decoded
[sizeof(msgData
)];
493 SetLastError(0xdeadbeef);
494 ret
= CryptVerifyMessageSignature(NULL
, 0, NULL
, 0, NULL
, 0, NULL
);
495 ok(!ret
&& GetLastError() == E_INVALIDARG
,
496 "Expected E_INVALIDARG, got %08x\n", GetLastError());
497 /* Is cbDecoded set when invalid parameters are passed? */
498 cbDecoded
= 0xdeadbeef;
499 ret
= CryptVerifyMessageSignature(NULL
, 0, NULL
, 0, NULL
, &cbDecoded
,
501 ok(cbDecoded
== 0, "expected 0, got %08x\n", cbDecoded
);
502 SetLastError(0xdeadbeef);
503 ret
= CryptVerifyMessageSignature(¶
, 0, NULL
, 0, NULL
, 0, NULL
);
504 ok(!ret
&& GetLastError() == E_INVALIDARG
,
505 "Expected E_INVALIDARG, got %08x\n", GetLastError());
506 para
.cbSize
= sizeof(para
);
507 SetLastError(0xdeadbeef);
508 ret
= CryptVerifyMessageSignature(¶
, 0, NULL
, 0, NULL
, 0, NULL
);
509 ok(!ret
&& GetLastError() == E_INVALIDARG
,
510 "Expected E_INVALIDARG, got %08x\n", GetLastError());
512 para
.dwMsgAndCertEncodingType
= PKCS_7_ASN_ENCODING
;
513 SetLastError(0xdeadbeef);
514 ret
= CryptVerifyMessageSignature(¶
, 0, NULL
, 0, NULL
, 0, NULL
);
515 ok(!ret
&& GetLastError() == E_INVALIDARG
,
516 "Expected E_INVALIDARG, got %08x\n", GetLastError());
517 para
.cbSize
= sizeof(para
);
518 SetLastError(0xdeadbeef);
519 ret
= CryptVerifyMessageSignature(¶
, 0, NULL
, 0, NULL
, 0, NULL
);
521 (GetLastError() == CRYPT_E_ASN1_EOD
||
522 GetLastError() == OSS_BAD_ARG
), /* win9x */
523 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
524 /* Check whether cert is set on error */
525 cert
= (PCCERT_CONTEXT
)0xdeadbeef;
526 ret
= CryptVerifyMessageSignature(¶
, 0, NULL
, 0, NULL
, 0, &cert
);
527 ok(cert
== NULL
, "Expected NULL cert\n");
528 /* Check whether cbDecoded is set on error */
529 cbDecoded
= 0xdeadbeef;
530 ret
= CryptVerifyMessageSignature(¶
, 0, NULL
, 0, NULL
, &cbDecoded
,
532 ok(!cbDecoded
, "Expected 0\n");
533 SetLastError(0xdeadbeef);
534 ret
= CryptVerifyMessageSignature(¶
, 0, dataEmptyBareContent
,
535 sizeof(dataEmptyBareContent
), NULL
, 0, NULL
);
536 ok(GetLastError() == CRYPT_E_ASN1_BADTAG
||
537 GetLastError() == OSS_PDU_MISMATCH
, /* win9x */
538 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
539 SetLastError(0xdeadbeef);
540 ret
= CryptVerifyMessageSignature(¶
, 0, dataEmptyContent
,
541 sizeof(dataEmptyContent
), NULL
, 0, NULL
);
542 ok(!ret
&& GetLastError() == CRYPT_E_UNEXPECTED_MSG_TYPE
,
543 "Expected CRYPT_E_UNEXPECTED_MSG_TYPE, got %08x\n", GetLastError());
544 SetLastError(0xdeadbeef);
545 ret
= CryptVerifyMessageSignature(¶
, 0, signedEmptyBareContent
,
546 sizeof(signedEmptyBareContent
), NULL
, 0, NULL
);
548 (GetLastError() == CRYPT_E_ASN1_BADTAG
||
549 GetLastError() == OSS_DATA_ERROR
), /* win9x */
550 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
551 SetLastError(0xdeadbeef);
552 ret
= CryptVerifyMessageSignature(¶
, 0, signedEmptyContent
,
553 sizeof(signedEmptyContent
), NULL
, 0, NULL
);
555 (GetLastError() == CRYPT_E_NOT_FOUND
||
556 GetLastError() == OSS_DATA_ERROR
), /* win9x */
557 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
558 SetLastError(0xdeadbeef);
559 ret
= CryptVerifyMessageSignature(¶
, 0, signedContent
,
560 sizeof(signedContent
), NULL
, 0, NULL
);
562 (GetLastError() == CRYPT_E_NOT_FOUND
||
563 GetLastError() == OSS_DATA_ERROR
), /* win9x */
564 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
565 /* FIXME: Windows fails with CRYPT_E_NOT_FOUND for these messages, but
566 * their signer certs have invalid public keys that fail to decode. In
567 * Wine therefore the failure is an ASN error. Need some messages with
568 * valid public keys and invalid signatures to check against.
570 ret
= CryptVerifyMessageSignature(¶
, 0, signedWithCertEmptyContent
,
571 sizeof(signedWithCertEmptyContent
), NULL
, 0, NULL
);
572 ok(!ret
, "Expected failure\n");
573 ret
= CryptVerifyMessageSignature(¶
, 0, signedWithCertContent
,
574 sizeof(signedWithCertContent
), NULL
, 0, NULL
);
575 ok(!ret
, "Expected failure\n");
576 ret
= CryptVerifyMessageSignature(¶
, 0, signedWithCertWithPubKeyContent
,
577 sizeof(signedWithCertWithPubKeyContent
), NULL
, 0, NULL
);
578 ok(!ret
, "Expected failure\n");
579 /* Apparently, an output pcbDecoded parameter is expected. */
580 ret
= CryptVerifyMessageSignature(¶
, 0,
581 signedWithCertWithValidPubKeyContent
,
582 sizeof(signedWithCertWithValidPubKeyContent
), NULL
, 0, NULL
);
583 ok(!ret
, "Expected failure\n");
584 /* Finally, a message signed with a valid public key verifies successfully
586 cbDecoded
= 0xdeadbeef;
587 ret
= CryptVerifyMessageSignature(¶
, 0,
588 signedWithCertWithValidPubKeyContent
,
589 sizeof(signedWithCertWithValidPubKeyContent
), NULL
, &cbDecoded
, NULL
);
590 ok(ret
, "CryptVerifyMessageSignature failed: %08x\n", GetLastError());
591 ok(cbDecoded
== sizeof(msgData
), "expected 4, got %d\n", cbDecoded
);
593 ret
= CryptVerifyMessageSignature(¶
, 0,
594 signedWithCertWithValidPubKeyContent
,
595 sizeof(signedWithCertWithValidPubKeyContent
), NULL
, &cbDecoded
, NULL
);
596 /* Setting cbDecoded to 0 succeeds when a NULL buffer is provided */
597 ok(ret
, "CryptVerifyMessageSignature failed: %08x\n", GetLastError());
598 ok(cbDecoded
== sizeof(msgData
), "expected 4, got %d\n", cbDecoded
);
600 ret
= CryptVerifyMessageSignature(¶
, 0,
601 signedWithCertWithValidPubKeyContent
,
602 sizeof(signedWithCertWithValidPubKeyContent
), decoded
, &cbDecoded
, NULL
);
603 /* When a non-NULL buffer is provided, cbDecoded must not be too small */
604 ok(!ret
&& GetLastError() == ERROR_MORE_DATA
,
605 "expected ERROR_MORE_DATA, got %d (%08x)\n", GetLastError(),
609 static const BYTE detachedHashBlob
[] = {
610 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
611 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
612 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
613 0x07,0x01,0x04,0x10,0x2d,0x1b,0xbc,0x1f,0xc7,0xab,0x36,0x8d,0xdb,0x95,0xe6,
614 0x24,0xb9,0x66,0x7c,0x21 };
615 static const BYTE hashBlob
[] = {
616 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
617 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
618 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
619 0x07,0x01,0xa0,0x06,0x04,0x04,0xde,0xad,0xbe,0xef,0x04,0x10,0x2f,0x24,0x92,
620 0x30,0xa8,0xe7,0xc2,0xbf,0x60,0x05,0xcc,0xd2,0x67,0x92,0x59,0xec };
621 static const BYTE hashVal
[] = {
622 0x2d,0x1b,0xbc,0x1f,0xc7,0xab,0x36,0x8d,0xdb,0x95,0xe6,0x24,0xb9,0x66,0x7c,
625 static void test_hash_message(void)
628 CRYPT_HASH_MESSAGE_PARA para
;
629 static const BYTE blob1
[] = { 0xde, 0xad, 0xbe, 0xef };
630 static const BYTE blob2
[] = { 0xba, 0xad, 0xf0, 0x0d };
631 const BYTE
*toHash
[] = { blob1
, blob2
};
632 DWORD hashSize
[] = { sizeof(blob1
), sizeof(blob2
) };
633 DWORD hashedBlobSize
, computedHashSize
;
634 static char oid_rsa_md5
[] = szOID_RSA_MD5
;
635 LPBYTE hashedBlob
, computedHash
;
638 ret = CryptHashMessage(NULL, FALSE, 0, NULL, 0, NULL, NULL, NULL, NULL);
640 memset(¶
, 0, sizeof(para
));
641 SetLastError(0xdeadbeef);
642 ret
= CryptHashMessage(¶
, FALSE
, 0, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
643 ok(!ret
&& GetLastError() == E_INVALIDARG
,
644 "expected E_INVALIDARG, got 0x%08x\n", GetLastError());
645 para
.cbSize
= sizeof(para
);
646 /* Not quite sure what "success" means in this case, but it does succeed */
647 SetLastError(0xdeadbeef);
648 ret
= CryptHashMessage(¶
, FALSE
, 0, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
649 ok(ret
, "CryptHashMessage failed: 0x%08x\n", GetLastError());
650 /* With a bogus encoding type it "succeeds" */
651 para
.dwMsgEncodingType
= 0xdeadbeef;
652 SetLastError(0xdeadbeef);
653 ret
= CryptHashMessage(¶
, FALSE
, 0, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
654 ok(ret
, "CryptHashMessage failed: 0x%08x\n", GetLastError());
655 /* According to MSDN, the third parameter (cToBeHashed) must be 1 if the
656 * second parameter (fDetached) is FALSE, but again it "succeeds."
658 SetLastError(0xdeadbeef);
659 ret
= CryptHashMessage(¶
, FALSE
, 2, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
660 ok(ret
, "CryptHashMessage failed: 0x%08x\n", GetLastError());
661 /* Even passing parameters to hash results in "success." */
662 SetLastError(0xdeadbeef);
663 ret
= CryptHashMessage(¶
, FALSE
, 2, toHash
, hashSize
, NULL
, NULL
, NULL
,
665 /* Try again with a valid encoding type */
666 para
.dwMsgEncodingType
= PKCS_7_ASN_ENCODING
;
667 SetLastError(0xdeadbeef);
668 ret
= CryptHashMessage(¶
, FALSE
, 2, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
669 ok(ret
, "CryptHashMessage failed: 0x%08x\n", GetLastError());
670 /* And with valid data to hash */
671 SetLastError(0xdeadbeef);
672 ret
= CryptHashMessage(¶
, FALSE
, 2, toHash
, hashSize
, NULL
, NULL
, NULL
,
674 ok(ret
, "CryptHashMessage failed: 0x%08x\n", GetLastError());
675 /* But requesting the size of the hashed blob and indicating there's data
676 * to hash results in a crash
680 ret
= CryptHashMessage(¶
, FALSE
, 2, NULL
, NULL
, NULL
,
681 &hashedBlobSize
, NULL
, NULL
);
683 /* Passing a valid pointer for the data to hash fails, as the hash
684 * algorithm is finally checked.
686 SetLastError(0xdeadbeef);
687 ret
= CryptHashMessage(¶
, FALSE
, 2, toHash
, hashSize
, NULL
,
688 &hashedBlobSize
, NULL
, NULL
);
690 (GetLastError() == CRYPT_E_UNKNOWN_ALGO
||
691 GetLastError() == CRYPT_E_OID_FORMAT
), /* Vista */
692 "expected CRYPT_E_UNKNOWN_ALGO or CRYPT_E_OID_FORMAT, got 0x%08x (%d)\n",
693 GetLastError(), GetLastError());
694 para
.HashAlgorithm
.pszObjId
= oid_rsa_md5
;
695 /* With a valid hash algorithm, this succeeds, even though fDetached is
698 SetLastError(0xdeadbeef);
699 ret
= CryptHashMessage(¶
, FALSE
, 2, toHash
, hashSize
, NULL
,
700 &hashedBlobSize
, NULL
, NULL
);
702 ok(ret
, "CryptHashMessage failed: 0x%08x\n", GetLastError());
705 /* Actually attempting to get the hashed data fails, perhaps because
708 hashedBlob
= HeapAlloc(GetProcessHeap(), 0, hashedBlobSize
);
709 SetLastError(0xdeadbeef);
710 ret
= CryptHashMessage(¶
, FALSE
, 2, toHash
, hashSize
, hashedBlob
,
711 &hashedBlobSize
, NULL
, NULL
);
712 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
713 "expected CRYPT_E_MSG_ERROR, got 0x%08x (%d)\n", GetLastError(),
715 HeapFree(GetProcessHeap(), 0, hashedBlob
);
717 /* Repeating tests with fDetached = TRUE results in success */
718 SetLastError(0xdeadbeef);
719 ret
= CryptHashMessage(¶
, TRUE
, 2, toHash
, hashSize
, NULL
,
720 &hashedBlobSize
, NULL
, NULL
);
721 ok(ret
, "CryptHashMessage failed: 0x%08x\n", GetLastError());
724 hashedBlob
= HeapAlloc(GetProcessHeap(), 0, hashedBlobSize
);
725 SetLastError(0xdeadbeef);
726 ret
= CryptHashMessage(¶
, TRUE
, 2, toHash
, hashSize
, hashedBlob
,
727 &hashedBlobSize
, NULL
, NULL
);
728 ok(ret
, "CryptHashMessage failed: 0x%08x\n", GetLastError());
729 ok(hashedBlobSize
== sizeof(detachedHashBlob
),
730 "unexpected size of detached blob %d\n", hashedBlobSize
);
731 ok(!memcmp(hashedBlob
, detachedHashBlob
, hashedBlobSize
),
732 "unexpected detached blob value\n");
733 HeapFree(GetProcessHeap(), 0, hashedBlob
);
735 /* Hashing a single item with fDetached = FALSE also succeeds */
736 SetLastError(0xdeadbeef);
737 ret
= CryptHashMessage(¶
, FALSE
, 1, toHash
, hashSize
, NULL
,
738 &hashedBlobSize
, NULL
, NULL
);
739 ok(ret
, "CryptHashMessage failed: 0x%08x\n", GetLastError());
742 hashedBlob
= HeapAlloc(GetProcessHeap(), 0, hashedBlobSize
);
743 ret
= CryptHashMessage(¶
, FALSE
, 1, toHash
, hashSize
, hashedBlob
,
744 &hashedBlobSize
, NULL
, NULL
);
745 ok(ret
, "CryptHashMessage failed: 0x%08x\n", GetLastError());
746 ok(hashedBlobSize
== sizeof(hashBlob
),
747 "unexpected size of detached blob %d\n", hashedBlobSize
);
748 ok(!memcmp(hashedBlob
, hashBlob
, hashedBlobSize
),
749 "unexpected detached blob value\n");
750 HeapFree(GetProcessHeap(), 0, hashedBlob
);
752 /* Check the computed hash value too. You don't need to get the encoded
755 computedHashSize
= 0xdeadbeef;
756 ret
= CryptHashMessage(¶
, TRUE
, 2, toHash
, hashSize
, NULL
,
757 &hashedBlobSize
, NULL
, &computedHashSize
);
758 ok(ret
, "CryptHashMessage failed: 0x%08x\n", GetLastError());
759 ok(computedHashSize
== 16, "expected hash size of 16, got %d\n",
763 computedHash
= HeapAlloc(GetProcessHeap(), 0, computedHashSize
);
764 SetLastError(0xdeadbeef);
765 ret
= CryptHashMessage(¶
, TRUE
, 2, toHash
, hashSize
, NULL
,
766 &hashedBlobSize
, computedHash
, &computedHashSize
);
767 ok(computedHashSize
== sizeof(hashVal
),
768 "unexpected size of hash value %d\n", computedHashSize
);
769 ok(!memcmp(computedHash
, hashVal
, computedHashSize
),
770 "unexpected value\n");
771 HeapFree(GetProcessHeap(), 0, computedHash
);
777 test_msg_get_signer_count();
778 test_verify_detached_message_hash();
779 test_verify_message_hash();
780 test_verify_detached_message_signature();
781 test_verify_message_signature();