Skip to content

Commit

Permalink
Add handling of many typical input errors and cert only export (no key)
Browse files Browse the repository at this point in the history
  • Loading branch information
georg-jung committed Mar 11, 2020
1 parent 0cb32bc commit c88e83a
Showing 1 changed file with 39 additions and 6 deletions.
45 changes: 39 additions & 6 deletions PfxCreator/MainForm.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.X509;
Expand Down Expand Up @@ -52,26 +52,56 @@ private AsymmetricKeyParameter ReadPrivateKey(string keyPem)
return ReadPem<AsymmetricKeyParameter>(keyPem);
}

private void WritePfx(string certPem, string keyPem, string password, string filePath)
/// <returns>True if a private key was written, false if just the certificate was written.</returns>
private bool WritePfx(string certPem, string keyPem, string password, string filePath)
{
var cert = ReadCertificate(certPem);
var certEntry = new X509CertificateEntry(cert);
var chain = new X509CertificateEntry[] { certEntry };

var privKey = ReadPrivateKey(keyPem);
if (certEntry?.Certificate == null)
throw new ArgumentException("The string given as a PEM representation of the certificate could not be read accordingly.", nameof(certPem));

AsymmetricKeyParameter privKey = null;
if (!string.IsNullOrEmpty(keyPem))
{
privKey = ReadPrivateKey(keyPem);
if (privKey == null)
throw new ArgumentException("The string given as a PEM representation of the private key could not be read accordingly.", nameof(keyPem));
}

var store = new Pkcs12StoreBuilder().Build();
store.SetKeyEntry("", new AsymmetricKeyEntry(privKey), chain);
if (privKey != null)
{
var chain = new X509CertificateEntry[] { certEntry };
store.SetKeyEntry("", new AsymmetricKeyEntry(privKey), chain);
}
else
store.SetCertificateEntry("", certEntry);

using (var p12file = File.Create(filePath))
{
store.Save(p12file, password.ToCharArray(), new SecureRandom());
}
return privKey != null;
}

private void savePfxButton_Click(object sender, EventArgs e)
{
string fileName;
var certPem = certTextBox.Text;
var psw = pfxPasswordTextBox.Text;
if (string.IsNullOrEmpty(certPem))
{
MessageBox.Show("You did not specify a certificate. To export a PFX file, at least the certificate is needed.",
"Invalid input", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
if (string.IsNullOrEmpty(psw))
if (MessageBox.Show("You did not specify a password. If you continue saving the PFX file, it will be " +
"saved encrypted but with an empty string as passphrase. Do you want to continue?",
"No password specified", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != DialogResult.Yes)
return;

using (var sfd = new SaveFileDialog())
{
sfd.Filter = "PKCS #12 files (*.pfx)|*.pfx|PKCS #12 files (*.p12)|*.p12";
Expand All @@ -83,7 +113,10 @@ private void savePfxButton_Click(object sender, EventArgs e)

try
{
WritePfx(certTextBox.Text, privateKeyTextBox.Text, pfxPasswordTextBox.Text, fileName);
var keyWritten = WritePfx(certPem, privateKeyTextBox.Text, psw, fileName);
if (!keyWritten)
MessageBox.Show("You did not specify a private key. The exported PFX file contains just the certificate.",
"PFX without private key", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
Expand Down

0 comments on commit c88e83a

Please sign in to comment.