pyauth / python-pkcs11

PKCS#11/Cryptoki support for Python
MIT License
150 stars 70 forks source link

AES_KEY_WRAP mechanism not usable #15

Closed ralphstone closed 6 years ago

ralphstone commented 6 years ago

AES_KEY_WRAP is defined as an available mechanism, however the following code around line 1007 seems to ignore the mechanism passed in, and use the default wrap (CBC) instead. AWS cloudhsm does not support cbc for key wrapping, so the method fails with 'invalid mechanism' returned.

mech = MechanismWithParam( self.key_type, DEFAULT_WRAP_MECHANISMS, mechanism, mechanism_param)

(refer https://docs.aws.amazon.com/cloudhsm/latest/userguide/pkcs11-library.html for supported mechanisms). i think it is not only aws; new hsm's are using the newer mechanism for wrapping.

danni commented 6 years ago

It shouldn't ignore the mechanism being passed in. It only uses DEFAULT_WRAP_MECHANISMS if mechanism is None. How are you calling the key wrap function? What is most likely is that it's unhappy for some other reason. Many PKCS#11 libraries let you set environment variables for more useful debugging of the actual error.

My HSM devices don't support AES_KEY_WRAP and while recent versions of SoftHSM2 allegedly do, it's not appearing in the mechanism list for me. I suspect this is related to my version of OpenSSL.

Could you add a test case in test_aes.py that highlights the issue?

ralphstone commented 6 years ago

thanks danni, i'll try to round up some more info, but in the meantime, how can i export an aes key then? what i am doing is generating a key, which i need to share with a remote party. i wanted to export the key and wrap it with rsa/public to send to them so they can rsa/private decrypt is and use the AES key.. is there another way i can generate an AES key and then send it RSA encrypted to the remote party?

danni commented 6 years ago

If you're trying to wrap an AES key with an RSA key that will be why you're getting invalid mechanism. The mechanism is invalid for the key type. You'll need to use an RSA mechanism, e.g. RSA_PKCS_OAEP (which is the default).

The mechanisms document gives the full details: http://docs.oasis-open.org/pkcs11/pkcs11-curr/v2.40/errata01/os/pkcs11-curr-v2.40-errata01-os-complete.html#_Toc441850412

Your key also needs to be EXTRACTABLE (and sometimes not SENSITIVE depending on the PKCS#11 implementation). See http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/errata01/os/pkcs11-base-v2.40-errata01-os-complete.html#_Toc323024158 Not all implementations return not wrappable as documented they should.

test_rsa.test_key_wrap shows an example of wrapping an AES key in an RSA key.

ralphstone commented 6 years ago

OK i think i know what is happening. you define: AES_KEY_WRAP = 0x00001090 whereas the current pkcs#11 spec (as per oasis above) defines:

define CKM_AES_KEY_WRAP 0x00002109

so AWS is throwing back an error: invalid mechanism

danni commented 6 years ago

What have they done? They've moved the mechanism and then reassigned the number. All within the same version number header, the 2013 v2.40 and 2016 v2.40 files are different.

ralphstone commented 6 years ago

yes it wasn't obvious. i am now past the 'invalid mechanism' response from cloudhsm (yay), but am now getting an 'inconsistent template' message returned. getting there...

danni commented 6 years ago

I will work on a branch that updates to the 2016 spec.

danni commented 6 years ago

16 updates for the new headers. Also adds an AES_KEY_WRAP example that works with SoftHSM at least. I would be super keen to see a PR that updates/improves the testcases for CloudHSM.

ralphstone commented 6 years ago

thanks danni, that worked a treat; i can wrap and unwrap keys for import (i need to import because i have one remote partner who sends me his transport key). however for cloudhsm i needed to set: pkcs11.Attribute.SENSITIVE: True to avoid an 'inconsistent template' message. i think i can fly cloudhsm ok now. this is the Cavium model (from AWS's getHSMInfo): https://www.cavium.com/pdfFiles/NITROXIII_NFBE_PB_Rev1.pdf?x=3

danni commented 6 years ago

Yeah, the attributes required are not well specified and most of the HSMs do something completely different. Does #16 pass the tests for you? I have it passing against SoftHSM locally, but not in Travis (again suspect OpenSSL version). Neither my Thales HSM, my Nitrokey HSM nor the TPM stuff supports the mechanism, so I have no real devices to test with.

ralphstone commented 6 years ago

yes, as long as i set sensitive to true, i can unwrap fine. thanks for the prompt support, much appreciated.

danni commented 6 years ago

Released v0.5.0 with this fix.