extern static bool PFXExportCertStoreEx( CertificateStoreHandle hStore, IntPtr pPFX, //IntPtr szPassword, string password, IntPtr pvReserved, PfxExportFlags dwFlags);
private void Export() { using (CertificateStoreHandle handle = CertOpenStore(new IntPtr(2), 0, IntPtr.Zero, 0, IntPtr.Zero)) { StoreCertificateHandle handle2; if (!CertAddCertificateContextToStore(handle, this.cert, AddDisposition.ReplaceExisting, out handle2)) { int error = Marshal.GetLastWin32Error(); Utility.CloseInvalidOutSafeHandle(handle2); PeerExceptionHelper.ThrowInvalidOperation_PeerCertGenFailure(new Win32Exception(error)); } using (handle2) { CryptoApiBlob blob = new CryptoApiBlob(); CryptoApiBlob.InteropHelper memoryForPinning = blob.GetMemoryForPinning(); GCHandle handle3 = GCHandle.Alloc(memoryForPinning, GCHandleType.Pinned); try { if (!PFXExportCertStoreEx(handle, handle3.AddrOfPinnedObject(), this.password, IntPtr.Zero, PfxExportFlags.ExportPrivateKeys | PfxExportFlags.ReportNotAbleToExportPrivateKey | PfxExportFlags.ReportNoPrivateKey)) { PeerExceptionHelper.ThrowInvalidOperation_PeerCertGenFailure(PeerExceptionHelper.GetLastException()); } int size = memoryForPinning.size; handle3.Free(); blob.AllocateBlob(size); handle3 = GCHandle.Alloc(blob.GetMemoryForPinning(), GCHandleType.Pinned); if (!PFXExportCertStoreEx(handle, handle3.AddrOfPinnedObject(), this.password, IntPtr.Zero, PfxExportFlags.ExportPrivateKeys | PfxExportFlags.ReportNotAbleToExportPrivateKey | PfxExportFlags.ReportNoPrivateKey)) { PeerExceptionHelper.ThrowInvalidOperation_PeerCertGenFailure(PeerExceptionHelper.GetLastException()); } this.exportedBytes = blob.GetBytes(); } finally { handle3.Free(); if (blob != null) { blob.Dispose(); } } } } }
extern static bool CertAddCertificateContextToStore( CertificateStoreHandle hCertStore, CertificateHandle pCertContext, AddDisposition dwAddDisposition, [Out]out StoreCertificateHandle ppStoreContext);
extern static bool CertAddCertificateContextToStore( CertificateStoreHandle hCertStore, CertificateHandle pCertContext, AddDisposition dwAddDisposition, [Out] out StoreCertificateHandle ppStoreContext);
void Export() { Fx.Assert(this.exportedBytes == null, "calling Export twice!!"); // create a temporary store to export using (CertificateStoreHandle store = CertOpenStore(new IntPtr(CERT_STORE_PROV_MEMORY), 0, IntPtr.Zero, 0, IntPtr.Zero)) { // add the certificate to the store StoreCertificateHandle addedCert; if (!CertAddCertificateContextToStore(store, cert, AddDisposition.ReplaceExisting, out addedCert)) { int error = Marshal.GetLastWin32Error(); Utility.CloseInvalidOutSafeHandle(addedCert); PeerExceptionHelper.ThrowInvalidOperation_PeerCertGenFailure(new Win32Exception(error)); } using (addedCert) { // Translate to a PFX CryptoApiBlob pfxBlob = new CryptoApiBlob(); CryptoApiBlob.InteropHelper blob = pfxBlob.GetMemoryForPinning(); GCHandle pfxHandle = GCHandle.Alloc(blob, GCHandleType.Pinned); try { // first figure out the storage space necessary bool result = PFXExportCertStoreEx(store, pfxHandle.AddrOfPinnedObject(), password, IntPtr.Zero, PfxExportFlags.ExportPrivateKeys | PfxExportFlags.ReportNoPrivateKey | PfxExportFlags.ReportNotAbleToExportPrivateKey); if (!result) { PeerExceptionHelper.ThrowInvalidOperation_PeerCertGenFailure(PeerExceptionHelper.GetLastException()); } int storageSize = blob.size; pfxHandle.Free(); pfxBlob.AllocateBlob(storageSize); blob = pfxBlob.GetMemoryForPinning(); pfxHandle = GCHandle.Alloc(blob, GCHandleType.Pinned); // now do the translation if (!PFXExportCertStoreEx(store, pfxHandle.AddrOfPinnedObject(), password, IntPtr.Zero, PfxExportFlags.ExportPrivateKeys | PfxExportFlags.ReportNoPrivateKey | PfxExportFlags.ReportNotAbleToExportPrivateKey)) { PeerExceptionHelper.ThrowInvalidOperation_PeerCertGenFailure(PeerExceptionHelper.GetLastException()); } exportedBytes = pfxBlob.GetBytes(); } finally { if (pfxHandle != null) { pfxHandle.Free(); } if (pfxBlob != null) { pfxBlob.Dispose(); } } } } }