Skip to content

Instantly share code, notes, and snippets.

@jay
Last active August 29, 2015 14:14
Show Gist options
  • Save jay/17940f346ab5a164a8c2 to your computer and use it in GitHub Desktop.
Save jay/17940f346ab5a164a8c2 to your computer and use it in GitHub Desktop.
Excerpt from my Fiddler CustomRules.js of ValidateCert. https://groups.google.com/forum/#!topic/httpfiddler/cjGlrTWnnZk
static function Main() {
var today: Date = new Date();
FiddlerObject.StatusText = " CustomRules.js was loaded at: " + today;
// Uncomment to add a "Server" column containing the response "Server" header, if present
// FiddlerObject.UI.lvSessions.AddBoundColumn("Server", 50, "@response.server");
// https://groups.google.com/forum/#!topic/httpfiddler/RIjfLBU58Io
CONFIG.oAcceptedServerHTTPSProtocols = System.Security.Authentication.SslProtocols.Tls
| System.Security.Authentication.SslProtocols.Tls11
| System.Security.Authentication.SslProtocols.Tls12;
FiddlerApplication.add_OnValidateServerCertificate(ValidateCert);
}
static function OnRetire() {
FiddlerApplication.remove_OnValidateServerCertificate(ValidateCert);
}
// https://groups.google.com/forum/#!topic/httpfiddler/cjGlrTWnnZk
static function ValidateCert(sender, ea: ValidateServerCertificateEventArgs)
{
if (ea.CertificatePolicyErrors == System.Net.Security.SslPolicyErrors.None) {
return;
}
var arrIgnoreInvalid: String[] = ["www.whitehouse.gov"];
var host = ea.ExpectedCN.ToLower();
for (var i in arrIgnoreInvalid) {
if (host.Equals(arrIgnoreInvalid[i])) {
ea.ValidityState = CertificateValidity.ForceInvalid;
return;
}
}
var store_chain: Boolean = FiddlerApplication.Prefs.GetBoolPref(
"fiddler.network.https.storeservercertchain", false);
var reason: String = "unknown";
switch (ea.CertificatePolicyErrors) {
case System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors:
reason = "RemoteCertificateChainErrors";
break;
case System.Net.Security.SslPolicyErrors.RemoteCertificateNameMismatch:
reason = "RemoteCertificateNameMismatch";
break;
case System.Net.Security.SslPolicyErrors.RemoteCertificateNotAvailable:
reason = "RemoteCertificateNotAvailable";
break;
}
var details = "Session #" + ea.Session.id + ": The remote server (" + ea.ExpectedCN
+ ") presented a certificate that did not validate, due to " + reason + "." + endl;
if (store_chain) {
details += endl + "##### CHAIN_START #####" + endl;
}
var found: Boolean = false;
if (store_chain
&& ea.ServerCertificateChain != undefined
&& ea.ServerCertificateChain.ChainElements != undefined)
{
for (var i = 0; i < ea.ServerCertificateChain.ChainElements.Count; i++) {
details += endl;
/* X509Certificate.Equals method only compares issuer and serial number.
For speed we compare those first before the raw data comparison.
StructuralComparisons is only .NET 4+ so substitute if necessary:
http://stackoverflow.com/questions/43289/comparing-two-byte-arrays-in-net
*/
if (!found
&& ea.ServerCertificate != undefined
&& ea.ServerCertificateChain.ChainElements[i].Certificate != undefined
&& ea.ServerCertificate.Equals(
ea.ServerCertificateChain.ChainElements[i].Certificate)
&& System.Collections.StructuralComparisons.StructuralEqualityComparer.Equals(
ea.ServerCertificate.GetRawCertData(),
ea.ServerCertificateChain.ChainElements[i].Certificate.GetRawCertData()))
{
found = true;
details += GetServerCertSessionString(ea.Session, ea.ExpectedCN);
}
details += GetCertDetailString(
ea.ServerCertificateChain.ChainElements[i].Certificate,
ea.ServerCertificateChain.ChainElements[i].ChainElementStatus);
}
}
if (store_chain) {
details += endl + "##### CHAIN_END #####" + endl;
}
if (!found) {
details += endl;
if (store_chain) {
details += "WARNING: The server's certificate was not found in the chain." + endl
+ endl;
}
details += GetServerCertSessionString(ea.Session, ea.ExpectedCN)
+ GetCertDetailString(ea.ServerCertificate);
}
ea.Session["cert_validation_details"] = details;
// For tunnels append details to the request data so they're visible in the inspector
if (ea.Session.isTunnel)
{
var a: Byte[] = ea.Session.requestBodyBytes;
var b: Byte[] = System.Text.Encoding.UTF8.GetBytes(details);
ea.Session.requestBodyBytes = new Byte[a.Length + b.Length];
System.Buffer.BlockCopy(a, 0, ea.Session.requestBodyBytes, 0, a.Length);
System.Buffer.BlockCopy(b, 0, ea.Session.requestBodyBytes, a.Length, b.Length);
}
FiddlerObject.log(details);
}
static function GetServerCertSessionString(oSession: Session, expectedCN: String): String
{
var comments = "## Server certificate from " + oSession.hostname + ":" + oSession.port
+ " (m_hostIP: " + oSession.m_hostIP + ", expectedCN: " + expectedCN + ")." + endl;
comments += "## Timers.ServerConnected: " + oSession.Timers.ServerConnected.ToString()
+ " (UTC: " + oSession.Timers.ServerConnected.ToUniversalTime().ToString("o") + ")."
+ endl;
comments += "##" + endl;
return comments;
}
static function GetCertDetailString(
cert: System.Security.Cryptography.X509Certificates.X509Certificate,
... status: System.Security.Cryptography.X509Certificates.X509ChainStatus[]): String
{
var details = "";
if (cert != undefined) {
details += "## SUBJECT: " + cert.Subject + endl
+ "## ISSUER: " + cert.Issuer + endl
+ "## EXPIRES: " + cert.GetExpirationDateString() + endl;
}
if (status != undefined) {
for (var j = 0; j < status.Length; j++) {
details += "## STATUS: " + status[j].StatusInformation.Trim() + endl;
}
}
if (cert != undefined) {
details += "-----BEGIN CERTIFICATE-----" + endl
+ Convert.ToBase64String(cert.GetRawCertData(),
Base64FormattingOptions.InsertLineBreaks) + endl
+ "-----END CERTIFICATE-----" + endl;
} else {
details += "## Certificate undefined!" + endl;
}
return details;
}
public static ContextAction("Copy certificate validation details")
function CopyCertValidationDetails(oSessions: Fiddler.Session[])
{
if (oSessions == undefined || !oSessions.Length) {
FiddlerObject.alert("Please select sessions to copy certificate validation details.");
return;
}
var found: int = 0;
var border = "============================================================================";
var s = border + endl + endl;
for (var i = 0; i < oSessions.Length; i++) {
if (!oSessions[i].oFlags.ContainsKey("cert_validation_details")) {
continue;
}
s += oSessions[i].oFlags["cert_validation_details"] + endl + border + endl + endl;
found++;
}
if (!found) {
FiddlerObject.alert("The selected sessions don't have certificate validation details.");
return;
}
Utilities.CopyToClipboard(s);
}
static const endl: String = "\r\n";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment