OLD | NEW |
---|---|
1 # Authors: | 1 # Authors: |
2 # Trevor Perrin | 2 # Trevor Perrin |
3 # Dave Baggett (Arcode Corporation) - cleanup handling of constants | 3 # Dave Baggett (Arcode Corporation) - cleanup handling of constants |
4 # | 4 # |
5 # See the LICENSE file for legal information regarding use of this file. | 5 # See the LICENSE file for legal information regarding use of this file. |
6 | 6 |
7 """Class for setting handshake parameters.""" | 7 """Class for setting handshake parameters.""" |
8 | 8 |
9 from .constants import CertificateType | 9 from .constants import CertificateType |
10 from .utils import cryptomath | 10 from .utils import cryptomath |
11 from .utils import cipherfactory | 11 from .utils import cipherfactory |
12 | 12 |
13 # RC4 is preferred as faster in Python, works in SSL3, and immune to CBC | 13 # RC4 is preferred as faster in Python, works in SSL3, and immune to CBC |
14 # issues such as timing attacks | 14 # issues such as timing attacks |
15 CIPHER_NAMES = ["rc4", "aes256", "aes128", "3des"] | 15 CIPHER_NAMES = ["rc4", "aes256", "aes128", "3des"] |
16 MAC_NAMES = ["sha"] # Don't allow "md5" by default. | 16 MAC_NAMES = ["sha"] # Don't allow "md5" by default. |
17 ALL_MAC_NAMES = ["sha", "md5"] | 17 ALL_MAC_NAMES = ["sha", "md5"] |
18 KEY_EXCHANGE_NAMES = ["rsa", "dhe_rsa", "srp_sha", "srp_sha_rsa", "dh_anon"] | 18 KEY_EXCHANGE_NAMES = ["rsa", "dhe_rsa", "srp_sha", "srp_sha_rsa", "dh_anon"] |
19 CIPHER_IMPLEMENTATIONS = ["openssl", "pycrypto", "python"] | 19 CIPHER_IMPLEMENTATIONS = ["openssl", "pycrypto", "python"] |
20 CERTIFICATE_TYPES = ["x509"] | 20 CERTIFICATE_TYPES = ["x509"] |
21 TLS_INTOLERANCE_TYPES = ["alert", "close", "reset"] | |
21 | 22 |
22 class HandshakeSettings(object): | 23 class HandshakeSettings(object): |
23 """This class encapsulates various parameters that can be used with | 24 """This class encapsulates various parameters that can be used with |
24 a TLS handshake. | 25 a TLS handshake. |
25 @sort: minKeySize, maxKeySize, cipherNames, macNames, certificateTypes, | 26 @sort: minKeySize, maxKeySize, cipherNames, macNames, certificateTypes, |
26 minVersion, maxVersion | 27 minVersion, maxVersion |
27 | 28 |
28 @type minKeySize: int | 29 @type minKeySize: int |
29 @ivar minKeySize: The minimum bit length for asymmetric keys. | 30 @ivar minKeySize: The minimum bit length for asymmetric keys. |
30 | 31 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
85 | 86 |
86 @type maxVersion: tuple | 87 @type maxVersion: tuple |
87 @ivar maxVersion: The maximum allowed SSL/TLS version. | 88 @ivar maxVersion: The maximum allowed SSL/TLS version. |
88 | 89 |
89 This variable can be set to (3,0) for SSL 3.0, (3,1) for | 90 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 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 use a higher version, a protocol_version alert will be signalled. |
92 The default is (3,2). (WARNING: Some servers may (improperly) | 93 The default is (3,2). (WARNING: Some servers may (improperly) |
93 reject clients which offer support for TLS 1.1. In this case, | 94 reject clients which offer support for TLS 1.1. In this case, |
94 try lowering maxVersion to (3,1)). | 95 try lowering maxVersion to (3,1)). |
96 | |
97 @type tlsIntolerant: tuple | |
98 @ivar tlsIntolerant: TLS version intolerance for servers. | |
wtc
2014/06/24 21:33:29
The comment should point out the tuple represents
davidben
2014/06/25 21:19:56
Done.
| |
99 | |
100 If tlsIntolerant is not None, the server will simulate TLS version | |
101 intolerance by returning a fatal handshake_failure alert or a TCP reset to | |
wtc
2014/06/24 21:33:29
Nit: this comment doesn't mention the "close" type
davidben
2014/06/25 21:19:56
Done.
| |
102 all TLS versions tlsIntolerant or higher. | |
103 | |
104 @type tlsIntoleranceType: str | |
105 @ivar tlsIntoleranceType: How the server should react when simulating | |
106 TLS intolerance. | |
wtc
2014/06/24 21:33:29
Nit: should we document the possible values here?
davidben
2014/06/25 21:19:56
Done.
| |
95 | 107 |
96 @type useExperimentalTackExtension: bool | 108 @type useExperimentalTackExtension: bool |
97 @ivar useExperimentalTackExtension: Whether to enabled TACK support. | 109 @ivar useExperimentalTackExtension: Whether to enabled TACK support. |
98 | 110 |
99 Note that TACK support is not standardized by IETF and uses a temporary | 111 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. | 112 TLS Extension number, so should NOT be used in production software. |
101 """ | 113 """ |
102 def __init__(self): | 114 def __init__(self): |
103 self.minKeySize = 1023 | 115 self.minKeySize = 1023 |
104 self.maxKeySize = 8193 | 116 self.maxKeySize = 8193 |
105 self.cipherNames = CIPHER_NAMES | 117 self.cipherNames = CIPHER_NAMES |
106 self.macNames = MAC_NAMES | 118 self.macNames = MAC_NAMES |
107 self.keyExchangeNames = KEY_EXCHANGE_NAMES | 119 self.keyExchangeNames = KEY_EXCHANGE_NAMES |
108 self.cipherImplementations = CIPHER_IMPLEMENTATIONS | 120 self.cipherImplementations = CIPHER_IMPLEMENTATIONS |
109 self.certificateTypes = CERTIFICATE_TYPES | 121 self.certificateTypes = CERTIFICATE_TYPES |
110 self.minVersion = (3,0) | 122 self.minVersion = (3,0) |
111 self.maxVersion = (3,2) | 123 self.maxVersion = (3,2) |
124 self.tlsIntolerant = None | |
125 self.tlsIntoleranceType = 'alert' | |
112 self.useExperimentalTackExtension = False | 126 self.useExperimentalTackExtension = False |
113 | 127 |
114 # Validates the min/max fields, and certificateTypes | 128 # Validates the min/max fields, and certificateTypes |
115 # Filters out unsupported cipherNames and cipherImplementations | 129 # Filters out unsupported cipherNames and cipherImplementations |
116 def _filter(self): | 130 def _filter(self): |
117 other = HandshakeSettings() | 131 other = HandshakeSettings() |
118 other.minKeySize = self.minKeySize | 132 other.minKeySize = self.minKeySize |
119 other.maxKeySize = self.maxKeySize | 133 other.maxKeySize = self.maxKeySize |
120 other.cipherNames = self.cipherNames | 134 other.cipherNames = self.cipherNames |
121 other.macNames = self.macNames | 135 other.macNames = self.macNames |
122 other.keyExchangeNames = self.keyExchangeNames | 136 other.keyExchangeNames = self.keyExchangeNames |
123 other.cipherImplementations = self.cipherImplementations | 137 other.cipherImplementations = self.cipherImplementations |
124 other.certificateTypes = self.certificateTypes | 138 other.certificateTypes = self.certificateTypes |
125 other.minVersion = self.minVersion | 139 other.minVersion = self.minVersion |
126 other.maxVersion = self.maxVersion | 140 other.maxVersion = self.maxVersion |
141 other.tlsIntolerant = self.tlsIntolerant | |
142 other.tlsIntoleranceType = self.tlsIntoleranceType | |
127 | 143 |
128 if not cipherfactory.tripleDESPresent: | 144 if not cipherfactory.tripleDESPresent: |
129 other.cipherNames = [e for e in self.cipherNames if e != "3des"] | 145 other.cipherNames = [e for e in self.cipherNames if e != "3des"] |
130 if len(other.cipherNames)==0: | 146 if len(other.cipherNames)==0: |
131 raise ValueError("No supported ciphers") | 147 raise ValueError("No supported ciphers") |
132 if len(other.certificateTypes)==0: | 148 if len(other.certificateTypes)==0: |
133 raise ValueError("No supported certificate types") | 149 raise ValueError("No supported certificate types") |
134 | 150 |
135 if not cryptomath.m2cryptoLoaded: | 151 if not cryptomath.m2cryptoLoaded: |
136 other.cipherImplementations = \ | 152 other.cipherImplementations = \ |
(...skipping 21 matching lines...) Expand all Loading... | |
158 for s in other.keyExchangeNames: | 174 for s in other.keyExchangeNames: |
159 if s not in KEY_EXCHANGE_NAMES: | 175 if s not in KEY_EXCHANGE_NAMES: |
160 raise ValueError("Unknown key exchange name: '%s'" % s) | 176 raise ValueError("Unknown key exchange name: '%s'" % s) |
161 for s in other.cipherImplementations: | 177 for s in other.cipherImplementations: |
162 if s not in CIPHER_IMPLEMENTATIONS: | 178 if s not in CIPHER_IMPLEMENTATIONS: |
163 raise ValueError("Unknown cipher implementation: '%s'" % s) | 179 raise ValueError("Unknown cipher implementation: '%s'" % s) |
164 for s in other.certificateTypes: | 180 for s in other.certificateTypes: |
165 if s not in CERTIFICATE_TYPES: | 181 if s not in CERTIFICATE_TYPES: |
166 raise ValueError("Unknown certificate type: '%s'" % s) | 182 raise ValueError("Unknown certificate type: '%s'" % s) |
167 | 183 |
184 if other.tlsIntoleranceType not in TLS_INTOLERANCE_TYPES: | |
185 raise ValueError( | |
186 "Unknown TLS intolerance type: '%s'" % other.tlsIntoleranceType) | |
187 | |
168 if other.minVersion > other.maxVersion: | 188 if other.minVersion > other.maxVersion: |
169 raise ValueError("Versions set incorrectly") | 189 raise ValueError("Versions set incorrectly") |
170 | 190 |
171 if not other.minVersion in ((3,0), (3,1), (3,2)): | 191 if not other.minVersion in ((3,0), (3,1), (3,2)): |
172 raise ValueError("minVersion set incorrectly") | 192 raise ValueError("minVersion set incorrectly") |
173 | 193 |
174 if not other.maxVersion in ((3,0), (3,1), (3,2)): | 194 if not other.maxVersion in ((3,0), (3,1), (3,2)): |
175 raise ValueError("maxVersion set incorrectly") | 195 raise ValueError("maxVersion set incorrectly") |
176 | 196 |
177 return other | 197 return other |
178 | 198 |
179 def _getCertificateTypes(self): | 199 def _getCertificateTypes(self): |
180 l = [] | 200 l = [] |
181 for ct in self.certificateTypes: | 201 for ct in self.certificateTypes: |
182 if ct == "x509": | 202 if ct == "x509": |
183 l.append(CertificateType.x509) | 203 l.append(CertificateType.x509) |
184 else: | 204 else: |
185 raise AssertionError() | 205 raise AssertionError() |
186 return l | 206 return l |
OLD | NEW |