source: trunk/src/crypt32/message.c@ 21354

Last change on this file since 21354 was 21354, checked in by rlwalsh, 16 years ago

eliminate VACPP warning & info msgs - see Ticket #1

File size: 13.0 KB
Line 
1/*
2 * Copyright 2007 Juan Lang
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19#include <stdarg.h>
20#include <string.h>
21#include "windef.h"
22#include "winbase.h"
23#include "winerror.h"
24#include "wincrypt.h"
25
26#include "wine/debug.h"
27
28WINE_DEFAULT_DEBUG_CHANNEL(crypt);
29
30HCERTSTORE WINAPI CryptGetMessageCertificates(DWORD dwMsgAndCertEncodingType,
31 HCRYPTPROV_LEGACY hCryptProv, DWORD dwFlags, const BYTE* pbSignedBlob,
32 DWORD cbSignedBlob)
33{
34 CRYPT_DATA_BLOB blob = { cbSignedBlob, (LPBYTE)pbSignedBlob };
35
36 TRACE("(%08x, %ld, %d08x %p, %d)\n", dwMsgAndCertEncodingType, hCryptProv,
37 dwFlags, pbSignedBlob, cbSignedBlob);
38
39 return CertOpenStore(CERT_STORE_PROV_PKCS7, dwMsgAndCertEncodingType,
40 hCryptProv, dwFlags, &blob);
41}
42
43LONG WINAPI CryptGetMessageSignerCount(DWORD dwMsgEncodingType,
44 const BYTE *pbSignedBlob, DWORD cbSignedBlob)
45{
46 HCRYPTMSG msg;
47 LONG count = -1;
48
49 TRACE("(%08x, %p, %d)\n", dwMsgEncodingType, pbSignedBlob, cbSignedBlob);
50
51 msg = CryptMsgOpenToDecode(dwMsgEncodingType, 0, 0, 0, NULL, NULL);
52 if (msg)
53 {
54 if (CryptMsgUpdate(msg, pbSignedBlob, cbSignedBlob, TRUE))
55 {
56 DWORD size = sizeof(count);
57
58 CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &count, &size);
59 }
60 CryptMsgClose(msg);
61 }
62 return count;
63}
64
65static CERT_INFO *CRYPT_GetSignerCertInfoFromMsg(HCRYPTMSG msg,
66 DWORD dwSignerIndex)
67{
68 CERT_INFO *certInfo = NULL;
69 DWORD size;
70
71 if (CryptMsgGetParam(msg, CMSG_SIGNER_CERT_INFO_PARAM, dwSignerIndex, NULL,
72 &size))
73 {
74 certInfo = CryptMemAlloc(size);
75 if (certInfo)
76 {
77 if (!CryptMsgGetParam(msg, CMSG_SIGNER_CERT_INFO_PARAM,
78 dwSignerIndex, certInfo, &size))
79 {
80 CryptMemFree(certInfo);
81 certInfo = NULL;
82 }
83 }
84 }
85 else
86 SetLastError(CRYPT_E_UNEXPECTED_MSG_TYPE);
87 return certInfo;
88}
89
90static PCCERT_CONTEXT WINAPI CRYPT_DefaultGetSignerCertificate(void *pvGetArg,
91 DWORD dwCertEncodingType, PCERT_INFO pSignerId, HCERTSTORE hMsgCertStore)
92{
93 return CertFindCertificateInStore(hMsgCertStore, dwCertEncodingType, 0,
94 CERT_FIND_SUBJECT_CERT, pSignerId, NULL);
95}
96
97static inline PCCERT_CONTEXT CRYPT_GetSignerCertificate(HCRYPTMSG msg,
98 PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, PCERT_INFO certInfo, HCERTSTORE store)
99{
100 PFN_CRYPT_GET_SIGNER_CERTIFICATE getCert;
101
102 if (pVerifyPara->pfnGetSignerCertificate)
103 getCert = pVerifyPara->pfnGetSignerCertificate;
104 else
105 getCert = CRYPT_DefaultGetSignerCertificate;
106 return getCert(pVerifyPara->pvGetArg,
107 pVerifyPara->dwMsgAndCertEncodingType, certInfo, store);
108}
109
110BOOL WINAPI CryptVerifyDetachedMessageSignature(
111 PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, DWORD dwSignerIndex,
112 const BYTE *pbDetachedSignBlob, DWORD cbDetachedSignBlob, DWORD cToBeSigned,
113 const BYTE *rgpbToBeSigned[], DWORD rgcbToBeSigned[],
114 PCCERT_CONTEXT *ppSignerCert)
115{
116 BOOL ret = FALSE;
117 HCRYPTMSG msg;
118
119 TRACE("(%p, %d, %p, %d, %d, %p, %p, %p)\n", pVerifyPara, dwSignerIndex,
120 pbDetachedSignBlob, cbDetachedSignBlob, cToBeSigned, rgpbToBeSigned,
121 rgcbToBeSigned, ppSignerCert);
122
123 if (ppSignerCert)
124 *ppSignerCert = NULL;
125 if (!pVerifyPara ||
126 pVerifyPara->cbSize != sizeof(CRYPT_VERIFY_MESSAGE_PARA) ||
127 GET_CMSG_ENCODING_TYPE(pVerifyPara->dwMsgAndCertEncodingType) !=
128 PKCS_7_ASN_ENCODING)
129 {
130 SetLastError(E_INVALIDARG);
131 return FALSE;
132 }
133
134 msg = CryptMsgOpenToDecode(pVerifyPara->dwMsgAndCertEncodingType,
135 CMSG_DETACHED_FLAG, 0, pVerifyPara->hCryptProv, NULL, NULL);
136 if (msg)
137 {
138 ret = CryptMsgUpdate(msg, pbDetachedSignBlob, cbDetachedSignBlob, TRUE);
139 if (ret)
140 {
141 DWORD i;
142
143 for (i = 0; ret && i < cToBeSigned; i++)
144 ret = CryptMsgUpdate(msg, rgpbToBeSigned[i], rgcbToBeSigned[i],
145 i == cToBeSigned - 1 ? TRUE : FALSE);
146 }
147 if (ret)
148 {
149 CERT_INFO *certInfo = CRYPT_GetSignerCertInfoFromMsg(msg,
150 dwSignerIndex);
151
152 ret = FALSE;
153 if (certInfo)
154 {
155 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MSG,
156 pVerifyPara->dwMsgAndCertEncodingType,
157 pVerifyPara->hCryptProv, 0, msg);
158
159 if (store)
160 {
161 PCCERT_CONTEXT cert = CRYPT_GetSignerCertificate(
162 msg, pVerifyPara, certInfo, store);
163
164 if (cert)
165 {
166 ret = CryptMsgControl(msg, 0,
167 CMSG_CTRL_VERIFY_SIGNATURE, cert->pCertInfo);
168 if (ret && ppSignerCert)
169 *ppSignerCert = cert;
170 else
171 CertFreeCertificateContext(cert);
172 }
173 else
174 SetLastError(CRYPT_E_NOT_FOUND);
175 CertCloseStore(store, 0);
176 }
177 CryptMemFree(certInfo);
178 }
179 }
180 CryptMsgClose(msg);
181 }
182 TRACE("returning %d\n", ret);
183 return ret;
184}
185
186BOOL WINAPI CryptVerifyMessageSignature(PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
187 DWORD dwSignerIndex, const BYTE* pbSignedBlob, DWORD cbSignedBlob,
188 BYTE* pbDecoded, DWORD* pcbDecoded, PCCERT_CONTEXT* ppSignerCert)
189{
190 BOOL ret = FALSE;
191 HCRYPTMSG msg;
192
193 TRACE("(%p, %d, %p, %d, %p, %p, %p)\n",
194 pVerifyPara, dwSignerIndex, pbSignedBlob, cbSignedBlob,
195 pbDecoded, pcbDecoded, ppSignerCert);
196
197 if (ppSignerCert)
198 *ppSignerCert = NULL;
199 if (pcbDecoded)
200 *pcbDecoded = 0;
201 if (!pVerifyPara ||
202 pVerifyPara->cbSize != sizeof(CRYPT_VERIFY_MESSAGE_PARA) ||
203 GET_CMSG_ENCODING_TYPE(pVerifyPara->dwMsgAndCertEncodingType) !=
204 PKCS_7_ASN_ENCODING)
205 {
206 SetLastError(E_INVALIDARG);
207 return FALSE;
208 }
209
210 msg = CryptMsgOpenToDecode(pVerifyPara->dwMsgAndCertEncodingType, 0, 0,
211 pVerifyPara->hCryptProv, NULL, NULL);
212 if (msg)
213 {
214 ret = CryptMsgUpdate(msg, pbSignedBlob, cbSignedBlob, TRUE);
215 if (ret && pcbDecoded)
216 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, pbDecoded,
217 pcbDecoded);
218 if (ret)
219 {
220 CERT_INFO *certInfo = CRYPT_GetSignerCertInfoFromMsg(msg,
221 dwSignerIndex);
222
223 ret = FALSE;
224 if (certInfo)
225 {
226 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MSG,
227 pVerifyPara->dwMsgAndCertEncodingType,
228 pVerifyPara->hCryptProv, 0, msg);
229
230 if (store)
231 {
232 PCCERT_CONTEXT cert = CRYPT_GetSignerCertificate(
233 msg, pVerifyPara, certInfo, store);
234
235 if (cert)
236 {
237 ret = CryptMsgControl(msg, 0,
238 CMSG_CTRL_VERIFY_SIGNATURE, cert->pCertInfo);
239 if (ret && ppSignerCert)
240 *ppSignerCert = cert;
241 else
242 CertFreeCertificateContext(cert);
243 }
244 CertCloseStore(store, 0);
245 }
246 }
247 CryptMemFree(certInfo);
248 }
249 CryptMsgClose(msg);
250 }
251 TRACE("returning %d\n", ret);
252 return ret;
253}
254
255BOOL WINAPI CryptHashMessage(PCRYPT_HASH_MESSAGE_PARA pHashPara,
256 BOOL fDetachedHash, DWORD cToBeHashed, const BYTE *rgpbToBeHashed[],
257 DWORD rgcbToBeHashed[], BYTE *pbHashedBlob, DWORD *pcbHashedBlob,
258 BYTE *pbComputedHash, DWORD *pcbComputedHash)
259{
260 DWORD i, flags;
261 BOOL ret = FALSE;
262 HCRYPTMSG msg;
263 CMSG_HASHED_ENCODE_INFO info;
264
265 TRACE("(%p, %d, %d, %p, %p, %p, %p, %p, %p)\n", pHashPara, fDetachedHash,
266 cToBeHashed, rgpbToBeHashed, rgcbToBeHashed, pbHashedBlob, pcbHashedBlob,
267 pbComputedHash, pcbComputedHash);
268
269 if (pHashPara->cbSize != sizeof(CRYPT_HASH_MESSAGE_PARA))
270 {
271 SetLastError(E_INVALIDARG);
272 return FALSE;
273 }
274 /* Native seems to ignore any encoding type other than the expected
275 * PKCS_7_ASN_ENCODING
276 */
277 if (GET_CMSG_ENCODING_TYPE(pHashPara->dwMsgEncodingType) !=
278 PKCS_7_ASN_ENCODING)
279 return TRUE;
280 /* Native also seems to do nothing if the output parameter isn't given */
281 if (!pcbHashedBlob)
282 return TRUE;
283
284 flags = fDetachedHash ? CMSG_DETACHED_FLAG : 0;
285 memset(&info, 0, sizeof(info));
286 info.cbSize = sizeof(info);
287 info.hCryptProv = pHashPara->hCryptProv;
288 memcpy(&info.HashAlgorithm, &pHashPara->HashAlgorithm,
289 sizeof(info.HashAlgorithm));
290 info.pvHashAuxInfo = pHashPara->pvHashAuxInfo;
291 msg = CryptMsgOpenToEncode(pHashPara->dwMsgEncodingType, flags, CMSG_HASHED,
292 &info, NULL, NULL);
293 if (msg)
294 {
295 for (i = 0, ret = TRUE; ret && i < cToBeHashed; i++)
296 ret = CryptMsgUpdate(msg, rgpbToBeHashed[i], rgcbToBeHashed[i],
297 i == cToBeHashed - 1 ? TRUE : FALSE);
298 if (ret)
299 {
300 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, pbHashedBlob,
301 pcbHashedBlob);
302 if (ret && pcbComputedHash)
303 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0,
304 pbComputedHash, pcbComputedHash);
305 }
306 CryptMsgClose(msg);
307 }
308 return ret;
309}
310
311BOOL WINAPI CryptVerifyDetachedMessageHash(PCRYPT_HASH_MESSAGE_PARA pHashPara,
312 BYTE *pbDetachedHashBlob, DWORD cbDetachedHashBlob, DWORD cToBeHashed,
313 const BYTE *rgpbToBeHashed[], DWORD rgcbToBeHashed[], BYTE *pbComputedHash,
314 DWORD *pcbComputedHash)
315{
316 HCRYPTMSG msg;
317 BOOL ret = FALSE;
318
319 TRACE("(%p, %p, %d, %d, %p, %p, %p, %p)\n", pHashPara, pbDetachedHashBlob,
320 cbDetachedHashBlob, cToBeHashed, rgpbToBeHashed, rgcbToBeHashed,
321 pbComputedHash, pcbComputedHash);
322
323 if (pHashPara->cbSize != sizeof(CRYPT_HASH_MESSAGE_PARA))
324 {
325 SetLastError(E_INVALIDARG);
326 return FALSE;
327 }
328 if (GET_CMSG_ENCODING_TYPE(pHashPara->dwMsgEncodingType) !=
329 PKCS_7_ASN_ENCODING)
330 {
331 SetLastError(E_INVALIDARG);
332 return FALSE;
333 }
334 msg = CryptMsgOpenToDecode(pHashPara->dwMsgEncodingType, CMSG_DETACHED_FLAG,
335 0, pHashPara->hCryptProv, NULL, NULL);
336 if (msg)
337 {
338 DWORD i;
339
340 ret = CryptMsgUpdate(msg, pbDetachedHashBlob, cbDetachedHashBlob, TRUE);
341 if (ret)
342 {
343 if (cToBeHashed)
344 {
345 for (i = 0; ret && i < cToBeHashed; i++)
346 {
347 ret = CryptMsgUpdate(msg, rgpbToBeHashed[i],
348 rgcbToBeHashed[i], i == cToBeHashed - 1 ? TRUE : FALSE);
349 }
350 }
351 else
352 ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
353 }
354 if (ret)
355 {
356 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
357 if (ret && pcbComputedHash)
358 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0,
359 pbComputedHash, pcbComputedHash);
360 }
361 CryptMsgClose(msg);
362 }
363 return ret;
364}
365
366BOOL WINAPI CryptVerifyMessageHash(PCRYPT_HASH_MESSAGE_PARA pHashPara,
367 BYTE *pbHashedBlob, DWORD cbHashedBlob, BYTE *pbToBeHashed,
368 DWORD *pcbToBeHashed, BYTE *pbComputedHash, DWORD *pcbComputedHash)
369{
370 HCRYPTMSG msg;
371 BOOL ret = FALSE;
372
373 TRACE("(%p, %p, %d, %p, %p, %p, %p)\n", pHashPara, pbHashedBlob,
374 cbHashedBlob, pbToBeHashed, pcbToBeHashed, pbComputedHash,
375 pcbComputedHash);
376
377 if (pHashPara->cbSize != sizeof(CRYPT_HASH_MESSAGE_PARA))
378 {
379 SetLastError(E_INVALIDARG);
380 return FALSE;
381 }
382 if (GET_CMSG_ENCODING_TYPE(pHashPara->dwMsgEncodingType) !=
383 PKCS_7_ASN_ENCODING)
384 {
385 SetLastError(E_INVALIDARG);
386 return FALSE;
387 }
388 msg = CryptMsgOpenToDecode(pHashPara->dwMsgEncodingType, 0, 0,
389 pHashPara->hCryptProv, NULL, NULL);
390 if (msg)
391 {
392 ret = CryptMsgUpdate(msg, pbHashedBlob, cbHashedBlob, TRUE);
393 if (ret)
394 {
395 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
396 if (ret && pcbToBeHashed)
397 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0,
398 pbToBeHashed, pcbToBeHashed);
399 if (ret && pcbComputedHash)
400 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0,
401 pbComputedHash, pcbComputedHash);
402 }
403 CryptMsgClose(msg);
404 }
405 return ret;
406}
Note: See TracBrowser for help on using the repository browser.