Module: wine Branch: master Commit: 0d961d9ce37b45a43f04a0afb2c03deec0c1e291 URL: http://source.winehq.org/git/wine.git/?a=commit;h=0d961d9ce37b45a43f04a0afb2...
Author: Juan Lang juan.lang@gmail.com Date: Sun Feb 1 14:27:59 2009 -0800
cryptui: Implement exporting to a PFX file.
---
dlls/cryptui/main.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 91 insertions(+), 2 deletions(-)
diff --git a/dlls/cryptui/main.c b/dlls/cryptui/main.c index 6a8e9e8..ee01c6e 100644 --- a/dlls/cryptui/main.c +++ b/dlls/cryptui/main.c @@ -6413,6 +6413,96 @@ static BOOL save_serialized_store(HANDLE file, HCERTSTORE store) CERT_STORE_SAVE_AS_STORE, CERT_STORE_SAVE_TO_FILE, file, 0); }
+static BOOL save_pfx(HANDLE file, PCCRYPTUI_WIZ_EXPORT_INFO pExportInfo, + PCCRYPTUI_WIZ_EXPORT_CERTCONTEXT_INFO pContextInfo) +{ + HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING, + 0, CERT_STORE_CREATE_NEW_FLAG, NULL); + BOOL ret = FALSE; + + if (store) + { + CRYPT_DATA_BLOB pfxBlob = { 0, NULL }; + + if (pContextInfo->fExportChain) + { + HCERTCHAINENGINE engine = NULL; + + if (pExportInfo->cStores) + { + CERT_CHAIN_ENGINE_CONFIG config; + + memset(&config, 0, sizeof(config)); + config.cbSize = sizeof(config); + config.cAdditionalStore = pExportInfo->cStores; + config.rghAdditionalStore = pExportInfo->rghStores; + ret = CertCreateCertificateChainEngine(&config, &engine); + } + else + ret = TRUE; + if (ret) + { + CERT_CHAIN_PARA chainPara; + PCCERT_CHAIN_CONTEXT chain; + + memset(&chainPara, 0, sizeof(chainPara)); + chainPara.cbSize = sizeof(chainPara); + ret = CertGetCertificateChain(engine, + pExportInfo->u.pCertContext, NULL, NULL, &chainPara, 0, NULL, + &chain); + if (ret) + { + DWORD i, j; + + for (i = 0; ret && i < chain->cChain; i++) + for (j = 0; ret && j < chain->rgpChain[i]->cElement; + j++) + ret = CertAddCertificateContextToStore(store, + chain->rgpChain[i]->rgpElement[j]->pCertContext, + CERT_STORE_ADD_ALWAYS, NULL); + CertFreeCertificateChain(chain); + } + } + if (engine) + CertFreeCertificateChainEngine(engine); + } + else + ret = CertAddCertificateContextToStore(store, + pExportInfo->u.pCertContext, CERT_STORE_ADD_ALWAYS, NULL); + if (ret) + { + DWORD exportFlags = + REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY | EXPORT_PRIVATE_KEYS; + + ret = PFXExportCertStore(store, &pfxBlob, + pContextInfo->pwszPassword, exportFlags); + if (ret) + { + pfxBlob.pbData = HeapAlloc(GetProcessHeap(), 0, pfxBlob.cbData); + if (pfxBlob.pbData) + { + ret = PFXExportCertStore(store, &pfxBlob, + pContextInfo->pwszPassword, exportFlags); + if (ret) + { + DWORD bytesWritten; + + ret = WriteFile(file, pfxBlob.pbData, pfxBlob.cbData, + &bytesWritten, NULL); + } + } + else + { + SetLastError(ERROR_OUTOFMEMORY); + ret = FALSE; + } + } + } + CertCloseStore(store, 0); + } + return ret; +} + static BOOL do_export(HANDLE file, PCCRYPTUI_WIZ_EXPORT_INFO pExportInfo, PCCRYPTUI_WIZ_EXPORT_CERTCONTEXT_INFO pContextInfo) { @@ -6458,8 +6548,7 @@ static BOOL do_export(HANDLE file, PCCRYPTUI_WIZ_EXPORT_INFO pExportInfo, pContextInfo->fExportChain); break; case CRYPTUI_WIZ_EXPORT_FORMAT_PFX: - FIXME("unimplemented for PFX\n"); - ret = FALSE; + ret = save_pfx(file, pExportInfo, pContextInfo); break; default: SetLastError(E_FAIL);