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

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 

5import typing 

6 

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) 

13 

14if typing.TYPE_CHECKING: 

15 from cryptography.hazmat.backends.openssl.backend import Backend 

16 

17 

18_X25519_KEY_SIZE = 32 

19 

20 

21class _X25519PublicKey(X25519PublicKey): 

22 def __init__(self, backend: "Backend", evp_pkey): 

23 self._backend = backend 

24 self._evp_pkey = evp_pkey 

25 

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 ) 

42 

43 return self._raw_public_bytes() 

44 

45 return self._backend._public_key_bytes( 

46 encoding, format, self, self._evp_pkey, None 

47 ) 

48 

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)[:] 

58 

59 

60class _X25519PrivateKey(X25519PrivateKey): 

61 def __init__(self, backend: "Backend", evp_pkey): 

62 self._backend = backend 

63 self._evp_pkey = evp_pkey 

64 

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) 

77 

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.") 

81 

82 return _evp_pkey_derive(self._backend, self._evp_pkey, peer_public_key) 

83 

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 ) 

105 

106 return self._raw_private_bytes() 

107 

108 return self._backend._private_key_bytes( 

109 encoding, format, encryption_algorithm, self, self._evp_pkey, None 

110 ) 

111 

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)[:]