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 absolute_import, division, print_function 6 7import abc 8 9import six 10 11from cryptography import utils 12 13 14def generate_parameters(generator, key_size, backend): 15 return backend.generate_dh_parameters(generator, key_size) 16 17 18class DHPrivateNumbers(object): 19 def __init__(self, x, public_numbers): 20 if not isinstance(x, six.integer_types): 21 raise TypeError("x must be an integer.") 22 23 if not isinstance(public_numbers, DHPublicNumbers): 24 raise TypeError("public_numbers must be an instance of " 25 "DHPublicNumbers.") 26 27 self._x = x 28 self._public_numbers = public_numbers 29 30 def __eq__(self, other): 31 if not isinstance(other, DHPrivateNumbers): 32 return NotImplemented 33 34 return ( 35 self._x == other._x and 36 self._public_numbers == other._public_numbers 37 ) 38 39 def __ne__(self, other): 40 return not self == other 41 42 def private_key(self, backend): 43 return backend.load_dh_private_numbers(self) 44 45 public_numbers = utils.read_only_property("_public_numbers") 46 x = utils.read_only_property("_x") 47 48 49class DHPublicNumbers(object): 50 def __init__(self, y, parameter_numbers): 51 if not isinstance(y, six.integer_types): 52 raise TypeError("y must be an integer.") 53 54 if not isinstance(parameter_numbers, DHParameterNumbers): 55 raise TypeError( 56 "parameters must be an instance of DHParameterNumbers.") 57 58 self._y = y 59 self._parameter_numbers = parameter_numbers 60 61 def __eq__(self, other): 62 if not isinstance(other, DHPublicNumbers): 63 return NotImplemented 64 65 return ( 66 self._y == other._y and 67 self._parameter_numbers == other._parameter_numbers 68 ) 69 70 def __ne__(self, other): 71 return not self == other 72 73 def public_key(self, backend): 74 return backend.load_dh_public_numbers(self) 75 76 y = utils.read_only_property("_y") 77 parameter_numbers = utils.read_only_property("_parameter_numbers") 78 79 80class DHParameterNumbers(object): 81 def __init__(self, p, g, q=None): 82 if ( 83 not isinstance(p, six.integer_types) or 84 not isinstance(g, six.integer_types) 85 ): 86 raise TypeError("p and g must be integers") 87 if q is not None and not isinstance(q, six.integer_types): 88 raise TypeError("q must be integer or None") 89 90 if g < 2: 91 raise ValueError("DH generator must be 2 or greater") 92 93 self._p = p 94 self._g = g 95 self._q = q 96 97 def __eq__(self, other): 98 if not isinstance(other, DHParameterNumbers): 99 return NotImplemented 100 101 return ( 102 self._p == other._p and 103 self._g == other._g and 104 self._q == other._q 105 ) 106 107 def __ne__(self, other): 108 return not self == other 109 110 def parameters(self, backend): 111 return backend.load_dh_parameter_numbers(self) 112 113 p = utils.read_only_property("_p") 114 g = utils.read_only_property("_g") 115 q = utils.read_only_property("_q") 116 117 118@six.add_metaclass(abc.ABCMeta) 119class DHParameters(object): 120 @abc.abstractmethod 121 def generate_private_key(self): 122 """ 123 Generates and returns a DHPrivateKey. 124 """ 125 126 @abc.abstractmethod 127 def parameter_bytes(self, encoding, format): 128 """ 129 Returns the parameters serialized as bytes. 130 """ 131 132 @abc.abstractmethod 133 def parameter_numbers(self): 134 """ 135 Returns a DHParameterNumbers. 136 """ 137 138 139DHParametersWithSerialization = DHParameters 140 141 142@six.add_metaclass(abc.ABCMeta) 143class DHPrivateKey(object): 144 @abc.abstractproperty 145 def key_size(self): 146 """ 147 The bit length of the prime modulus. 148 """ 149 150 @abc.abstractmethod 151 def public_key(self): 152 """ 153 The DHPublicKey associated with this private key. 154 """ 155 156 @abc.abstractmethod 157 def parameters(self): 158 """ 159 The DHParameters object associated with this private key. 160 """ 161 162 @abc.abstractmethod 163 def exchange(self, peer_public_key): 164 """ 165 Given peer's DHPublicKey, carry out the key exchange and 166 return shared key as bytes. 167 """ 168 169 170@six.add_metaclass(abc.ABCMeta) 171class DHPrivateKeyWithSerialization(DHPrivateKey): 172 @abc.abstractmethod 173 def private_numbers(self): 174 """ 175 Returns a DHPrivateNumbers. 176 """ 177 178 @abc.abstractmethod 179 def private_bytes(self, encoding, format, encryption_algorithm): 180 """ 181 Returns the key serialized as bytes. 182 """ 183 184 185@six.add_metaclass(abc.ABCMeta) 186class DHPublicKey(object): 187 @abc.abstractproperty 188 def key_size(self): 189 """ 190 The bit length of the prime modulus. 191 """ 192 193 @abc.abstractmethod 194 def parameters(self): 195 """ 196 The DHParameters object associated with this public key. 197 """ 198 199 @abc.abstractmethod 200 def public_numbers(self): 201 """ 202 Returns a DHPublicNumbers. 203 """ 204 205 @abc.abstractmethod 206 def public_bytes(self, encoding, format): 207 """ 208 Returns the key serialized as bytes. 209 """ 210 211 212DHPublicKeyWithSerialization = DHPublicKey 213