1# This file is dual licensed under the terms of the Apache License, Version 2# 2.0, and the BSD License. See the LICENSE file in the root of this repository 3# for complete details. 4 5from __future__ import absolute_import, division, print_function 6 7from cryptography import utils 8from cryptography.hazmat.backends.openssl.utils import _evp_pkey_derive 9from cryptography.hazmat.primitives import serialization 10from cryptography.hazmat.primitives.asymmetric.x448 import ( 11 X448PrivateKey, 12 X448PublicKey, 13) 14 15_X448_KEY_SIZE = 56 16 17 18@utils.register_interface(X448PublicKey) 19class _X448PublicKey(object): 20 def __init__(self, backend, evp_pkey): 21 self._backend = backend 22 self._evp_pkey = evp_pkey 23 24 def public_bytes(self, encoding, format): 25 if ( 26 encoding is serialization.Encoding.Raw 27 or format is serialization.PublicFormat.Raw 28 ): 29 if ( 30 encoding is not serialization.Encoding.Raw 31 or format is not serialization.PublicFormat.Raw 32 ): 33 raise ValueError( 34 "When using Raw both encoding and format must be Raw" 35 ) 36 37 return self._raw_public_bytes() 38 39 return self._backend._public_key_bytes( 40 encoding, format, self, self._evp_pkey, None 41 ) 42 43 def _raw_public_bytes(self): 44 buf = self._backend._ffi.new("unsigned char []", _X448_KEY_SIZE) 45 buflen = self._backend._ffi.new("size_t *", _X448_KEY_SIZE) 46 res = self._backend._lib.EVP_PKEY_get_raw_public_key( 47 self._evp_pkey, buf, buflen 48 ) 49 self._backend.openssl_assert(res == 1) 50 self._backend.openssl_assert(buflen[0] == _X448_KEY_SIZE) 51 return self._backend._ffi.buffer(buf, _X448_KEY_SIZE)[:] 52 53 54@utils.register_interface(X448PrivateKey) 55class _X448PrivateKey(object): 56 def __init__(self, backend, evp_pkey): 57 self._backend = backend 58 self._evp_pkey = evp_pkey 59 60 def public_key(self): 61 buf = self._backend._ffi.new("unsigned char []", _X448_KEY_SIZE) 62 buflen = self._backend._ffi.new("size_t *", _X448_KEY_SIZE) 63 res = self._backend._lib.EVP_PKEY_get_raw_public_key( 64 self._evp_pkey, buf, buflen 65 ) 66 self._backend.openssl_assert(res == 1) 67 self._backend.openssl_assert(buflen[0] == _X448_KEY_SIZE) 68 return self._backend.x448_load_public_bytes(buf) 69 70 def exchange(self, peer_public_key): 71 if not isinstance(peer_public_key, X448PublicKey): 72 raise TypeError("peer_public_key must be X448PublicKey.") 73 74 return _evp_pkey_derive(self._backend, self._evp_pkey, peer_public_key) 75 76 def private_bytes(self, encoding, format, encryption_algorithm): 77 if ( 78 encoding is serialization.Encoding.Raw 79 or format is serialization.PublicFormat.Raw 80 ): 81 if ( 82 format is not serialization.PrivateFormat.Raw 83 or encoding is not serialization.Encoding.Raw 84 or not isinstance( 85 encryption_algorithm, serialization.NoEncryption 86 ) 87 ): 88 raise ValueError( 89 "When using Raw both encoding and format must be Raw " 90 "and encryption_algorithm must be NoEncryption()" 91 ) 92 93 return self._raw_private_bytes() 94 95 return self._backend._private_key_bytes( 96 encoding, format, encryption_algorithm, self, self._evp_pkey, None 97 ) 98 99 def _raw_private_bytes(self): 100 buf = self._backend._ffi.new("unsigned char []", _X448_KEY_SIZE) 101 buflen = self._backend._ffi.new("size_t *", _X448_KEY_SIZE) 102 res = self._backend._lib.EVP_PKEY_get_raw_private_key( 103 self._evp_pkey, buf, buflen 104 ) 105 self._backend.openssl_assert(res == 1) 106 self._backend.openssl_assert(buflen[0] == _X448_KEY_SIZE) 107 return self._backend._ffi.buffer(buf, _X448_KEY_SIZE)[:] 108