1
2
3
4
5
6
7
8 """Class for setting handshake parameters."""
9
10 from .constants import CertificateType
11 from .utils import cryptomath
12 from .utils import cipherfactory
13 from .utils.compat import ecdsaAllCurves, int_types
14
15 CIPHER_NAMES = ["chacha20-poly1305",
16 "aes256gcm", "aes128gcm",
17 "aes256", "aes128",
18 "3des"]
19 ALL_CIPHER_NAMES = CIPHER_NAMES + ["chacha20-poly1305_draft00",
20 "rc4", "null"]
21 MAC_NAMES = ["sha", "sha256", "sha384", "aead"]
22 ALL_MAC_NAMES = MAC_NAMES + ["md5"]
23 KEY_EXCHANGE_NAMES = ["rsa", "dhe_rsa", "ecdhe_rsa", "srp_sha", "srp_sha_rsa",
24 "ecdh_anon", "dh_anon"]
25 CIPHER_IMPLEMENTATIONS = ["openssl", "pycrypto", "python"]
26 CERTIFICATE_TYPES = ["x509"]
27 RSA_SIGNATURE_HASHES = ["sha512", "sha384", "sha256", "sha224", "sha1"]
28 ALL_RSA_SIGNATURE_HASHES = RSA_SIGNATURE_HASHES + ["md5"]
29
30
31 CURVE_NAMES = ["secp384r1", "secp256r1", "secp521r1"]
32 ALL_CURVE_NAMES = CURVE_NAMES + ["secp256k1"]
33 if ecdsaAllCurves:
34 ALL_CURVE_NAMES += ["secp224r1", "secp192r1"]
35 ALL_DH_GROUP_NAMES = ["ffdhe2048", "ffdhe3072", "ffdhe4096", "ffdhe6144",
36 "ffdhe8192"]
39 """This class encapsulates various parameters that can be used with
40 a TLS handshake.
41 @sort: minKeySize, maxKeySize, cipherNames, macNames, certificateTypes,
42 minVersion, maxVersion
43
44 @type minKeySize: int
45 @ivar minKeySize: The minimum bit length for asymmetric keys.
46
47 If the other party tries to use SRP, RSA, or Diffie-Hellman
48 parameters smaller than this length, an alert will be
49 signalled. The default is 1023.
50
51 @type maxKeySize: int
52 @ivar maxKeySize: The maximum bit length for asymmetric keys.
53
54 If the other party tries to use SRP, RSA, or Diffie-Hellman
55 parameters larger than this length, an alert will be signalled.
56 The default is 8193.
57
58 @type cipherNames: list
59 @ivar cipherNames: The allowed ciphers.
60
61 The allowed values in this list are 'aes256', 'aes128', '3des', and
62 'rc4'. If these settings are used with a client handshake, they
63 determine the order of the ciphersuites offered in the ClientHello
64 message.
65
66 If these settings are used with a server handshake, the server will
67 choose whichever ciphersuite matches the earliest entry in this
68 list.
69
70 NOTE: If '3des' is used in this list, but TLS Lite can't find an
71 add-on library that supports 3DES, then '3des' will be silently
72 removed.
73
74 The default value is ['rc4', 'aes256', 'aes128', '3des'].
75
76 @type macNames: list
77 @ivar macNames: The allowed MAC algorithms.
78
79 The allowed values in this list are 'sha' and 'md5'.
80
81 The default value is ['sha'].
82
83
84 @type certificateTypes: list
85 @ivar certificateTypes: The allowed certificate types.
86
87 The only allowed certificate type is 'x509'. This list is only used with a
88 client handshake. The client will advertise to the server which certificate
89 types are supported, and will check that the server uses one of the
90 appropriate types.
91
92
93 @type minVersion: tuple
94 @ivar minVersion: The minimum allowed SSL/TLS version.
95
96 This variable can be set to (3,0) for SSL 3.0, (3,1) for TLS 1.0, (3,2) for
97 TLS 1.1, or (3,3) for TLS 1.2. If the other party wishes to use a lower
98 version, a protocol_version alert will be signalled. The default is (3,1).
99
100 @type maxVersion: tuple
101 @ivar maxVersion: The maximum allowed SSL/TLS version.
102
103 This variable can be set to (3,0) for SSL 3.0, (3,1) for TLS 1.0, (3,2) for
104 TLS 1.1, or (3,3) for TLS 1.2. If the other party wishes to use a higher
105 version, a protocol_version alert will be signalled. The default is (3,3).
106 (WARNING: Some servers may (improperly) reject clients which offer support
107 for TLS 1.1. In this case, try lowering maxVersion to (3,1)).
108
109 @type useExperimentalTackExtension: bool
110 @ivar useExperimentalTackExtension: Whether to enabled TACK support.
111
112 Note that TACK support is not standardized by IETF and uses a temporary
113 TLS Extension number, so should NOT be used in production software.
114
115 @type sendFallbackSCSV: bool
116 @ivar sendFallbackSCSV: Whether to, as a client, send FALLBACK_SCSV.
117
118 @type rsaSigHashes: list
119 @ivar rsaSigHashes: List of hashes supported (and advertised as such) for
120 TLS 1.2 signatures over Server Key Exchange or Certificate Verify with
121 RSA signature algorithm.
122
123 The list is sorted from most wanted to least wanted algorithm.
124
125 The allowed hashes are: "md5", "sha1", "sha224", "sha256",
126 "sha384" and "sha512". The default list does not include md5.
127
128 @type eccCurves: list
129 @ivar eccCurves: List of named curves that are to be supported
130
131 @type useEncryptThenMAC: bool
132 @ivar useEncryptThenMAC: whether to support the encrypt then MAC extension
133 from RFC 7366. True by default.
134
135 @type useExtendedMasterSecret: bool
136 @ivar useExtendedMasterSecret: whether to support the extended master
137 secret calculation from RFC 7627. True by default.
138
139 @type requireExtendedMasterSecret: bool
140 @ivar requireExtendedMasterSecret: whether to require negotiation of
141 extended master secret calculation for successful connection. Requires
142 useExtendedMasterSecret to be set to true. False by default.
143 """
145 self.minKeySize = 1023
146 self.maxKeySize = 8193
147 self.cipherNames = list(CIPHER_NAMES)
148 self.macNames = list(MAC_NAMES)
149 self.keyExchangeNames = list(KEY_EXCHANGE_NAMES)
150 self.cipherImplementations = list(CIPHER_IMPLEMENTATIONS)
151 self.certificateTypes = list(CERTIFICATE_TYPES)
152 self.minVersion = (3, 1)
153 self.maxVersion = (3, 3)
154 self.useExperimentalTackExtension = False
155 self.sendFallbackSCSV = False
156 self.useEncryptThenMAC = True
157 self.rsaSigHashes = list(RSA_SIGNATURE_HASHES)
158 self.eccCurves = list(CURVE_NAMES)
159 self.usePaddingExtension = True
160 self.useExtendedMasterSecret = True
161 self.requireExtendedMasterSecret = False
162 self.dhParams = None
163 self.dhGroups = list(ALL_DH_GROUP_NAMES)
164
165 @staticmethod
167 """Check if key size limits are sane"""
168 if other.minKeySize < 512:
169 raise ValueError("minKeySize too small")
170 if other.minKeySize > 16384:
171 raise ValueError("minKeySize too large")
172 if other.maxKeySize < 512:
173 raise ValueError("maxKeySize too small")
174 if other.maxKeySize > 16384:
175 raise ValueError("maxKeySize too large")
176 if other.maxKeySize < other.minKeySize:
177 raise ValueError("maxKeySize smaller than minKeySize")
178
179 @staticmethod
181 """Check if specified cryptographic primitive names are known"""
182 unknownCiphers = [val for val in other.cipherNames \
183 if val not in ALL_CIPHER_NAMES]
184 if unknownCiphers:
185 raise ValueError("Unknown cipher name: %s" % unknownCiphers)
186
187 unknownMacs = [val for val in other.macNames \
188 if val not in ALL_MAC_NAMES]
189 if unknownMacs:
190 raise ValueError("Unknown MAC name: %s" % unknownMacs)
191
192 unknownKex = [val for val in other.keyExchangeNames \
193 if val not in KEY_EXCHANGE_NAMES]
194 if unknownKex:
195 raise ValueError("Unknown key exchange name: %s" % unknownKex)
196
197 unknownImpl = [val for val in other.cipherImplementations \
198 if val not in CIPHER_IMPLEMENTATIONS]
199 if unknownImpl:
200 raise ValueError("Unknown cipher implementation: %s" % \
201 unknownImpl)
202
203 unknownType = [val for val in other.certificateTypes \
204 if val not in CERTIFICATE_TYPES]
205 if unknownType:
206 raise ValueError("Unknown certificate type: %s" % unknownType)
207
208 unknownCurve = [val for val in other.eccCurves \
209 if val not in ALL_CURVE_NAMES]
210 if unknownCurve:
211 raise ValueError("Unknown ECC Curve name: {0}".format(unknownCurve))
212
213 unknownSigHash = [val for val in other.rsaSigHashes \
214 if val not in ALL_RSA_SIGNATURE_HASHES]
215 if unknownSigHash:
216 raise ValueError("Unknown RSA signature hash: '{0}'".\
217 format(unknownSigHash))
218
219 unknownDHGroup = [val for val in other.dhGroups
220 if val not in ALL_DH_GROUP_NAMES]
221 if unknownDHGroup:
222 raise ValueError("Unknown FFDHE group name: '{0}'"
223 .format(unknownDHGroup))
224
225 @staticmethod
227 """Check if set protocol version are sane"""
228 if other.minVersion > other.maxVersion:
229 raise ValueError("Versions set incorrectly")
230 if other.minVersion not in ((3, 0), (3, 1), (3, 2), (3, 3)):
231 raise ValueError("minVersion set incorrectly")
232 if other.maxVersion not in ((3, 0), (3, 1), (3, 2), (3, 3)):
233 raise ValueError("maxVersion set incorrectly")
234
235 @staticmethod
237 """Check if set extension settings are sane"""
238 if other.useEncryptThenMAC not in (True, False):
239 raise ValueError("useEncryptThenMAC can only be True or False")
240
241 if other.useExtendedMasterSecret not in (True, False):
242 raise ValueError("useExtendedMasterSecret must be True or False")
243 if other.requireExtendedMasterSecret not in (True, False):
244 raise ValueError("requireExtendedMasterSecret must be True "
245 "or False")
246 if other.requireExtendedMasterSecret and \
247 not other.useExtendedMasterSecret:
248 raise ValueError("requireExtendedMasterSecret requires "
249 "useExtendedMasterSecret")
250
251 if other.usePaddingExtension not in (True, False):
252 raise ValueError("usePaddingExtension must be True or False")
253
255 """
256 Validate the settings, filter out unsupported ciphersuites and return
257 a copy of object. Does not modify the original object.
258
259 @rtype: HandshakeSettings
260 @return: a self-consistent copy of settings
261 @raise ValueError: when settings are invalid, insecure or unsupported.
262 """
263 other = HandshakeSettings()
264 other.minKeySize = self.minKeySize
265 other.maxKeySize = self.maxKeySize
266 other.cipherNames = self.cipherNames
267 other.macNames = self.macNames
268 other.keyExchangeNames = self.keyExchangeNames
269 other.cipherImplementations = self.cipherImplementations
270 other.certificateTypes = self.certificateTypes
271 other.minVersion = self.minVersion
272 other.maxVersion = self.maxVersion
273 other.sendFallbackSCSV = self.sendFallbackSCSV
274 other.useEncryptThenMAC = self.useEncryptThenMAC
275 other.usePaddingExtension = self.usePaddingExtension
276 other.rsaSigHashes = self.rsaSigHashes
277 other.eccCurves = self.eccCurves
278 other.useExtendedMasterSecret = self.useExtendedMasterSecret
279 other.requireExtendedMasterSecret = self.requireExtendedMasterSecret
280 other.dhParams = self.dhParams
281 other.dhGroups = self.dhGroups
282
283 if not cipherfactory.tripleDESPresent:
284 other.cipherNames = [i for i in self.cipherNames if i != "3des"]
285 if len(other.cipherNames) == 0:
286 raise ValueError("No supported ciphers")
287 if len(other.certificateTypes) == 0:
288 raise ValueError("No supported certificate types")
289
290 if not cryptomath.m2cryptoLoaded:
291 other.cipherImplementations = \
292 [e for e in other.cipherImplementations if e != "openssl"]
293 if not cryptomath.pycryptoLoaded:
294 other.cipherImplementations = \
295 [e for e in other.cipherImplementations if e != "pycrypto"]
296 if len(other.cipherImplementations) == 0:
297 raise ValueError("No supported cipher implementations")
298
299 self._sanityCheckKeySizes(other)
300
301 self._sanityCheckPrimitivesNames(other)
302
303 self._sanityCheckProtocolVersions(other)
304
305 self._sanityCheckExtensions(other)
306
307 if other.maxVersion < (3,3):
308
309 other.macNames = [e for e in self.macNames if \
310 e == "sha" or e == "md5"]
311
312 if len(other.rsaSigHashes) == 0 and other.maxVersion >= (3, 3):
313 raise ValueError("TLS 1.2 requires signature algorithms to be set")
314
315 if other.dhParams and (len(other.dhParams) != 2 or
316 not isinstance(other.dhParams[0], int_types) or
317 not isinstance(other.dhParams[1], int_types)):
318 raise ValueError("DH parameters need to be a tuple of integers")
319
320 return other
321
323 """Get list of certificate types as IDs"""
324 ret = []
325 for ct in self.certificateTypes:
326 if ct == "x509":
327 ret.append(CertificateType.x509)
328 else:
329 raise AssertionError()
330 return ret
331