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: The TLS ClientHello version which the server |
| 99 simulates intolerance of. |
| 100 |
| 101 If tlsIntolerant is not None, the server will simulate TLS version |
| 102 intolerance by aborting the handshake in response to all TLS versions |
| 103 tlsIntolerant or higher. |
| 104 |
| 105 @type tlsIntoleranceType: str |
| 106 @ivar tlsIntoleranceType: How the server should react when simulating TLS |
| 107 intolerance. |
| 108 |
| 109 The allowed values are "alert" (return a fatal handshake_failure alert), |
| 110 "close" (abruptly close the connection), and "reset" (send a TCP reset). |
95 | 111 |
96 @type useExperimentalTackExtension: bool | 112 @type useExperimentalTackExtension: bool |
97 @ivar useExperimentalTackExtension: Whether to enabled TACK support. | 113 @ivar useExperimentalTackExtension: Whether to enabled TACK support. |
98 | 114 |
99 Note that TACK support is not standardized by IETF and uses a temporary | 115 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. | 116 TLS Extension number, so should NOT be used in production software. |
101 """ | 117 """ |
102 def __init__(self): | 118 def __init__(self): |
103 self.minKeySize = 1023 | 119 self.minKeySize = 1023 |
104 self.maxKeySize = 8193 | 120 self.maxKeySize = 8193 |
105 self.cipherNames = CIPHER_NAMES | 121 self.cipherNames = CIPHER_NAMES |
106 self.macNames = MAC_NAMES | 122 self.macNames = MAC_NAMES |
107 self.keyExchangeNames = KEY_EXCHANGE_NAMES | 123 self.keyExchangeNames = KEY_EXCHANGE_NAMES |
108 self.cipherImplementations = CIPHER_IMPLEMENTATIONS | 124 self.cipherImplementations = CIPHER_IMPLEMENTATIONS |
109 self.certificateTypes = CERTIFICATE_TYPES | 125 self.certificateTypes = CERTIFICATE_TYPES |
110 self.minVersion = (3,0) | 126 self.minVersion = (3,0) |
111 self.maxVersion = (3,2) | 127 self.maxVersion = (3,2) |
| 128 self.tlsIntolerant = None |
| 129 self.tlsIntoleranceType = 'alert' |
112 self.useExperimentalTackExtension = False | 130 self.useExperimentalTackExtension = False |
113 | 131 |
114 # Validates the min/max fields, and certificateTypes | 132 # Validates the min/max fields, and certificateTypes |
115 # Filters out unsupported cipherNames and cipherImplementations | 133 # Filters out unsupported cipherNames and cipherImplementations |
116 def _filter(self): | 134 def _filter(self): |
117 other = HandshakeSettings() | 135 other = HandshakeSettings() |
118 other.minKeySize = self.minKeySize | 136 other.minKeySize = self.minKeySize |
119 other.maxKeySize = self.maxKeySize | 137 other.maxKeySize = self.maxKeySize |
120 other.cipherNames = self.cipherNames | 138 other.cipherNames = self.cipherNames |
121 other.macNames = self.macNames | 139 other.macNames = self.macNames |
122 other.keyExchangeNames = self.keyExchangeNames | 140 other.keyExchangeNames = self.keyExchangeNames |
123 other.cipherImplementations = self.cipherImplementations | 141 other.cipherImplementations = self.cipherImplementations |
124 other.certificateTypes = self.certificateTypes | 142 other.certificateTypes = self.certificateTypes |
125 other.minVersion = self.minVersion | 143 other.minVersion = self.minVersion |
126 other.maxVersion = self.maxVersion | 144 other.maxVersion = self.maxVersion |
| 145 other.tlsIntolerant = self.tlsIntolerant |
| 146 other.tlsIntoleranceType = self.tlsIntoleranceType |
127 | 147 |
128 if not cipherfactory.tripleDESPresent: | 148 if not cipherfactory.tripleDESPresent: |
129 other.cipherNames = [e for e in self.cipherNames if e != "3des"] | 149 other.cipherNames = [e for e in self.cipherNames if e != "3des"] |
130 if len(other.cipherNames)==0: | 150 if len(other.cipherNames)==0: |
131 raise ValueError("No supported ciphers") | 151 raise ValueError("No supported ciphers") |
132 if len(other.certificateTypes)==0: | 152 if len(other.certificateTypes)==0: |
133 raise ValueError("No supported certificate types") | 153 raise ValueError("No supported certificate types") |
134 | 154 |
135 if not cryptomath.m2cryptoLoaded: | 155 if not cryptomath.m2cryptoLoaded: |
136 other.cipherImplementations = \ | 156 other.cipherImplementations = \ |
(...skipping 21 matching lines...) Expand all Loading... |
158 for s in other.keyExchangeNames: | 178 for s in other.keyExchangeNames: |
159 if s not in KEY_EXCHANGE_NAMES: | 179 if s not in KEY_EXCHANGE_NAMES: |
160 raise ValueError("Unknown key exchange name: '%s'" % s) | 180 raise ValueError("Unknown key exchange name: '%s'" % s) |
161 for s in other.cipherImplementations: | 181 for s in other.cipherImplementations: |
162 if s not in CIPHER_IMPLEMENTATIONS: | 182 if s not in CIPHER_IMPLEMENTATIONS: |
163 raise ValueError("Unknown cipher implementation: '%s'" % s) | 183 raise ValueError("Unknown cipher implementation: '%s'" % s) |
164 for s in other.certificateTypes: | 184 for s in other.certificateTypes: |
165 if s not in CERTIFICATE_TYPES: | 185 if s not in CERTIFICATE_TYPES: |
166 raise ValueError("Unknown certificate type: '%s'" % s) | 186 raise ValueError("Unknown certificate type: '%s'" % s) |
167 | 187 |
| 188 if other.tlsIntoleranceType not in TLS_INTOLERANCE_TYPES: |
| 189 raise ValueError( |
| 190 "Unknown TLS intolerance type: '%s'" % other.tlsIntoleranceType) |
| 191 |
168 if other.minVersion > other.maxVersion: | 192 if other.minVersion > other.maxVersion: |
169 raise ValueError("Versions set incorrectly") | 193 raise ValueError("Versions set incorrectly") |
170 | 194 |
171 if not other.minVersion in ((3,0), (3,1), (3,2)): | 195 if not other.minVersion in ((3,0), (3,1), (3,2)): |
172 raise ValueError("minVersion set incorrectly") | 196 raise ValueError("minVersion set incorrectly") |
173 | 197 |
174 if not other.maxVersion in ((3,0), (3,1), (3,2)): | 198 if not other.maxVersion in ((3,0), (3,1), (3,2)): |
175 raise ValueError("maxVersion set incorrectly") | 199 raise ValueError("maxVersion set incorrectly") |
176 | 200 |
177 return other | 201 return other |
178 | 202 |
179 def _getCertificateTypes(self): | 203 def _getCertificateTypes(self): |
180 l = [] | 204 l = [] |
181 for ct in self.certificateTypes: | 205 for ct in self.certificateTypes: |
182 if ct == "x509": | 206 if ct == "x509": |
183 l.append(CertificateType.x509) | 207 l.append(CertificateType.x509) |
184 else: | 208 else: |
185 raise AssertionError() | 209 raise AssertionError() |
186 return l | 210 return l |
OLD | NEW |