def _get_e_n(backend, handle): # TODO: These buffers could be dynamically sized in the future, but # it would require two calls to the PKCS11 layer. Right now it will # work with a single call as long as the key is 8192-bit or smaller and # the modulus isn't some ludicrous value. attrs = build_attributes([ ( backend._binding.CKA_MODULUS, backend._ffi.new("unsigned char[]", 1024) ), ( backend._binding.CKA_PUBLIC_EXPONENT, backend._ffi.new("unsigned char[]", 64) ), ], backend) session = backend._session_pool.acquire() res = backend._lib.C_GetAttributeValue( session[0], handle, attrs.template, len(attrs.template) ) backend._check_error(res) n = utils.int_from_bytes( backend._ffi.buffer( attrs.template[0].value, attrs.template[0].value_len )[:], 'big' ) e = utils.int_from_bytes( backend._ffi.buffer( attrs.template[1].value, attrs.template[1].value_len )[:], 'big' ) return e, n
def generate_rsa_private_key(self, public_exponent, key_size): # TODO: we need to be able to pass templates in. right now all keys # are generated as session only and exportable. And this is all # untested so far session = self._session_pool.acquire() public_handle = self._ffi.new("CK_OBJECT_HANDLE *") private_handle = self._ffi.new("CK_OBJECT_HANDLE *") mech = self._ffi.new("CK_MECHANISM *") mech.mechanism = self._binding.CKM_RSA_PKCS_KEY_PAIR_GEN pub_attrs = build_attributes([ ( self._binding.CKA_PUBLIC_EXPONENT, utils.int_to_bytes(public_exponent) ), (self._binding.CKA_MODULUS_BITS, key_size), (self._binding.CKA_TOKEN, False), # don't persist it (self._binding.CKA_PRIVATE, False), (self._binding.CKA_ENCRYPT, True), (self._binding.CKA_VERIFY, True), ], self) priv_attrs = build_attributes([ (self._binding.CKA_TOKEN, False), # don't persist it (self._binding.CKA_PRIVATE, False), (self._binding.CKA_DECRYPT, True), (self._binding.CKA_SIGN, True), (self._binding.CKA_EXTRACTABLE, True) ], self) # TODO: remember that you can get the public key values from # CKA_MODULUS and CKA_PUBLIC_EXPONENT. but you can't perform # operations on them so we probably still need to think of these as # keypairs res = self._lib.C_GenerateKeyPair( session[0], mech, pub_attrs.template, len(pub_attrs.template), priv_attrs.template, len(priv_attrs.template), public_handle, private_handle ) self._check_error(res) return _RSAPrivateKey(self, private_handle[0])
def load_rsa_private_numbers(self, numbers): rsa._check_private_key_components( numbers.p, numbers.q, numbers.d, numbers.dmp1, numbers.dmq1, numbers.iqmp, numbers.public_numbers.e, numbers.public_numbers.n ) attrs = build_attributes([ (self._binding.CKA_TOKEN, False), # don't persist it (self._binding.CKA_CLASS, self._binding.CKO_PRIVATE_KEY), (self._binding.CKA_KEY_TYPE, self._binding.CKK_RSA), ( self._binding.CKA_MODULUS, utils.int_to_bytes(numbers.public_numbers.n) ), ( self._binding.CKA_PUBLIC_EXPONENT, utils.int_to_bytes(numbers.public_numbers.e) ), ( self._binding.CKA_PRIVATE_EXPONENT, utils.int_to_bytes(numbers.d) ), (self._binding.CKA_PRIME_1, utils.int_to_bytes(numbers.p)), (self._binding.CKA_PRIME_2, utils.int_to_bytes(numbers.q)), (self._binding.CKA_EXPONENT_1, utils.int_to_bytes(numbers.dmp1)), (self._binding.CKA_EXPONENT_2, utils.int_to_bytes(numbers.dmq1)), (self._binding.CKA_COEFFICIENT, utils.int_to_bytes(numbers.iqmp)), ], self) session = self._session_pool.acquire() # TODO: do we want to delete the object from the session when it # is no longer in scope? object_handle = self._ffi.new("CK_OBJECT_HANDLE *") res = self._lib.C_CreateObject( session[0], attrs.template, len(attrs.template), object_handle ) self._check_error(res) return _RSAPrivateKey(self, object_handle[0])