Tuesday, April 21, 2009

roll your own EV

In working on a project recently, I found myself wanting to become an EV-SSL certificate authority (EV means Extended Validation). Lofty goals, yes, but really I just wanted to play with EV certificates and see if a couple of things were feasible. I'll post what happens as I figure it out.

Anyway, I needed to find a way to get a browser to accept a root CA that I created, and then get the browser to trust that root CA to issue EV certificates. This is harder than it sounds; regular SSL root certificates can be added easily to any browser, but the EV root certs can't. This is to protect users from accidental or malicious installation of EV root certs -- but unfortunately also protected me from easily doing it too.

Turns out, Firefox will let you "test" some CA certs as EV authorities, but you have to get your hands on a debugging build. Not only that, but unless you want to maintain a fresh CRL or OCSP server, you'll have to modify the source code. Sounds daunting, but it really isn't too bad. I've documented the whole process here, and I'll summarize in this blog post.

1. Create an EV-SSL Certificate Authority, and make an EV cert. This sounds fancy, but basically means: create a certificate authority, then issue a cert with a specific policy OID. The differences between regular CAs and EV CAs are minimal except in how the browser decides to classify them. In short, this should do the trick:
./CA.pl -newca

openssl req -config ./openssl.cnf -new -keyout newkey.pem \
-out newreq.pem -days 30

openssl ca -config ./openssl.cnf -policy policy_anything \
-out newcert.pem -infiles newreq.pem
Details here.

2. Tame Firefox. This involves patching the Firefox source code to perform lazy freshness checks on certificates (and there's a patch for that here), and set it up to accept externally defined EV root authorities (you will list them in a text file). Then you must compile the source in debug mode to enable it. Details here.

3. Install your CA and go. You have to extract the base-64 encoded subject and serial number out of your CA certificate by installing this patch, compiling the NSS tools, and running the pp tool on your root certificate. Once you've got that data, put it, the EV policy OID of your choice, and the CA cert fingerprint in a file called "test_ev_roots.txt". That text file goes in your Firefox profile directory. Once that's set up, you run Firefox, install the root CA as a regular SSL trusted authority, and you're ready to go. Details here.

Summary. It's not impossible to install a root certificate and get Firefox to consider it an EV root, but it is surely difficult (and this is good). The instructions presented in this post are simply summary, and not indended to be details, which can be found here.

Edit: I guess I should explain that EV means Extended validation; basically a more thorough check is performed by a certificate authority before issuing an EV certificate [EV on wikipedia]

16 comments:

  1. I'm sure this is common knowledge in your field, but what is EV?

    ReplyDelete
  2. @btornado: hah, yeah, I should probably clarify that, thanks. (See edit.)

    ReplyDelete
  3. I filed a bug on figuring out a way to add EV tests to our mochitest suite a while back:
    https://bugzilla.mozilla.org/show_bug.cgi?id=458727

    ReplyDelete
  4. Can you provide a link to a patched firefox?

    ReplyDelete
  5. @Anonymous: no, I won't post a patched build of Firefox. You have to patch it and compile it with your own CA and OID details anyway, so unless I post my custom CA's private key and cert along with the patch it is useless.

    I also am of the opinion that if you want to play with fire, you should know how fire works. :)

    ReplyDelete
  6. I understand your reasoning, but all of the makefiles that I get, have no target for nss_build_all so is there a way I can add that?

    ReplyDelete
  7. I know that this article is a little old, but may I ask what version of Firefox you used?

    ReplyDelete
  8. @Anonymous: It's still there (see http://mxr.mozilla.org/mozilla-central/source/security/nss/Makefile#81). I tried it today and it worked.

    With mozilla-central checked out, you have to change to the security/nss/ subdirectory and issue the make command there.

    @dsage: I think this was 3.0.17. Should still work in 3.6 or trunk builds today since NSS hasn't changed a whole lot.

    ReplyDelete
  9. @dsage: I take that back, it was probably a pre-release 3.5 build since I was working on mozilla-central in April 2009.

    ReplyDelete
  10. Since I don't have the CA.pl or the batch file, I'm wondering if the basicConstraints,keyUsage, and OID fields are required for the CA to then make the EV. I already have a CA cert at https://podaci.co.uk/root.crt without those properties and am wondering if I will have to create a new one and re-issue the current certs in order to use it to make an EV intermediary CA.

    ReplyDelete
  11. For the life of me, I can't understand why these comments all have times but no dates, which is the most relevant.

    ReplyDelete
  12. Thanks for the great blog post! I'm having trouble working out the details of the openssl.cnf to get to actually sign a request. I find that if I have the businessCategory = 2.5.4.15 in the [ new_oids ] section (as you suggest), that ca complains that "object identifier routines:OBJ_create:oid exists" (and points to ../crypto/objects/obj_dat.c). Well, then, if I remove that from new_oids, then I can get farther (past the signature check) but then "The businessCategory field needed to be supplied and was missing". Let me know if I'm missing something very obvious or if there are more in-depth resources I should be studying.

    ReplyDelete
  13. I'm receiving an error when trying to use the openssl-ca utility to create the request and sign the certificate (OpenSSL 1.1.1-pre3-dev): https://gist.github.com/h1nk/aa8531930e0f8b0f5d880c1a391fd484

    ReplyDelete
  14. I'm receiving an error when trying to use the openssl-ca utility to create the request and sign the certificate (OpenSSL 1.1.1-pre3-dev): https://gist.github.com/h1nk/aa8531930e0f8b0f5d880c1a391fd484

    ReplyDelete
  15. When using the openssl-ca utility to create the request and sign certificate I'm receiving an error about creating the object 'businessCategory' from the example openssl config: https://gist.github.com/h1nk/aa8531930e0f8b0f5d880c1a391fd484

    ReplyDelete
  16. I haven't done anything with EV SSL in quite a long time, but if you're having trouble with the businessCategory, check out the CA/Browser Forum's EV SSL requirements: https://cabforum.org/ev-certificate-contents/

    There it says businessCategory is a string, which seems to have changed since I wrote this blog post in April 2009.
    "Business Category (EVG 9.2.4) – This field must contain one of the following strings: “Private Organization”, “Government Entity”, “Business Entity”, or “Non-Commercial Entity”."

    ReplyDelete