ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

message.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.