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 """
129 self.minKeySize = 1023
130 self.maxKeySize = 8193
131 self.cipherNames = list(CIPHER_NAMES)
132 self.macNames = list(MAC_NAMES)
133 self.keyExchangeNames = list(KEY_EXCHANGE_NAMES)
134 self.cipherImplementations = list(CIPHER_IMPLEMENTATIONS)
135 self.certificateTypes = list(CERTIFICATE_TYPES)
136 self.minVersion = (3, 1)
137 self.maxVersion = (3, 3)
138 self.useExperimentalTackExtension = False
139 self.sendFallbackSCSV = False
140 self.useEncryptThenMAC = True
141 self.rsaSigHashes = list(RSA_SIGNATURE_HASHES)
142 self.eccCurves = list(CURVE_NAMES)
143
144 @staticmethod
146 """Check if key size limits are sane"""
147 if other.minKeySize < 512:
148 raise ValueError("minKeySize too small")
149 if other.minKeySize > 16384:
150 raise ValueError("minKeySize too large")
151 if other.maxKeySize < 512:
152 raise ValueError("maxKeySize too small")
153 if other.maxKeySize > 16384:
154 raise ValueError("maxKeySize too large")
155 if other.maxKeySize < other.minKeySize:
156 raise ValueError("maxKeySize smaller than minKeySize")
157
158 @staticmethod
160 """Check if specified cryptographic primitive names are known"""
161 unknownCiphers = [val for val in other.cipherNames \
162 if val not in ALL_CIPHER_NAMES]
163 if unknownCiphers:
164 raise ValueError("Unknown cipher name: %s" % unknownCiphers)
165
166 unknownMacs = [val for val in other.macNames \
167 if val not in ALL_MAC_NAMES]
168 if unknownMacs:
169 raise ValueError("Unknown MAC name: %s" % unknownMacs)
170
171 unknownKex = [val for val in other.keyExchangeNames \
172 if val not in KEY_EXCHANGE_NAMES]
173 if unknownKex:
174 raise ValueError("Unknown key exchange name: %s" % unknownKex)
175
176 unknownImpl = [val for val in other.cipherImplementations \
177 if val not in CIPHER_IMPLEMENTATIONS]
178 if unknownImpl:
179 raise ValueError("Unknown cipher implementation: %s" % \
180 unknownImpl)
181
182 unknownType = [val for val in other.certificateTypes \
183 if val not in CERTIFICATE_TYPES]
184 if unknownType:
185 raise ValueError("Unknown certificate type: %s" % unknownType)
186
187 unknownCurve = [val for val in other.eccCurves \
188 if val not in ALL_CURVE_NAMES]
189 if unknownCurve:
190 raise ValueError("Unknown ECC Curve name: {0}".format(unknownCurve))
191
192 if other.useEncryptThenMAC not in (True, False):
193 raise ValueError("useEncryptThenMAC can only be True or False")
194
195 unknownSigHash = [val for val in other.rsaSigHashes \
196 if val not in ALL_RSA_SIGNATURE_HASHES]
197 if unknownSigHash:
198 raise ValueError("Unknown RSA signature hash: '{0}'".\
199 format(unknownSigHash))
200
201 @staticmethod
203 """Check if set protocol version are sane"""
204 if other.minVersion > other.maxVersion:
205 raise ValueError("Versions set incorrectly")
206 if other.minVersion not in ((3, 0), (3, 1), (3, 2), (3, 3)):
207 raise ValueError("minVersion set incorrectly")
208 if other.maxVersion not in ((3, 0), (3, 1), (3, 2), (3, 3)):
209 raise ValueError("maxVersion set incorrectly")
210
212 """
213 Validate the settings, filter out unsupported ciphersuites and return
214 a copy of object. Does not modify the original object.
215
216 @rtype: HandshakeSettings
217 @return: a self-consistent copy of settings
218 @raise ValueError: when settings are invalid, insecure or unsupported.
219 """
220 other = HandshakeSettings()
221 other.minKeySize = self.minKeySize
222 other.maxKeySize = self.maxKeySize
223 other.cipherNames = self.cipherNames
224 other.macNames = self.macNames
225 other.keyExchangeNames = self.keyExchangeNames
226 other.cipherImplementations = self.cipherImplementations
227 other.certificateTypes = self.certificateTypes
228 other.minVersion = self.minVersion
229 other.maxVersion = self.maxVersion
230 other.sendFallbackSCSV = self.sendFallbackSCSV
231 other.useEncryptThenMAC = self.useEncryptThenMAC
232 other.rsaSigHashes = self.rsaSigHashes
233 other.eccCurves = self.eccCurves
234
235 if not cipherfactory.tripleDESPresent:
236 other.cipherNames = [i for i in self.cipherNames if i != "3des"]
237 if len(other.cipherNames) == 0:
238 raise ValueError("No supported ciphers")
239 if len(other.certificateTypes) == 0:
240 raise ValueError("No supported certificate types")
241
242 if not cryptomath.m2cryptoLoaded:
243 other.cipherImplementations = \
244 [e for e in other.cipherImplementations if e != "openssl"]
245 if not cryptomath.pycryptoLoaded:
246 other.cipherImplementations = \
247 [e for e in other.cipherImplementations if e != "pycrypto"]
248 if len(other.cipherImplementations) == 0:
249 raise ValueError("No supported cipher implementations")
250
251 self._sanityCheckKeySizes(other)
252
253 self._sanityCheckPrimitivesNames(other)
254
255 self._sanityCheckProtocolVersions(other)
256
257 if other.maxVersion < (3,3):
258
259 other.macNames = [e for e in self.macNames if \
260 e == "sha" or e == "md5"]
261
262 if len(other.rsaSigHashes) == 0 and other.maxVersion >= (3, 3):
263 raise ValueError("TLS 1.2 requires signature algorithms to be set")
264
265 return other
266
268 """Get list of certificate types as IDs"""
269 ret = []
270 for ct in self.certificateTypes:
271 if ct == "x509":
272 ret.append(CertificateType.x509)
273 else:
274 raise AssertionError()
275 return ret
276