1c2c66affSColin Finck /*
2c2c66affSColin Finck * Copyright 2007 Juan Lang
3c2c66affSColin Finck *
4c2c66affSColin Finck * This library is free software; you can redistribute it and/or
5c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public
6c2c66affSColin Finck * License as published by the Free Software Foundation; either
7c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version.
8c2c66affSColin Finck *
9c2c66affSColin Finck * This library is distributed in the hope that it will be useful,
10c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
11c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12c2c66affSColin Finck * Lesser General Public License for more details.
13c2c66affSColin Finck *
14c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public
15c2c66affSColin Finck * License along with this library; if not, write to the Free Software
16c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17c2c66affSColin Finck */
18c2c66affSColin Finck
19*a6e10342SAmine Khaldi #include <stdarg.h>
20*a6e10342SAmine Khaldi #include "windef.h"
21*a6e10342SAmine Khaldi #include "winbase.h"
22*a6e10342SAmine Khaldi #include "wincrypt.h"
23*a6e10342SAmine Khaldi
24*a6e10342SAmine Khaldi #include "wine/debug.h"
25c2c66affSColin Finck
26c2c66affSColin Finck WINE_DEFAULT_DEBUG_CHANNEL(crypt);
27c2c66affSColin Finck
CryptGetMessageCertificates(DWORD dwMsgAndCertEncodingType,HCRYPTPROV_LEGACY hCryptProv,DWORD dwFlags,const BYTE * pbSignedBlob,DWORD cbSignedBlob)28c2c66affSColin Finck HCERTSTORE WINAPI CryptGetMessageCertificates(DWORD dwMsgAndCertEncodingType,
29c2c66affSColin Finck HCRYPTPROV_LEGACY hCryptProv, DWORD dwFlags, const BYTE* pbSignedBlob,
30c2c66affSColin Finck DWORD cbSignedBlob)
31c2c66affSColin Finck {
32c2c66affSColin Finck CRYPT_DATA_BLOB blob = { cbSignedBlob, (LPBYTE)pbSignedBlob };
33c2c66affSColin Finck
34c2c66affSColin Finck TRACE("(%08x, %ld, %d08x %p, %d)\n", dwMsgAndCertEncodingType, hCryptProv,
35c2c66affSColin Finck dwFlags, pbSignedBlob, cbSignedBlob);
36c2c66affSColin Finck
37c2c66affSColin Finck return CertOpenStore(CERT_STORE_PROV_PKCS7, dwMsgAndCertEncodingType,
38c2c66affSColin Finck hCryptProv, dwFlags, &blob);
39c2c66affSColin Finck }
40c2c66affSColin Finck
CryptGetMessageSignerCount(DWORD dwMsgEncodingType,const BYTE * pbSignedBlob,DWORD cbSignedBlob)41c2c66affSColin Finck LONG WINAPI CryptGetMessageSignerCount(DWORD dwMsgEncodingType,
42c2c66affSColin Finck const BYTE *pbSignedBlob, DWORD cbSignedBlob)
43c2c66affSColin Finck {
44c2c66affSColin Finck HCRYPTMSG msg;
45c2c66affSColin Finck LONG count = -1;
46c2c66affSColin Finck
47c2c66affSColin Finck TRACE("(%08x, %p, %d)\n", dwMsgEncodingType, pbSignedBlob, cbSignedBlob);
48c2c66affSColin Finck
49c2c66affSColin Finck msg = CryptMsgOpenToDecode(dwMsgEncodingType, 0, 0, 0, NULL, NULL);
50c2c66affSColin Finck if (msg)
51c2c66affSColin Finck {
52c2c66affSColin Finck if (CryptMsgUpdate(msg, pbSignedBlob, cbSignedBlob, TRUE))
53c2c66affSColin Finck {
54c2c66affSColin Finck DWORD size = sizeof(count);
55c2c66affSColin Finck
56c2c66affSColin Finck CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &count, &size);
57c2c66affSColin Finck }
58c2c66affSColin Finck CryptMsgClose(msg);
59c2c66affSColin Finck }
60c2c66affSColin Finck return count;
61c2c66affSColin Finck }
62c2c66affSColin Finck
CRYPT_GetSignerCertInfoFromMsg(HCRYPTMSG msg,DWORD dwSignerIndex)63c2c66affSColin Finck static CERT_INFO *CRYPT_GetSignerCertInfoFromMsg(HCRYPTMSG msg,
64c2c66affSColin Finck DWORD dwSignerIndex)
65c2c66affSColin Finck {
66c2c66affSColin Finck CERT_INFO *certInfo = NULL;
67c2c66affSColin Finck DWORD size;
68c2c66affSColin Finck
69c2c66affSColin Finck if (CryptMsgGetParam(msg, CMSG_SIGNER_CERT_INFO_PARAM, dwSignerIndex, NULL,
70c2c66affSColin Finck &size))
71c2c66affSColin Finck {
72c2c66affSColin Finck certInfo = CryptMemAlloc(size);
73c2c66affSColin Finck if (certInfo)
74c2c66affSColin Finck {
75c2c66affSColin Finck if (!CryptMsgGetParam(msg, CMSG_SIGNER_CERT_INFO_PARAM,
76c2c66affSColin Finck dwSignerIndex, certInfo, &size))
77c2c66affSColin Finck {
78c2c66affSColin Finck CryptMemFree(certInfo);
79c2c66affSColin Finck certInfo = NULL;
80c2c66affSColin Finck }
81c2c66affSColin Finck }
82c2c66affSColin Finck }
83c2c66affSColin Finck else
84c2c66affSColin Finck SetLastError(CRYPT_E_UNEXPECTED_MSG_TYPE);
85c2c66affSColin Finck return certInfo;
86c2c66affSColin Finck }
87c2c66affSColin Finck
CRYPT_DefaultGetSignerCertificate(void * pvGetArg,DWORD dwCertEncodingType,PCERT_INFO pSignerId,HCERTSTORE hMsgCertStore)88c2c66affSColin Finck static PCCERT_CONTEXT WINAPI CRYPT_DefaultGetSignerCertificate(void *pvGetArg,
89c2c66affSColin Finck DWORD dwCertEncodingType, PCERT_INFO pSignerId, HCERTSTORE hMsgCertStore)
90c2c66affSColin Finck {
91c2c66affSColin Finck return CertFindCertificateInStore(hMsgCertStore, dwCertEncodingType, 0,
92c2c66affSColin Finck CERT_FIND_SUBJECT_CERT, pSignerId, NULL);
93c2c66affSColin Finck }
94c2c66affSColin Finck
CRYPT_GetSignerCertificate(HCRYPTMSG msg,PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,PCERT_INFO certInfo,HCERTSTORE store)95c2c66affSColin Finck static inline PCCERT_CONTEXT CRYPT_GetSignerCertificate(HCRYPTMSG msg,
96c2c66affSColin Finck PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, PCERT_INFO certInfo, HCERTSTORE store)
97c2c66affSColin Finck {
98c2c66affSColin Finck PFN_CRYPT_GET_SIGNER_CERTIFICATE getCert;
99c2c66affSColin Finck
100c2c66affSColin Finck if (pVerifyPara->pfnGetSignerCertificate)
101c2c66affSColin Finck getCert = pVerifyPara->pfnGetSignerCertificate;
102c2c66affSColin Finck else
103c2c66affSColin Finck getCert = CRYPT_DefaultGetSignerCertificate;
104c2c66affSColin Finck return getCert(pVerifyPara->pvGetArg,
105c2c66affSColin Finck pVerifyPara->dwMsgAndCertEncodingType, certInfo, store);
106c2c66affSColin Finck }
107c2c66affSColin Finck
CryptVerifyDetachedMessageSignature(PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,DWORD dwSignerIndex,const BYTE * pbDetachedSignBlob,DWORD cbDetachedSignBlob,DWORD cToBeSigned,const BYTE * rgpbToBeSigned[],DWORD rgcbToBeSigned[],PCCERT_CONTEXT * ppSignerCert)108c2c66affSColin Finck BOOL WINAPI CryptVerifyDetachedMessageSignature(
109c2c66affSColin Finck PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, DWORD dwSignerIndex,
110c2c66affSColin Finck const BYTE *pbDetachedSignBlob, DWORD cbDetachedSignBlob, DWORD cToBeSigned,
111c2c66affSColin Finck const BYTE *rgpbToBeSigned[], DWORD rgcbToBeSigned[],
112c2c66affSColin Finck PCCERT_CONTEXT *ppSignerCert)
113c2c66affSColin Finck {
114c2c66affSColin Finck BOOL ret = FALSE;
115c2c66affSColin Finck HCRYPTMSG msg;
116c2c66affSColin Finck
117c2c66affSColin Finck TRACE("(%p, %d, %p, %d, %d, %p, %p, %p)\n", pVerifyPara, dwSignerIndex,
118c2c66affSColin Finck pbDetachedSignBlob, cbDetachedSignBlob, cToBeSigned, rgpbToBeSigned,
119c2c66affSColin Finck rgcbToBeSigned, ppSignerCert);
120c2c66affSColin Finck
121c2c66affSColin Finck if (ppSignerCert)
122c2c66affSColin Finck *ppSignerCert = NULL;
123c2c66affSColin Finck if (!pVerifyPara ||
124c2c66affSColin Finck pVerifyPara->cbSize != sizeof(CRYPT_VERIFY_MESSAGE_PARA) ||
125c2c66affSColin Finck GET_CMSG_ENCODING_TYPE(pVerifyPara->dwMsgAndCertEncodingType) !=
126c2c66affSColin Finck PKCS_7_ASN_ENCODING)
127c2c66affSColin Finck {
128c2c66affSColin Finck SetLastError(E_INVALIDARG);
129c2c66affSColin Finck return FALSE;
130c2c66affSColin Finck }
131c2c66affSColin Finck
132c2c66affSColin Finck msg = CryptMsgOpenToDecode(pVerifyPara->dwMsgAndCertEncodingType,
133c2c66affSColin Finck CMSG_DETACHED_FLAG, 0, pVerifyPara->hCryptProv, NULL, NULL);
134c2c66affSColin Finck if (msg)
135c2c66affSColin Finck {
136c2c66affSColin Finck ret = CryptMsgUpdate(msg, pbDetachedSignBlob, cbDetachedSignBlob, TRUE);
137c2c66affSColin Finck if (ret)
138c2c66affSColin Finck {
139c2c66affSColin Finck DWORD i;
140c2c66affSColin Finck
141c2c66affSColin Finck for (i = 0; ret && i < cToBeSigned; i++)
142c2c66affSColin Finck ret = CryptMsgUpdate(msg, rgpbToBeSigned[i], rgcbToBeSigned[i],
143c2c66affSColin Finck i == cToBeSigned - 1);
144c2c66affSColin Finck }
145c2c66affSColin Finck if (ret)
146c2c66affSColin Finck {
147c2c66affSColin Finck CERT_INFO *certInfo = CRYPT_GetSignerCertInfoFromMsg(msg,
148c2c66affSColin Finck dwSignerIndex);
149c2c66affSColin Finck
150c2c66affSColin Finck ret = FALSE;
151c2c66affSColin Finck if (certInfo)
152c2c66affSColin Finck {
153c2c66affSColin Finck HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MSG,
154c2c66affSColin Finck pVerifyPara->dwMsgAndCertEncodingType,
155c2c66affSColin Finck pVerifyPara->hCryptProv, 0, msg);
156c2c66affSColin Finck
157c2c66affSColin Finck if (store)
158c2c66affSColin Finck {
159c2c66affSColin Finck PCCERT_CONTEXT cert = CRYPT_GetSignerCertificate(
160c2c66affSColin Finck msg, pVerifyPara, certInfo, store);
161c2c66affSColin Finck
162c2c66affSColin Finck if (cert)
163c2c66affSColin Finck {
164c2c66affSColin Finck ret = CryptMsgControl(msg, 0,
165c2c66affSColin Finck CMSG_CTRL_VERIFY_SIGNATURE, cert->pCertInfo);
166c2c66affSColin Finck if (ret && ppSignerCert)
167c2c66affSColin Finck *ppSignerCert = cert;
168c2c66affSColin Finck else
169c2c66affSColin Finck CertFreeCertificateContext(cert);
170c2c66affSColin Finck }
171c2c66affSColin Finck else
172c2c66affSColin Finck SetLastError(CRYPT_E_NOT_FOUND);
173c2c66affSColin Finck CertCloseStore(store, 0);
174c2c66affSColin Finck }
175c2c66affSColin Finck CryptMemFree(certInfo);
176c2c66affSColin Finck }
177c2c66affSColin Finck }
178c2c66affSColin Finck CryptMsgClose(msg);
179c2c66affSColin Finck }
180c2c66affSColin Finck TRACE("returning %d\n", ret);
181c2c66affSColin Finck return ret;
182c2c66affSColin Finck }
183c2c66affSColin Finck
CryptVerifyMessageSignature(PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,DWORD dwSignerIndex,const BYTE * pbSignedBlob,DWORD cbSignedBlob,BYTE * pbDecoded,DWORD * pcbDecoded,PCCERT_CONTEXT * ppSignerCert)184c2c66affSColin Finck BOOL WINAPI CryptVerifyMessageSignature(PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
185c2c66affSColin Finck DWORD dwSignerIndex, const BYTE* pbSignedBlob, DWORD cbSignedBlob,
186c2c66affSColin Finck BYTE* pbDecoded, DWORD* pcbDecoded, PCCERT_CONTEXT* ppSignerCert)
187c2c66affSColin Finck {
188c2c66affSColin Finck BOOL ret = FALSE;
189c2c66affSColin Finck HCRYPTMSG msg;
190c2c66affSColin Finck
191c2c66affSColin Finck TRACE("(%p, %d, %p, %d, %p, %p, %p)\n",
192c2c66affSColin Finck pVerifyPara, dwSignerIndex, pbSignedBlob, cbSignedBlob,
193c2c66affSColin Finck pbDecoded, pcbDecoded, ppSignerCert);
194c2c66affSColin Finck
195c2c66affSColin Finck if (ppSignerCert)
196c2c66affSColin Finck *ppSignerCert = NULL;
197c2c66affSColin Finck if (!pVerifyPara ||
198c2c66affSColin Finck pVerifyPara->cbSize != sizeof(CRYPT_VERIFY_MESSAGE_PARA) ||
199c2c66affSColin Finck GET_CMSG_ENCODING_TYPE(pVerifyPara->dwMsgAndCertEncodingType) !=
200c2c66affSColin Finck PKCS_7_ASN_ENCODING)
201c2c66affSColin Finck {
202c2c66affSColin Finck if(pcbDecoded)
203c2c66affSColin Finck *pcbDecoded = 0;
204c2c66affSColin Finck SetLastError(E_INVALIDARG);
205c2c66affSColin Finck return FALSE;
206c2c66affSColin Finck }
207c2c66affSColin Finck
208c2c66affSColin Finck msg = CryptMsgOpenToDecode(pVerifyPara->dwMsgAndCertEncodingType, 0, 0,
209c2c66affSColin Finck pVerifyPara->hCryptProv, NULL, NULL);
210c2c66affSColin Finck if (msg)
211c2c66affSColin Finck {
212c2c66affSColin Finck ret = CryptMsgUpdate(msg, pbSignedBlob, cbSignedBlob, TRUE);
213c2c66affSColin Finck if (ret && pcbDecoded)
214c2c66affSColin Finck ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, pbDecoded,
215c2c66affSColin Finck pcbDecoded);
216c2c66affSColin Finck if (ret)
217c2c66affSColin Finck {
218c2c66affSColin Finck CERT_INFO *certInfo = CRYPT_GetSignerCertInfoFromMsg(msg,
219c2c66affSColin Finck dwSignerIndex);
220c2c66affSColin Finck
221c2c66affSColin Finck ret = FALSE;
222c2c66affSColin Finck if (certInfo)
223c2c66affSColin Finck {
224c2c66affSColin Finck HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MSG,
225c2c66affSColin Finck pVerifyPara->dwMsgAndCertEncodingType,
226c2c66affSColin Finck pVerifyPara->hCryptProv, 0, msg);
227c2c66affSColin Finck
228c2c66affSColin Finck if (store)
229c2c66affSColin Finck {
230c2c66affSColin Finck PCCERT_CONTEXT cert = CRYPT_GetSignerCertificate(
231c2c66affSColin Finck msg, pVerifyPara, certInfo, store);
232c2c66affSColin Finck
233c2c66affSColin Finck if (cert)
234c2c66affSColin Finck {
235c2c66affSColin Finck ret = CryptMsgControl(msg, 0,
236c2c66affSColin Finck CMSG_CTRL_VERIFY_SIGNATURE, cert->pCertInfo);
237c2c66affSColin Finck if (ret && ppSignerCert)
238c2c66affSColin Finck *ppSignerCert = cert;
239c2c66affSColin Finck else
240c2c66affSColin Finck CertFreeCertificateContext(cert);
241c2c66affSColin Finck }
242c2c66affSColin Finck CertCloseStore(store, 0);
243c2c66affSColin Finck }
244c2c66affSColin Finck }
245c2c66affSColin Finck CryptMemFree(certInfo);
246c2c66affSColin Finck }
247c2c66affSColin Finck CryptMsgClose(msg);
248c2c66affSColin Finck }
249c2c66affSColin Finck if(!ret && pcbDecoded)
250c2c66affSColin Finck *pcbDecoded = 0;
251c2c66affSColin Finck TRACE("returning %d\n", ret);
252c2c66affSColin Finck return ret;
253c2c66affSColin Finck }
254c2c66affSColin Finck
CryptHashMessage(PCRYPT_HASH_MESSAGE_PARA pHashPara,BOOL fDetachedHash,DWORD cToBeHashed,const BYTE * rgpbToBeHashed[],DWORD rgcbToBeHashed[],BYTE * pbHashedBlob,DWORD * pcbHashedBlob,BYTE * pbComputedHash,DWORD * pcbComputedHash)255c2c66affSColin Finck BOOL WINAPI CryptHashMessage(PCRYPT_HASH_MESSAGE_PARA pHashPara,
256c2c66affSColin Finck BOOL fDetachedHash, DWORD cToBeHashed, const BYTE *rgpbToBeHashed[],
257c2c66affSColin Finck DWORD rgcbToBeHashed[], BYTE *pbHashedBlob, DWORD *pcbHashedBlob,
258c2c66affSColin Finck BYTE *pbComputedHash, DWORD *pcbComputedHash)
259c2c66affSColin Finck {
260c2c66affSColin Finck DWORD i, flags;
261c2c66affSColin Finck BOOL ret = FALSE;
262c2c66affSColin Finck HCRYPTMSG msg;
263c2c66affSColin Finck CMSG_HASHED_ENCODE_INFO info;
264c2c66affSColin Finck
265c2c66affSColin Finck TRACE("(%p, %d, %d, %p, %p, %p, %p, %p, %p)\n", pHashPara, fDetachedHash,
266c2c66affSColin Finck cToBeHashed, rgpbToBeHashed, rgcbToBeHashed, pbHashedBlob, pcbHashedBlob,
267c2c66affSColin Finck pbComputedHash, pcbComputedHash);
268c2c66affSColin Finck
269c2c66affSColin Finck if (pHashPara->cbSize != sizeof(CRYPT_HASH_MESSAGE_PARA))
270c2c66affSColin Finck {
271c2c66affSColin Finck SetLastError(E_INVALIDARG);
272c2c66affSColin Finck return FALSE;
273c2c66affSColin Finck }
274c2c66affSColin Finck /* Native seems to ignore any encoding type other than the expected
275c2c66affSColin Finck * PKCS_7_ASN_ENCODING
276c2c66affSColin Finck */
277c2c66affSColin Finck if (GET_CMSG_ENCODING_TYPE(pHashPara->dwMsgEncodingType) !=
278c2c66affSColin Finck PKCS_7_ASN_ENCODING)
279c2c66affSColin Finck return TRUE;
280c2c66affSColin Finck /* Native also seems to do nothing if the output parameter isn't given */
281c2c66affSColin Finck if (!pcbHashedBlob)
282c2c66affSColin Finck return TRUE;
283c2c66affSColin Finck
284c2c66affSColin Finck flags = fDetachedHash ? CMSG_DETACHED_FLAG : 0;
285c2c66affSColin Finck memset(&info, 0, sizeof(info));
286c2c66affSColin Finck info.cbSize = sizeof(info);
287c2c66affSColin Finck info.hCryptProv = pHashPara->hCryptProv;
288c2c66affSColin Finck info.HashAlgorithm = pHashPara->HashAlgorithm;
289c2c66affSColin Finck info.pvHashAuxInfo = pHashPara->pvHashAuxInfo;
290c2c66affSColin Finck msg = CryptMsgOpenToEncode(pHashPara->dwMsgEncodingType, flags, CMSG_HASHED,
291c2c66affSColin Finck &info, NULL, NULL);
292c2c66affSColin Finck if (msg)
293c2c66affSColin Finck {
294c2c66affSColin Finck for (i = 0, ret = TRUE; ret && i < cToBeHashed; i++)
295c2c66affSColin Finck ret = CryptMsgUpdate(msg, rgpbToBeHashed[i], rgcbToBeHashed[i], i == cToBeHashed - 1);
296c2c66affSColin Finck if (ret)
297c2c66affSColin Finck {
298c2c66affSColin Finck ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, pbHashedBlob,
299c2c66affSColin Finck pcbHashedBlob);
300c2c66affSColin Finck if (ret && pcbComputedHash)
301c2c66affSColin Finck ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0,
302c2c66affSColin Finck pbComputedHash, pcbComputedHash);
303c2c66affSColin Finck }
304c2c66affSColin Finck CryptMsgClose(msg);
305c2c66affSColin Finck }
306c2c66affSColin Finck return ret;
307c2c66affSColin Finck }
308c2c66affSColin Finck
CryptVerifyDetachedMessageHash(PCRYPT_HASH_MESSAGE_PARA pHashPara,BYTE * pbDetachedHashBlob,DWORD cbDetachedHashBlob,DWORD cToBeHashed,const BYTE * rgpbToBeHashed[],DWORD rgcbToBeHashed[],BYTE * pbComputedHash,DWORD * pcbComputedHash)309c2c66affSColin Finck BOOL WINAPI CryptVerifyDetachedMessageHash(PCRYPT_HASH_MESSAGE_PARA pHashPara,
310c2c66affSColin Finck BYTE *pbDetachedHashBlob, DWORD cbDetachedHashBlob, DWORD cToBeHashed,
311c2c66affSColin Finck const BYTE *rgpbToBeHashed[], DWORD rgcbToBeHashed[], BYTE *pbComputedHash,
312c2c66affSColin Finck DWORD *pcbComputedHash)
313c2c66affSColin Finck {
314c2c66affSColin Finck HCRYPTMSG msg;
315c2c66affSColin Finck BOOL ret = FALSE;
316c2c66affSColin Finck
317c2c66affSColin Finck TRACE("(%p, %p, %d, %d, %p, %p, %p, %p)\n", pHashPara, pbDetachedHashBlob,
318c2c66affSColin Finck cbDetachedHashBlob, cToBeHashed, rgpbToBeHashed, rgcbToBeHashed,
319c2c66affSColin Finck pbComputedHash, pcbComputedHash);
320c2c66affSColin Finck
321c2c66affSColin Finck if (pHashPara->cbSize != sizeof(CRYPT_HASH_MESSAGE_PARA))
322c2c66affSColin Finck {
323c2c66affSColin Finck SetLastError(E_INVALIDARG);
324c2c66affSColin Finck return FALSE;
325c2c66affSColin Finck }
326c2c66affSColin Finck if (GET_CMSG_ENCODING_TYPE(pHashPara->dwMsgEncodingType) !=
327c2c66affSColin Finck PKCS_7_ASN_ENCODING)
328c2c66affSColin Finck {
329c2c66affSColin Finck SetLastError(E_INVALIDARG);
330c2c66affSColin Finck return FALSE;
331c2c66affSColin Finck }
332c2c66affSColin Finck msg = CryptMsgOpenToDecode(pHashPara->dwMsgEncodingType, CMSG_DETACHED_FLAG,
333c2c66affSColin Finck 0, pHashPara->hCryptProv, NULL, NULL);
334c2c66affSColin Finck if (msg)
335c2c66affSColin Finck {
336c2c66affSColin Finck DWORD i;
337c2c66affSColin Finck
338c2c66affSColin Finck ret = CryptMsgUpdate(msg, pbDetachedHashBlob, cbDetachedHashBlob, TRUE);
339c2c66affSColin Finck if (ret)
340c2c66affSColin Finck {
341c2c66affSColin Finck if (cToBeHashed)
342c2c66affSColin Finck {
343c2c66affSColin Finck for (i = 0; ret && i < cToBeHashed; i++)
344c2c66affSColin Finck {
345c2c66affSColin Finck ret = CryptMsgUpdate(msg, rgpbToBeHashed[i],
346c2c66affSColin Finck rgcbToBeHashed[i], i == cToBeHashed - 1);
347c2c66affSColin Finck }
348c2c66affSColin Finck }
349c2c66affSColin Finck else
350c2c66affSColin Finck ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
351c2c66affSColin Finck }
352c2c66affSColin Finck if (ret)
353c2c66affSColin Finck {
354c2c66affSColin Finck ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
355c2c66affSColin Finck if (ret && pcbComputedHash)
356c2c66affSColin Finck ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0,
357c2c66affSColin Finck pbComputedHash, pcbComputedHash);
358c2c66affSColin Finck }
359c2c66affSColin Finck CryptMsgClose(msg);
360c2c66affSColin Finck }
361c2c66affSColin Finck return ret;
362c2c66affSColin Finck }
363c2c66affSColin Finck
CryptVerifyMessageHash(PCRYPT_HASH_MESSAGE_PARA pHashPara,BYTE * pbHashedBlob,DWORD cbHashedBlob,BYTE * pbToBeHashed,DWORD * pcbToBeHashed,BYTE * pbComputedHash,DWORD * pcbComputedHash)364c2c66affSColin Finck BOOL WINAPI CryptVerifyMessageHash(PCRYPT_HASH_MESSAGE_PARA pHashPara,
365c2c66affSColin Finck BYTE *pbHashedBlob, DWORD cbHashedBlob, BYTE *pbToBeHashed,
366c2c66affSColin Finck DWORD *pcbToBeHashed, BYTE *pbComputedHash, DWORD *pcbComputedHash)
367c2c66affSColin Finck {
368c2c66affSColin Finck HCRYPTMSG msg;
369c2c66affSColin Finck BOOL ret = FALSE;
370c2c66affSColin Finck
371c2c66affSColin Finck TRACE("(%p, %p, %d, %p, %p, %p, %p)\n", pHashPara, pbHashedBlob,
372c2c66affSColin Finck cbHashedBlob, pbToBeHashed, pcbToBeHashed, pbComputedHash,
373c2c66affSColin Finck pcbComputedHash);
374c2c66affSColin Finck
375c2c66affSColin Finck if (pHashPara->cbSize != sizeof(CRYPT_HASH_MESSAGE_PARA))
376c2c66affSColin Finck {
377c2c66affSColin Finck SetLastError(E_INVALIDARG);
378c2c66affSColin Finck return FALSE;
379c2c66affSColin Finck }
380c2c66affSColin Finck if (GET_CMSG_ENCODING_TYPE(pHashPara->dwMsgEncodingType) !=
381c2c66affSColin Finck PKCS_7_ASN_ENCODING)
382c2c66affSColin Finck {
383c2c66affSColin Finck SetLastError(E_INVALIDARG);
384c2c66affSColin Finck return FALSE;
385c2c66affSColin Finck }
386c2c66affSColin Finck msg = CryptMsgOpenToDecode(pHashPara->dwMsgEncodingType, 0, 0,
387c2c66affSColin Finck pHashPara->hCryptProv, NULL, NULL);
388c2c66affSColin Finck if (msg)
389c2c66affSColin Finck {
390c2c66affSColin Finck ret = CryptMsgUpdate(msg, pbHashedBlob, cbHashedBlob, TRUE);
391c2c66affSColin Finck if (ret)
392c2c66affSColin Finck {
393c2c66affSColin Finck ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
394c2c66affSColin Finck if (ret && pcbToBeHashed)
395c2c66affSColin Finck ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0,
396c2c66affSColin Finck pbToBeHashed, pcbToBeHashed);
397c2c66affSColin Finck if (ret && pcbComputedHash)
398c2c66affSColin Finck ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0,
399c2c66affSColin Finck pbComputedHash, pcbComputedHash);
400c2c66affSColin Finck }
401c2c66affSColin Finck CryptMsgClose(msg);
402c2c66affSColin Finck }
403c2c66affSColin Finck return ret;
404c2c66affSColin Finck }
405c2c66affSColin Finck
CryptSignMessage(PCRYPT_SIGN_MESSAGE_PARA pSignPara,BOOL fDetachedSignature,DWORD cToBeSigned,const BYTE * rgpbToBeSigned[],DWORD rgcbToBeSigned[],BYTE * pbSignedBlob,DWORD * pcbSignedBlob)406c2c66affSColin Finck BOOL WINAPI CryptSignMessage(PCRYPT_SIGN_MESSAGE_PARA pSignPara,
407c2c66affSColin Finck BOOL fDetachedSignature, DWORD cToBeSigned, const BYTE *rgpbToBeSigned[],
408c2c66affSColin Finck DWORD rgcbToBeSigned[], BYTE *pbSignedBlob, DWORD *pcbSignedBlob)
409c2c66affSColin Finck {
410c2c66affSColin Finck HCRYPTPROV hCryptProv;
411c2c66affSColin Finck BOOL ret, freeProv = FALSE;
412c2c66affSColin Finck DWORD i, keySpec;
413c2c66affSColin Finck PCERT_BLOB certBlob = NULL;
414c2c66affSColin Finck PCRL_BLOB crlBlob = NULL;
415c2c66affSColin Finck CMSG_SIGNED_ENCODE_INFO signInfo;
416c2c66affSColin Finck CMSG_SIGNER_ENCODE_INFO signer;
417c2c66affSColin Finck HCRYPTMSG msg = 0;
418c2c66affSColin Finck
419c2c66affSColin Finck TRACE("(%p, %d, %d, %p, %p, %p, %p)\n", pSignPara, fDetachedSignature,
420c2c66affSColin Finck cToBeSigned, rgpbToBeSigned, rgcbToBeSigned, pbSignedBlob, pcbSignedBlob);
421c2c66affSColin Finck
422c2c66affSColin Finck if (pSignPara->cbSize != sizeof(CRYPT_SIGN_MESSAGE_PARA) ||
423c2c66affSColin Finck GET_CMSG_ENCODING_TYPE(pSignPara->dwMsgEncodingType) !=
424c2c66affSColin Finck PKCS_7_ASN_ENCODING)
425c2c66affSColin Finck {
426c2c66affSColin Finck *pcbSignedBlob = 0;
427c2c66affSColin Finck SetLastError(E_INVALIDARG);
428c2c66affSColin Finck return FALSE;
429c2c66affSColin Finck }
430c2c66affSColin Finck if (!pSignPara->pSigningCert)
431c2c66affSColin Finck return TRUE;
432c2c66affSColin Finck
433c2c66affSColin Finck ret = CryptAcquireCertificatePrivateKey(pSignPara->pSigningCert,
434c2c66affSColin Finck CRYPT_ACQUIRE_CACHE_FLAG, NULL, &hCryptProv, &keySpec, &freeProv);
435c2c66affSColin Finck if (!ret)
436c2c66affSColin Finck return FALSE;
437c2c66affSColin Finck
438c2c66affSColin Finck memset(&signer, 0, sizeof(signer));
439c2c66affSColin Finck signer.cbSize = sizeof(signer);
440c2c66affSColin Finck signer.pCertInfo = pSignPara->pSigningCert->pCertInfo;
441c2c66affSColin Finck signer.hCryptProv = hCryptProv;
442c2c66affSColin Finck signer.dwKeySpec = keySpec;
443c2c66affSColin Finck signer.HashAlgorithm = pSignPara->HashAlgorithm;
444c2c66affSColin Finck signer.pvHashAuxInfo = pSignPara->pvHashAuxInfo;
445c2c66affSColin Finck signer.cAuthAttr = pSignPara->cAuthAttr;
446c2c66affSColin Finck signer.rgAuthAttr = pSignPara->rgAuthAttr;
447c2c66affSColin Finck signer.cUnauthAttr = pSignPara->cUnauthAttr;
448c2c66affSColin Finck signer.rgUnauthAttr = pSignPara->rgUnauthAttr;
449c2c66affSColin Finck
450c2c66affSColin Finck memset(&signInfo, 0, sizeof(signInfo));
451c2c66affSColin Finck signInfo.cbSize = sizeof(signInfo);
452c2c66affSColin Finck signInfo.cSigners = 1;
453c2c66affSColin Finck signInfo.rgSigners = &signer;
454c2c66affSColin Finck
455c2c66affSColin Finck if (pSignPara->cMsgCert)
456c2c66affSColin Finck {
457c2c66affSColin Finck certBlob = CryptMemAlloc(sizeof(CERT_BLOB) * pSignPara->cMsgCert);
458c2c66affSColin Finck if (certBlob)
459c2c66affSColin Finck {
460c2c66affSColin Finck for (i = 0; i < pSignPara->cMsgCert; ++i)
461c2c66affSColin Finck {
462c2c66affSColin Finck certBlob[i].cbData = pSignPara->rgpMsgCert[i]->cbCertEncoded;
463c2c66affSColin Finck certBlob[i].pbData = pSignPara->rgpMsgCert[i]->pbCertEncoded;
464c2c66affSColin Finck }
465c2c66affSColin Finck signInfo.cCertEncoded = pSignPara->cMsgCert;
466c2c66affSColin Finck signInfo.rgCertEncoded = certBlob;
467c2c66affSColin Finck }
468c2c66affSColin Finck else
469c2c66affSColin Finck ret = FALSE;
470c2c66affSColin Finck }
471c2c66affSColin Finck if (pSignPara->cMsgCrl)
472c2c66affSColin Finck {
473c2c66affSColin Finck crlBlob = CryptMemAlloc(sizeof(CRL_BLOB) * pSignPara->cMsgCrl);
474c2c66affSColin Finck if (crlBlob)
475c2c66affSColin Finck {
476c2c66affSColin Finck for (i = 0; i < pSignPara->cMsgCrl; ++i)
477c2c66affSColin Finck {
478c2c66affSColin Finck crlBlob[i].cbData = pSignPara->rgpMsgCrl[i]->cbCrlEncoded;
479c2c66affSColin Finck crlBlob[i].pbData = pSignPara->rgpMsgCrl[i]->pbCrlEncoded;
480c2c66affSColin Finck }
481c2c66affSColin Finck signInfo.cCrlEncoded = pSignPara->cMsgCrl;
482c2c66affSColin Finck signInfo.rgCrlEncoded = crlBlob;
483c2c66affSColin Finck }
484c2c66affSColin Finck else
485c2c66affSColin Finck ret = FALSE;
486c2c66affSColin Finck }
487c2c66affSColin Finck if (pSignPara->dwFlags || pSignPara->dwInnerContentType)
488c2c66affSColin Finck FIXME("unimplemented feature\n");
489c2c66affSColin Finck
490c2c66affSColin Finck if (ret)
491c2c66affSColin Finck msg = CryptMsgOpenToEncode(pSignPara->dwMsgEncodingType,
492c2c66affSColin Finck fDetachedSignature ? CMSG_DETACHED_FLAG : 0, CMSG_SIGNED, &signInfo,
493c2c66affSColin Finck NULL, NULL);
494c2c66affSColin Finck if (msg)
495c2c66affSColin Finck {
496c2c66affSColin Finck if (cToBeSigned)
497c2c66affSColin Finck {
498c2c66affSColin Finck for (i = 0; ret && i < cToBeSigned; ++i)
499c2c66affSColin Finck {
500c2c66affSColin Finck ret = CryptMsgUpdate(msg, rgpbToBeSigned[i], rgcbToBeSigned[i],
501c2c66affSColin Finck i == cToBeSigned - 1);
502c2c66affSColin Finck }
503c2c66affSColin Finck }
504c2c66affSColin Finck else
505c2c66affSColin Finck ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
506c2c66affSColin Finck if (ret)
507c2c66affSColin Finck ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, pbSignedBlob,
508c2c66affSColin Finck pcbSignedBlob);
509c2c66affSColin Finck CryptMsgClose(msg);
510c2c66affSColin Finck }
511c2c66affSColin Finck else
512c2c66affSColin Finck ret = FALSE;
513c2c66affSColin Finck
514c2c66affSColin Finck CryptMemFree(crlBlob);
515c2c66affSColin Finck CryptMemFree(certBlob);
516c2c66affSColin Finck if (freeProv)
517c2c66affSColin Finck CryptReleaseContext(hCryptProv, 0);
518c2c66affSColin Finck return ret;
519c2c66affSColin Finck }
520c2c66affSColin Finck
CryptEncryptMessage(PCRYPT_ENCRYPT_MESSAGE_PARA pEncryptPara,DWORD cRecipientCert,PCCERT_CONTEXT rgpRecipientCert[],const BYTE * pbToBeEncrypted,DWORD cbToBeEncrypted,BYTE * pbEncryptedBlob,DWORD * pcbEncryptedBlob)521c2c66affSColin Finck BOOL WINAPI CryptEncryptMessage(PCRYPT_ENCRYPT_MESSAGE_PARA pEncryptPara,
522c2c66affSColin Finck DWORD cRecipientCert, PCCERT_CONTEXT rgpRecipientCert[],
523c2c66affSColin Finck const BYTE *pbToBeEncrypted, DWORD cbToBeEncrypted, BYTE *pbEncryptedBlob,
524c2c66affSColin Finck DWORD *pcbEncryptedBlob)
525c2c66affSColin Finck {
526c2c66affSColin Finck BOOL ret = TRUE;
527c2c66affSColin Finck DWORD i;
528c2c66affSColin Finck PCERT_INFO *certInfo = NULL;
529c2c66affSColin Finck CMSG_ENVELOPED_ENCODE_INFO envelopedInfo;
530c2c66affSColin Finck HCRYPTMSG msg = 0;
531c2c66affSColin Finck
532c2c66affSColin Finck TRACE("(%p, %d, %p, %p, %d, %p, %p)\n", pEncryptPara, cRecipientCert,
533c2c66affSColin Finck rgpRecipientCert, pbToBeEncrypted, cbToBeEncrypted, pbEncryptedBlob,
534c2c66affSColin Finck pcbEncryptedBlob);
535c2c66affSColin Finck
536c2c66affSColin Finck if (pEncryptPara->cbSize != sizeof(CRYPT_ENCRYPT_MESSAGE_PARA) ||
537c2c66affSColin Finck GET_CMSG_ENCODING_TYPE(pEncryptPara->dwMsgEncodingType) !=
538c2c66affSColin Finck PKCS_7_ASN_ENCODING)
539c2c66affSColin Finck {
540c2c66affSColin Finck *pcbEncryptedBlob = 0;
541c2c66affSColin Finck SetLastError(E_INVALIDARG);
542c2c66affSColin Finck return FALSE;
543c2c66affSColin Finck }
544c2c66affSColin Finck
545c2c66affSColin Finck memset(&envelopedInfo, 0, sizeof(envelopedInfo));
546c2c66affSColin Finck envelopedInfo.cbSize = sizeof(envelopedInfo);
547c2c66affSColin Finck envelopedInfo.hCryptProv = pEncryptPara->hCryptProv;
548c2c66affSColin Finck envelopedInfo.ContentEncryptionAlgorithm =
549c2c66affSColin Finck pEncryptPara->ContentEncryptionAlgorithm;
550c2c66affSColin Finck envelopedInfo.pvEncryptionAuxInfo = pEncryptPara->pvEncryptionAuxInfo;
551c2c66affSColin Finck
552c2c66affSColin Finck if (cRecipientCert)
553c2c66affSColin Finck {
554c2c66affSColin Finck certInfo = CryptMemAlloc(sizeof(PCERT_INFO) * cRecipientCert);
555c2c66affSColin Finck if (certInfo)
556c2c66affSColin Finck {
557c2c66affSColin Finck for (i = 0; i < cRecipientCert; ++i)
558c2c66affSColin Finck certInfo[i] = rgpRecipientCert[i]->pCertInfo;
559c2c66affSColin Finck envelopedInfo.cRecipients = cRecipientCert;
560c2c66affSColin Finck envelopedInfo.rgpRecipientCert = certInfo;
561c2c66affSColin Finck }
562c2c66affSColin Finck else
563c2c66affSColin Finck ret = FALSE;
564c2c66affSColin Finck }
565c2c66affSColin Finck
566c2c66affSColin Finck if (ret)
567c2c66affSColin Finck msg = CryptMsgOpenToEncode(pEncryptPara->dwMsgEncodingType, 0,
568c2c66affSColin Finck CMSG_ENVELOPED, &envelopedInfo, NULL, NULL);
569c2c66affSColin Finck if (msg)
570c2c66affSColin Finck {
571c2c66affSColin Finck ret = CryptMsgUpdate(msg, pbToBeEncrypted, cbToBeEncrypted, TRUE);
572c2c66affSColin Finck if (ret)
573c2c66affSColin Finck ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, pbEncryptedBlob,
574c2c66affSColin Finck pcbEncryptedBlob);
575c2c66affSColin Finck CryptMsgClose(msg);
576c2c66affSColin Finck }
577c2c66affSColin Finck else
578c2c66affSColin Finck ret = FALSE;
579c2c66affSColin Finck
580c2c66affSColin Finck CryptMemFree(certInfo);
581c2c66affSColin Finck if (!ret) *pcbEncryptedBlob = 0;
582c2c66affSColin Finck return ret;
583c2c66affSColin Finck }
584