Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/x25519.py: 30%
53 statements
« prev ^ index » next coverage.py v7.2.1, created at 2023-03-14 06:36 +0000
« prev ^ index » next coverage.py v7.2.1, created at 2023-03-14 06:36 +0000
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.
5import typing
7from cryptography.hazmat.backends.openssl.utils import _evp_pkey_derive
8from cryptography.hazmat.primitives import serialization
9from cryptography.hazmat.primitives.asymmetric.x25519 import (
10 X25519PrivateKey,
11 X25519PublicKey,
12)
14if typing.TYPE_CHECKING:
15 from cryptography.hazmat.backends.openssl.backend import Backend
18_X25519_KEY_SIZE = 32
21class _X25519PublicKey(X25519PublicKey):
22 def __init__(self, backend: "Backend", evp_pkey):
23 self._backend = backend
24 self._evp_pkey = evp_pkey
26 def public_bytes(
27 self,
28 encoding: serialization.Encoding,
29 format: serialization.PublicFormat,
30 ) -> bytes:
31 if (
32 encoding is serialization.Encoding.Raw
33 or format is serialization.PublicFormat.Raw
34 ):
35 if (
36 encoding is not serialization.Encoding.Raw
37 or format is not serialization.PublicFormat.Raw
38 ):
39 raise ValueError(
40 "When using Raw both encoding and format must be Raw"
41 )
43 return self._raw_public_bytes()
45 return self._backend._public_key_bytes(
46 encoding, format, self, self._evp_pkey, None
47 )
49 def _raw_public_bytes(self) -> bytes:
50 buf = self._backend._ffi.new("unsigned char []", _X25519_KEY_SIZE)
51 buflen = self._backend._ffi.new("size_t *", _X25519_KEY_SIZE)
52 res = self._backend._lib.EVP_PKEY_get_raw_public_key(
53 self._evp_pkey, buf, buflen
54 )
55 self._backend.openssl_assert(res == 1)
56 self._backend.openssl_assert(buflen[0] == _X25519_KEY_SIZE)
57 return self._backend._ffi.buffer(buf, _X25519_KEY_SIZE)[:]
60class _X25519PrivateKey(X25519PrivateKey):
61 def __init__(self, backend: "Backend", evp_pkey):
62 self._backend = backend
63 self._evp_pkey = evp_pkey
65 def public_key(self) -> X25519PublicKey:
66 bio = self._backend._create_mem_bio_gc()
67 res = self._backend._lib.i2d_PUBKEY_bio(bio, self._evp_pkey)
68 self._backend.openssl_assert(res == 1)
69 evp_pkey = self._backend._lib.d2i_PUBKEY_bio(
70 bio, self._backend._ffi.NULL
71 )
72 self._backend.openssl_assert(evp_pkey != self._backend._ffi.NULL)
73 evp_pkey = self._backend._ffi.gc(
74 evp_pkey, self._backend._lib.EVP_PKEY_free
75 )
76 return _X25519PublicKey(self._backend, evp_pkey)
78 def exchange(self, peer_public_key: X25519PublicKey) -> bytes:
79 if not isinstance(peer_public_key, X25519PublicKey):
80 raise TypeError("peer_public_key must be X25519PublicKey.")
82 return _evp_pkey_derive(self._backend, self._evp_pkey, peer_public_key)
84 def private_bytes(
85 self,
86 encoding: serialization.Encoding,
87 format: serialization.PrivateFormat,
88 encryption_algorithm: serialization.KeySerializationEncryption,
89 ) -> bytes:
90 if (
91 encoding is serialization.Encoding.Raw
92 or format is serialization.PrivateFormat.Raw
93 ):
94 if (
95 format is not serialization.PrivateFormat.Raw
96 or encoding is not serialization.Encoding.Raw
97 or not isinstance(
98 encryption_algorithm, serialization.NoEncryption
99 )
100 ):
101 raise ValueError(
102 "When using Raw both encoding and format must be Raw "
103 "and encryption_algorithm must be NoEncryption()"
104 )
106 return self._raw_private_bytes()
108 return self._backend._private_key_bytes(
109 encoding, format, encryption_algorithm, self, self._evp_pkey, None
110 )
112 def _raw_private_bytes(self) -> bytes:
113 buf = self._backend._ffi.new("unsigned char []", _X25519_KEY_SIZE)
114 buflen = self._backend._ffi.new("size_t *", _X25519_KEY_SIZE)
115 res = self._backend._lib.EVP_PKEY_get_raw_private_key(
116 self._evp_pkey, buf, buflen
117 )
118 self._backend.openssl_assert(res == 1)
119 self._backend.openssl_assert(buflen[0] == _X25519_KEY_SIZE)
120 return self._backend._ffi.buffer(buf, _X25519_KEY_SIZE)[:]