Installing Certificates Into Firefox

UPDATE: Due to various bugs around accessing the certDB too early, I’ve updated the code to update the certDB on a delay.

There are lots of organizations that use their own certificate authority to issue certificates for their internal servers. Unfortunately since Firefox does not use the Windows certificate store[1], these have to be manually added into Firefox. This post will cover how to get those CAs into Firefox.

CCK2

The easiest way to get your CAs into Firefox is to use CCK2. CCK2 allows certificate authorities and server certificates to be installed into the browser. It supports PEM, DER and text. It also allows you to designate certificate overrides (sites where certificate errors are ignored). Just go to the certificate page and point to either a URL or a local file where the certificate is contained.

AutoConfig via JavaScript

If you’re using AutoConfig without CCK2, you can still use the API that the CCK2 uses to install certificate authorities. Here’s what it looks like to install the cacert.org root certificate:

var observer = {
  observe: function observe(aSubject, aTopic, aData) {
    var certdb = Components.classes["@mozilla.org/security/x509certdb;1"].getService(Components.interfaces.nsIX509CertDB);
    var certdb2 = certdb;
    try {
      certdb2 = Components.classes["@mozilla.org/security/x509certdb;1"].getService(Components.interfaces.nsIX509CertDB2);
    } catch (e) {}
    cert = "MIIHPT...zTMVD"; // This should be the certificate content with no line breaks at all.
    certdb2.addCertFromBase64(cert, "C,C,C", "");
  }
}
Components.utils.import("resource://gre/modules/Services.jsm");
Services.obs.addObserver(observer, "profile-after-change", false);

The three Cs mean to trust the certficate for servers, email and objects. The third parameter is the name, but it is ignored. If you want to install binary certificates, things get more complicated. In that case, I’d definitely recommend the CCK2.

PolicyPak

PolicyPak supports adding certificate authorites to Firefox via Group Policy.

Preload the certificate databases

Some people create a new profile in Firefox, install the certificates they need, and then distribute the various db files (cert8.db, key3.db and secmod.db) into new profiles using this method. I don’t recommend this method (and it only works for new profiles).

certutil

If you’re a real diehard, you can use certutil to update the Firefox certificate databases from the command line.

Hopefully one of these methods will work for you. Did I miss a method? Let me know in the comments.

[1] See: bug 432802 and bug 472113

Please note: I reserve the right to delete comments that are offensive or off-topic.

Leave a Reply

Your email address will not be published. Required fields are marked *

