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