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

softpub.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 #include <stdarg.h>
00019 
00020 #define NONAMELESSUNION
00021 
00022 #include "windef.h"
00023 #include "winbase.h"
00024 #include "wintrust.h"
00025 #include "mssip.h"
00026 #include "softpub.h"
00027 #include "wine/debug.h"
00028 
00029 WINE_DEFAULT_DEBUG_CHANNEL(wintrust);
00030 
00031 HRESULT WINAPI SoftpubDefCertInit(CRYPT_PROVIDER_DATA *data)
00032 {
00033     HRESULT ret = S_FALSE;
00034 
00035     TRACE("(%p)\n", data);
00036 
00037     if (data->padwTrustStepErrors &&
00038      !data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_WVTINIT])
00039         ret = S_OK;
00040     TRACE("returning %08x\n", ret);
00041     return ret;
00042 }
00043 
00044 HRESULT WINAPI SoftpubInitialize(CRYPT_PROVIDER_DATA *data)
00045 {
00046     HRESULT ret = S_FALSE;
00047 
00048     TRACE("(%p)\n", data);
00049 
00050     if (data->padwTrustStepErrors &&
00051      !data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_WVTINIT])
00052         ret = S_OK;
00053     TRACE("returning %08x\n", ret);
00054     return ret;
00055 }
00056 
00057 HRESULT WINAPI DriverInitializePolicy(CRYPT_PROVIDER_DATA *data)
00058 {
00059     FIXME("stub\n");
00060     return S_OK;
00061 }
00062 
00063 HRESULT WINAPI DriverCleanupPolicy(CRYPT_PROVIDER_DATA *data)
00064 {
00065     FIXME("stub\n");
00066     return S_OK;
00067 }
00068 
00069 HRESULT WINAPI DriverFinalPolicy(CRYPT_PROVIDER_DATA *data)
00070 {
00071     FIXME("stub\n");
00072     return S_OK;
00073 }
00074 
00075 /* Assumes data->pWintrustData->u.pFile exists.  Makes sure a file handle is
00076  * open for the file.
00077  */
00078 static DWORD SOFTPUB_OpenFile(CRYPT_PROVIDER_DATA *data)
00079 {
00080     DWORD err = ERROR_SUCCESS;
00081 
00082     /* PSDK implies that all values should be initialized to NULL, so callers
00083      * typically have hFile as NULL rather than INVALID_HANDLE_VALUE.  Check
00084      * for both.
00085      */
00086     if (!data->pWintrustData->u.pFile->hFile ||
00087      data->pWintrustData->u.pFile->hFile == INVALID_HANDLE_VALUE)
00088     {
00089         data->pWintrustData->u.pFile->hFile =
00090             CreateFileW(data->pWintrustData->u.pFile->pcwszFilePath, GENERIC_READ,
00091           FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
00092         if (data->pWintrustData->u.pFile->hFile != INVALID_HANDLE_VALUE)
00093             data->fOpenedFile = TRUE;
00094         else
00095             err = GetLastError();
00096     }
00097     if (!err)
00098         GetFileTime(data->pWintrustData->u.pFile->hFile, &data->sftSystemTime,
00099          NULL, NULL);
00100     TRACE("returning %d\n", err);
00101     return err;
00102 }
00103 
00104 /* Assumes data->pWintrustData->u.pFile exists.  Sets data->pPDSip->gSubject to
00105  * the file's subject GUID.
00106  */
00107 static DWORD SOFTPUB_GetFileSubject(CRYPT_PROVIDER_DATA *data)
00108 {
00109     DWORD err = ERROR_SUCCESS;
00110 
00111     if (!WVT_ISINSTRUCT(WINTRUST_FILE_INFO,
00112      data->pWintrustData->u.pFile->cbStruct, pgKnownSubject) ||
00113      !data->pWintrustData->u.pFile->pgKnownSubject)
00114     {
00115         if (!CryptSIPRetrieveSubjectGuid(
00116          data->pWintrustData->u.pFile->pcwszFilePath,
00117          data->pWintrustData->u.pFile->hFile,
00118          &data->u.pPDSip->gSubject))
00119             err = GetLastError();
00120     }
00121     else
00122         data->u.pPDSip->gSubject = *data->pWintrustData->u.pFile->pgKnownSubject;
00123     TRACE("returning %d\n", err);
00124     return err;
00125 }
00126 
00127 /* Assumes data->u.pPDSip exists, and its gSubject member set.
00128  * Allocates data->u.pPDSip->pSip and loads it, if possible.
00129  */
00130 static DWORD SOFTPUB_GetSIP(CRYPT_PROVIDER_DATA *data)
00131 {
00132     DWORD err = ERROR_SUCCESS;
00133 
00134     data->u.pPDSip->pSip = data->psPfns->pfnAlloc(sizeof(SIP_DISPATCH_INFO));
00135     if (data->u.pPDSip->pSip)
00136     {
00137         if (!CryptSIPLoad(&data->u.pPDSip->gSubject, 0, data->u.pPDSip->pSip))
00138             err = GetLastError();
00139     }
00140     else
00141         err = ERROR_OUTOFMEMORY;
00142     TRACE("returning %d\n", err);
00143     return err;
00144 }
00145 
00146 /* Assumes data->u.pPDSip has been loaded, and data->u.pPDSip->pSip allocated.
00147  * Calls data->u.pPDSip->pSip->pfGet to construct data->hMsg.
00148  */
00149 static DWORD SOFTPUB_GetMessageFromFile(CRYPT_PROVIDER_DATA *data, HANDLE file,
00150  LPCWSTR filePath)
00151 {
00152     DWORD err = ERROR_SUCCESS;
00153     BOOL ret;
00154     LPBYTE buf = NULL;
00155     DWORD size = 0;
00156 
00157     data->u.pPDSip->psSipSubjectInfo =
00158      data->psPfns->pfnAlloc(sizeof(SIP_SUBJECTINFO));
00159     if (!data->u.pPDSip->psSipSubjectInfo)
00160         return ERROR_OUTOFMEMORY;
00161 
00162     data->u.pPDSip->psSipSubjectInfo->cbSize = sizeof(SIP_SUBJECTINFO);
00163     data->u.pPDSip->psSipSubjectInfo->pgSubjectType = &data->u.pPDSip->gSubject;
00164     data->u.pPDSip->psSipSubjectInfo->hFile = file;
00165     data->u.pPDSip->psSipSubjectInfo->pwsFileName = filePath;
00166     data->u.pPDSip->psSipSubjectInfo->hProv = data->hProv;
00167     ret = data->u.pPDSip->pSip->pfGet(data->u.pPDSip->psSipSubjectInfo,
00168      &data->dwEncoding, 0, &size, 0);
00169     if (!ret)
00170         return TRUST_E_NOSIGNATURE;
00171 
00172     buf = data->psPfns->pfnAlloc(size);
00173     if (!buf)
00174         return ERROR_OUTOFMEMORY;
00175 
00176     ret = data->u.pPDSip->pSip->pfGet(data->u.pPDSip->psSipSubjectInfo,
00177      &data->dwEncoding, 0, &size, buf);
00178     if (ret)
00179     {
00180         data->hMsg = CryptMsgOpenToDecode(data->dwEncoding, 0, 0, data->hProv,
00181          NULL, NULL);
00182         if (data->hMsg)
00183         {
00184             ret = CryptMsgUpdate(data->hMsg, buf, size, TRUE);
00185             if (!ret)
00186                 err = GetLastError();
00187         }
00188     }
00189     else
00190         err = GetLastError();
00191 
00192     data->psPfns->pfnFree(buf);
00193     TRACE("returning %d\n", err);
00194     return err;
00195 }
00196 
00197 static DWORD SOFTPUB_CreateStoreFromMessage(CRYPT_PROVIDER_DATA *data)
00198 {
00199     DWORD err = ERROR_SUCCESS;
00200     HCERTSTORE store;
00201 
00202     store = CertOpenStore(CERT_STORE_PROV_MSG, data->dwEncoding,
00203      data->hProv, CERT_STORE_NO_CRYPT_RELEASE_FLAG, data->hMsg);
00204     if (store)
00205     {
00206         if (!data->psPfns->pfnAddStore2Chain(data, store))
00207             err = GetLastError();
00208         CertCloseStore(store, 0);
00209     }
00210     else
00211         err = GetLastError();
00212     TRACE("returning %d\n", err);
00213     return err;
00214 }
00215 
00216 static DWORD SOFTPUB_DecodeInnerContent(CRYPT_PROVIDER_DATA *data)
00217 {
00218     BOOL ret;
00219     DWORD size, err = ERROR_SUCCESS;
00220     LPSTR oid = NULL;
00221     LPBYTE buf = NULL;
00222 
00223     ret = CryptMsgGetParam(data->hMsg, CMSG_INNER_CONTENT_TYPE_PARAM, 0, NULL,
00224      &size);
00225     if (!ret)
00226     {
00227         err = GetLastError();
00228         goto error;
00229     }
00230     oid = data->psPfns->pfnAlloc(size);
00231     if (!oid)
00232     {
00233         err = ERROR_OUTOFMEMORY;
00234         goto error;
00235     }
00236     ret = CryptMsgGetParam(data->hMsg, CMSG_INNER_CONTENT_TYPE_PARAM, 0, oid,
00237      &size);
00238     if (!ret)
00239     {
00240         err = GetLastError();
00241         goto error;
00242     }
00243     ret = CryptMsgGetParam(data->hMsg, CMSG_CONTENT_PARAM, 0, NULL, &size);
00244     if (!ret)
00245     {
00246         err = GetLastError();
00247         goto error;
00248     }
00249     buf = data->psPfns->pfnAlloc(size);
00250     if (!buf)
00251     {
00252         err = ERROR_OUTOFMEMORY;
00253         goto error;
00254     }
00255     ret = CryptMsgGetParam(data->hMsg, CMSG_CONTENT_PARAM, 0, buf, &size);
00256     if (!ret)
00257     {
00258         err = GetLastError();
00259         goto error;
00260     }
00261     ret = CryptDecodeObject(data->dwEncoding, oid, buf, size, 0, NULL, &size);
00262     if (!ret)
00263     {
00264         err = GetLastError();
00265         goto error;
00266     }
00267     data->u.pPDSip->psIndirectData = data->psPfns->pfnAlloc(size);
00268     if (!data->u.pPDSip->psIndirectData)
00269     {
00270         err = ERROR_OUTOFMEMORY;
00271         goto error;
00272     }
00273     ret = CryptDecodeObject(data->dwEncoding, oid, buf, size, 0,
00274      data->u.pPDSip->psIndirectData, &size);
00275     if (!ret)
00276         err = GetLastError();
00277 
00278 error:
00279     TRACE("returning %d\n", err);
00280     data->psPfns->pfnFree(oid);
00281     data->psPfns->pfnFree(buf);
00282     return err;
00283 }
00284 
00285 static DWORD SOFTPUB_LoadCertMessage(CRYPT_PROVIDER_DATA *data)
00286 {
00287     DWORD err = ERROR_SUCCESS;
00288 
00289     if (data->pWintrustData->u.pCert &&
00290      WVT_IS_CBSTRUCT_GT_MEMBEROFFSET(WINTRUST_CERT_INFO,
00291      data->pWintrustData->u.pCert->cbStruct, psCertContext))
00292     {
00293         if (data->psPfns)
00294         {
00295             CRYPT_PROVIDER_SGNR signer = { sizeof(signer), { 0 } };
00296             DWORD i;
00297             BOOL ret;
00298 
00299             /* Add a signer with nothing but the time to verify, so we can
00300              * add a cert to it
00301              */
00302             if (WVT_ISINSTRUCT(WINTRUST_CERT_INFO,
00303              data->pWintrustData->u.pCert->cbStruct, psftVerifyAsOf) &&
00304              data->pWintrustData->u.pCert->psftVerifyAsOf)
00305                 data->sftSystemTime = signer.sftVerifyAsOf;
00306             else
00307             {
00308                 SYSTEMTIME sysTime;
00309 
00310                 GetSystemTime(&sysTime);
00311                 SystemTimeToFileTime(&sysTime, &signer.sftVerifyAsOf);
00312             }
00313             ret = data->psPfns->pfnAddSgnr2Chain(data, FALSE, 0, &signer);
00314             if (ret)
00315             {
00316                 ret = data->psPfns->pfnAddCert2Chain(data, 0, FALSE, 0,
00317                  data->pWintrustData->u.pCert->psCertContext);
00318                 if (WVT_ISINSTRUCT(WINTRUST_CERT_INFO,
00319                  data->pWintrustData->u.pCert->cbStruct, pahStores))
00320                         for (i = 0;
00321                          ret && i < data->pWintrustData->u.pCert->chStores; i++)
00322                             ret = data->psPfns->pfnAddStore2Chain(data,
00323                              data->pWintrustData->u.pCert->pahStores[i]);
00324             }
00325             if (!ret)
00326                 err = GetLastError();
00327         }
00328     }
00329     else
00330         err = ERROR_INVALID_PARAMETER;
00331     return err;
00332 }
00333 
00334 static DWORD SOFTPUB_LoadFileMessage(CRYPT_PROVIDER_DATA *data)
00335 {
00336     DWORD err = ERROR_SUCCESS;
00337 
00338     if (!data->pWintrustData->u.pFile)
00339     {
00340         err = ERROR_INVALID_PARAMETER;
00341         goto error;
00342     }
00343     err = SOFTPUB_OpenFile(data);
00344     if (err)
00345         goto error;
00346     err = SOFTPUB_GetFileSubject(data);
00347     if (err)
00348         goto error;
00349     err = SOFTPUB_GetSIP(data);
00350     if (err)
00351         goto error;
00352     err = SOFTPUB_GetMessageFromFile(data, data->pWintrustData->u.pFile->hFile,
00353      data->pWintrustData->u.pFile->pcwszFilePath);
00354     if (err)
00355         goto error;
00356     err = SOFTPUB_CreateStoreFromMessage(data);
00357     if (err)
00358         goto error;
00359     err = SOFTPUB_DecodeInnerContent(data);
00360 
00361 error:
00362     if (err && data->fOpenedFile && data->pWintrustData->u.pFile)
00363     {
00364         /* The caller won't expect the file to be open on failure, so close it.
00365          */
00366         CloseHandle(data->pWintrustData->u.pFile->hFile);
00367         data->pWintrustData->u.pFile->hFile = INVALID_HANDLE_VALUE;
00368         data->fOpenedFile = FALSE;
00369     }
00370     return err;
00371 }
00372 
00373 static DWORD SOFTPUB_LoadCatalogMessage(CRYPT_PROVIDER_DATA *data)
00374 {
00375     DWORD err;
00376     HANDLE catalog = INVALID_HANDLE_VALUE;
00377 
00378     if (!data->pWintrustData->u.pCatalog)
00379     {
00380         SetLastError(ERROR_INVALID_PARAMETER);
00381         return FALSE;
00382     }
00383     catalog = CreateFileW(data->pWintrustData->u.pCatalog->pcwszCatalogFilePath,
00384      GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
00385      NULL);
00386     if (catalog == INVALID_HANDLE_VALUE)
00387         return GetLastError();
00388     if (!CryptSIPRetrieveSubjectGuid(
00389      data->pWintrustData->u.pCatalog->pcwszCatalogFilePath, catalog,
00390      &data->u.pPDSip->gSubject))
00391     {
00392         err = GetLastError();
00393         goto error;
00394     }
00395     err = SOFTPUB_GetSIP(data);
00396     if (err)
00397         goto error;
00398     err = SOFTPUB_GetMessageFromFile(data, catalog,
00399      data->pWintrustData->u.pCatalog->pcwszCatalogFilePath);
00400     if (err)
00401         goto error;
00402     err = SOFTPUB_CreateStoreFromMessage(data);
00403     if (err)
00404         goto error;
00405     err = SOFTPUB_DecodeInnerContent(data);
00406     /* FIXME: this loads the catalog file, but doesn't validate the member. */
00407 error:
00408     CloseHandle(catalog);
00409     return err;
00410 }
00411 
00412 HRESULT WINAPI SoftpubLoadMessage(CRYPT_PROVIDER_DATA *data)
00413 {
00414     DWORD err = ERROR_SUCCESS;
00415 
00416     TRACE("(%p)\n", data);
00417 
00418     if (!data->padwTrustStepErrors)
00419         return S_FALSE;
00420 
00421     switch (data->pWintrustData->dwUnionChoice)
00422     {
00423     case WTD_CHOICE_CERT:
00424         err = SOFTPUB_LoadCertMessage(data);
00425         break;
00426     case WTD_CHOICE_FILE:
00427         err = SOFTPUB_LoadFileMessage(data);
00428         break;
00429     case WTD_CHOICE_CATALOG:
00430         err = SOFTPUB_LoadCatalogMessage(data);
00431         break;
00432     default:
00433         FIXME("unimplemented for %d\n", data->pWintrustData->dwUnionChoice);
00434         err = ERROR_INVALID_PARAMETER;
00435     }
00436 
00437     if (err)
00438         data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] = err;
00439     TRACE("returning %d (%08x)\n", !err ? S_OK : S_FALSE,
00440      data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]);
00441     return !err ? S_OK : S_FALSE;
00442 }
00443 
00444 static CMSG_SIGNER_INFO *WINTRUST_GetSigner(CRYPT_PROVIDER_DATA *data,
00445  DWORD signerIdx)
00446 {
00447     BOOL ret;
00448     CMSG_SIGNER_INFO *signerInfo = NULL;
00449     DWORD size;
00450 
00451     ret = CryptMsgGetParam(data->hMsg, CMSG_SIGNER_INFO_PARAM, signerIdx,
00452      NULL, &size);
00453     if (ret)
00454     {
00455         signerInfo = data->psPfns->pfnAlloc(size);
00456         if (signerInfo)
00457         {
00458             ret = CryptMsgGetParam(data->hMsg, CMSG_SIGNER_INFO_PARAM,
00459              signerIdx, signerInfo, &size);
00460             if (!ret)
00461             {
00462                 data->psPfns->pfnFree(signerInfo);
00463                 signerInfo = NULL;
00464             }
00465         }
00466         else
00467             SetLastError(ERROR_OUTOFMEMORY);
00468     }
00469     return signerInfo;
00470 }
00471 
00472 static DWORD WINTRUST_SaveSigner(CRYPT_PROVIDER_DATA *data, DWORD signerIdx)
00473 {
00474     DWORD err;
00475     CMSG_SIGNER_INFO *signerInfo = WINTRUST_GetSigner(data, signerIdx);
00476 
00477     if (signerInfo)
00478     {
00479         CRYPT_PROVIDER_SGNR sgnr = { sizeof(sgnr), { 0 } };
00480 
00481         sgnr.psSigner = signerInfo;
00482         sgnr.sftVerifyAsOf = data->sftSystemTime;
00483         if (!data->psPfns->pfnAddSgnr2Chain(data, FALSE, signerIdx, &sgnr))
00484             err = GetLastError();
00485         else
00486             err = ERROR_SUCCESS;
00487     }
00488     else
00489         err = GetLastError();
00490     return err;
00491 }
00492 
00493 static CERT_INFO *WINTRUST_GetSignerCertInfo(CRYPT_PROVIDER_DATA *data,
00494  DWORD signerIdx)
00495 {
00496     BOOL ret;
00497     CERT_INFO *certInfo = NULL;
00498     DWORD size;
00499 
00500     ret = CryptMsgGetParam(data->hMsg, CMSG_SIGNER_CERT_INFO_PARAM, signerIdx,
00501      NULL, &size);
00502     if (ret)
00503     {
00504         certInfo = data->psPfns->pfnAlloc(size);
00505         if (certInfo)
00506         {
00507             ret = CryptMsgGetParam(data->hMsg, CMSG_SIGNER_CERT_INFO_PARAM,
00508              signerIdx, certInfo, &size);
00509             if (!ret)
00510             {
00511                 data->psPfns->pfnFree(certInfo);
00512                 certInfo = NULL;
00513             }
00514         }
00515         else
00516             SetLastError(ERROR_OUTOFMEMORY);
00517     }
00518     return certInfo;
00519 }
00520 
00521 static DWORD WINTRUST_VerifySigner(CRYPT_PROVIDER_DATA *data, DWORD signerIdx)
00522 {
00523     DWORD err;
00524     CERT_INFO *certInfo = WINTRUST_GetSignerCertInfo(data, signerIdx);
00525 
00526     if (certInfo)
00527     {
00528         PCCERT_CONTEXT subject = CertGetSubjectCertificateFromStore(
00529          data->pahStores[0], data->dwEncoding, certInfo);
00530 
00531         if (subject)
00532         {
00533             CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA para = { sizeof(para), 0,
00534              signerIdx, CMSG_VERIFY_SIGNER_CERT, (LPVOID)subject };
00535 
00536             if (!CryptMsgControl(data->hMsg, 0, CMSG_CTRL_VERIFY_SIGNATURE_EX,
00537              &para))
00538                 err = TRUST_E_CERT_SIGNATURE;
00539             else
00540             {
00541                 data->psPfns->pfnAddCert2Chain(data, signerIdx, FALSE, 0,
00542                  subject);
00543                 err = ERROR_SUCCESS;
00544             }
00545             CertFreeCertificateContext(subject);
00546         }
00547         else
00548             err = TRUST_E_NO_SIGNER_CERT;
00549         data->psPfns->pfnFree(certInfo);
00550     }
00551     else
00552         err = GetLastError();
00553     return err;
00554 }
00555 
00556 HRESULT WINAPI SoftpubLoadSignature(CRYPT_PROVIDER_DATA *data)
00557 {
00558     DWORD err;
00559 
00560     TRACE("(%p)\n", data);
00561 
00562     if (!data->padwTrustStepErrors)
00563         return S_FALSE;
00564 
00565     if (data->hMsg)
00566     {
00567         DWORD signerCount, size;
00568 
00569         size = sizeof(signerCount);
00570         if (CryptMsgGetParam(data->hMsg, CMSG_SIGNER_COUNT_PARAM, 0,
00571          &signerCount, &size))
00572         {
00573             DWORD i;
00574 
00575             err = ERROR_SUCCESS;
00576             for (i = 0; !err && i < signerCount; i++)
00577             {
00578                 if (!(err = WINTRUST_SaveSigner(data, i)))
00579                     err = WINTRUST_VerifySigner(data, i);
00580             }
00581         }
00582         else
00583             err = TRUST_E_NOSIGNATURE;
00584     }
00585     else
00586         err = ERROR_SUCCESS;
00587     if (err)
00588         data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_SIGPROV] = err;
00589     return !err ? S_OK : S_FALSE;
00590 }
00591 
00592 static DWORD WINTRUST_TrustStatusToConfidence(DWORD errorStatus)
00593 {
00594     DWORD confidence = 0;
00595 
00596     confidence = 0;
00597     if (!(errorStatus & CERT_TRUST_IS_NOT_SIGNATURE_VALID))
00598         confidence |= CERT_CONFIDENCE_SIG;
00599     if (!(errorStatus & CERT_TRUST_IS_NOT_TIME_VALID))
00600         confidence |= CERT_CONFIDENCE_TIME;
00601     if (!(errorStatus & CERT_TRUST_IS_NOT_TIME_NESTED))
00602         confidence |= CERT_CONFIDENCE_TIMENEST;
00603     return confidence;
00604 }
00605 
00606 BOOL WINAPI SoftpubCheckCert(CRYPT_PROVIDER_DATA *data, DWORD idxSigner,
00607  BOOL fCounterSignerChain, DWORD idxCounterSigner)
00608 {
00609     BOOL ret;
00610 
00611     TRACE("(%p, %d, %d, %d)\n", data, idxSigner, fCounterSignerChain,
00612      idxCounterSigner);
00613 
00614     if (fCounterSignerChain)
00615     {
00616         FIXME("unimplemented for counter signers\n");
00617         ret = FALSE;
00618     }
00619     else
00620     {
00621         PCERT_SIMPLE_CHAIN simpleChain =
00622          data->pasSigners[idxSigner].pChainContext->rgpChain[0];
00623         DWORD i;
00624 
00625         ret = TRUE;
00626         for (i = 0; i < simpleChain->cElement; i++)
00627         {
00628             /* Set confidence */
00629             data->pasSigners[idxSigner].pasCertChain[i].dwConfidence =
00630              WINTRUST_TrustStatusToConfidence(
00631              simpleChain->rgpElement[i]->TrustStatus.dwErrorStatus);
00632             /* Set additional flags */
00633             if (!(simpleChain->rgpElement[i]->TrustStatus.dwErrorStatus &
00634              CERT_TRUST_IS_UNTRUSTED_ROOT))
00635                 data->pasSigners[idxSigner].pasCertChain[i].fTrustedRoot = TRUE;
00636             if (simpleChain->rgpElement[i]->TrustStatus.dwInfoStatus &
00637              CERT_TRUST_IS_SELF_SIGNED)
00638                 data->pasSigners[idxSigner].pasCertChain[i].fSelfSigned = TRUE;
00639             if (simpleChain->rgpElement[i]->TrustStatus.dwErrorStatus &
00640              CERT_TRUST_IS_CYCLIC)
00641                 data->pasSigners[idxSigner].pasCertChain[i].fIsCyclic = TRUE;
00642         }
00643     }
00644     return ret;
00645 }
00646 
00647 static DWORD WINTRUST_TrustStatusToError(DWORD errorStatus)
00648 {
00649     DWORD error;
00650 
00651     if (errorStatus & CERT_TRUST_IS_NOT_SIGNATURE_VALID)
00652         error = TRUST_E_CERT_SIGNATURE;
00653     else if (errorStatus & CERT_TRUST_IS_UNTRUSTED_ROOT)
00654         error = CERT_E_UNTRUSTEDROOT;
00655     else if (errorStatus & CERT_TRUST_IS_NOT_TIME_VALID)
00656         error = CERT_E_EXPIRED;
00657     else if (errorStatus & CERT_TRUST_IS_NOT_TIME_NESTED)
00658         error = CERT_E_VALIDITYPERIODNESTING;
00659     else if (errorStatus & CERT_TRUST_IS_REVOKED)
00660         error = CERT_E_REVOKED;
00661     else if (errorStatus & CERT_TRUST_IS_OFFLINE_REVOCATION ||
00662      errorStatus & CERT_TRUST_REVOCATION_STATUS_UNKNOWN)
00663         error = CERT_E_REVOCATION_FAILURE;
00664     else if (errorStatus & CERT_TRUST_IS_NOT_VALID_FOR_USAGE)
00665         error = CERT_E_WRONG_USAGE;
00666     else if (errorStatus & CERT_TRUST_IS_CYCLIC)
00667         error = CERT_E_CHAINING;
00668     else if (errorStatus & CERT_TRUST_INVALID_EXTENSION)
00669         error = CERT_E_CRITICAL;
00670     else if (errorStatus & CERT_TRUST_INVALID_POLICY_CONSTRAINTS)
00671         error = CERT_E_INVALID_POLICY;
00672     else if (errorStatus & CERT_TRUST_INVALID_BASIC_CONSTRAINTS)
00673         error = TRUST_E_BASIC_CONSTRAINTS;
00674     else if (errorStatus & CERT_TRUST_INVALID_NAME_CONSTRAINTS ||
00675      errorStatus & CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT ||
00676      errorStatus & CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT ||
00677      errorStatus & CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT ||
00678      errorStatus & CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT)
00679         error = CERT_E_INVALID_NAME;
00680     else if (errorStatus & CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY)
00681         error = CERT_E_INVALID_POLICY;
00682     else if (errorStatus)
00683     {
00684         FIXME("unknown error status %08x\n", errorStatus);
00685         error = TRUST_E_SYSTEM_ERROR;
00686     }
00687     else
00688         error = S_OK;
00689     return error;
00690 }
00691 
00692 static DWORD WINTRUST_CopyChain(CRYPT_PROVIDER_DATA *data, DWORD signerIdx)
00693 {
00694     DWORD err, i;
00695     PCERT_SIMPLE_CHAIN simpleChain =
00696      data->pasSigners[signerIdx].pChainContext->rgpChain[0];
00697 
00698     data->pasSigners[signerIdx].pasCertChain[0].dwConfidence =
00699      WINTRUST_TrustStatusToConfidence(
00700      simpleChain->rgpElement[0]->TrustStatus.dwErrorStatus);
00701     data->pasSigners[signerIdx].pasCertChain[0].pChainElement =
00702      simpleChain->rgpElement[0];
00703     err = ERROR_SUCCESS;
00704     for (i = 1; !err && i < simpleChain->cElement; i++)
00705     {
00706         if (data->psPfns->pfnAddCert2Chain(data, signerIdx, FALSE, 0,
00707          simpleChain->rgpElement[i]->pCertContext))
00708         {
00709             data->pasSigners[signerIdx].pasCertChain[i].pChainElement =
00710              simpleChain->rgpElement[i];
00711             data->pasSigners[signerIdx].pasCertChain[i].dwConfidence =
00712              WINTRUST_TrustStatusToConfidence(
00713              simpleChain->rgpElement[i]->TrustStatus.dwErrorStatus);
00714         }
00715         else
00716             err = GetLastError();
00717     }
00718     data->pasSigners[signerIdx].pasCertChain[simpleChain->cElement - 1].dwError
00719      = WINTRUST_TrustStatusToError(
00720      simpleChain->rgpElement[simpleChain->cElement - 1]->
00721      TrustStatus.dwErrorStatus);
00722     return err;
00723 }
00724 
00725 static void WINTRUST_CreateChainPolicyCreateInfo(
00726  const CRYPT_PROVIDER_DATA *data, PWTD_GENERIC_CHAIN_POLICY_CREATE_INFO info,
00727  PCERT_CHAIN_PARA chainPara)
00728 {
00729     chainPara->cbSize = sizeof(CERT_CHAIN_PARA);
00730     if (data->pRequestUsage)
00731         chainPara->RequestedUsage = *data->pRequestUsage;
00732     else
00733     {
00734         chainPara->RequestedUsage.dwType = 0;
00735         chainPara->RequestedUsage.Usage.cUsageIdentifier = 0;
00736     }
00737     info->u.cbSize = sizeof(WTD_GENERIC_CHAIN_POLICY_CREATE_INFO);
00738     info->hChainEngine = NULL;
00739     info->pChainPara = chainPara;
00740     if (data->dwProvFlags & CPD_REVOCATION_CHECK_END_CERT)
00741         info->dwFlags = CERT_CHAIN_REVOCATION_CHECK_END_CERT;
00742     else if (data->dwProvFlags & CPD_REVOCATION_CHECK_CHAIN)
00743         info->dwFlags = CERT_CHAIN_REVOCATION_CHECK_CHAIN;
00744     else if (data->dwProvFlags & CPD_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT)
00745         info->dwFlags = CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT;
00746     else
00747         info->dwFlags = 0;
00748     info->pvReserved = NULL;
00749 }
00750 
00751 static DWORD WINTRUST_CreateChainForSigner(CRYPT_PROVIDER_DATA *data,
00752  DWORD signer, PWTD_GENERIC_CHAIN_POLICY_CREATE_INFO createInfo,
00753  PCERT_CHAIN_PARA chainPara)
00754 {
00755     DWORD err = ERROR_SUCCESS;
00756     HCERTSTORE store = NULL;
00757 
00758     if (data->chStores)
00759     {
00760         store = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
00761          CERT_STORE_CREATE_NEW_FLAG, NULL);
00762         if (store)
00763         {
00764             DWORD i;
00765 
00766             for (i = 0; i < data->chStores; i++)
00767                 CertAddStoreToCollection(store, data->pahStores[i], 0, 0);
00768         }
00769         else
00770             err = GetLastError();
00771     }
00772     if (!err)
00773     {
00774         /* Expect the end certificate for each signer to be the only cert in
00775          * the chain:
00776          */
00777         if (data->pasSigners[signer].csCertChain)
00778         {
00779             BOOL ret;
00780 
00781             /* Create a certificate chain for each signer */
00782             ret = CertGetCertificateChain(createInfo->hChainEngine,
00783              data->pasSigners[signer].pasCertChain[0].pCert,
00784              &data->pasSigners[signer].sftVerifyAsOf, store,
00785              chainPara, createInfo->dwFlags, createInfo->pvReserved,
00786              &data->pasSigners[signer].pChainContext);
00787             if (ret)
00788             {
00789                 if (data->pasSigners[signer].pChainContext->cChain != 1)
00790                 {
00791                     FIXME("unimplemented for more than 1 simple chain\n");
00792                     err = E_NOTIMPL;
00793                 }
00794                 else
00795                 {
00796                     if (!(err = WINTRUST_CopyChain(data, signer)))
00797                     {
00798                         if (data->psPfns->pfnCertCheckPolicy)
00799                         {
00800                             ret = data->psPfns->pfnCertCheckPolicy(data, signer,
00801                              FALSE, 0);
00802                             if (!ret)
00803                                 err = GetLastError();
00804                         }
00805                         else
00806                             TRACE(
00807                              "no cert check policy, skipping policy check\n");
00808                     }
00809                 }
00810             }
00811             else
00812                 err = GetLastError();
00813         }
00814         CertCloseStore(store, 0);
00815     }
00816     return err;
00817 }
00818 
00819 HRESULT WINAPI WintrustCertificateTrust(CRYPT_PROVIDER_DATA *data)
00820 {
00821     DWORD err;
00822 
00823     TRACE("(%p)\n", data);
00824 
00825     if (!data->csSigners)
00826         err = TRUST_E_NOSIGNATURE;
00827     else
00828     {
00829         DWORD i;
00830         WTD_GENERIC_CHAIN_POLICY_CREATE_INFO createInfo;
00831         CERT_CHAIN_PARA chainPara;
00832 
00833         WINTRUST_CreateChainPolicyCreateInfo(data, &createInfo, &chainPara);
00834         err = ERROR_SUCCESS;
00835         for (i = 0; !err && i < data->csSigners; i++)
00836             err = WINTRUST_CreateChainForSigner(data, i, &createInfo,
00837              &chainPara);
00838     }
00839     if (err)
00840         data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTPROV] = err;
00841     TRACE("returning %d (%08x)\n", !err ? S_OK : S_FALSE,
00842      data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTPROV]);
00843     return !err ? S_OK : S_FALSE;
00844 }
00845 
00846 HRESULT WINAPI GenericChainCertificateTrust(CRYPT_PROVIDER_DATA *data)
00847 {
00848     DWORD err;
00849     WTD_GENERIC_CHAIN_POLICY_DATA *policyData =
00850      data->pWintrustData->pPolicyCallbackData;
00851 
00852     TRACE("(%p)\n", data);
00853 
00854     if (policyData && policyData->u.cbSize !=
00855      sizeof(WTD_GENERIC_CHAIN_POLICY_CREATE_INFO))
00856     {
00857         err = ERROR_INVALID_PARAMETER;
00858         goto end;
00859     }
00860     if (!data->csSigners)
00861         err = TRUST_E_NOSIGNATURE;
00862     else
00863     {
00864         DWORD i;
00865         WTD_GENERIC_CHAIN_POLICY_CREATE_INFO createInfo, *pCreateInfo;
00866         CERT_CHAIN_PARA chainPara, *pChainPara;
00867 
00868         if (policyData)
00869         {
00870             pCreateInfo = policyData->pSignerChainInfo;
00871             pChainPara = pCreateInfo->pChainPara;
00872         }
00873         else
00874         {
00875             WINTRUST_CreateChainPolicyCreateInfo(data, &createInfo, &chainPara);
00876             pChainPara = &chainPara;
00877             pCreateInfo = &createInfo;
00878         }
00879         err = ERROR_SUCCESS;
00880         for (i = 0; !err && i < data->csSigners; i++)
00881             err = WINTRUST_CreateChainForSigner(data, i, pCreateInfo,
00882              pChainPara);
00883     }
00884 
00885 end:
00886     if (err)
00887         data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTPROV] = err;
00888     TRACE("returning %d (%08x)\n", !err ? S_OK : S_FALSE,
00889      data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTPROV]);
00890     return !err ? S_OK : S_FALSE;
00891 }
00892 
00893 HRESULT WINAPI SoftpubAuthenticode(CRYPT_PROVIDER_DATA *data)
00894 {
00895     BOOL ret;
00896     CERT_CHAIN_POLICY_STATUS policyStatus = { sizeof(policyStatus), 0 };
00897 
00898     TRACE("(%p)\n", data);
00899 
00900     if (data->pWintrustData->dwUIChoice != WTD_UI_NONE)
00901         FIXME("unimplemented for UI choice %d\n",
00902          data->pWintrustData->dwUIChoice);
00903     if (!data->csSigners)
00904     {
00905         ret = FALSE;
00906         policyStatus.dwError = TRUST_E_NOSIGNATURE;
00907     }
00908     else
00909     {
00910         DWORD i;
00911 
00912         ret = TRUE;
00913         for (i = 0; ret && i < data->csSigners; i++)
00914         {
00915             BYTE hash[20];
00916             DWORD size = sizeof(hash);
00917 
00918             /* First make sure cert isn't disallowed */
00919             if ((ret = CertGetCertificateContextProperty(
00920              data->pasSigners[i].pasCertChain[0].pCert,
00921              CERT_SIGNATURE_HASH_PROP_ID, hash, &size)))
00922             {
00923                 static const WCHAR disallowedW[] =
00924                  { 'D','i','s','a','l','l','o','w','e','d',0 };
00925                 HCERTSTORE disallowed = CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
00926                  X509_ASN_ENCODING, 0, CERT_SYSTEM_STORE_CURRENT_USER,
00927                  disallowedW);
00928 
00929                 if (disallowed)
00930                 {
00931                     PCCERT_CONTEXT found = CertFindCertificateInStore(
00932                      disallowed, X509_ASN_ENCODING, 0, CERT_FIND_SIGNATURE_HASH,
00933                      hash, NULL);
00934 
00935                     if (found)
00936                     {
00937                         /* Disallowed!  Can't verify it. */
00938                         policyStatus.dwError = TRUST_E_SUBJECT_NOT_TRUSTED;
00939                         ret = FALSE;
00940                         CertFreeCertificateContext(found);
00941                     }
00942                     CertCloseStore(disallowed, 0);
00943                 }
00944             }
00945             if (ret)
00946             {
00947                 CERT_CHAIN_POLICY_PARA policyPara = { sizeof(policyPara), 0 };
00948 
00949                 if (data->dwRegPolicySettings & WTPF_TRUSTTEST)
00950                     policyPara.dwFlags |= CERT_CHAIN_POLICY_TRUST_TESTROOT_FLAG;
00951                 if (data->dwRegPolicySettings & WTPF_TESTCANBEVALID)
00952                     policyPara.dwFlags |= CERT_CHAIN_POLICY_ALLOW_TESTROOT_FLAG;
00953                 if (data->dwRegPolicySettings & WTPF_IGNOREEXPIRATION)
00954                     policyPara.dwFlags |=
00955                      CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG |
00956                      CERT_CHAIN_POLICY_IGNORE_CTL_NOT_TIME_VALID_FLAG |
00957                      CERT_CHAIN_POLICY_IGNORE_NOT_TIME_NESTED_FLAG;
00958                 if (data->dwRegPolicySettings & WTPF_IGNOREREVOKATION)
00959                     policyPara.dwFlags |=
00960                      CERT_CHAIN_POLICY_IGNORE_END_REV_UNKNOWN_FLAG |
00961                      CERT_CHAIN_POLICY_IGNORE_CTL_SIGNER_REV_UNKNOWN_FLAG |
00962                      CERT_CHAIN_POLICY_IGNORE_CA_REV_UNKNOWN_FLAG |
00963                      CERT_CHAIN_POLICY_IGNORE_ROOT_REV_UNKNOWN_FLAG;
00964                 CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_AUTHENTICODE,
00965                  data->pasSigners[i].pChainContext, &policyPara, &policyStatus);
00966                 if (policyStatus.dwError != NO_ERROR)
00967                     ret = FALSE;
00968             }
00969         }
00970     }
00971     if (!ret)
00972         data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_POLICYPROV] =
00973          policyStatus.dwError;
00974     TRACE("returning %d (%08x)\n", ret ? S_OK : S_FALSE,
00975      data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_POLICYPROV]);
00976     return ret ? S_OK : S_FALSE;
00977 }
00978 
00979 static HRESULT WINAPI WINTRUST_DefaultPolicy(CRYPT_PROVIDER_DATA *pProvData,
00980  DWORD dwStepError, DWORD dwRegPolicySettings, DWORD cSigner,
00981  PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO rgpSigner, void *pvPolicyArg)
00982 {
00983     DWORD i;
00984     CERT_CHAIN_POLICY_STATUS policyStatus = { sizeof(policyStatus), 0 };
00985 
00986     for (i = 0; !policyStatus.dwError && i < cSigner; i++)
00987     {
00988         CERT_CHAIN_POLICY_PARA policyPara = { sizeof(policyPara), 0 };
00989 
00990         if (dwRegPolicySettings & WTPF_IGNOREEXPIRATION)
00991             policyPara.dwFlags |=
00992              CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG |
00993              CERT_CHAIN_POLICY_IGNORE_CTL_NOT_TIME_VALID_FLAG |
00994              CERT_CHAIN_POLICY_IGNORE_NOT_TIME_NESTED_FLAG;
00995         if (dwRegPolicySettings & WTPF_IGNOREREVOKATION)
00996             policyPara.dwFlags |=
00997              CERT_CHAIN_POLICY_IGNORE_END_REV_UNKNOWN_FLAG |
00998              CERT_CHAIN_POLICY_IGNORE_CTL_SIGNER_REV_UNKNOWN_FLAG |
00999              CERT_CHAIN_POLICY_IGNORE_CA_REV_UNKNOWN_FLAG |
01000              CERT_CHAIN_POLICY_IGNORE_ROOT_REV_UNKNOWN_FLAG;
01001         CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_BASE,
01002          rgpSigner[i].pChainContext, &policyPara, &policyStatus);
01003     }
01004     return policyStatus.dwError;
01005 }
01006 
01007 HRESULT WINAPI GenericChainFinalProv(CRYPT_PROVIDER_DATA *data)
01008 {
01009     HRESULT err = NO_ERROR; /* not a typo, MS confused the types */
01010     WTD_GENERIC_CHAIN_POLICY_DATA *policyData =
01011      data->pWintrustData->pPolicyCallbackData;
01012 
01013     TRACE("(%p)\n", data);
01014 
01015     if (data->pWintrustData->dwUIChoice != WTD_UI_NONE)
01016         FIXME("unimplemented for UI choice %d\n",
01017          data->pWintrustData->dwUIChoice);
01018     if (!data->csSigners)
01019         err = TRUST_E_NOSIGNATURE;
01020     else
01021     {
01022         PFN_WTD_GENERIC_CHAIN_POLICY_CALLBACK policyCallback;
01023         void *policyArg;
01024         WTD_GENERIC_CHAIN_POLICY_SIGNER_INFO *signers = NULL;
01025 
01026         if (policyData)
01027         {
01028             policyCallback = policyData->pfnPolicyCallback;
01029             policyArg = policyData->pvPolicyArg;
01030         }
01031         else
01032         {
01033             policyCallback = WINTRUST_DefaultPolicy;
01034             policyArg = NULL;
01035         }
01036         if (data->csSigners)
01037         {
01038             DWORD i;
01039 
01040             signers = data->psPfns->pfnAlloc(
01041              data->csSigners * sizeof(WTD_GENERIC_CHAIN_POLICY_SIGNER_INFO));
01042             if (signers)
01043             {
01044                 for (i = 0; i < data->csSigners; i++)
01045                 {
01046                     signers[i].u.cbSize =
01047                      sizeof(WTD_GENERIC_CHAIN_POLICY_SIGNER_INFO);
01048                     signers[i].pChainContext =
01049                      data->pasSigners[i].pChainContext;
01050                     signers[i].dwSignerType = data->pasSigners[i].dwSignerType;
01051                     signers[i].pMsgSignerInfo = data->pasSigners[i].psSigner;
01052                     signers[i].dwError = data->pasSigners[i].dwError;
01053                     if (data->pasSigners[i].csCounterSigners)
01054                         FIXME("unimplemented for counter signers\n");
01055                     signers[i].cCounterSigner = 0;
01056                     signers[i].rgpCounterSigner = NULL;
01057                 }
01058             }
01059             else
01060                 err = ERROR_OUTOFMEMORY;
01061         }
01062         if (err == NO_ERROR)
01063             err = policyCallback(data, TRUSTERROR_STEP_FINAL_POLICYPROV,
01064              data->dwRegPolicySettings, data->csSigners, signers, policyArg);
01065         data->psPfns->pfnFree(signers);
01066     }
01067     if (err != NO_ERROR)
01068         data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_POLICYPROV] = err;
01069     TRACE("returning %d (%08x)\n", err == NO_ERROR ? S_OK : S_FALSE,
01070      data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_POLICYPROV]);
01071     return err == NO_ERROR ? S_OK : S_FALSE;
01072 }
01073 
01074 HRESULT WINAPI SoftpubCleanup(CRYPT_PROVIDER_DATA *data)
01075 {
01076     DWORD i, j;
01077 
01078     for (i = 0; i < data->csSigners; i++)
01079     {
01080         for (j = 0; j < data->pasSigners[i].csCertChain; j++)
01081             CertFreeCertificateContext(data->pasSigners[i].pasCertChain[j].pCert);
01082         data->psPfns->pfnFree(data->pasSigners[i].pasCertChain);
01083         data->psPfns->pfnFree(data->pasSigners[i].psSigner);
01084         CertFreeCertificateChain(data->pasSigners[i].pChainContext);
01085     }
01086     data->psPfns->pfnFree(data->pasSigners);
01087 
01088     for (i = 0; i < data->chStores; i++)
01089         CertCloseStore(data->pahStores[i], 0);
01090     data->psPfns->pfnFree(data->pahStores);
01091 
01092     if (data->u.pPDSip)
01093     {
01094         data->psPfns->pfnFree(data->u.pPDSip->pSip);
01095         data->psPfns->pfnFree(data->u.pPDSip->pCATSip);
01096         data->psPfns->pfnFree(data->u.pPDSip->psSipSubjectInfo);
01097         data->psPfns->pfnFree(data->u.pPDSip->psSipCATSubjectInfo);
01098         data->psPfns->pfnFree(data->u.pPDSip->psIndirectData);
01099     }
01100 
01101     CryptMsgClose(data->hMsg);
01102 
01103     if (data->fOpenedFile &&
01104      data->pWintrustData->dwUnionChoice == WTD_CHOICE_FILE)
01105         CloseHandle(data->pWintrustData->u.pFile->hFile);
01106 
01107     return S_OK;
01108 }
01109 
01110 HRESULT WINAPI HTTPSCertificateTrust(CRYPT_PROVIDER_DATA *data)
01111 {
01112     FIXME("(%p)\n", data);
01113     return S_OK;
01114 }
01115 
01116 HRESULT WINAPI HTTPSFinalProv(CRYPT_PROVIDER_DATA *data)
01117 {
01118     FIXME("(%p)\n", data);
01119     return S_OK;
01120 }

Generated on Sun May 27 2012 04:27:02 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.