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 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
64 SetLastError(0xdeadbeef);
65 count
= CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING
,
66 dataEmptyBareContent
, sizeof(dataEmptyBareContent
));
67 ok(count
== -1, "Expected -1, got %d\n", count
);
68 ok(GetLastError() == CRYPT_E_ASN1_BADTAG
,
69 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
70 SetLastError(0xdeadbeef);
71 count
= CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING
,
72 dataEmptyContent
, sizeof(dataEmptyContent
));
73 ok(count
== -1, "Expected -1, got %d\n", count
);
74 ok(GetLastError() == CRYPT_E_INVALID_MSG_TYPE
,
75 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
76 SetLastError(0xdeadbeef);
77 count
= CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING
,
78 signedEmptyBareContent
, sizeof(signedEmptyBareContent
));
79 ok(count
== -1, "Expected -1, got %d\n", count
);
80 ok(GetLastError() == CRYPT_E_ASN1_BADTAG
,
81 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
82 count
= CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING
,
83 signedEmptyContent
, sizeof(signedEmptyContent
));
84 ok(count
== 1, "Expected 1, got %d\n", count
);
87 static BYTE detachedHashContent
[] = {
88 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
89 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
90 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
91 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
92 0x9d,0x2a,0x8f,0x26,0x2f };
93 static const BYTE msgData
[] = { 1, 2, 3, 4 };
95 static void test_verify_detached_message_hash(void)
98 CRYPT_HASH_MESSAGE_PARA para
;
100 const BYTE
*pMsgData
= msgData
;
105 ret
= CryptVerifyDetachedMessageHash(NULL
, NULL
, 0, 0, NULL
, NULL
, NULL
,
108 memset(¶
, 0, sizeof(para
));
109 SetLastError(0xdeadbeef);
110 ret
= CryptVerifyDetachedMessageHash(¶
, NULL
, 0, 0, NULL
, NULL
, NULL
,
112 ok(!ret
&& GetLastError() == E_INVALIDARG
,
113 "expected E_INVALIDARG, got %08x\n", GetLastError());
114 para
.cbSize
= sizeof(para
);
115 SetLastError(0xdeadbeef);
116 ret
= CryptVerifyDetachedMessageHash(¶
, NULL
, 0, 0, NULL
, NULL
, NULL
,
118 ok(!ret
&& GetLastError() == E_INVALIDARG
,
119 "expected E_INVALIDARG, got %08x\n", GetLastError());
120 para
.dwMsgEncodingType
= PKCS_7_ASN_ENCODING
;
121 SetLastError(0xdeadbeef);
122 ret
= CryptVerifyDetachedMessageHash(¶
, NULL
, 0, 0, NULL
, NULL
, NULL
,
124 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_EOD
,
125 "expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
126 para
.dwMsgEncodingType
= X509_ASN_ENCODING
;
127 SetLastError(0xdeadbeef);
128 ret
= CryptVerifyDetachedMessageHash(¶
, NULL
, 0, 0, NULL
, NULL
, NULL
,
130 ok(!ret
&& GetLastError() == E_INVALIDARG
,
131 "expected E_INVALIDARG, got %08x\n", GetLastError());
132 para
.dwMsgEncodingType
= X509_ASN_ENCODING
| PKCS_7_ASN_ENCODING
;
133 SetLastError(0xdeadbeef);
134 ret
= CryptVerifyDetachedMessageHash(¶
, NULL
, 0, 0, NULL
, NULL
, NULL
,
136 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_EOD
,
137 "expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
138 /* Curiously, passing no data to hash succeeds.. */
139 ret
= CryptVerifyDetachedMessageHash(¶
, detachedHashContent
,
140 sizeof(detachedHashContent
), 0, NULL
, NULL
, NULL
, NULL
);
142 ok(ret
, "CryptVerifyDetachedMessageHash failed: %08x\n", GetLastError());
143 /* as does passing the actual content of the message to hash.. */
144 size
= sizeof(msgData
);
146 ret
= CryptVerifyDetachedMessageHash(¶
, detachedHashContent
,
147 sizeof(detachedHashContent
), 1, &pMsgData
, &size
, NULL
, NULL
);
148 ok(ret
, "CryptVerifyDetachedMessageHash failed: %08x\n", GetLastError());
149 /* while passing data to hash that isn't the content of the message fails.
151 size
= sizeof(detachedHashContent
);
152 pMsgData
= detachedHashContent
;
153 SetLastError(0xdeadbeef);
154 ret
= CryptVerifyDetachedMessageHash(¶
, detachedHashContent
,
155 sizeof(detachedHashContent
), 1, &pMsgData
, &size
, NULL
, NULL
);
156 ok(!ret
&& GetLastError() == CRYPT_E_HASH_VALUE
,
157 "expected CRYPT_E_HASH_VALUE, got %08x\n", GetLastError());
158 /* Getting the size of the hash while passing no hash data causes the
159 * hash to be checked (and fail.)
161 SetLastError(0xdeadbeef);
162 ret
= CryptVerifyDetachedMessageHash(¶
, detachedHashContent
,
163 sizeof(detachedHashContent
), 0, NULL
, NULL
, NULL
, &hashSize
);
164 ok(!ret
&& GetLastError() == CRYPT_E_HASH_VALUE
,
165 "expected CRYPT_E_HASH_VALUE, got %08x\n", GetLastError());
166 size
= sizeof(msgData
);
168 ret
= CryptVerifyDetachedMessageHash(¶
, detachedHashContent
,
169 sizeof(detachedHashContent
), 1, &pMsgData
, &size
, NULL
, &hashSize
);
170 ok(ret
, "CryptVerifyDetachedMessageHash failed: %08x\n", GetLastError());
171 ok(hashSize
== sizeof(hash
), "unexpected size %d\n", hashSize
);
173 SetLastError(0xdeadbeef);
174 ret
= CryptVerifyDetachedMessageHash(¶
, detachedHashContent
,
175 sizeof(detachedHashContent
), 1, &pMsgData
, &size
, hash
, &hashSize
);
176 ok(!ret
&& GetLastError() == ERROR_MORE_DATA
,
177 "expected ERROR_MORE_DATA, got %08x\n", GetLastError());
178 hashSize
= sizeof(hash
);
179 ret
= CryptVerifyDetachedMessageHash(¶
, detachedHashContent
,
180 sizeof(detachedHashContent
), 1, &pMsgData
, &size
, hash
, &hashSize
);
181 ok(ret
, "CryptVerifyDetachedMessageHash failed: %08x\n", GetLastError());
184 static const BYTE signedContent
[] = {
185 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
186 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
187 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
188 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
189 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
190 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
191 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
192 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
193 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
194 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
195 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
196 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
198 static const BYTE signedWithCertEmptyContent
[] = {
199 0x30,0x81,0xdf,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
200 0x81,0xd1,0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
201 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,
202 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
203 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
204 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
205 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
206 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
207 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
208 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
209 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
210 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
211 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
212 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
213 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
215 static const BYTE signedWithCertContent
[] = {
216 0x30,0x82,0x01,0x32,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
217 0xa0,0x82,0x01,0x23,0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
218 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
219 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
220 0x02,0x03,0x04,0xa0,0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
221 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
222 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
223 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
224 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
225 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
226 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,
227 0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,
228 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,
229 0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,
230 0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,
231 0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,
232 0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,
233 0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,
234 0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,
235 0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,
236 0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
237 static const BYTE signedWithCertWithPubKeyContent
[] = {
238 0x30,0x81,0xfc,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
239 0x81,0xee,0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
240 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,
241 0x98,0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,
242 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
243 0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
244 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
245 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,
246 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
247 0x6e,0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
248 0x01,0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,
249 0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,
250 0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,
251 0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
252 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
253 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
254 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
256 static void test_verify_message_signature(void)
259 CRYPT_VERIFY_MESSAGE_PARA para
= { 0 };
263 SetLastError(0xdeadbeef);
264 ret
= CryptVerifyMessageSignature(NULL
, 0, NULL
, 0, NULL
, 0, NULL
);
265 ok(!ret
&& GetLastError() == E_INVALIDARG
,
266 "Expected E_INVALIDARG, got %08x\n", GetLastError());
267 SetLastError(0xdeadbeef);
268 ret
= CryptVerifyMessageSignature(¶
, 0, NULL
, 0, NULL
, 0, NULL
);
269 ok(!ret
&& GetLastError() == E_INVALIDARG
,
270 "Expected E_INVALIDARG, got %08x\n", GetLastError());
271 para
.cbSize
= sizeof(para
);
272 SetLastError(0xdeadbeef);
273 ret
= CryptVerifyMessageSignature(¶
, 0, NULL
, 0, NULL
, 0, NULL
);
274 ok(!ret
&& GetLastError() == E_INVALIDARG
,
275 "Expected E_INVALIDARG, got %08x\n", GetLastError());
277 para
.dwMsgAndCertEncodingType
= PKCS_7_ASN_ENCODING
;
278 SetLastError(0xdeadbeef);
279 ret
= CryptVerifyMessageSignature(¶
, 0, NULL
, 0, NULL
, 0, NULL
);
280 ok(!ret
&& GetLastError() == E_INVALIDARG
,
281 "Expected E_INVALIDARG, got %08x\n", GetLastError());
282 para
.cbSize
= sizeof(para
);
283 SetLastError(0xdeadbeef);
284 ret
= CryptVerifyMessageSignature(¶
, 0, NULL
, 0, NULL
, 0, NULL
);
285 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_EOD
,
286 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
287 /* Check whether cert is set on error */
288 cert
= (PCCERT_CONTEXT
)0xdeadbeef;
289 ret
= CryptVerifyMessageSignature(¶
, 0, NULL
, 0, NULL
, 0, &cert
);
290 ok(cert
== NULL
, "Expected NULL cert\n");
291 /* Check whether cbDecoded is set on error */
292 cbDecoded
= 0xdeadbeef;
293 ret
= CryptVerifyMessageSignature(¶
, 0, NULL
, 0, NULL
, &cbDecoded
,
295 ok(!cbDecoded
, "Expected 0\n");
296 SetLastError(0xdeadbeef);
297 ret
= CryptVerifyMessageSignature(¶
, 0, dataEmptyBareContent
,
298 sizeof(dataEmptyBareContent
), NULL
, 0, NULL
);
299 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_BADTAG
,
300 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
301 SetLastError(0xdeadbeef);
302 ret
= CryptVerifyMessageSignature(¶
, 0, dataEmptyContent
,
303 sizeof(dataEmptyContent
), NULL
, 0, NULL
);
304 ok(!ret
&& GetLastError() == CRYPT_E_UNEXPECTED_MSG_TYPE
,
305 "Expected CRYPT_E_UNEXPECTED_MSG_TYPE, got %08x\n", GetLastError());
306 SetLastError(0xdeadbeef);
307 ret
= CryptVerifyMessageSignature(¶
, 0, signedEmptyBareContent
,
308 sizeof(signedEmptyBareContent
), NULL
, 0, NULL
);
309 ok(!ret
&& GetLastError() == CRYPT_E_ASN1_BADTAG
,
310 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
311 SetLastError(0xdeadbeef);
312 ret
= CryptVerifyMessageSignature(¶
, 0, signedEmptyContent
,
313 sizeof(signedEmptyContent
), NULL
, 0, NULL
);
314 ok(!ret
&& GetLastError() == CRYPT_E_NOT_FOUND
,
315 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
316 SetLastError(0xdeadbeef);
317 ret
= CryptVerifyMessageSignature(¶
, 0, signedContent
,
318 sizeof(signedContent
), NULL
, 0, NULL
);
319 ok(!ret
&& GetLastError() == CRYPT_E_NOT_FOUND
,
320 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
321 /* FIXME: Windows fails with CRYPT_E_NOT_FOUND for these messages, but
322 * their signer certs have invalid public keys that fail to decode. In
323 * Wine therefore the failure is an ASN error. Need some messages with
324 * valid public keys and invalid signatures to check against.
326 ret
= CryptVerifyMessageSignature(¶
, 0, signedWithCertEmptyContent
,
327 sizeof(signedWithCertEmptyContent
), NULL
, 0, NULL
);
328 ok(!ret
, "Expected failure\n");
329 ret
= CryptVerifyMessageSignature(¶
, 0, signedWithCertContent
,
330 sizeof(signedWithCertContent
), NULL
, 0, NULL
);
331 ok(!ret
, "Expected failure\n");
332 ret
= CryptVerifyMessageSignature(¶
, 0, signedWithCertWithPubKeyContent
,
333 sizeof(signedWithCertWithPubKeyContent
), NULL
, 0, NULL
);
334 ok(!ret
, "Expected failure\n");
337 static const BYTE detachedHashBlob
[] = {
338 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
339 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
340 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
341 0x07,0x01,0x04,0x10,0x2d,0x1b,0xbc,0x1f,0xc7,0xab,0x36,0x8d,0xdb,0x95,0xe6,
342 0x24,0xb9,0x66,0x7c,0x21 };
343 static const BYTE hashBlob
[] = {
344 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
345 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
346 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
347 0x07,0x01,0xa0,0x06,0x04,0x04,0xde,0xad,0xbe,0xef,0x04,0x10,0x2f,0x24,0x92,
348 0x30,0xa8,0xe7,0xc2,0xbf,0x60,0x05,0xcc,0xd2,0x67,0x92,0x59,0xec };
349 static const BYTE hashVal
[] = {
350 0x2d,0x1b,0xbc,0x1f,0xc7,0xab,0x36,0x8d,0xdb,0x95,0xe6,0x24,0xb9,0x66,0x7c,
353 static void test_hash_message(void)
356 CRYPT_HASH_MESSAGE_PARA para
;
357 static const BYTE blob1
[] = { 0xde, 0xad, 0xbe, 0xef };
358 static const BYTE blob2
[] = { 0xba, 0xad, 0xf0, 0x0d };
359 const BYTE
*toHash
[] = { blob1
, blob2
};
360 DWORD hashSize
[] = { sizeof(blob1
), sizeof(blob2
) };
361 DWORD hashedBlobSize
, computedHashSize
;
362 static char oid_rsa_md5
[] = szOID_RSA_MD5
;
363 LPBYTE hashedBlob
, computedHash
;
366 ret = CryptHashMessage(NULL, FALSE, 0, NULL, 0, NULL, NULL, NULL, NULL);
368 memset(¶
, 0, sizeof(para
));
369 SetLastError(0xdeadbeef);
370 ret
= CryptHashMessage(¶
, FALSE
, 0, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
371 ok(!ret
&& GetLastError() == E_INVALIDARG
,
372 "expected E_INVALIDARG, got 0x%08x\n", GetLastError());
373 para
.cbSize
= sizeof(para
);
374 /* Not quite sure what "success" means in this case, but it does succeed */
375 SetLastError(0xdeadbeef);
376 ret
= CryptHashMessage(¶
, FALSE
, 0, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
377 ok(ret
, "CryptHashMessage failed: 0x%08x\n", GetLastError());
378 /* With a bogus encoding type it "succeeds" */
379 para
.dwMsgEncodingType
= 0xdeadbeef;
380 SetLastError(0xdeadbeef);
381 ret
= CryptHashMessage(¶
, FALSE
, 0, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
382 ok(ret
, "CryptHashMessage failed: 0x%08x\n", GetLastError());
383 /* According to MSDN, the third parameter (cToBeHashed) must be 1 if the
384 * second parameter (fDetached) is FALSE, but again it "succeeds."
386 SetLastError(0xdeadbeef);
387 ret
= CryptHashMessage(¶
, FALSE
, 2, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
388 ok(ret
, "CryptHashMessage failed: 0x%08x\n", GetLastError());
389 /* Even passing parameters to hash results in "success." */
390 SetLastError(0xdeadbeef);
391 ret
= CryptHashMessage(¶
, FALSE
, 2, toHash
, hashSize
, NULL
, NULL
, NULL
,
393 /* Try again with a valid encoding type */
394 para
.dwMsgEncodingType
= PKCS_7_ASN_ENCODING
;
395 SetLastError(0xdeadbeef);
396 ret
= CryptHashMessage(¶
, FALSE
, 2, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
397 ok(ret
, "CryptHashMessage failed: 0x%08x\n", GetLastError());
398 /* And with valid data to hash */
399 SetLastError(0xdeadbeef);
400 ret
= CryptHashMessage(¶
, FALSE
, 2, toHash
, hashSize
, NULL
, NULL
, NULL
,
402 ok(ret
, "CryptHashMessage failed: 0x%08x\n", GetLastError());
403 /* But requesting the size of the hashed blob and indicating there's data
404 * to hash results in a crash
408 ret
= CryptHashMessage(¶
, FALSE
, 2, NULL
, NULL
, NULL
,
409 &hashedBlobSize
, NULL
, NULL
);
411 /* Passing a valid pointer for the data to hash fails, as the hash
412 * algorithm is finally checked.
414 SetLastError(0xdeadbeef);
415 ret
= CryptHashMessage(¶
, FALSE
, 2, toHash
, hashSize
, NULL
,
416 &hashedBlobSize
, NULL
, NULL
);
417 ok(!ret
&& GetLastError() == CRYPT_E_UNKNOWN_ALGO
,
418 "expected CRYPT_E_UNKNOWN_ALGO, got 0x%08x (%d)\n", GetLastError(),
420 para
.HashAlgorithm
.pszObjId
= oid_rsa_md5
;
421 /* With a valid hash algorithm, this succeeds, even though fDetached is
424 SetLastError(0xdeadbeef);
425 ret
= CryptHashMessage(¶
, FALSE
, 2, toHash
, hashSize
, NULL
,
426 &hashedBlobSize
, NULL
, NULL
);
428 ok(ret
, "CryptHashMessage failed: 0x%08x\n", GetLastError());
431 /* Actually attempting to get the hashed data fails, perhaps because
434 hashedBlob
= HeapAlloc(GetProcessHeap(), 0, hashedBlobSize
);
435 SetLastError(0xdeadbeef);
436 ret
= CryptHashMessage(¶
, FALSE
, 2, toHash
, hashSize
, hashedBlob
,
437 &hashedBlobSize
, NULL
, NULL
);
438 ok(!ret
&& GetLastError() == CRYPT_E_MSG_ERROR
,
439 "expected CRYPT_E_MSG_ERROR, got 0x%08x (%d)\n", GetLastError(),
441 HeapFree(GetProcessHeap(), 0, hashedBlob
);
443 /* Repeating tests with fDetached = TRUE results in success */
444 SetLastError(0xdeadbeef);
445 ret
= CryptHashMessage(¶
, TRUE
, 2, toHash
, hashSize
, NULL
,
446 &hashedBlobSize
, NULL
, NULL
);
447 ok(ret
, "CryptHashMessage failed: 0x%08x\n", GetLastError());
450 hashedBlob
= HeapAlloc(GetProcessHeap(), 0, hashedBlobSize
);
451 SetLastError(0xdeadbeef);
452 ret
= CryptHashMessage(¶
, TRUE
, 2, toHash
, hashSize
, hashedBlob
,
453 &hashedBlobSize
, NULL
, NULL
);
454 ok(ret
, "CryptHashMessage failed: 0x%08x\n", GetLastError());
455 ok(hashedBlobSize
== sizeof(detachedHashBlob
),
456 "unexpected size of detached blob %d\n", hashedBlobSize
);
457 ok(!memcmp(hashedBlob
, detachedHashBlob
, hashedBlobSize
),
458 "unexpected detached blob value\n");
459 HeapFree(GetProcessHeap(), 0, hashedBlob
);
461 /* Hashing a single item with fDetached = FALSE also succeeds */
462 SetLastError(0xdeadbeef);
463 ret
= CryptHashMessage(¶
, FALSE
, 1, toHash
, hashSize
, NULL
,
464 &hashedBlobSize
, NULL
, NULL
);
465 ok(ret
, "CryptHashMessage failed: 0x%08x\n", GetLastError());
468 hashedBlob
= HeapAlloc(GetProcessHeap(), 0, hashedBlobSize
);
469 ret
= CryptHashMessage(¶
, FALSE
, 1, toHash
, hashSize
, hashedBlob
,
470 &hashedBlobSize
, NULL
, NULL
);
471 ok(ret
, "CryptHashMessage failed: 0x%08x\n", GetLastError());
472 ok(hashedBlobSize
== sizeof(hashBlob
),
473 "unexpected size of detached blob %d\n", hashedBlobSize
);
474 ok(!memcmp(hashedBlob
, hashBlob
, hashedBlobSize
),
475 "unexpected detached blob value\n");
476 HeapFree(GetProcessHeap(), 0, hashedBlob
);
478 /* Check the computed hash value too. You don't need to get the encoded
481 computedHashSize
= 0xdeadbeef;
482 ret
= CryptHashMessage(¶
, TRUE
, 2, toHash
, hashSize
, NULL
,
483 &hashedBlobSize
, NULL
, &computedHashSize
);
484 ok(ret
, "CryptHashMessage failed: 0x%08x\n", GetLastError());
485 ok(computedHashSize
== 16, "expected hash size of 16, got %d\n",
489 computedHash
= HeapAlloc(GetProcessHeap(), 0, computedHashSize
);
490 SetLastError(0xdeadbeef);
491 ret
= CryptHashMessage(¶
, TRUE
, 2, toHash
, hashSize
, NULL
,
492 &hashedBlobSize
, computedHash
, &computedHashSize
);
493 ok(computedHashSize
== sizeof(hashVal
),
494 "unexpected size of hash value %d\n", computedHashSize
);
495 ok(!memcmp(computedHash
, hashVal
, computedHashSize
),
496 "unexpected value\n");
497 HeapFree(GetProcessHeap(), 0, computedHash
);
503 test_msg_get_signer_count();
504 test_verify_detached_message_hash();
505 test_verify_message_signature();