diff --git a/App.config b/App.config
new file mode 100644
index 0000000..5754728
--- /dev/null
+++ b/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PFXConverter.csproj b/PFXConverter.csproj
new file mode 100644
index 0000000..b00f717
--- /dev/null
+++ b/PFXConverter.csproj
@@ -0,0 +1,126 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {9D19C230-2034-4AD5-A991-A0D85F8EFE00}
+ WinExe
+ PFXConverter
+ PFXConverter
+ v4.7.2
+ 512
+ true
+ true
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Form
+
+
+ frmPfxConverter.cs
+
+
+
+
+ frmPfxConverter.cs
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+ Designer
+
+
+ True
+ Resources.resx
+ True
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+ True
+ Settings.settings
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+ Microsoft .NET Framework 4.7.2 %28x86 and x64%29
+ true
+
+
+ False
+ .NET Framework 3.5 SP1
+ false
+
+
+
+
\ No newline at end of file
diff --git a/PFXConverter.csproj.user b/PFXConverter.csproj.user
new file mode 100644
index 0000000..9c755a1
--- /dev/null
+++ b/PFXConverter.csproj.user
@@ -0,0 +1,13 @@
+
+
+
+ publish\
+
+
+
+
+
+ en-US
+ false
+
+
\ No newline at end of file
diff --git a/PFXConverter.sln b/PFXConverter.sln
new file mode 100644
index 0000000..938b702
--- /dev/null
+++ b/PFXConverter.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30320.27
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PFXConverter", "PFXConverter.csproj", "{9D19C230-2034-4AD5-A991-A0D85F8EFE00}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {9D19C230-2034-4AD5-A991-A0D85F8EFE00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9D19C230-2034-4AD5-A991-A0D85F8EFE00}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9D19C230-2034-4AD5-A991-A0D85F8EFE00}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9D19C230-2034-4AD5-A991-A0D85F8EFE00}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {90E00BC9-F29B-452B-AD9F-7FF4504704B4}
+ EndGlobalSection
+EndGlobal
diff --git a/Program.cs b/Program.cs
new file mode 100644
index 0000000..88f07d0
--- /dev/null
+++ b/Program.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace PFXConverter
+{
+ static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new frmPfxConverter());
+ }
+ }
+}
diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..28d29dc
--- /dev/null
+++ b/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("PFXConverter")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("PFXConverter")]
+[assembly: AssemblyCopyright("Copyright © 2022")]
+[assembly: AssemblyTrademark("Elad Ben-Matityahu")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("9d19c230-2034-4ad5-a991-a0d85f8efe00")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..6dcd42e
--- /dev/null
+++ b/Properties/Resources.Designer.cs
@@ -0,0 +1,93 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace PFXConverter.Properties {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PFXConverter.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Byte[].
+ ///
+ internal static byte[] jli_dll {
+ get {
+ object obj = ResourceManager.GetObject("jli.dll", resourceCulture);
+ return ((byte[])(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Byte[].
+ ///
+ internal static byte[] keytool_exe {
+ get {
+ object obj = ResourceManager.GetObject("keytool.exe", resourceCulture);
+ return ((byte[])(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Byte[].
+ ///
+ internal static byte[] openssl_exe {
+ get {
+ object obj = ResourceManager.GetObject("openssl.exe", resourceCulture);
+ return ((byte[])(obj));
+ }
+ }
+ }
+}
diff --git a/Properties/Resources.resx b/Properties/Resources.resx
new file mode 100644
index 0000000..a8fce63
--- /dev/null
+++ b/Properties/Resources.resx
@@ -0,0 +1,130 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+ ..\Resources\jli.dll;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ ..\Resources\keytool.exe;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ ..\Resources\openssl.exe;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/Properties/Settings.Designer.cs b/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..563a099
--- /dev/null
+++ b/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace PFXConverter.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/Properties/Settings.settings b/Properties/Settings.settings
new file mode 100644
index 0000000..abf36c5
--- /dev/null
+++ b/Properties/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/Resources/jli.dll b/Resources/jli.dll
new file mode 100644
index 0000000..c1c3bc8
Binary files /dev/null and b/Resources/jli.dll differ
diff --git a/Resources/keytool.exe b/Resources/keytool.exe
new file mode 100644
index 0000000..d871266
Binary files /dev/null and b/Resources/keytool.exe differ
diff --git a/Resources/openssl.exe b/Resources/openssl.exe
new file mode 100644
index 0000000..49424e7
Binary files /dev/null and b/Resources/openssl.exe differ
diff --git a/bin/Debug/PFXConverter.exe b/bin/Debug/PFXConverter.exe
new file mode 100644
index 0000000..fd49892
Binary files /dev/null and b/bin/Debug/PFXConverter.exe differ
diff --git a/bin/Debug/PFXConverter.exe.config b/bin/Debug/PFXConverter.exe.config
new file mode 100644
index 0000000..5754728
--- /dev/null
+++ b/bin/Debug/PFXConverter.exe.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bin/Debug/PFXConverter.pdb b/bin/Debug/PFXConverter.pdb
new file mode 100644
index 0000000..7a07829
Binary files /dev/null and b/bin/Debug/PFXConverter.pdb differ
diff --git a/frmPfxConverter.Designer.cs b/frmPfxConverter.Designer.cs
new file mode 100644
index 0000000..15e860a
--- /dev/null
+++ b/frmPfxConverter.Designer.cs
@@ -0,0 +1,202 @@
+namespace PFXConverter
+{
+ partial class frmPfxConverter
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.lblStep1 = new System.Windows.Forms.Label();
+ this.btnBrowseSource = new System.Windows.Forms.Button();
+ this.lblStep2 = new System.Windows.Forms.Label();
+ this.txtSourcePassword = new System.Windows.Forms.TextBox();
+ this.lblStep3 = new System.Windows.Forms.Label();
+ this.cmbOutputFormat = new System.Windows.Forms.ComboBox();
+ this.lblStep5 = new System.Windows.Forms.Label();
+ this.btnBrowseDestination = new System.Windows.Forms.Button();
+ this.btnConvert = new System.Windows.Forms.Button();
+ this.lblStep4 = new System.Windows.Forms.Label();
+ this.txtDestinationPassword = new System.Windows.Forms.TextBox();
+ this.SuspendLayout();
+ //
+ // lblStep1
+ //
+ this.lblStep1.AutoSize = true;
+ this.lblStep1.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(177)));
+ this.lblStep1.Location = new System.Drawing.Point(12, 26);
+ this.lblStep1.Name = "lblStep1";
+ this.lblStep1.Size = new System.Drawing.Size(190, 13);
+ this.lblStep1.TabIndex = 0;
+ this.lblStep1.Text = "Step #1 - Choose the source file:";
+ //
+ // btnBrowseSource
+ //
+ this.btnBrowseSource.Location = new System.Drawing.Point(231, 21);
+ this.btnBrowseSource.Name = "btnBrowseSource";
+ this.btnBrowseSource.Size = new System.Drawing.Size(75, 23);
+ this.btnBrowseSource.TabIndex = 1;
+ this.btnBrowseSource.Text = "Browse...";
+ this.btnBrowseSource.UseVisualStyleBackColor = true;
+ this.btnBrowseSource.Click += new System.EventHandler(this.btnBrowseSource_Click);
+ //
+ // lblStep2
+ //
+ this.lblStep2.AutoSize = true;
+ this.lblStep2.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(177)));
+ this.lblStep2.Location = new System.Drawing.Point(12, 50);
+ this.lblStep2.Name = "lblStep2";
+ this.lblStep2.Size = new System.Drawing.Size(207, 13);
+ this.lblStep2.TabIndex = 0;
+ this.lblStep2.Text = "Step #2 - Enter the PFX\'s password:";
+ //
+ // txtSourcePassword
+ //
+ this.txtSourcePassword.Location = new System.Drawing.Point(232, 47);
+ this.txtSourcePassword.Name = "txtSourcePassword";
+ this.txtSourcePassword.Size = new System.Drawing.Size(125, 21);
+ this.txtSourcePassword.TabIndex = 2;
+ this.txtSourcePassword.UseSystemPasswordChar = true;
+ this.txtSourcePassword.TextChanged += new System.EventHandler(this.txtSourcePassword_TextChanged);
+ //
+ // lblStep3
+ //
+ this.lblStep3.AutoSize = true;
+ this.lblStep3.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(177)));
+ this.lblStep3.Location = new System.Drawing.Point(12, 75);
+ this.lblStep3.Name = "lblStep3";
+ this.lblStep3.Size = new System.Drawing.Size(212, 13);
+ this.lblStep3.TabIndex = 0;
+ this.lblStep3.Text = "Step #3 - Choose the output format:";
+ //
+ // cmbOutputFormat
+ //
+ this.cmbOutputFormat.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.cmbOutputFormat.FormattingEnabled = true;
+ this.cmbOutputFormat.Items.AddRange(new object[] {
+ "PEM (Base64)",
+ "JKS (Java Keystore)",
+ "PSE (SAP Proprietary)"});
+ this.cmbOutputFormat.Location = new System.Drawing.Point(232, 72);
+ this.cmbOutputFormat.Name = "cmbOutputFormat";
+ this.cmbOutputFormat.Size = new System.Drawing.Size(125, 21);
+ this.cmbOutputFormat.TabIndex = 3;
+ this.cmbOutputFormat.SelectedIndexChanged += new System.EventHandler(this.cmbOutputFormat_SelectedIndexChanged);
+ //
+ // lblStep5
+ //
+ this.lblStep5.AutoSize = true;
+ this.lblStep5.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(177)));
+ this.lblStep5.Location = new System.Drawing.Point(12, 126);
+ this.lblStep5.Name = "lblStep5";
+ this.lblStep5.Size = new System.Drawing.Size(199, 13);
+ this.lblStep5.TabIndex = 0;
+ this.lblStep5.Text = "Step #5 - Choose the output path:";
+ //
+ // btnBrowseDestination
+ //
+ this.btnBrowseDestination.Location = new System.Drawing.Point(231, 121);
+ this.btnBrowseDestination.Name = "btnBrowseDestination";
+ this.btnBrowseDestination.Size = new System.Drawing.Size(75, 23);
+ this.btnBrowseDestination.TabIndex = 5;
+ this.btnBrowseDestination.Text = "Browse...";
+ this.btnBrowseDestination.UseVisualStyleBackColor = true;
+ this.btnBrowseDestination.Click += new System.EventHandler(this.btnBrowseDestination_Click);
+ //
+ // btnConvert
+ //
+ this.btnConvert.Enabled = false;
+ this.btnConvert.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(177)));
+ this.btnConvert.Location = new System.Drawing.Point(282, 161);
+ this.btnConvert.Name = "btnConvert";
+ this.btnConvert.Size = new System.Drawing.Size(75, 23);
+ this.btnConvert.TabIndex = 6;
+ this.btnConvert.Text = "Convert";
+ this.btnConvert.UseVisualStyleBackColor = true;
+ this.btnConvert.Click += new System.EventHandler(this.btnConvert_Click);
+ //
+ // lblStep4
+ //
+ this.lblStep4.AutoSize = true;
+ this.lblStep4.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(177)));
+ this.lblStep4.Location = new System.Drawing.Point(12, 100);
+ this.lblStep4.Name = "lblStep4";
+ this.lblStep4.Size = new System.Drawing.Size(216, 13);
+ this.lblStep4.TabIndex = 0;
+ this.lblStep4.Text = "Step #4 - Enter the output password:";
+ //
+ // txtDestinationPassword
+ //
+ this.txtDestinationPassword.Location = new System.Drawing.Point(232, 97);
+ this.txtDestinationPassword.Name = "txtDestinationPassword";
+ this.txtDestinationPassword.Size = new System.Drawing.Size(125, 21);
+ this.txtDestinationPassword.TabIndex = 4;
+ this.txtDestinationPassword.UseSystemPasswordChar = true;
+ this.txtDestinationPassword.TextChanged += new System.EventHandler(this.txtDestinationPassword_TextChanged);
+ //
+ // frmPfxConverter
+ //
+ this.AllowDrop = true;
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(373, 198);
+ this.Controls.Add(this.cmbOutputFormat);
+ this.Controls.Add(this.txtDestinationPassword);
+ this.Controls.Add(this.txtSourcePassword);
+ this.Controls.Add(this.btnConvert);
+ this.Controls.Add(this.btnBrowseDestination);
+ this.Controls.Add(this.btnBrowseSource);
+ this.Controls.Add(this.lblStep5);
+ this.Controls.Add(this.lblStep4);
+ this.Controls.Add(this.lblStep3);
+ this.Controls.Add(this.lblStep2);
+ this.Controls.Add(this.lblStep1);
+ this.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(177)));
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "frmPfxConverter";
+ this.Text = "PFX Converter For Dummies [by Elad Ben-Matityahu]";
+ this.DragDrop += new System.Windows.Forms.DragEventHandler(this.frmPfxConverter_DragDrop);
+ this.DragEnter += new System.Windows.Forms.DragEventHandler(this.frmPfxConverter_DragEnter);
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Label lblStep1;
+ private System.Windows.Forms.Button btnBrowseSource;
+ private System.Windows.Forms.Label lblStep2;
+ private System.Windows.Forms.TextBox txtSourcePassword;
+ private System.Windows.Forms.Label lblStep3;
+ private System.Windows.Forms.ComboBox cmbOutputFormat;
+ private System.Windows.Forms.Label lblStep5;
+ private System.Windows.Forms.Button btnBrowseDestination;
+ private System.Windows.Forms.Button btnConvert;
+ private System.Windows.Forms.Label lblStep4;
+ private System.Windows.Forms.TextBox txtDestinationPassword;
+ }
+}
+
diff --git a/frmPfxConverter.cs b/frmPfxConverter.cs
new file mode 100644
index 0000000..5c9cd07
--- /dev/null
+++ b/frmPfxConverter.cs
@@ -0,0 +1,246 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Diagnostics;
+using System.Drawing;
+using System.IO;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Security.Cryptography.X509Certificates;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace PFXConverter
+{
+ public partial class frmPfxConverter : Form
+ {
+ private string sourceFile = "", destinationFile = "";
+
+ public frmPfxConverter()
+ {
+ InitializeComponent();
+ this.cmbOutputFormat.SelectedIndex = 0;
+ }
+
+ private bool ExtractResource(string resourceName)
+ {
+ try
+ {
+ object obj = Properties.Resources.ResourceManager.GetObject(resourceName);
+ byte[] resourceBytes = (byte[])obj;
+ using (FileStream fs = new FileStream(Path.GetTempPath() + resourceName, FileMode.Create, FileAccess.Write))
+ {
+ byte[] bytes = resourceBytes;
+ fs.Write(bytes, 0, bytes.Length);
+ fs.Close();
+ fs.Dispose();
+ }
+ return true;
+ }
+ catch(Exception ex)
+ {
+ MessageBox.Show("Error extracting " + resourceName + " to your temporary folder (" + Path.GetTempPath() + resourceName + ")" + Environment.NewLine + "Details: " + ex.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
+
+ return false;
+ }
+
+ private string RunExecutable(string filename, string arguments)
+ {
+ Process p = new Process();
+ p.StartInfo.UseShellExecute = false;
+ p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
+ p.StartInfo.CreateNoWindow = true;
+ p.StartInfo.RedirectStandardOutput = true;
+ p.StartInfo.FileName = filename;
+ p.StartInfo.Arguments = arguments;
+ p.Start();
+ string output = p.StandardOutput.ReadToEnd();
+ p.WaitForExit();
+
+ return output;
+ }
+
+ private bool VerifyPfxPassword()
+ {
+ try
+ {
+ X509Certificate2 certificate = new X509Certificate2(File.ReadAllBytes(this.sourceFile), this.txtSourcePassword.Text);
+ return true;
+ }
+ catch (CryptographicException ex)
+ {
+ if ((ex.HResult & 0xFFFF) == 0x56)
+ {
+ return false;
+ };
+ }
+
+ return false;
+ }
+
+ private void ToggleConvertButton()
+ {
+ bool enabled = false;
+ if (this.sourceFile != string.Empty && this.txtSourcePassword.Text != string.Empty && this.destinationFile != string.Empty && this.VerifyPfxPassword())
+ {
+ if (this.cmbOutputFormat.Text != "JKS (Java Keystore)" || this.txtDestinationPassword.Text.Length >= 6) enabled = true;
+ }
+ this.btnConvert.Enabled = enabled;
+ }
+
+ private void btnBrowseSource_Click(object sender, EventArgs e)
+ {
+ OpenFileDialog ofd = new OpenFileDialog();
+ ofd.Multiselect = false;
+ ofd.Filter = "PKCS#12 Files|*.pfx;*.p12";
+ ofd.ShowDialog();
+ if (ofd.FileName != string.Empty) sourceFile = ofd.FileName;
+ this.txtSourcePassword_TextChanged(sender, e);
+ }
+
+ private void btnBrowseDestination_Click(object sender, EventArgs e)
+ {
+ SaveFileDialog sfd = new SaveFileDialog();
+ string filter = "PEM & Key Files|*.pem;*.key";
+ if (this.cmbOutputFormat.Text == "JKS (Java Keystore)") filter = "Java Keystore Files|*.jks";
+ else if (this.cmbOutputFormat.Text == "PSE (SAP Proprietary)") filter = "PSE Files|*.pse";
+ sfd.Filter = filter;
+ sfd.ShowDialog();
+ if (sfd.FileName != string.Empty) destinationFile = sfd.FileName;
+ this.ToggleConvertButton();
+ }
+
+ private void txtSourcePassword_TextChanged(object sender, EventArgs e)
+ {
+ if (sourceFile != string.Empty) if (this.VerifyPfxPassword()) this.txtSourcePassword.BackColor = Color.White; else this.txtSourcePassword.BackColor = Color.Red;
+ this.ToggleConvertButton();
+ }
+
+ private void cmbOutputFormat_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ this.txtDestinationPassword_TextChanged(sender, e);
+ }
+
+ private void txtDestinationPassword_TextChanged(object sender, EventArgs e)
+ {
+ if (this.cmbOutputFormat.Text == "JKS (Java Keystore)" && this.txtDestinationPassword.Text.Length < 6) this.txtDestinationPassword.BackColor = Color.Red; else this.txtDestinationPassword.BackColor = Color.White;
+ this.ToggleConvertButton();
+ }
+
+ private void frmPfxConverter_DragDrop(object sender, DragEventArgs e)
+ {
+ if (IsDroppedFileSupported(e))
+ {
+ this.sourceFile = ((string[])e.Data.GetData(DataFormats.FileDrop))[0];
+ MessageBox.Show("Selected PFX file: " + this.sourceFile, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
+ }
+ }
+
+ private void frmPfxConverter_DragEnter(object sender, DragEventArgs e)
+ {
+ if (IsDroppedFileSupported(e)) e.Effect = DragDropEffects.Copy;
+ }
+
+ private bool IsDroppedFileSupported(DragEventArgs e)
+ {
+ string[] supportedExtensions = new string[] { ".pfx", ".p12" };
+
+ if (e.Data.GetDataPresent(DataFormats.FileDrop))
+ {
+ string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
+ if (files.Length == 1) if (Path.HasExtension(files[0])) foreach (string supportedExtension in supportedExtensions) if (Path.GetExtension(files[0]).ToLower().Equals(supportedExtension.ToLower())) return true;
+ }
+
+ return false;
+ }
+
+ private void btnConvert_Click(object sender, EventArgs e)
+ {
+ this.btnConvert.Enabled = false;
+ bool succeeded = false;
+ switch(this.cmbOutputFormat.Text)
+ {
+ case "PEM (Base64)":
+ if (this.ExtractResource("openssl.exe"))
+ {
+ this.destinationFile = this.destinationFile.Substring(0, this.destinationFile.Length - 4);
+ string outputFile = this.destinationFile + ".key";
+ if (File.Exists(outputFile)) File.Delete(outputFile);
+ this.RunExecutable(Path.GetTempPath() + "openssl.exe", "pkcs12 -in \"" + this.sourceFile + "\" -out \"" + outputFile + "\" -nocerts -passin pass:" + this.txtSourcePassword.Text + (this.txtDestinationPassword.Text == string.Empty ? " -nodes" : " -passout pass:" + this.txtDestinationPassword.Text));
+ if (!File.Exists(outputFile) || File.ReadAllText(outputFile).Length == 0)
+ {
+ MessageBox.Show("Error extracting the private key from " + this.sourceFile, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
+ else
+ {
+ outputFile = this.destinationFile + ".pem";
+ if (File.Exists(outputFile)) File.Delete(outputFile);
+ this.RunExecutable(Path.GetTempPath() + "openssl.exe", "pkcs12 -in \"" + this.sourceFile + "\" -out \"" + outputFile + "\" -nokeys -clcerts -passin pass:" + this.txtSourcePassword.Text);
+ if (!File.Exists(outputFile) || File.ReadAllText(outputFile).Length == 0)
+ {
+ MessageBox.Show("Error extracting the certificate from " + this.sourceFile, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
+ else
+ {
+ outputFile = this.destinationFile + "-chain.pem";
+ if (File.Exists(outputFile)) File.Delete(outputFile);
+ this.RunExecutable(Path.GetTempPath() + "openssl.exe", "pkcs12 -in \"" + this.sourceFile + "\" -out \"" + outputFile + "\" -nokeys -cacerts -passin pass:" + this.txtSourcePassword.Text);
+ if (File.ReadAllText(outputFile).Length == 0) File.Delete(outputFile);
+ succeeded = true;
+ }
+ }
+ }
+ break;
+ case "JKS (Java Keystore)":
+ if (this.ExtractResource("keytool.exe") && this.ExtractResource("jli.dll"))
+ {
+ if (File.Exists(this.destinationFile)) File.Delete(this.destinationFile);
+ this.RunExecutable(Path.GetTempPath() + "keytool.exe", "-importkeystore -srckeystore \"" + this.sourceFile + "\" -srcstoretype PKCS12 -srcstorepass \"" + this.txtSourcePassword.Text + "\" -destkeystore \"" + this.destinationFile + "\" -deststoretype JKS -deststorepass \"" + this.txtDestinationPassword.Text + "\" -destkeypass \"" + this.txtDestinationPassword.Text + "\"");
+ if (!File.Exists(this.destinationFile) || File.ReadAllText(this.destinationFile).Length == 0) MessageBox.Show("Error generating a JKS file from " + this.sourceFile, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
+ else succeeded = true;
+ }
+ break;
+ case "PSE (SAP Proprietary)":
+ bool sapDependenciesResolved = false;
+ if (File.Exists(Path.GetTempPath() + "sapgenpse.exe") && File.Exists(Path.GetTempPath() + "sapcrypto.dll")) sapDependenciesResolved = true;
+ else
+ {
+ OpenFileDialog ofd = new OpenFileDialog();
+ ofd.Multiselect = false;
+ ofd.Title = "Please locate the 'sapgenpse.exe' dependency file.";
+ ofd.Filter = "SAP 'sapgenpse.exe' binary|sapgenpse.exe";
+ ofd.ShowDialog();
+ if (ofd.FileName == string.Empty) MessageBox.Show("In order to convert the file to PSE format, you have to load the dependency (sapgenpse.exe) from your SAP runtime binaries path.", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
+ else
+ {
+ File.Copy(ofd.FileName, Path.GetTempPath() + "sapgenpse.exe", true);
+ ofd.FileName = string.Empty;
+ ofd.Title = "Please locate the 'sapcrypto.dll' dependency file.";
+ ofd.Filter = "SAP 'sapcrypto.dll' binary|sapcrypto.dll";
+ ofd.ShowDialog();
+ if (ofd.FileName == string.Empty) MessageBox.Show("In order to convert the file to PSE format, you have to load the dependency (sapcrypto.dll) from your SAP runtime binaries path.", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
+ else
+ {
+ File.Copy(ofd.FileName, Path.GetTempPath() + "sapcrypto.dll", true);
+ sapDependenciesResolved = true;
+ }
+ }
+ }
+
+ if (sapDependenciesResolved)
+ {
+ if (File.Exists(this.destinationFile)) File.Delete(this.destinationFile);
+ this.RunExecutable(Path.GetTempPath() + "sapgenpse.exe", "import_p12 -z " + this.txtSourcePassword.Text + " -x \"" + this.txtDestinationPassword.Text + "\"" + " -p \"" + this.destinationFile + "\" \"" + this.sourceFile + "\"");
+ if (!File.Exists(this.destinationFile) || File.ReadAllText(this.destinationFile).Length == 0) MessageBox.Show("Error generating a PSE file from " + this.sourceFile + Environment.NewLine + Environment.NewLine + "Make sure your PFX file contains the full issuance chain.", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
+ else succeeded = true;
+ }
+ break;
+ }
+ if (succeeded) MessageBox.Show("Converted succesfully!", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
+ this.btnConvert.Enabled = true;
+ }
+ }
+}
diff --git a/frmPfxConverter.resx b/frmPfxConverter.resx
new file mode 100644
index 0000000..29dcb1b
--- /dev/null
+++ b/frmPfxConverter.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/obj/Debug/DesignTimeResolveAssemblyReferences.cache b/obj/Debug/DesignTimeResolveAssemblyReferences.cache
new file mode 100644
index 0000000..7a18486
Binary files /dev/null and b/obj/Debug/DesignTimeResolveAssemblyReferences.cache differ
diff --git a/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache b/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache
new file mode 100644
index 0000000..9e75f55
Binary files /dev/null and b/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache differ
diff --git a/obj/Debug/PFXConverter.Properties.Resources.resources b/obj/Debug/PFXConverter.Properties.Resources.resources
new file mode 100644
index 0000000..ba25199
Binary files /dev/null and b/obj/Debug/PFXConverter.Properties.Resources.resources differ
diff --git a/obj/Debug/PFXConverter.csproj.CoreCompileInputs.cache b/obj/Debug/PFXConverter.csproj.CoreCompileInputs.cache
new file mode 100644
index 0000000..6720a46
--- /dev/null
+++ b/obj/Debug/PFXConverter.csproj.CoreCompileInputs.cache
@@ -0,0 +1 @@
+fc268fa99ac0a24bb1b4e8ad091a91084406ea95
diff --git a/obj/Debug/PFXConverter.csproj.FileListAbsolute.txt b/obj/Debug/PFXConverter.csproj.FileListAbsolute.txt
new file mode 100644
index 0000000..73b32bd
--- /dev/null
+++ b/obj/Debug/PFXConverter.csproj.FileListAbsolute.txt
@@ -0,0 +1,9 @@
+D:\Projects\PFXConverter\bin\Debug\PFXConverter.exe.config
+D:\Projects\PFXConverter\bin\Debug\PFXConverter.exe
+D:\Projects\PFXConverter\bin\Debug\PFXConverter.pdb
+D:\Projects\PFXConverter\obj\Debug\PFXConverter.frmPfxConverter.resources
+D:\Projects\PFXConverter\obj\Debug\PFXConverter.Properties.Resources.resources
+D:\Projects\PFXConverter\obj\Debug\PFXConverter.csproj.GenerateResource.cache
+D:\Projects\PFXConverter\obj\Debug\PFXConverter.csproj.CoreCompileInputs.cache
+D:\Projects\PFXConverter\obj\Debug\PFXConverter.exe
+D:\Projects\PFXConverter\obj\Debug\PFXConverter.pdb
diff --git a/obj/Debug/PFXConverter.csproj.GenerateResource.cache b/obj/Debug/PFXConverter.csproj.GenerateResource.cache
new file mode 100644
index 0000000..36278d1
Binary files /dev/null and b/obj/Debug/PFXConverter.csproj.GenerateResource.cache differ
diff --git a/obj/Debug/PFXConverter.exe b/obj/Debug/PFXConverter.exe
new file mode 100644
index 0000000..fd49892
Binary files /dev/null and b/obj/Debug/PFXConverter.exe differ
diff --git a/obj/Debug/PFXConverter.frmPfxConverter.resources b/obj/Debug/PFXConverter.frmPfxConverter.resources
new file mode 100644
index 0000000..6c05a97
Binary files /dev/null and b/obj/Debug/PFXConverter.frmPfxConverter.resources differ
diff --git a/obj/Debug/PFXConverter.pdb b/obj/Debug/PFXConverter.pdb
new file mode 100644
index 0000000..7a07829
Binary files /dev/null and b/obj/Debug/PFXConverter.pdb differ
diff --git a/obj/Debug/TempPE/Properties.Resources.Designer.cs.dll b/obj/Debug/TempPE/Properties.Resources.Designer.cs.dll
new file mode 100644
index 0000000..3b04c8a
Binary files /dev/null and b/obj/Debug/TempPE/Properties.Resources.Designer.cs.dll differ