Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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 import utils 

10from cryptography.hazmat.backends import _get_backend 

11from cryptography.hazmat.primitives import serialization 

12 

13 

14_MIN_MODULUS_SIZE = 512 

15 

16 

17def generate_parameters(generator, key_size, backend=None) -> "DHParameters": 

18 backend = _get_backend(backend) 

19 return backend.generate_dh_parameters(generator, key_size) 

20 

21 

22class DHParameterNumbers(object): 

23 def __init__(self, p: int, g: int, q: typing.Optional[int] = 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() < _MIN_MODULUS_SIZE: 

33 raise ValueError( 

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

35 ) 

36 

37 self._p = p 

38 self._g = g 

39 self._q = q 

40 

41 def __eq__(self, other): 

42 if not isinstance(other, DHParameterNumbers): 

43 return NotImplemented 

44 

45 return ( 

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

47 ) 

48 

49 def __ne__(self, other): 

50 return not self == other 

51 

52 def parameters(self, backend=None): 

53 backend = _get_backend(backend) 

54 return backend.load_dh_parameter_numbers(self) 

55 

56 p = utils.read_only_property("_p") 

57 g = utils.read_only_property("_g") 

58 q = utils.read_only_property("_q") 

59 

60 

61class DHPublicNumbers(object): 

62 def __init__(self, y, parameter_numbers: DHParameterNumbers): 

63 if not isinstance(y, int): 

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

65 

66 if not isinstance(parameter_numbers, DHParameterNumbers): 

67 raise TypeError( 

68 "parameters must be an instance of DHParameterNumbers." 

69 ) 

70 

71 self._y = y 

72 self._parameter_numbers = parameter_numbers 

73 

74 def __eq__(self, other): 

75 if not isinstance(other, DHPublicNumbers): 

76 return NotImplemented 

77 

78 return ( 

79 self._y == other._y 

80 and self._parameter_numbers == other._parameter_numbers 

81 ) 

82 

83 def __ne__(self, other): 

84 return not self == other 

85 

86 def public_key(self, backend=None) -> "DHPublicKey": 

87 backend = _get_backend(backend) 

88 return backend.load_dh_public_numbers(self) 

89 

90 y = utils.read_only_property("_y") 

91 parameter_numbers = utils.read_only_property("_parameter_numbers") 

92 

93 

94class DHPrivateNumbers(object): 

95 def __init__(self, x, public_numbers: DHPublicNumbers): 

96 if not isinstance(x, int): 

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

98 

99 if not isinstance(public_numbers, DHPublicNumbers): 

100 raise TypeError( 

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

102 ) 

103 

104 self._x = x 

105 self._public_numbers = public_numbers 

106 

107 def __eq__(self, other): 

108 if not isinstance(other, DHPrivateNumbers): 

109 return NotImplemented 

110 

111 return ( 

112 self._x == other._x 

113 and self._public_numbers == other._public_numbers 

114 ) 

115 

116 def __ne__(self, other): 

117 return not self == other 

118 

119 def private_key(self, backend=None) -> "DHPrivateKey": 

120 backend = _get_backend(backend) 

121 return backend.load_dh_private_numbers(self) 

122 

123 public_numbers = utils.read_only_property("_public_numbers") 

124 x = utils.read_only_property("_x") 

125 

126 

127class DHParameters(metaclass=abc.ABCMeta): 

128 @abc.abstractmethod 

129 def generate_private_key(self) -> "DHPrivateKey": 

130 """ 

131 Generates and returns a DHPrivateKey. 

132 """ 

133 

134 @abc.abstractmethod 

135 def parameter_bytes( 

136 self, 

137 encoding: "serialization.Encoding", 

138 format: "serialization.ParameterFormat", 

139 ) -> bytes: 

140 """ 

141 Returns the parameters serialized as bytes. 

142 """ 

143 

144 @abc.abstractmethod 

145 def parameter_numbers(self) -> DHParameterNumbers: 

146 """ 

147 Returns a DHParameterNumbers. 

148 """ 

149 

150 

151DHParametersWithSerialization = DHParameters 

152 

153 

154class DHPublicKey(metaclass=abc.ABCMeta): 

155 @abc.abstractproperty 

156 def key_size(self) -> int: 

157 """ 

158 The bit length of the prime modulus. 

159 """ 

160 

161 @abc.abstractmethod 

162 def parameters(self) -> DHParameters: 

163 """ 

164 The DHParameters object associated with this public key. 

165 """ 

166 

167 @abc.abstractmethod 

168 def public_numbers(self) -> DHPublicNumbers: 

169 """ 

170 Returns a DHPublicNumbers. 

171 """ 

172 

173 @abc.abstractmethod 

174 def public_bytes( 

175 self, 

176 encoding: "serialization.Encoding", 

177 format: "serialization.PublicFormat", 

178 ) -> bytes: 

179 """ 

180 Returns the key serialized as bytes. 

181 """ 

182 

183 

184DHPublicKeyWithSerialization = DHPublicKey 

185 

186 

187class DHPrivateKey(metaclass=abc.ABCMeta): 

188 @abc.abstractproperty 

189 def key_size(self) -> int: 

190 """ 

191 The bit length of the prime modulus. 

192 """ 

193 

194 @abc.abstractmethod 

195 def public_key(self) -> DHPublicKey: 

196 """ 

197 The DHPublicKey associated with this private key. 

198 """ 

199 

200 @abc.abstractmethod 

201 def parameters(self) -> DHParameters: 

202 """ 

203 The DHParameters object associated with this private key. 

204 """ 

205 

206 @abc.abstractmethod 

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

208 """ 

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

210 return shared key as bytes. 

211 """ 

212 

213 @abc.abstractmethod 

214 def private_numbers(self) -> DHPrivateNumbers: 

215 """ 

216 Returns a DHPrivateNumbers. 

217 """ 

218 

219 @abc.abstractmethod 

220 def private_bytes( 

221 self, 

222 encoding: "serialization.Encoding", 

223 format: "serialization.PrivateFormat", 

224 encryption_algorithm: "serialization.KeySerializationEncryption", 

225 ) -> bytes: 

226 """ 

227 Returns the key serialized as bytes. 

228 """ 

229 

230 

231DHPrivateKeyWithSerialization = DHPrivateKey