Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmessage.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 2007 Juan Lang 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00017 */ 00018 00019 #include <stdarg.h> 00020 #include "windef.h" 00021 #include "winbase.h" 00022 #include "wincrypt.h" 00023 00024 #include "wine/debug.h" 00025 00026 WINE_DEFAULT_DEBUG_CHANNEL(crypt); 00027 00028 HCERTSTORE WINAPI CryptGetMessageCertificates(DWORD dwMsgAndCertEncodingType, 00029 HCRYPTPROV_LEGACY hCryptProv, DWORD dwFlags, const BYTE* pbSignedBlob, 00030 DWORD cbSignedBlob) 00031 { 00032 CRYPT_DATA_BLOB blob = { cbSignedBlob, (LPBYTE)pbSignedBlob }; 00033 00034 TRACE("(%08x, %ld, %d08x %p, %d)\n", dwMsgAndCertEncodingType, hCryptProv, 00035 dwFlags, pbSignedBlob, cbSignedBlob); 00036 00037 return CertOpenStore(CERT_STORE_PROV_PKCS7, dwMsgAndCertEncodingType, 00038 hCryptProv, dwFlags, &blob); 00039 } 00040 00041 LONG WINAPI CryptGetMessageSignerCount(DWORD dwMsgEncodingType, 00042 const BYTE *pbSignedBlob, DWORD cbSignedBlob) 00043 { 00044 HCRYPTMSG msg; 00045 LONG count = -1; 00046 00047 TRACE("(%08x, %p, %d)\n", dwMsgEncodingType, pbSignedBlob, cbSignedBlob); 00048 00049 msg = CryptMsgOpenToDecode(dwMsgEncodingType, 0, 0, 0, NULL, NULL); 00050 if (msg) 00051 { 00052 if (CryptMsgUpdate(msg, pbSignedBlob, cbSignedBlob, TRUE)) 00053 { 00054 DWORD size = sizeof(count); 00055 00056 CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &count, &size); 00057 } 00058 CryptMsgClose(msg); 00059 } 00060 return count; 00061 } 00062 00063 static CERT_INFO *CRYPT_GetSignerCertInfoFromMsg(HCRYPTMSG msg, 00064 DWORD dwSignerIndex) 00065 { 00066 CERT_INFO *certInfo = NULL; 00067 DWORD size; 00068 00069 if (CryptMsgGetParam(msg, CMSG_SIGNER_CERT_INFO_PARAM, dwSignerIndex, NULL, 00070 &size)) 00071 { 00072 certInfo = CryptMemAlloc(size); 00073 if (certInfo) 00074 { 00075 if (!CryptMsgGetParam(msg, CMSG_SIGNER_CERT_INFO_PARAM, 00076 dwSignerIndex, certInfo, &size)) 00077 { 00078 CryptMemFree(certInfo); 00079 certInfo = NULL; 00080 } 00081 } 00082 } 00083 else 00084 SetLastError(CRYPT_E_UNEXPECTED_MSG_TYPE); 00085 return certInfo; 00086 } 00087 00088 static PCCERT_CONTEXT WINAPI CRYPT_DefaultGetSignerCertificate(void *pvGetArg, 00089 DWORD dwCertEncodingType, PCERT_INFO pSignerId, HCERTSTORE hMsgCertStore) 00090 { 00091 return CertFindCertificateInStore(hMsgCertStore, dwCertEncodingType, 0, 00092 CERT_FIND_SUBJECT_CERT, pSignerId, NULL); 00093 } 00094 00095 static inline PCCERT_CONTEXT CRYPT_GetSignerCertificate(HCRYPTMSG msg, 00096 PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, PCERT_INFO certInfo, HCERTSTORE store) 00097 { 00098 PFN_CRYPT_GET_SIGNER_CERTIFICATE getCert; 00099 00100 if (pVerifyPara->pfnGetSignerCertificate) 00101 getCert = pVerifyPara->pfnGetSignerCertificate; 00102 else 00103 getCert = CRYPT_DefaultGetSignerCertificate; 00104 return getCert(pVerifyPara->pvGetArg, 00105 pVerifyPara->dwMsgAndCertEncodingType, certInfo, store); 00106 } 00107 00108 BOOL WINAPI CryptVerifyDetachedMessageSignature( 00109 PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, DWORD dwSignerIndex, 00110 const BYTE *pbDetachedSignBlob, DWORD cbDetachedSignBlob, DWORD cToBeSigned, 00111 const BYTE *rgpbToBeSigned[], DWORD rgcbToBeSigned[], 00112 PCCERT_CONTEXT *ppSignerCert) 00113 { 00114 BOOL ret = FALSE; 00115 HCRYPTMSG msg; 00116 00117 TRACE("(%p, %d, %p, %d, %d, %p, %p, %p)\n", pVerifyPara, dwSignerIndex, 00118 pbDetachedSignBlob, cbDetachedSignBlob, cToBeSigned, rgpbToBeSigned, 00119 rgcbToBeSigned, ppSignerCert); 00120 00121 if (ppSignerCert) 00122 *ppSignerCert = NULL; 00123 if (!pVerifyPara || 00124 pVerifyPara->cbSize != sizeof(CRYPT_VERIFY_MESSAGE_PARA) || 00125 GET_CMSG_ENCODING_TYPE(pVerifyPara->dwMsgAndCertEncodingType) != 00126 PKCS_7_ASN_ENCODING) 00127 { 00128 SetLastError(E_INVALIDARG); 00129 return FALSE; 00130 } 00131 00132 msg = CryptMsgOpenToDecode(pVerifyPara->dwMsgAndCertEncodingType, 00133 CMSG_DETACHED_FLAG, 0, pVerifyPara->hCryptProv, NULL, NULL); 00134 if (msg) 00135 { 00136 ret = CryptMsgUpdate(msg, pbDetachedSignBlob, cbDetachedSignBlob, TRUE); 00137 if (ret) 00138 { 00139 DWORD i; 00140 00141 for (i = 0; ret && i < cToBeSigned; i++) 00142 ret = CryptMsgUpdate(msg, rgpbToBeSigned[i], rgcbToBeSigned[i], 00143 i == cToBeSigned - 1 ? TRUE : FALSE); 00144 } 00145 if (ret) 00146 { 00147 CERT_INFO *certInfo = CRYPT_GetSignerCertInfoFromMsg(msg, 00148 dwSignerIndex); 00149 00150 ret = FALSE; 00151 if (certInfo) 00152 { 00153 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MSG, 00154 pVerifyPara->dwMsgAndCertEncodingType, 00155 pVerifyPara->hCryptProv, 0, msg); 00156 00157 if (store) 00158 { 00159 PCCERT_CONTEXT cert = CRYPT_GetSignerCertificate( 00160 msg, pVerifyPara, certInfo, store); 00161 00162 if (cert) 00163 { 00164 ret = CryptMsgControl(msg, 0, 00165 CMSG_CTRL_VERIFY_SIGNATURE, cert->pCertInfo); 00166 if (ret && ppSignerCert) 00167 *ppSignerCert = cert; 00168 else 00169 CertFreeCertificateContext(cert); 00170 } 00171 else 00172 SetLastError(CRYPT_E_NOT_FOUND); 00173 CertCloseStore(store, 0); 00174 } 00175 CryptMemFree(certInfo); 00176 } 00177 } 00178 CryptMsgClose(msg); 00179 } 00180 TRACE("returning %d\n", ret); 00181 return ret; 00182 } 00183 00184 BOOL WINAPI CryptVerifyMessageSignature(PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, 00185 DWORD dwSignerIndex, const BYTE* pbSignedBlob, DWORD cbSignedBlob, 00186 BYTE* pbDecoded, DWORD* pcbDecoded, PCCERT_CONTEXT* ppSignerCert) 00187 { 00188 BOOL ret = FALSE; 00189 HCRYPTMSG msg; 00190 00191 TRACE("(%p, %d, %p, %d, %p, %p, %p)\n", 00192 pVerifyPara, dwSignerIndex, pbSignedBlob, cbSignedBlob, 00193 pbDecoded, pcbDecoded, ppSignerCert); 00194 00195 if (ppSignerCert) 00196 *ppSignerCert = NULL; 00197 if (!pVerifyPara || 00198 pVerifyPara->cbSize != sizeof(CRYPT_VERIFY_MESSAGE_PARA) || 00199 GET_CMSG_ENCODING_TYPE(pVerifyPara->dwMsgAndCertEncodingType) != 00200 PKCS_7_ASN_ENCODING) 00201 { 00202 if(pcbDecoded) 00203 *pcbDecoded = 0; 00204 SetLastError(E_INVALIDARG); 00205 return FALSE; 00206 } 00207 00208 msg = CryptMsgOpenToDecode(pVerifyPara->dwMsgAndCertEncodingType, 0, 0, 00209 pVerifyPara->hCryptProv, NULL, NULL); 00210 if (msg) 00211 { 00212 ret = CryptMsgUpdate(msg, pbSignedBlob, cbSignedBlob, TRUE); 00213 if (ret) 00214 { 00215 CERT_INFO *certInfo = CRYPT_GetSignerCertInfoFromMsg(msg, 00216 dwSignerIndex); 00217 00218 ret = FALSE; 00219 if (certInfo) 00220 { 00221 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MSG, 00222 pVerifyPara->dwMsgAndCertEncodingType, 00223 pVerifyPara->hCryptProv, 0, msg); 00224 00225 if (store) 00226 { 00227 PCCERT_CONTEXT cert = CRYPT_GetSignerCertificate( 00228 msg, pVerifyPara, certInfo, store); 00229 00230 if (cert) 00231 { 00232 ret = CryptMsgControl(msg, 0, 00233 CMSG_CTRL_VERIFY_SIGNATURE, cert->pCertInfo); 00234 if (ret && ppSignerCert) 00235 *ppSignerCert = cert; 00236 else 00237 CertFreeCertificateContext(cert); 00238 } 00239 CertCloseStore(store, 0); 00240 } 00241 } 00242 CryptMemFree(certInfo); 00243 } 00244 if (ret) 00245 { 00246 /* The caller is expected to pass a valid pointer to pcbDecoded 00247 * when the message verifies successfully. 00248 */ 00249 if (pcbDecoded) 00250 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, pbDecoded, 00251 pcbDecoded); 00252 else 00253 { 00254 SetLastError(CRYPT_E_NOT_FOUND); 00255 ret = FALSE; 00256 } 00257 } 00258 CryptMsgClose(msg); 00259 } 00260 if(!ret && pcbDecoded) 00261 *pcbDecoded = 0; 00262 TRACE("returning %d\n", ret); 00263 return ret; 00264 } 00265 00266 BOOL WINAPI CryptHashMessage(PCRYPT_HASH_MESSAGE_PARA pHashPara, 00267 BOOL fDetachedHash, DWORD cToBeHashed, const BYTE *rgpbToBeHashed[], 00268 DWORD rgcbToBeHashed[], BYTE *pbHashedBlob, DWORD *pcbHashedBlob, 00269 BYTE *pbComputedHash, DWORD *pcbComputedHash) 00270 { 00271 DWORD i, flags; 00272 BOOL ret = FALSE; 00273 HCRYPTMSG msg; 00274 CMSG_HASHED_ENCODE_INFO info; 00275 00276 TRACE("(%p, %d, %d, %p, %p, %p, %p, %p, %p)\n", pHashPara, fDetachedHash, 00277 cToBeHashed, rgpbToBeHashed, rgcbToBeHashed, pbHashedBlob, pcbHashedBlob, 00278 pbComputedHash, pcbComputedHash); 00279 00280 if (pHashPara->cbSize != sizeof(CRYPT_HASH_MESSAGE_PARA)) 00281 { 00282 SetLastError(E_INVALIDARG); 00283 return FALSE; 00284 } 00285 /* Native seems to ignore any encoding type other than the expected 00286 * PKCS_7_ASN_ENCODING 00287 */ 00288 if (GET_CMSG_ENCODING_TYPE(pHashPara->dwMsgEncodingType) != 00289 PKCS_7_ASN_ENCODING) 00290 return TRUE; 00291 /* Native also seems to do nothing if the output parameter isn't given */ 00292 if (!pcbHashedBlob) 00293 return TRUE; 00294 00295 flags = fDetachedHash ? CMSG_DETACHED_FLAG : 0; 00296 memset(&info, 0, sizeof(info)); 00297 info.cbSize = sizeof(info); 00298 info.hCryptProv = pHashPara->hCryptProv; 00299 memcpy(&info.HashAlgorithm, &pHashPara->HashAlgorithm, 00300 sizeof(info.HashAlgorithm)); 00301 info.pvHashAuxInfo = pHashPara->pvHashAuxInfo; 00302 msg = CryptMsgOpenToEncode(pHashPara->dwMsgEncodingType, flags, CMSG_HASHED, 00303 &info, NULL, NULL); 00304 if (msg) 00305 { 00306 for (i = 0, ret = TRUE; ret && i < cToBeHashed; i++) 00307 ret = CryptMsgUpdate(msg, rgpbToBeHashed[i], rgcbToBeHashed[i], 00308 i == cToBeHashed - 1 ? TRUE : FALSE); 00309 if (ret) 00310 { 00311 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, pbHashedBlob, 00312 pcbHashedBlob); 00313 if (ret && pcbComputedHash) 00314 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, 00315 pbComputedHash, pcbComputedHash); 00316 } 00317 CryptMsgClose(msg); 00318 } 00319 return ret; 00320 } 00321 00322 BOOL WINAPI CryptVerifyDetachedMessageHash(PCRYPT_HASH_MESSAGE_PARA pHashPara, 00323 BYTE *pbDetachedHashBlob, DWORD cbDetachedHashBlob, DWORD cToBeHashed, 00324 const BYTE *rgpbToBeHashed[], DWORD rgcbToBeHashed[], BYTE *pbComputedHash, 00325 DWORD *pcbComputedHash) 00326 { 00327 HCRYPTMSG msg; 00328 BOOL ret = FALSE; 00329 00330 TRACE("(%p, %p, %d, %d, %p, %p, %p, %p)\n", pHashPara, pbDetachedHashBlob, 00331 cbDetachedHashBlob, cToBeHashed, rgpbToBeHashed, rgcbToBeHashed, 00332 pbComputedHash, pcbComputedHash); 00333 00334 if (pHashPara->cbSize != sizeof(CRYPT_HASH_MESSAGE_PARA)) 00335 { 00336 SetLastError(E_INVALIDARG); 00337 return FALSE; 00338 } 00339 if (GET_CMSG_ENCODING_TYPE(pHashPara->dwMsgEncodingType) != 00340 PKCS_7_ASN_ENCODING) 00341 { 00342 SetLastError(E_INVALIDARG); 00343 return FALSE; 00344 } 00345 msg = CryptMsgOpenToDecode(pHashPara->dwMsgEncodingType, CMSG_DETACHED_FLAG, 00346 0, pHashPara->hCryptProv, NULL, NULL); 00347 if (msg) 00348 { 00349 DWORD i; 00350 00351 ret = CryptMsgUpdate(msg, pbDetachedHashBlob, cbDetachedHashBlob, TRUE); 00352 if (ret) 00353 { 00354 if (cToBeHashed) 00355 { 00356 for (i = 0; ret && i < cToBeHashed; i++) 00357 { 00358 ret = CryptMsgUpdate(msg, rgpbToBeHashed[i], 00359 rgcbToBeHashed[i], i == cToBeHashed - 1 ? TRUE : FALSE); 00360 } 00361 } 00362 else 00363 ret = CryptMsgUpdate(msg, NULL, 0, TRUE); 00364 } 00365 if (ret) 00366 { 00367 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL); 00368 if (ret && pcbComputedHash) 00369 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, 00370 pbComputedHash, pcbComputedHash); 00371 } 00372 CryptMsgClose(msg); 00373 } 00374 return ret; 00375 } 00376 00377 BOOL WINAPI CryptVerifyMessageHash(PCRYPT_HASH_MESSAGE_PARA pHashPara, 00378 BYTE *pbHashedBlob, DWORD cbHashedBlob, BYTE *pbToBeHashed, 00379 DWORD *pcbToBeHashed, BYTE *pbComputedHash, DWORD *pcbComputedHash) 00380 { 00381 HCRYPTMSG msg; 00382 BOOL ret = FALSE; 00383 00384 TRACE("(%p, %p, %d, %p, %p, %p, %p)\n", pHashPara, pbHashedBlob, 00385 cbHashedBlob, pbToBeHashed, pcbToBeHashed, pbComputedHash, 00386 pcbComputedHash); 00387 00388 if (pHashPara->cbSize != sizeof(CRYPT_HASH_MESSAGE_PARA)) 00389 { 00390 SetLastError(E_INVALIDARG); 00391 return FALSE; 00392 } 00393 if (GET_CMSG_ENCODING_TYPE(pHashPara->dwMsgEncodingType) != 00394 PKCS_7_ASN_ENCODING) 00395 { 00396 SetLastError(E_INVALIDARG); 00397 return FALSE; 00398 } 00399 msg = CryptMsgOpenToDecode(pHashPara->dwMsgEncodingType, 0, 0, 00400 pHashPara->hCryptProv, NULL, NULL); 00401 if (msg) 00402 { 00403 ret = CryptMsgUpdate(msg, pbHashedBlob, cbHashedBlob, TRUE); 00404 if (ret) 00405 { 00406 ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL); 00407 if (ret && pcbToBeHashed) 00408 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, 00409 pbToBeHashed, pcbToBeHashed); 00410 if (ret && pcbComputedHash) 00411 ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, 00412 pbComputedHash, pcbComputedHash); 00413 } 00414 CryptMsgClose(msg); 00415 } 00416 return ret; 00417 } 00418 00419 BOOL WINAPI CryptSignMessage(PCRYPT_SIGN_MESSAGE_PARA pSignPara, 00420 BOOL fDetachedSignature, DWORD cToBeSigned, const BYTE *rgpbToBeSigned[], 00421 DWORD rgcbToBeSigned[], BYTE *pbSignedBlob, DWORD *pcbSignedBlob) 00422 { 00423 HCRYPTPROV hCryptProv; 00424 BOOL ret, freeProv = FALSE; 00425 DWORD i, keySpec; 00426 PCERT_BLOB certBlob = NULL; 00427 PCRL_BLOB crlBlob = NULL; 00428 CMSG_SIGNED_ENCODE_INFO signInfo; 00429 CMSG_SIGNER_ENCODE_INFO signer; 00430 HCRYPTMSG msg = 0; 00431 00432 TRACE("(%p, %d, %d, %p, %p, %p, %p)\n", pSignPara, fDetachedSignature, 00433 cToBeSigned, rgpbToBeSigned, rgcbToBeSigned, pbSignedBlob, pcbSignedBlob); 00434 00435 if (pSignPara->cbSize != sizeof(CRYPT_SIGN_MESSAGE_PARA) || 00436 GET_CMSG_ENCODING_TYPE(pSignPara->dwMsgEncodingType) != 00437 PKCS_7_ASN_ENCODING) 00438 { 00439 *pcbSignedBlob = 0; 00440 SetLastError(E_INVALIDARG); 00441 return FALSE; 00442 } 00443 if (!pSignPara->pSigningCert) 00444 return TRUE; 00445 00446 ret = CryptAcquireCertificatePrivateKey(pSignPara->pSigningCert, 00447 CRYPT_ACQUIRE_CACHE_FLAG, NULL, &hCryptProv, &keySpec, &freeProv); 00448 if (!ret) 00449 return FALSE; 00450 00451 memset(&signer, 0, sizeof(signer)); 00452 signer.cbSize = sizeof(signer); 00453 signer.pCertInfo = pSignPara->pSigningCert->pCertInfo; 00454 signer.hCryptProv = hCryptProv; 00455 signer.dwKeySpec = keySpec; 00456 signer.HashAlgorithm = pSignPara->HashAlgorithm; 00457 signer.pvHashAuxInfo = pSignPara->pvHashAuxInfo; 00458 signer.cAuthAttr = pSignPara->cAuthAttr; 00459 signer.rgAuthAttr = pSignPara->rgAuthAttr; 00460 signer.cUnauthAttr = pSignPara->cUnauthAttr; 00461 signer.rgUnauthAttr = pSignPara->rgUnauthAttr; 00462 00463 memset(&signInfo, 0, sizeof(signInfo)); 00464 signInfo.cbSize = sizeof(signInfo); 00465 signInfo.cSigners = 1; 00466 signInfo.rgSigners = &signer; 00467 00468 if (pSignPara->cMsgCert) 00469 { 00470 certBlob = CryptMemAlloc(sizeof(CERT_BLOB) * pSignPara->cMsgCert); 00471 if (certBlob) 00472 { 00473 for (i = 0; i < pSignPara->cMsgCert; ++i) 00474 { 00475 certBlob[i].cbData = pSignPara->rgpMsgCert[i]->cbCertEncoded; 00476 certBlob[i].pbData = pSignPara->rgpMsgCert[i]->pbCertEncoded; 00477 } 00478 signInfo.cCertEncoded = pSignPara->cMsgCert; 00479 signInfo.rgCertEncoded = certBlob; 00480 } 00481 else 00482 ret = FALSE; 00483 } 00484 if (pSignPara->cMsgCrl) 00485 { 00486 crlBlob = CryptMemAlloc(sizeof(CRL_BLOB) * pSignPara->cMsgCrl); 00487 if (crlBlob) 00488 { 00489 for (i = 0; i < pSignPara->cMsgCrl; ++i) 00490 { 00491 crlBlob[i].cbData = pSignPara->rgpMsgCrl[i]->cbCrlEncoded; 00492 crlBlob[i].pbData = pSignPara->rgpMsgCrl[i]->pbCrlEncoded; 00493 } 00494 signInfo.cCrlEncoded = pSignPara->cMsgCrl; 00495 signInfo.rgCrlEncoded = crlBlob; 00496 } 00497 else 00498 ret = FALSE; 00499 } 00500 if (pSignPara->dwFlags || pSignPara->dwInnerContentType) 00501 FIXME("unimplemented feature\n"); 00502 00503 if (ret) 00504 msg = CryptMsgOpenToEncode(pSignPara->dwMsgEncodingType, 00505 fDetachedSignature ? CMSG_DETACHED_FLAG : 0, CMSG_SIGNED, &signInfo, 00506 NULL, NULL); 00507 if (msg) 00508 { 00509 if (cToBeSigned) 00510 { 00511 for (i = 0; ret && i < cToBeSigned; ++i) 00512 { 00513 ret = CryptMsgUpdate(msg, rgpbToBeSigned[i], rgcbToBeSigned[i], 00514 i == cToBeSigned - 1 ? TRUE : FALSE); 00515 } 00516 } 00517 else 00518 ret = CryptMsgUpdate(msg, NULL, 0, TRUE); 00519 if (ret) 00520 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, pbSignedBlob, 00521 pcbSignedBlob); 00522 CryptMsgClose(msg); 00523 } 00524 else 00525 ret = FALSE; 00526 00527 CryptMemFree(crlBlob); 00528 CryptMemFree(certBlob); 00529 if (freeProv) 00530 CryptReleaseContext(hCryptProv, 0); 00531 return ret; 00532 } 00533 00534 BOOL WINAPI CryptEncryptMessage(PCRYPT_ENCRYPT_MESSAGE_PARA pEncryptPara, 00535 DWORD cRecipientCert, PCCERT_CONTEXT rgpRecipientCert[], 00536 const BYTE *pbToBeEncrypted, DWORD cbToBeEncrypted, BYTE *pbEncryptedBlob, 00537 DWORD *pcbEncryptedBlob) 00538 { 00539 BOOL ret = TRUE; 00540 DWORD i; 00541 PCERT_INFO *certInfo = NULL; 00542 CMSG_ENVELOPED_ENCODE_INFO envelopedInfo; 00543 HCRYPTMSG msg = 0; 00544 00545 TRACE("(%p, %d, %p, %p, %d, %p, %p)\n", pEncryptPara, cRecipientCert, 00546 rgpRecipientCert, pbToBeEncrypted, cbToBeEncrypted, pbEncryptedBlob, 00547 pcbEncryptedBlob); 00548 00549 if (pEncryptPara->cbSize != sizeof(CRYPT_ENCRYPT_MESSAGE_PARA) || 00550 GET_CMSG_ENCODING_TYPE(pEncryptPara->dwMsgEncodingType) != 00551 PKCS_7_ASN_ENCODING) 00552 { 00553 *pcbEncryptedBlob = 0; 00554 SetLastError(E_INVALIDARG); 00555 return FALSE; 00556 } 00557 00558 memset(&envelopedInfo, 0, sizeof(envelopedInfo)); 00559 envelopedInfo.cbSize = sizeof(envelopedInfo); 00560 envelopedInfo.hCryptProv = pEncryptPara->hCryptProv; 00561 envelopedInfo.ContentEncryptionAlgorithm = 00562 pEncryptPara->ContentEncryptionAlgorithm; 00563 envelopedInfo.pvEncryptionAuxInfo = pEncryptPara->pvEncryptionAuxInfo; 00564 00565 if (cRecipientCert) 00566 { 00567 certInfo = CryptMemAlloc(sizeof(PCERT_INFO) * cRecipientCert); 00568 if (certInfo) 00569 { 00570 for (i = 0; i < cRecipientCert; ++i) 00571 certInfo[i] = rgpRecipientCert[i]->pCertInfo; 00572 envelopedInfo.cRecipients = cRecipientCert; 00573 envelopedInfo.rgpRecipientCert = certInfo; 00574 } 00575 else 00576 ret = FALSE; 00577 } 00578 00579 if (ret) 00580 msg = CryptMsgOpenToEncode(pEncryptPara->dwMsgEncodingType, 0, 00581 CMSG_ENVELOPED, &envelopedInfo, NULL, NULL); 00582 if (msg) 00583 { 00584 ret = CryptMsgUpdate(msg, pbToBeEncrypted, cbToBeEncrypted, TRUE); 00585 if (ret) 00586 ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, pbEncryptedBlob, 00587 pcbEncryptedBlob); 00588 CryptMsgClose(msg); 00589 } 00590 else 00591 ret = FALSE; 00592 00593 CryptMemFree(certInfo); 00594 if (!ret) *pcbEncryptedBlob = 0; 00595 return ret; 00596 } Generated on Fri May 25 2012 04:21:11 for ReactOS by
1.7.6.1
|