GoogleCloudPlatform / kms-integrations

https://cloud.google.com/kms
Apache License 2.0
39 stars 13 forks source link

Key generation not usable with standard PKCS#11 clients #7

Open primetomas opened 2 years ago

primetomas commented 2 years ago

The requirement for the vendor specific CKA_KMS_ALGORITHM in the private key template makes it impossible to use by other than custom developed clients.

One example: pkcs11-tool --module /usr/local/lib/softhsm/libsofthsm2.so --list-slots pkcs11-tool --module /usr/local/lib/softhsm/libsofthsm2.so --list-objects --token-label slot1 --login pkcs11-tool --module /usr/local/lib/softhsm/libsofthsm2.so --keypairgen --key-type rsa:2048 --label "my_key" --usage-sign --token-label slot1 --login

vs pkcs11-tool --module /opt/gcp/libkmsp11-1.1-linux-amd64/libkmsp11.so --list-slots pkcs11-tool --module /opt/gcp/libkmsp11-1.1-linux-amd64/libkmsp11.so --list-objects --token-label cloudhsm --login pkcs11-tool --module /opt/gcp/libkmsp11-1.1-linux-amd64/libkmsp11.so --keypairgen --key-type rsa:2048 --label "my_key" --usage-sign --token-label cloudhsm --login error: PKCS11 function C_GenerateKeyPair failed: rv = CKR_TEMPLATE_INCONSISTENT (0xd1)

I don't claim that the PKCS11 specification forbids custom template attributes, but using them makes it not possible to use with already existing tools and product that already work with most other PKCS#11 HSMs on the market.

primetomas commented 2 years ago

The ask for this issue is if it is not possible to offer other ways to configure this as well instead of only the vendor specific attributes in the private key template? I'm not really a fan of environment variables, but that could be one possible way?

primetomas commented 2 years ago

Also, how about a default value if nothing else is specified? For RSA it could be reasonable to use RSA_SIGN_RAW_PKCS1_2048 is an RSA 2048 bit signature key is generated?

bdhess commented 2 years ago

Quite right, our C_GenerateKeyPair implementation is not going to be compatible with existing code.

As we look toward future releases of this library, we're weighing the pros and cons of changing only this library, versus also relaxing some of the restrictions that exist in our managed service that forced this design in the PKCS #11 client.

In the meantime, is key generation with pkcs11-tool really the ask, or is that just a simple example of the class of problems? If there's more you can share about what you're trying to accomplish, we'd love to hear, either here or in email to cloudkms-feedback@google.com.

Thanks a bunch for taking the time to write.

primetomas commented 2 years ago

Thanks for the answer. You're right pkcs11-tool is just an example. My real use case is HSM support in the PKI product/project EJBCA. Currently we support just about every HSM out there using P11. We just tested and confirmed (with a small change) using the GCP KMS P11 and it works well for usage, but not key generation. We try to keep the code as generic as possible, so it looks and works the same for all different HSMs. I added a screenshot here: https://twitter.com/primetomas/status/1542434462809587712 Currently you have to manually match the algo used with the algo set on the key, which works. But making it "user friendly" with the algo restrictions in KMS will require a bunch of KMS specific code. Apart from the key generation itself you also want to limit the possible also selection for a user matching the restrictions on the key, which will be quite a table. For the other HSMs without the algo restrictions on keys it more (albeit not completely there either) straight forward.

tdbhacks commented 2 years ago

Thanks for the insights, this is very helpful! We will definitely keep this in mind for future iterations of the library, your comments and suggestions have been logged internally as a feature request.

A quick side question: I see that EJBCA uses Java, and I am assuming that adopting the java client library provided by KMS would be more painful than using the PKCS #11 library. Should we provide a JCA provider for KMS in the future, would that be something of interest? And/or, perhaps we could help specify how to write some custom code for this using GCP's KMS client library, like exists for Azure?

primetomas commented 2 years ago

Thanks. Correct. Using PKCS#11 is an "already supported" option which is easy to support.

It is possible to develop what we call "Crypto Token" using the java client library, or direct REST API calls (I have an earlier prototype for that). But it takes much more product development/QA/etc time for such a new major feature. (It will also affect the UI as the same concept of algorithm tied to key exist in the other APIs thus involving even more developers)

bdhess commented 2 years ago

Sorry for the lag on this @primetomas - we're still quite a ways away from the 'ideal' solution.

The ask for this issue is if it is not possible to offer other ways to configure this as well instead of only the vendor specific attributes in the private key template? I'm not really a fan of environment variables, but that could be one possible way?

Wondering what this would look like for EJBCA? Java doesn't have setenv - so would this involve something that your end user does at the CLI? I think something like this is an enhancement we can consider in the near term to get you unstuck.

primetomas commented 2 years ago

Good point. What could be done from Java to affect the environment/P11 library without making specific P11 calls. We don't want to rely on CLI command too much either as it's not very cloud/container "native". Touching the file system is a bit scary...hard to find anything obvious to use from within Java.

We can generate keys outside of EJBCA with CLI tools, and typically do so for cloud marketplace initial deployments (using a wizard). In these cases environment variable can be set, when scripted. Of course, these scripts may as well use the GCP CLI to generate keys, so not much of a gain there actually. Almost pointless :-).

xyakimo1 commented 1 year ago

A quick side question: I see that EJBCA uses Java, and I am assuming that adopting the java client library provided by KMS would be more painful than using the PKCS #11 library. Should we provide a JCA provider for KMS in the future, would that be something of interest? And/or, perhaps we could help specify how to write some custom code for this using GCP's KMS client library, like exists for Azure?

I also intended to use the kmsp11 library in Java. My plan was to use the SunPKCS11 JCA provider for it. This way, it would be possible to nicely decouple client code from an underlying HSM. To use different HSM's, one would need to only change SunPKCS11 configuration file, and existing code would work for all PKCS11-compliant HSM's. Unfortunately, at this moment, such approach cannot be used to generate keys in Google Cloud KMS due to the aforementioned template problem.

xyakimo1 commented 1 year ago

In fact, key generation with SunPKCS11 + kmsp11 is currently not working not only because the vendor specific CKA_KMS_ALGORITHM argument is required in private key template, but also because public key template must be empty. SunPKCS11 uses some default pubic key templates depending on key type (documentation, source code). Though documentation states that it is possible not to include a given attribute, the source code seems to be not reflecting this claim (the aforementioned default attributes will be used anyway).

I want to clarify that my intention is simply to highlight an additional concern regarding key generation with kmsp11 in Java.