3 # Dave Baggett (Arcode Corporation) - cleanup handling of constants
5 # See the LICENSE file for legal information regarding use of this file.
7 """Class for setting handshake parameters."""
9 from .constants import CertificateType
10 from .utils import cryptomath
11 from .utils import cipherfactory
13 # RC4 is preferred as faster in Python, works in SSL3, and immune to CBC
14 # issues such as timing attacks
15 CIPHER_NAMES = ["rc4", "aes256", "aes128", "3des"]
16 MAC_NAMES = ["sha"] # Don't allow "md5" by default.
17 ALL_MAC_NAMES = ["sha", "md5"]
18 KEY_EXCHANGE_NAMES = ["rsa", "dhe_rsa", "srp_sha", "srp_sha_rsa", "dh_anon"]
19 CIPHER_IMPLEMENTATIONS = ["openssl", "pycrypto", "python"]
20 CERTIFICATE_TYPES = ["x509"]
22 class HandshakeSettings(object):
23 """This class encapsulates various parameters that can be used with
25 @sort: minKeySize, maxKeySize, cipherNames, macNames, certificateTypes,
26 minVersion, maxVersion
29 @ivar minKeySize: The minimum bit length for asymmetric keys.
31 If the other party tries to use SRP, RSA, or Diffie-Hellman
32 parameters smaller than this length, an alert will be
33 signalled. The default is 1023.
36 @ivar maxKeySize: The maximum bit length for asymmetric keys.
38 If the other party tries to use SRP, RSA, or Diffie-Hellman
39 parameters larger than this length, an alert will be signalled.
42 @type cipherNames: list
43 @ivar cipherNames: The allowed ciphers, in order of preference.
45 The allowed values in this list are 'aes256', 'aes128', '3des', and
46 'rc4'. If these settings are used with a client handshake, they
47 determine the order of the ciphersuites offered in the ClientHello
50 If these settings are used with a server handshake, the server will
51 choose whichever ciphersuite matches the earliest entry in this
54 NOTE: If '3des' is used in this list, but TLS Lite can't find an
55 add-on library that supports 3DES, then '3des' will be silently
58 The default value is ['rc4', 'aes256', 'aes128', '3des'].
61 @ivar macNames: The allowed MAC algorithms.
63 The allowed values in this list are 'sha' and 'md5'.
65 The default value is ['sha'].
68 @type certificateTypes: list
69 @ivar certificateTypes: The allowed certificate types, in order of
72 The only allowed certificate type is 'x509'. This list is only used with a
73 client handshake. The client will advertise to the server which certificate
74 types are supported, and will check that the server uses one of the
78 @type minVersion: tuple
79 @ivar minVersion: The minimum allowed SSL/TLS version.
81 This variable can be set to (3,0) for SSL 3.0, (3,1) for
82 TLS 1.0, or (3,2) for TLS 1.1. If the other party wishes to
83 use a lower version, a protocol_version alert will be signalled.
86 @type maxVersion: tuple
87 @ivar maxVersion: The maximum allowed SSL/TLS version.
89 This variable can be set to (3,0) for SSL 3.0, (3,1) for
90 TLS 1.0, or (3,2) for TLS 1.1. If the other party wishes to
91 use a higher version, a protocol_version alert will be signalled.
92 The default is (3,2). (WARNING: Some servers may (improperly)
93 reject clients which offer support for TLS 1.1. In this case,
94 try lowering maxVersion to (3,1)).
96 @type useExperimentalTackExtension: bool
97 @ivar useExperimentalTackExtension: Whether to enabled TACK support.
99 Note that TACK support is not standardized by IETF and uses a temporary
100 TLS Extension number, so should NOT be used in production software.
103 self.minKeySize = 1023
104 self.maxKeySize = 8193
105 self.cipherNames = CIPHER_NAMES
106 self.macNames = MAC_NAMES
107 self.keyExchangeNames = KEY_EXCHANGE_NAMES
108 self.cipherImplementations = CIPHER_IMPLEMENTATIONS
109 self.certificateTypes = CERTIFICATE_TYPES
110 self.minVersion = (3,0)
111 self.maxVersion = (3,2)
112 self.useExperimentalTackExtension = False
114 # Validates the min/max fields, and certificateTypes
115 # Filters out unsupported cipherNames and cipherImplementations
117 other = HandshakeSettings()
118 other.minKeySize = self.minKeySize
119 other.maxKeySize = self.maxKeySize
120 other.cipherNames = self.cipherNames
121 other.macNames = self.macNames
122 other.keyExchangeNames = self.keyExchangeNames
123 other.cipherImplementations = self.cipherImplementations
124 other.certificateTypes = self.certificateTypes
125 other.minVersion = self.minVersion
126 other.maxVersion = self.maxVersion
128 if not cipherfactory.tripleDESPresent:
129 other.cipherNames = [e for e in self.cipherNames if e != "3des"]
130 if len(other.cipherNames)==0:
131 raise ValueError("No supported ciphers")
132 if len(other.certificateTypes)==0:
133 raise ValueError("No supported certificate types")
135 if not cryptomath.m2cryptoLoaded:
136 other.cipherImplementations = \
137 [e for e in other.cipherImplementations if e != "openssl"]
138 if not cryptomath.pycryptoLoaded:
139 other.cipherImplementations = \
140 [e for e in other.cipherImplementations if e != "pycrypto"]
141 if len(other.cipherImplementations)==0:
142 raise ValueError("No supported cipher implementations")
144 if other.minKeySize<512:
145 raise ValueError("minKeySize too small")
146 if other.minKeySize>16384:
147 raise ValueError("minKeySize too large")
148 if other.maxKeySize<512:
149 raise ValueError("maxKeySize too small")
150 if other.maxKeySize>16384:
151 raise ValueError("maxKeySize too large")
152 for s in other.cipherNames:
153 if s not in CIPHER_NAMES:
154 raise ValueError("Unknown cipher name: '%s'" % s)
155 for s in other.macNames:
156 if s not in ALL_MAC_NAMES:
157 raise ValueError("Unknown MAC name: '%s'" % s)
158 for s in other.keyExchangeNames:
159 if s not in KEY_EXCHANGE_NAMES:
160 raise ValueError("Unknown key exchange name: '%s'" % s)
161 for s in other.cipherImplementations:
162 if s not in CIPHER_IMPLEMENTATIONS:
163 raise ValueError("Unknown cipher implementation: '%s'" % s)
164 for s in other.certificateTypes:
165 if s not in CERTIFICATE_TYPES:
166 raise ValueError("Unknown certificate type: '%s'" % s)
168 if other.minVersion > other.maxVersion:
169 raise ValueError("Versions set incorrectly")
171 if not other.minVersion in ((3,0), (3,1), (3,2)):
172 raise ValueError("minVersion set incorrectly")
174 if not other.maxVersion in ((3,0), (3,1), (3,2)):
175 raise ValueError("maxVersion set incorrectly")
179 def _getCertificateTypes(self):
181 for ct in self.certificateTypes:
183 l.append(CertificateType.x509)
185 raise AssertionError()