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