Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PROTON-2594: Add OpenSSL PKCS#11 PROVIDER support to enable HSM use #430

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

a3f
Copy link

@a3f a3f commented Jul 10, 2024

Hardware Security Modules (HSMs) are physical computing devices that
safeguard secrets and allow performing cryptographic operations like
encryption and signing without necessarily divulging the private key
material.

PKCS#11 is a platform-independent API for cryptographic tokens like
HSMs. It defines a scheme for pkcs11: URIs that describe objects on the
token as well as an API to interact with them.

This commit adds support for transparent use of PKCS#11 URIs: Whenever a
certificate or private key path is prefixed with pkcs11: it will be
interpreted as PKCS#11 URI instead of a file path and OpenSSL will do
all necessary communication with the HSM behind the scenes.

For programs like proton that use OpenSSL, this could have been
realized in two ways:

  • OpenSSL ENGINE: Introduced in OpenSSL 0.9.6 and deprecated in 3.0
  • OpenSSL PROVIDER: Introduced in OpenSSL 3.0 to replace ENGINE

While both are supported in recent OpenSSL versions, it's more future
proof to use the PROVIDER API, even if this comes at the cost of having
to add an #ifdef to the code.

This has been tested on Linux/x86_64 with softhsm and Linux/arm32 with
OP-TEE, both with v0.5 of https://github.com/latchset/pkcs11-provider.

As everything is loaded dynamically, we do not link against any
PKCS#11-related shared libraries. It's expected that PKCS#11 provider
will already be loaded via OPENSSL_CONF if it's to be used.

a3f added 3 commits July 10, 2024 12:26
Hardware Security Modules (HSMs) are physical computing devices that
safeguard secrets and allow performing cryptographic operations like
encryption and signing without necessarily divulging the private key
material.

PKCS#11 is a platform-independent API for cryptographic tokens like
HSMs. It defines a scheme for pkcs11: URIs that describe objects on the
token as well as an API to interact with them.

This commit adds support for transparent use of PKCS#11 URIs: Whenever a
certificate or private key path is prefixed with pkcs11: it will be
interpreted as PKCS#11 URI instead of a file path and OpenSSL will do
all necessary communication with the HSM behind the scenes.

For programs like proton that use OpenSSL, this could have been
realized in two ways:

  - OpenSSL ENGINE:   Introduced in OpenSSL 0.9.6 and deprecated in 3.0
  - OpenSSL PROVIDER: Introduced in OpenSSL 3.0 to replace ENGINE

While both are supported in recent OpenSSL versions, it's more future
proof to use the PROVIDER API, even if this comes at the cost of having
to add an #ifdef to the code.

This has been tested on Linux/x86_64 with softhsm and Linux/arm32 with
OP-TEE, both with v0.5 of https://github.com/latchset/pkcs11-provider.

As everything is loaded dynamically, we do not link against any
PKCS#11-related shared libraries. It's expected that PKCS#11 provider
will already be loaded via OPENSSL_CONF if it's to be used.
The error message unconditionally mentions tserver-private-key.pem,
which is not applicable to Windows, where tserver-full.p12 is used
instead. Fix this by using a new PRIVATEKEY macro that expands to the
correct file name depending on whether we compile for Windows or not.

This prepares us for adding a third PKCS#11 #ifdef branch in the
follow-up commit, which is also why we are moving SSL_FILE specific
into the existing #ifdef branches.
The broker hardcodes the name of the files used at compile time,
depending on whether it's built for Windows or not.

Add a third option by checking whether PKCS11_URI is defined: If it is,
it will use it to reference a "tserver" certificate and private key that
should be used instead of the keys in the ssl-certs/ directory.

This allows an easy manual test of the PKCS#11 functionality.
@astitcher
Copy link
Member

This looks good to me - is there any way of testing this functionality in the CI job? (Rather than just testing that nothing regressed!)

@a3f
Copy link
Author

a3f commented Jul 12, 2024

is there any way of testing this functionality in the CI job? (Rather than just testing that nothing regressed!)

How about we apply this patch and then run the test twice once with PEM files and once with PKCS#11 or would you prefer I duplicate the relevant parts into a new test?

PKCS#11 test would use SoftHSM like done here, but I haven't attempted to do this in CI yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants