• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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