Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/cryptography/hazmat/primitives/asymmetric/dh.py: 60%

118 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-08 06:05 +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 

5from __future__ import annotations 

6 

7import abc 

8import typing 

9 

10from cryptography.hazmat.bindings._rust import openssl as rust_openssl 

11from cryptography.hazmat.primitives import _serialization 

12 

13 

14def generate_parameters( 

15 generator: int, key_size: int, backend: typing.Any = None 

16) -> DHParameters: 

17 from cryptography.hazmat.backends.openssl.backend import backend as ossl 

18 

19 return ossl.generate_dh_parameters(generator, key_size) 

20 

21 

22class DHParameterNumbers: 

23 def __init__(self, p: int, g: int, q: typing.Optional[int] = None) -> None: 

24 if not isinstance(p, int) or not isinstance(g, int): 

25 raise TypeError("p and g must be integers") 

26 if q is not None and not isinstance(q, int): 

27 raise TypeError("q must be integer or None") 

28 

29 if g < 2: 

30 raise ValueError("DH generator must be 2 or greater") 

31 

32 if p.bit_length() < rust_openssl.dh.MIN_MODULUS_SIZE: 

33 raise ValueError( 

34 f"p (modulus) must be at least " 

35 f"{rust_openssl.dh.MIN_MODULUS_SIZE}-bit" 

36 ) 

37 

38 self._p = p 

39 self._g = g 

40 self._q = q 

41 

42 def __eq__(self, other: object) -> bool: 

43 if not isinstance(other, DHParameterNumbers): 

44 return NotImplemented 

45 

46 return ( 

47 self._p == other._p and self._g == other._g and self._q == other._q 

48 ) 

49 

50 def parameters(self, backend: typing.Any = None) -> DHParameters: 

51 from cryptography.hazmat.backends.openssl.backend import ( 

52 backend as ossl, 

53 ) 

54 

55 return ossl.load_dh_parameter_numbers(self) 

56 

57 @property 

58 def p(self) -> int: 

59 return self._p 

60 

61 @property 

62 def g(self) -> int: 

63 return self._g 

64 

65 @property 

66 def q(self) -> typing.Optional[int]: 

67 return self._q 

68 

69 

70class DHPublicNumbers: 

71 def __init__(self, y: int, parameter_numbers: DHParameterNumbers) -> None: 

72 if not isinstance(y, int): 

73 raise TypeError("y must be an integer.") 

74 

75 if not isinstance(parameter_numbers, DHParameterNumbers): 

76 raise TypeError( 

77 "parameters must be an instance of DHParameterNumbers." 

78 ) 

79 

80 self._y = y 

81 self._parameter_numbers = parameter_numbers 

82 

83 def __eq__(self, other: object) -> bool: 

84 if not isinstance(other, DHPublicNumbers): 

85 return NotImplemented 

86 

87 return ( 

88 self._y == other._y 

89 and self._parameter_numbers == other._parameter_numbers 

90 ) 

91 

92 def public_key(self, backend: typing.Any = None) -> DHPublicKey: 

93 from cryptography.hazmat.backends.openssl.backend import ( 

94 backend as ossl, 

95 ) 

96 

97 return ossl.load_dh_public_numbers(self) 

98 

99 @property 

100 def y(self) -> int: 

101 return self._y 

102 

103 @property 

104 def parameter_numbers(self) -> DHParameterNumbers: 

105 return self._parameter_numbers 

106 

107 

108class DHPrivateNumbers: 

109 def __init__(self, x: int, public_numbers: DHPublicNumbers) -> None: 

110 if not isinstance(x, int): 

111 raise TypeError("x must be an integer.") 

112 

113 if not isinstance(public_numbers, DHPublicNumbers): 

114 raise TypeError( 

115 "public_numbers must be an instance of " "DHPublicNumbers." 

116 ) 

117 

118 self._x = x 

119 self._public_numbers = public_numbers 

120 

121 def __eq__(self, other: object) -> bool: 

122 if not isinstance(other, DHPrivateNumbers): 

123 return NotImplemented 

124 

