>A PKCS#11 driver can simply fork() itself to operate out-of-process, without implementing some sort of heavyweight daemon.
The OPs proposal was for a daemon so it could be run as a different user. My suggestion was indeed to fork and figure out how to isolate the process (as forking may not be enough if you have permissions to do things like ptrace processes running under the same user).
>Apache could ship a fall-back PKCS#11 driver implementation that did this, transparently.
What you are proposing then is something different. It's to make the only crypto code path the PKCS#11 one and then make the normal case the special case of that. So you are going Apache->Gnutls/OpenSSL->custom PKCS#11 driver->fork->Gnutls/OpenSSL(to actually do the crypto). Since apache already has working code for the first and last steps you could just do Apache->fork->Gnutls/OpenSSL and be done with it. Your suggestion adds more complexity but improves the support for other more exotic PKCS#11 providers.
After reading your responses and claims of complexity and architecture, I don't think you understand PKCS#11, the problem domain, or the architectural constraints to a level that is commiserate with your expressed level of certainty.
I say this as someone who works on PKCS#11 code: It's not really possible to have a productive conversation with someone that is missing key domain experience and knowledge, but is so certain of their correctness anyway.
More concretely, a forked daemon only needs to support RSA and other crypto operations without revealing their keying material. They don't need a full TLS/SSL stack.
That said, there's absolutely no additional complexity in having both Apache and the hypothetical daemon using a full TLS/SSL crypto library. Any __TEXT pages will be shared, and duplicated __DATA and base-line library allocations are essentially zero.
>After reading your responses and claims of complexity and architecture, I don't think you understand PKCS#11, the problem domain, or the architectural constraints to a level that is commiserate with your expressed level of certainty.
I'm happy to learn. But all I am saying is that you're adding a PKCS#11 step to the call stack when you can just fork and use the existing code. That's a simple assertion, is it wrong?
>To be a bit more concrete, a forked daemon only needs to support RSA and other crypto operations without revealing their keying material. They don't need a full TLS/SSL stack.
I didn't say they did. I said that you had to implement some GnuTLS/OpenSSL code in apache to invoke the PKCS#11 operations, then implement your forking PKCS#11 driver that will then need to call GnuTLS/OpenSSL to do the crypto to return the PKCS#11 results.
>That said, there's absolutely no additional complexity in having both Apache and the hypothetical daemon using a full TLS/SSL crypto library. Any __TEXT pages will be shared, and duplicated __DATA and base-line library allocations are essentially zero.
The complexity I was referring to was in the code that you need to setup the call stack you are proposing. Obviously the gnutls/openssl .so will be shared.
> I'm happy to learn. But all I am saying is that you're adding a PKCS#11 step to the call stack when you can just fork and use the existing code. That's a simple assertion, is it wrong?
Yes, that's wrong. What existing code is there that provides an IPC mechanism for offloading RSA signing operations that are done within the TLS libraries themselves?
I see where I've not explained myself properly. The existing code I'm referring to is the code that right now handles the TLS sessions in apache/nginx. That's the code I'm suggesting could be run from a forked process instead of in the main process. To need IPC to offload the RSA crypto you'd need to be doing Apache->TLS session code->fork->RSA operations. I'm saying you could do Apache->fork->TLS session code. Just run all your TLS sessions in a different process with the normal single process, no PKCS#11 GnuTLS/OpenSSL code. Is that not feasible?
To do that Apache needs some form of internal IPC to communicate its TLS sessions to the forked process. Maybe that's more complex than forking and doing IPC at the PKCS#11 driver level? Don't know.
> To do that Apache needs some form of internal IPC to communicate its TLS sessions to the forked process. Maybe that's more complex than forking and doing IPC at the PKCS#11 driver level? Don't know.
Yes.
Also, bear in mind that you can't just fork and continue running in modern software.
A process shall be created with a single thread. If a multi-threaded process calls fork(), the new process shall contain a replica of the calling thread and its entire address space, possibly including the states of mutexes and other resources. Consequently, to avoid errors, the child process may only execute async-signal-safe operations until such time as one of the exec functions is called.
The OPs proposal was for a daemon so it could be run as a different user. My suggestion was indeed to fork and figure out how to isolate the process (as forking may not be enough if you have permissions to do things like ptrace processes running under the same user).
>Apache could ship a fall-back PKCS#11 driver implementation that did this, transparently.
What you are proposing then is something different. It's to make the only crypto code path the PKCS#11 one and then make the normal case the special case of that. So you are going Apache->Gnutls/OpenSSL->custom PKCS#11 driver->fork->Gnutls/OpenSSL(to actually do the crypto). Since apache already has working code for the first and last steps you could just do Apache->fork->Gnutls/OpenSSL and be done with it. Your suggestion adds more complexity but improves the support for other more exotic PKCS#11 providers.