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