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