125 return ( 

126 self._x == other._x 

127 and self._public_numbers == other._public_numbers 

128 ) 

129 

130 def private_key(self, backend: typing.Any = None) -> DHPrivateKey: 

131 from cryptography.hazmat.backends.openssl.backend import ( 

132 backend as ossl, 

133 ) 

134 

135 return ossl.load_dh_private_numbers(self) 

136 

137 @property 

138 def public_numbers(self) -> DHPublicNumbers: 

139 return self._public_numbers 

140 

141 @property 

142 def x(self) -> int: 

143 return self._x 

144 

145 

146class DHParameters(metaclass=abc.ABCMeta): 

147 @abc.abstractmethod 

148 def generate_private_key(self) -> DHPrivateKey: 

149 """ 

150 Generates and returns a DHPrivateKey. 

151 """ 

152 

153 @abc.abstractmethod 

154 def parameter_bytes( 

155 self, 

156 encoding: _serialization.Encoding, 

157 format: _serialization.ParameterFormat, 

158 ) -> bytes: 

159 """ 

160 Returns the parameters serialized as bytes. 

161 """ 

162 

163 @abc.abstractmethod 

164 def parameter_numbers(self) -> DHParameterNumbers: 

165 """ 

166 Returns a DHParameterNumbers. 

167 """ 

168 

169 

170DHParametersWithSerialization = DHParameters 

171DHParameters.register(rust_openssl.dh.DHParameters) 

172 

173 

174class DHPublicKey(metaclass=abc.ABCMeta): 

175 @property 

176 @abc.abstractmethod 

177 def key_size(self) -> int: 

178 """ 

179 The bit length of the prime modulus. 

180 """ 

181 

182 @abc.abstractmethod 

183 def parameters(self) -> DHParameters: 

184 """ 

185 The DHParameters object associated with this public key. 

186 """ 

187 

188 @abc.abstractmethod 

189 def public_numbers(self) -> DHPublicNumbers: 

190 """ 

191 Returns a DHPublicNumbers. 

192 """ 

193 

194 @abc.abstractmethod 

195 def public_bytes( 

196 self, 

197 encoding: _serialization.Encoding, 

198 format: _serialization.PublicFormat, 

199 ) -> bytes: 

200 """ 

201 Returns the key serialized as bytes. 

202 """ 

203 

204 @abc.abstractmethod 

205 def __eq__(self, other: object) -> bool: 

206 """ 

207 Checks equality. 

208 """ 

209 

210 

211DHPublicKeyWithSerialization = DHPublicKey 

212DHPublicKey.register(rust_openssl.dh.DHPublicKey) 

213 

214 

215class DHPrivateKey(metaclass=abc.ABCMeta): 

216 @property 

217 @abc.abstractmethod 

218 def key_size(self) -> int: 

219 """ 

220 The bit length of the prime modulus. 

221 """ 

222 

223 @abc.abstractmethod 

224 def public_key(self) -> DHPublicKey: 

225 """ 

226 The DHPublicKey associated with this private key. 

227 """ 

228 

229 @abc.abstractmethod 

230 def parameters(self) -> DHParameters: 

231 """ 

232 The DHParameters object associated with this private key. 

233 """ 

234 

235 @abc.abstractmethod 

236 def exchange(self, peer_public_key: DHPublicKey) -> bytes: 

237 """ 

238 Given peer's DHPublicKey, carry out the key exchange and 

239 return shared key as bytes. 

240 """ 

241 

242 @abc.abstractmethod 

243 def private_numbers(self) -> DHPrivateNumbers: 

244 """ 

245 Returns a DHPrivateNumbers. 

246 """ 

247 

248 @abc.abstractmethod 

249 def private_bytes( 

250 self, 

251 encoding: _serialization.Encoding, 

252 format: _serialization.PrivateFormat, 

253 encryption_algorithm: _serialization.KeySerializationEncryption, 

254 ) -> bytes: 

255 """ 

256 Returns the key serialized as bytes. 

257 """ 

258 

259 

260DHPrivateKeyWithSerialization = DHPrivateKey 

261DHPrivateKey.register(rust_openssl.dh.DHPrivateKey)