38 thoughts on “Installing Certificates Into Firefox

  1. In your script example, please note nsIX509CertDB2 was collapsed into nsIX509CertDB API starting in Firefox 33. You will need to adjust the API call to make it work in 33 and up.

  2. Hey,

    might be worth updating but you forgot to include the declaration of the Cc and Ci constants in the example.

    const Cc = Components.classes;
    const Ci = Components.interfaces;

    I think the Cc is predeclared in the autoconfig engine some way but Ci is not from what I can tell.

    Keep up the good work!

  3. Hi, thank you great article. I found that the line

    var certdb = Components.classes[“@mozilla.org/security/x509certdb;1”].getService(Components.interfaces.nsIX509CertDB);

    causes Firefox > 40 (I tried it on all Firefox versions among 35 and 42) to not show the list of certificates in options -> advanced -> certificates -> view certificates. It still works properly, i.e. it installs the certificate. If the line gets commented, firefox shows the certificates list including the new one inserted (obviously after having launched firefox with the autoconfig).

    While this could seem a minor issue, my fear is that this can be an alarm bell about the compatibility of this approach with firefox. Could you tell me something about this? Thank you

  4. First off, thank you for this post. It has been extremely helpful so far.

    However, I’m having issues with getting the cert installed. My javascript skills are limited, but it seems like the observer is never firing. I put a few prompts in your code, and never see the ones in the observer itself. Other items in the config file work, though. Like setting the homepage.
    I’m currently running Firefox 42.0.

    var observer = {
    observe: function observe(aSubject, aTopic, aData) {
    var certdb = Components.classes[“@mozilla.org/security/x509certdb;1”].getService(Components.interfaces.nsIX509CertDB);
    var certdb2 = certdb;
    try {
    Services.prompt.alert(null, “Test”, “Opening certdb.”)
    certdb2 = Components.classes[“@mozilla.org/security/x509certdb;1”].getService(Components.interfaces.nsIX509CertDB2);
    } catch (e) {
    displayError(“Error in Autoconfig”, e);
    }

    // This should be the certificate content with no line breaks at all.
    cert = “key in one line”;
    try {
    Services.prompt.alert(null, “Test”, “Attempting to add cert…”)
    certdb2.addCertFromBase64(cert, “CTc,CTc,CTc”, “Server Name”);
    } catch (e) {
    displayError(“Error in Autoconfig”, e);
    }
    }
    }
    try{
    Components.utils.import(“resource://gre/modules/Services.jsm”);
    Services.prompt.alert(null, “Test”, “Attempting to add observer…”);
    Services.obs.addObserver(observer, “profile-after-change”, false);
    Services.prompt.alert(null, “Test”, “Observer added!”);
    } catch (e) {
    Services.prompt.alert(null, “Test”, “Error loading observer!”);
    console.error(e);
    }

    I see prompts for “Attempting to add observer…” and “Observer added!”, but the cert never shows up in my store and any sites that I visit that were issued certs from that authority still present the “untrusted” error. Any thoughts?

    • Try using

      Components.utils.reportError(“Foo”) and you’ll see things on the browser console.

      Can you add reporting inside the observer itself and see if it gets hit?

      I’ll test it again on 42.

  5. Thanks for post !
    I have a question about AutoConfig aproach. Is there a way to set up several .cfg files ? For example, if I want to install my certificate to firefox but don’t want to break any user preferences setting up via previous *.cfg

  6. Top notch! I’ve used this strategy for an open source project and it works on Windows and OS X very well.

    The recent observer logic was critical to avoiding the blank cert page. Much appreciated.

  7. Great post, it put me in the right direction with Certutil. Is there a way that you can add certificates to Firefox using certutil but for the entire machine? Currently it works with just a specific user’s profile but ideally I’d like to import the certificate to all instances of Firefox for all users on a local machine with one command.

    Any suggestions?

  8. sorry for the question, which could be inappropriate, but in this code:
    var certdb = Components.classes[“@mozilla.org/security/x509certdb;1”].getService(Components.interfaces.nsIX509CertDB);
    var certdb2 = certdb;
    try {
    certdb2 = Components.classes[“@mozilla.org/security/x509certdb;1”].getService(Components.interfaces.nsIX509CertDB2);
    } catch (e) {}
    cert = “MIIHPT…zTMVD”; // This should be the certificate content with no line breaks at all.
    certdb2.addCertFromBase64(cert, “C,C,C”, “”);

    One thing is annoying me: what is the behavior if the cert already exists in DB ? (several occurences ? error ?)
    No way to check if the cert is already present before adding it (again) ?

      • Unfortunately the addCertFromBase64 nickname is broke. That’s why I don’t use it.

        And generally the concepts of nicknames is broke (they can be duplicated).

        In my experience, there is no harm in adding the certificate multiple times (they replace each other).

        • > And generally the concepts of nicknames is broke (they can be duplicated).

          I noticed that too and also remove ” – #2″ which seems to cover the edge cases due to a rather guaranteed uniqueness to our OU name.

        • if they only replace each other, indeed i dont need to bother about this 😉

          was just asking because i plan to use this on a production environment (because of squid ssl bump which is driving me crazy ^^)

          better option would be firefox to trust OS store (managed via GPO), but thats not gonna happen i guess

  9. Hi Mike,

    Using the information here I have attempted to add our internal corporate CA without success.

    We are currently using Firefox 42, it started up and the mozilla.cfg file appears to have run but the certificate does not appear to be imported.

    I enabled MCD logging which didn’t yield anything helpful.

  10. Hi !

    I am not really a developer, but I’ve tried your JS. Is it complete ? 13 lines only ?

    Unfortunately I get the blocking error “on line 12: Expected identifier”.

    What am I missing ?

    Thank you

  11. Hello Mike,

    Actually I ve got a .cer certificate that has to be installed
    on all my domain computers. I ve created a GPO for that on my 2008 DC
    under:
    Computer configuration–policies–windows settings–security settings–public key policies
    and imported it on Trusted root certification authorities.
    it worked with Internet Explorer and Google Chrome.
    For mozilla i just followed this post
    https://4sysops.com/archives/group-policy-for-firefox-and-chrome/#comment-313021
    Unfortunatelly it did’t work.

    I would be thankfull for your help.

  12. I am using Firefox on Linux (RHEL6 installations). Your CCK2 procedure appears to be for Windows, not Linux. Is there a similar tool for Linux, or is the certutil command line the only option to add certs?

    • Nothing about the CCK2 procedure is Windows specific.

      The files it builds are all cross platform (and the extension is cross platform)

  13. Amazing post MK … thank you for the time and effort you’ve put into it, and replying to others’ comments!! Quality posts and information sharing such as this are what make the Internet a true marvel. (Now, if only we could get rid of the 95% that’s misinformation. *SIGH*) Cheers!