Juan Lang : cryptui: Implement exporting to a PFX file.

Alexandre Julliard julliard at winehq.org
Mon Feb 9 10:29:21 CST 2009


Module: wine
Branch: master
Commit: 0d961d9ce37b45a43f04a0afb2c03deec0c1e291
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=0d961d9ce37b45a43f04a0afb2c03deec0c1e291

Author: Juan Lang <juan.lang at 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);




More information about the wine-cvs mailing list