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

110 statements  

« prev     ^ index     » next       coverage.py v7.0.1, created at 2022-12-25 06:11 +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 

5 

6import abc 

7import typing 

8 

9from cryptography.hazmat.primitives import _serialization 

10 

11 

12_MIN_MODULUS_SIZE = 512 

13 

14 

15def generate_parameters( 

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

17) -> "DHParameters": 

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

19 

20 return ossl.generate_dh_parameters(generator, key_size) 

21 

22 

23class DHParameterNumbers: 

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

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

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

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

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

29 

30 if g < 2: 

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

32 

33 if p.bit_length() < _MIN_MODULUS_SIZE: 

34 raise ValueError( 

35 "p (modulus) must be at least {}-bit".format(_MIN_MODULUS_SIZE) 

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 

171 

172 

173class DHPublicKey(metaclass=abc.ABCMeta): 

174 @abc.abstractproperty 

175 def key_size(self) -> int: 

176 """ 

177 The bit length of the prime modulus. 

178 """ 

179 

180 @abc.abstractmethod 

181 def parameters(self) -> DHParameters: 

182 """ 

183 The DHParameters object associated with this public key. 

184 """ 

185 

186 @abc.abstractmethod 

187 def public_numbers(self) -> DHPublicNumbers: 

188 """ 

189 Returns a DHPublicNumbers. 

190 """ 

191 

192 @abc.abstractmethod 

193 def public_bytes( 

194 self, 

195 encoding: _serialization.Encoding, 

196 format: _serialization.PublicFormat, 

197 ) -> bytes: 

198 """ 

199 Returns the key serialized as bytes. 

200 """ 

201 

202 

203DHPublicKeyWithSerialization = DHPublicKey 

204 

205 

206class DHPrivateKey(metaclass=abc.ABCMeta): 

207 @abc.abstractproperty 

208 def key_size(self) -> int: 

209 """ 

210 The bit length of the prime modulus. 

211 """ 

212 

213 @abc.abstractmethod 

214 def public_key(self) -> DHPublicKey: 

215 """ 

216 The DHPublicKey associated with this private key. 

217 """ 

218 

219 @abc.abstractmethod 

220 def parameters(self) -> DHParameters: 

221 """ 

222 The DHParameters object associated with this private key. 

223 """ 

224 

225 @abc.abstractmethod 

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

227 """ 

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

229 return shared key as bytes. 

230 """ 

231 

232 @abc.abstractmethod 

233 def private_numbers(self) -> DHPrivateNumbers: 

234 """ 

235 Returns a DHPrivateNumbers. 

236 """ 

237 

238 @abc.abstractmethod 

239 def private_bytes( 

240 self, 

241 encoding: _serialization.Encoding, 

242 format: _serialization.PrivateFormat, 

243 encryption_algorithm: _serialization.KeySerializationEncryption, 

244 ) -> bytes: 

245 """ 

246 Returns the key serialized as bytes. 

247 """ 

248 

249 

250DHPrivateKeyWithSerialization = DHPrivateKey