Skip to content

Instantly share code, notes, and snippets.

@ericlaw1979
Created May 1, 2019 00:59
Show Gist options
  • Select an option

  • Save ericlaw1979/0efb0b22b7ad933e7f121bf70d99db35 to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown

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

@swobiteu
Copy link
Copy Markdown

swobiteu commented Oct 1, 2024

I converted this code to JScript.NET and wrote FiddlerScript code that defines a Custom Button "Default Client Cert" which lets you choose a client certificate from your local store and then sets it as default client certificate (FiddlerApplication.oDefaultClientCertificate). When you cancel the selection the default client certificate is reset to null.

If you are interested have a look at
https://stackoverflow.com/questions/79011364/defining-a-clientcertificateprovider-in-fiddlerscript/79042779#79042779

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