accessing digital cert with javascript

How can we get access to the digital certificate for the page that our browser just loaded using javascript?

It’s not possible in Chrome, but we can do it using an extension in Firefox. This stackoverflow question goes into more details.

The question doesn’t explain how to accomplish the feat. For that, let’s consult the Firefox extension from the CMU Perspectives Project.

The relevant section of code from perspectives/plugin/chrome/content/notaries.js

    // gets current certificate, if it PASSED the browser check
    psv_get_valid_cert: function(ui) {
        try {
            ui.QueryInterface(Components.interfaces.nsISSLStatusProvider);
            if(!ui.SSLStatus) {
                return null;
            }
            return ui.SSLStatus.serverCert;
        }
        catch (e) {
            Pers_debug.d_print("error", "Perspectives Error: " + e);
            return null;
        }
    },

    getCertificate: function(browser) {
        var uri = browser.currentURI;
        var ui  = browser.securityUI;
        var cert = this.psv_get_valid_cert(ui);
        if(!cert) {
            cert = this.psv_get_invalid_cert(uri);
        }

        if(!cert) {
            return null;
        }
        return cert;
    },

Essentially, we need to get the browser object and pass it’s securityUI property to psv_get_valid_cert(). This mozilla link explains how to get access to the browser object. The relevant bit of code looks like this.

// get the browser object from the most recent window
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
                   .getService(Components.interfaces.nsIWindowMediator);
var mainWindow = wm.getMostRecentWindow("navigator:browser");
mainWindow.gBrowser.addTab(...);

Then we put it all together in a Firefox Add-On.

const {Cc,Ci} = require("chrome");
require('sdk/tabs').on("ready", onLoad);

function onLoad(tabe) {
    var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
    var mainWindow = wm.getMostRecentWindow("navigator:browser");

    var cert = get_valid_cert(mainWindow.gBrowser);
    var root_issuer = cert.issuer;
    while (root_issuer && root_issuer.issuer) {
        root_issuer = root_issuer.issuer;
    }

    console.log("");
    console.log("common name:              " + cert.commonName);
    console.log("sha1 fingerprint:         " + cert.sha1Fingerprint);
    console.log("issuer common name:       " + cert.issuerCommonName);
    console.log("root issuer nickname:     " + root_issuer.nickname);
    console.log("root issuer subject name: " + root_issuer.subjectName);
    console.log("");
}

// stolen from perspectives project
function get_valid_cert(gb) {
    var ui = gb.securityUI;
    try {
        ui.QueryInterface(Ci.nsISSLStatusProvider);
        if(!ui.SSLStatus) {
            return null;
        }
        return ui.SSLStatus.serverCert;
    }
    catch (e) {
        Pers_debug.d_print("error", "Perspectives Error: " + e);
        return null;
    }
}

Output produced from the extension.

console.log: ffcert: 
console.log: ffcert: common name:                  www.google.com
console.log: ffcert: sha1 fingerprint:       69:70:F0:C0:C2:C9:D3:B9:C9:64:C3:58:E6:F4:74:18:D7:CA:6F:09
console.log: ffcert: issuer common name:       Google Internet Authority G2
console.log: ffcert: root issuer nickname:       Default Trust:Equifax Secure CA
console.log: ffcert: root issuer subject name: OU=Equifax Secure Certificate Authority,O=Equifax,C=US
console.log: ffcert: 

git repo available here

 
23
Kudos
 
23
Kudos

Now read this

optimal OOP play against a polarized range

Consider this simplified river spot. Hero is OOP with a condensed range against Villain’s polarized range. Hero’s hands can only beat Villain’s bluffs. Let’s also say that each player can only use an unmixed strategy for their entire... Continue →