Skip to content

Instantly share code, notes, and snippets.

@ericlaw1979
Created May 1, 2019 00:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ericlaw1979/0efb0b22b7ad933e7f121bf70d99db35 to your computer and use it in GitHub Desktop.
Save ericlaw1979/0efb0b22b7ad933e7f121bf70d99db35 to your computer and use it in GitHub Desktop.
Fiddler client certificate picker extension
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using Fiddler;
[assembly: Fiddler.RequiredVersion("2.5.0.0")]
namespace ClientCertPicker
{
public class ClientCertPicker: IFiddlerExtension
{
private X509Certificate ProvideCertificate(
object sender, // <------------ This points to the Session
string targetHost, // <------------ Target hostname
X509CertificateCollection localCertificates, // <------------ Local certificates we made available via oSession["https-Client-Certificate"]
X509Certificate remoteCertificate, // <------------ Remote site's certificate
string[] acceptableIssuers)
{
X509Store store = new X509Store("My", StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
X509Certificate2Collection oAllCerts = (X509Certificate2Collection)store.Certificates;
X509Certificate2Collection oFilteredCerts = (X509Certificate2Collection)oAllCerts.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
X509Certificate2Collection oClientCerts = new X509Certificate2Collection();
foreach (X509Certificate2 oCandidate in oFilteredCerts)
{
if (!oCandidate.HasPrivateKey || (null == oCandidate.Extensions))
{
continue;
}
foreach (X509Extension oCE in oCandidate.Extensions)
{
if (oCE.Oid.Value == "2.5.29.37" /* aka "Enhanced Key Usage" */)
{
if (HasClientAuthenticationFlag(oCandidate, oCE))
{
oClientCerts.Add(oCandidate);
continue;
}
}
}
}
X509Certificate2Collection oPickedCerts = X509Certificate2UI.SelectFromCollection(oClientCerts,
"Client Certificate", String.Format("Select a certificate to send to '{0}'", targetHost), X509SelectionFlag.SingleSelection);
if ((oPickedCerts != null) && (oPickedCerts.Count > 0))
{
return oPickedCerts[0];
}
return null;
}
private static bool HasClientAuthenticationFlag(X509Certificate2 oCandidate, X509Extension oCE)
{
X509EnhancedKeyUsageExtension ext = (X509EnhancedKeyUsageExtension)oCE;
OidCollection oids = ext.EnhancedKeyUsages;
foreach (Oid oid in oids)
{
if (oid.Value == "1.3.6.1.5.5.7.3.2" /* aka "Client Authentication" */)
{
return true;
}
}
return false;
}
public void OnBeforeUnload() {}
public void OnLoad()
{
FiddlerApplication.ClientCertificateProvider = new System.Net.Security.LocalCertificateSelectionCallback(ProvideCertificate);
FiddlerApplication.Log.LogString("Overriding Client Certificate Selection");
}
}
}
@avoidik
Copy link

avoidik commented May 24, 2019

Nice plugin, but unfortunately it doesn't work... it had been asking for a certificate in a 302 redirection loop, and has failed with a missing PKI card error message in the end, although it works if I disable "Capture Traffic" menu option.
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment