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

 
24
Kudos
 
24
Kudos

Now read this

quirk in bash security check (privileged mode)

Did you know the name given to bash affects its behavior? burrows@box:/tmp/priv$ ln -s /bin/bash sh burrows@box:/tmp/priv$ ln -s /bin/bash ba burrows@box:/tmp/priv$ ./ba -c "set -o | grep posix" posix off burrows@box:/tmp/priv$ ./sh -c... Continue →