Hacker News new | ask | show | jobs
by pedrocr 4454 days ago
This seems like a good idea but this fixation on PKCS#11 seems strange. Why use a whole API when Apache and Nginx can just add a simple daemon with their own internal API to do this?

The same amount of security can probably be obtained by just launching a process on server startup to do this with sufficient isolation from the parent process. I believe OpenSSH does something along these lines to run most of its code as an unprivileged user. It's probably even possible to do this seamlessly based on the existing SSL config directives in apache/nginx requiring no more intervention from the sysadmin than upgrading to a newer version.

3 comments

The major reason is that when your website becomes popular, and becomes more of a target, you can swap out the software hsm daemon with a more sophisticated hardware solution, if implemented properly, by just changing a pkcs11: url[1] to point at the new HSM.

PKCS#11 has a few irritants, but it's a fairly sensible API. and it's already implemented by many things (browsers, gnome-keyring, ssh, ...). OpenSSL, GnuTLS at least both support it via one mechanism or another, my only real complaint from the webserver side is that the configuration knobs aren't really plumbed through.

[1]: http://tools.ietf.org/html/draft-pechanec-pkcs11uri

That would be an argument for supporting both. I fear that otherwise what you will end up with is that a minority of security conscious people will have HSM (actual hardware or software) and most others will just configure their Apache/nginx software as quickly as possible and get on with it. Having the basic config be more secure by spawning the soft-hsm itself sounds like a win.
An external standard (de facto or not) is always better when dealing with things like this than a internal API. If I want to reuse that daemon for other things I know what to expect and how to operate it indipendently.
I disagree it's always better. It's a tradeoff. Now to install apache securely you need to go and install another daemon under a different user and configure apache to use it. How many people will actually bother? If it's builtin and driven by apache itself you just need to upgrade apache. So if you want mass adoption of this solution in HTTP servers a builtin solution works best. If you want to be able to reuse this for your openvpn/xmpp/etc server a separate daemon is best.
The value, in theory, is that PKCS#11 already exists, is already supported by software and hardware vendors, and is already comprehensive enough and has seen sufficient review to cover the gamut of use cases that such a solution would need to support.

PKCS#11 is a little funny looking and has some small rough edges, but it's actually reasonably designed and easy to implement from scratch. That's not something I can say for many of the other PKCS standards.

>PKCS#11 already exists, is already supported by software and hardware vendors

It's apparently not supported by Apache/nginx nor does a suitable software-HSM exist to use it, so you're basically writing both ends of the communication. But if you do go with a separate daemon PKCS#11 may very well be a good solution. I just think forking off a process yourself is much cleaner for the use case of securing a web server.

> It's apparently not supported by Apache/nginx nor does a suitable software-HSM exist to use it, so you're basically writing both ends of the communication.

Apache/nginx don't have to support pkcs11, they just need to support the use of existing crypto libraries that already support pkcs11:

http://www.gnutls.org/manual/html_node/Using-a-PKCS11-token-...

If a server uses gnutls and passes the user-supplied filename directly to gnutls_certificate_set_x509_key_file2(), a PKCS#11 URL can be used directly without changes to the server.

> I just think forking off a process yourself is much cleaner for the use case of securing a web server.

It's something that everyone has to write for every server; people will get it wrong. Additionally, there's no support for hardware modules or plugging in new software security modules, so you'd be starting with a handicapped solution.

>Apache/nginx don't have to support pkcs11, they just need to support the use of existing crypto libraries that already support pkcs11

Fine you get Apache->SSLLib->PKCS#11. Now you need to write a PKCS#11 compliant library to talk to your HSM, and a custom serialization protocol for that communication anyway.

>It's something that everyone has to write for every server; people will get it wrong. Additionally, there's no support for hardware modules or plugging in new software security modules, so you'd be starting with a handicapped solution.

If we're worried about http servers it's basically apache/nginx. As I mentioned in another comment if apache/nginx implement this directly most users will get it by default. If they implement it with a separately configured daemon only very security conscious people will do it. So if your objective is preventing the most dangerous bugs in the most exposed daemons (and HTTPS tends to be that) in the most number of cases doing this directly by default in those two servers seems like a better solution. That doesn't stop you from also doing the other option to support actual HSMs and other fancy 1% cases.

> Fine you get Apache->SSLLib->PKCS#11. Now you need to write a PKCS#11 compliant library to talk to your HSM, and a custom serialization protocol for that communication anyway.

HSM modules already have PKCS#11 drivers, because it's a standard, and that means they work readily with existing software and cover the requisite industry use-cases.

You're proposing taking web servers in a different direction simply because you find the general, widely supported solution to be antithetical to your tastes?

Unless you're actually going to write code here, I don't really understand why you care, or why you're advocating ignoring hard-won wisdom and experience that's encoded in a decent spec, just because you don't think you'll like it.

>HSM modules already have PKCS#11 drivers, because it's a standard, and that means they work readily with existing software and cover the requisite industry use-cases.

The OP isn't talking about using an actual HSM, but using a new software based daemon to do the HSM role just so the crypto calculations (and the key) aren't in the webserver's address space. He confirms that he is indeed trying to write the PKCS#11 driver himself. Just using the existing crypto code in Apache/nginx but moving it into a separate process seems much cleaner to me and has the one feature this suggestion doesn't, it works with existing config files without modification so will be used much more widely. That's all I am saying.

There are several softhsm's, they just share the address space with your frontline daemon which (IMHO) defeats the purpose.

While webserver's support for PKCS#11 is annoying, it's well supported by lots and lots of other stuff (usually client side stuff like ssh, browsers etc tho). You can get webservers to do PKCS#11 today, there are docs on how to do it. They usually start with "download the source, and run configure with this pile of options."

Isn't that just because PKCS#11 is an in-process API so not really meant for calls over a socket? So wouldn't you need to actually write a PKCS#11 compliant library to plug into the server, a software HSM and then some form of serializing protocol to talk between the two? Or is there a standard way to do PKCS#11 over a socket? A quick look at the spec made it look like a "here's how our struct's are packed" kind of standard.
Yup, that pretty much sums it up. I'm currently trying to figure out if dbus could be that serialisation since it takes care of a reasonable amount of the hard work for you. But I'm no expert on GObject, so slow going. (Also, I'm not sure that I'm the best person to be writing this... I don't really have that much security knowledge, I just spent a whole pile of time trying to figure out how to secure my (client) keys recently and wondered why we didn't do something sensible for server keys.
In that case why not skip the middle man and just implement enough soft-HSM for whatever Apache/nginx needs with a simple serialization protocol just for that? Emulating all of PKCS#11 sounds like a chore for very little gain.