| OLD | NEW |
| 1 # Authors: |
| 2 # Trevor Perrin |
| 3 # Dave Baggett (Arcode Corporation) - cleanup handling of constants |
| 4 # |
| 5 # See the LICENSE file for legal information regarding use of this file. |
| 6 |
| 1 """Class for setting handshake parameters.""" | 7 """Class for setting handshake parameters.""" |
| 2 | 8 |
| 3 from constants import CertificateType | 9 from .constants import CertificateType |
| 4 from utils import cryptomath | 10 from .utils import cryptomath |
| 5 from utils import cipherfactory | 11 from .utils import cipherfactory |
| 6 | 12 |
| 7 class HandshakeSettings: | 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"] # "md5" is allowed |
| 17 CIPHER_IMPLEMENTATIONS = ["openssl", "pycrypto", "python"] |
| 18 CERTIFICATE_TYPES = ["x509"] |
| 19 |
| 20 class HandshakeSettings(object): |
| 8 """This class encapsulates various parameters that can be used with | 21 """This class encapsulates various parameters that can be used with |
| 9 a TLS handshake. | 22 a TLS handshake. |
| 10 @sort: minKeySize, maxKeySize, cipherNames, certificateTypes, | 23 @sort: minKeySize, maxKeySize, cipherNames, macNames, certificateTypes, |
| 11 minVersion, maxVersion | 24 minVersion, maxVersion |
| 12 | 25 |
| 13 @type minKeySize: int | 26 @type minKeySize: int |
| 14 @ivar minKeySize: The minimum bit length for asymmetric keys. | 27 @ivar minKeySize: The minimum bit length for asymmetric keys. |
| 15 | 28 |
| 16 If the other party tries to use SRP, RSA, or Diffie-Hellman | 29 If the other party tries to use SRP, RSA, or Diffie-Hellman |
| 17 parameters smaller than this length, an alert will be | 30 parameters smaller than this length, an alert will be |
| 18 signalled. The default is 1023. | 31 signalled. The default is 1023. |
| 19 | 32 |
| 20 @type maxKeySize: int | 33 @type maxKeySize: int |
| (...skipping 12 matching lines...) Expand all Loading... |
| 33 message. | 46 message. |
| 34 | 47 |
| 35 If these settings are used with a server handshake, the server will | 48 If these settings are used with a server handshake, the server will |
| 36 choose whichever ciphersuite matches the earliest entry in this | 49 choose whichever ciphersuite matches the earliest entry in this |
| 37 list. | 50 list. |
| 38 | 51 |
| 39 NOTE: If '3des' is used in this list, but TLS Lite can't find an | 52 NOTE: If '3des' is used in this list, but TLS Lite can't find an |
| 40 add-on library that supports 3DES, then '3des' will be silently | 53 add-on library that supports 3DES, then '3des' will be silently |
| 41 removed. | 54 removed. |
| 42 | 55 |
| 43 The default value is ['aes256', 'aes128', '3des', 'rc4']. | 56 The default value is ['rc4', 'aes256', 'aes128', '3des']. |
| 57 |
| 58 @type macNames: list |
| 59 @ivar macNames: The allowed MAC algorithms. |
| 60 |
| 61 The allowed values in this list are 'sha' and 'md5'. |
| 62 |
| 63 The default value is ['sha']. |
| 64 |
| 44 | 65 |
| 45 @type certificateTypes: list | 66 @type certificateTypes: list |
| 46 @ivar certificateTypes: The allowed certificate types, in order of | 67 @ivar certificateTypes: The allowed certificate types, in order of |
| 47 preference. | 68 preference. |
| 48 | 69 |
| 49 The allowed values in this list are 'x509' and 'cryptoID'. This | 70 The only allowed certificate type is 'x509'. This list is only used with a |
| 50 list is only used with a client handshake. The client will | 71 client handshake. The client will advertise to the server which certificate |
| 51 advertise to the server which certificate types are supported, and | 72 types are supported, and will check that the server uses one of the |
| 52 will check that the server uses one of the appropriate types. | 73 appropriate types. |
| 53 | 74 |
| 54 NOTE: If 'cryptoID' is used in this list, but cryptoIDlib is not | |
| 55 installed, then 'cryptoID' will be silently removed. | |
| 56 | 75 |
| 57 @type minVersion: tuple | 76 @type minVersion: tuple |
| 58 @ivar minVersion: The minimum allowed SSL/TLS version. | 77 @ivar minVersion: The minimum allowed SSL/TLS version. |
| 59 | 78 |
| 60 This variable can be set to (3,0) for SSL 3.0, (3,1) for | 79 This variable can be set to (3,0) for SSL 3.0, (3,1) for |
| 61 TLS 1.0, or (3,2) for TLS 1.1. If the other party wishes to | 80 TLS 1.0, or (3,2) for TLS 1.1. If the other party wishes to |
| 62 use a lower version, a protocol_version alert will be signalled. | 81 use a lower version, a protocol_version alert will be signalled. |
| 63 The default is (3,0). | 82 The default is (3,0). |
| 64 | 83 |
| 65 @type maxVersion: tuple | 84 @type maxVersion: tuple |
| 66 @ivar maxVersion: The maximum allowed SSL/TLS version. | 85 @ivar maxVersion: The maximum allowed SSL/TLS version. |
| 67 | 86 |
| 68 This variable can be set to (3,0) for SSL 3.0, (3,1) for | 87 This variable can be set to (3,0) for SSL 3.0, (3,1) for |
| 69 TLS 1.0, or (3,2) for TLS 1.1. If the other party wishes to | 88 TLS 1.0, or (3,2) for TLS 1.1. If the other party wishes to |
| 70 use a higher version, a protocol_version alert will be signalled. | 89 use a higher version, a protocol_version alert will be signalled. |
| 71 The default is (3,2). (WARNING: Some servers may (improperly) | 90 The default is (3,2). (WARNING: Some servers may (improperly) |
| 72 reject clients which offer support for TLS 1.1. In this case, | 91 reject clients which offer support for TLS 1.1. In this case, |
| 73 try lowering maxVersion to (3,1)). | 92 try lowering maxVersion to (3,1)). |
| 93 |
| 94 @type useExperimentalTackExtension: bool |
| 95 @ivar useExperimentalTackExtension: Whether to enabled TACK support. |
| 96 |
| 97 Note that TACK support is not standardized by IETF and uses a temporary |
| 98 TLS Extension number, so should NOT be used in production software. |
| 74 """ | 99 """ |
| 75 def __init__(self): | 100 def __init__(self): |
| 76 self.minKeySize = 1023 | 101 self.minKeySize = 1023 |
| 77 self.maxKeySize = 8193 | 102 self.maxKeySize = 8193 |
| 78 self.cipherNames = ["aes256", "aes128", "3des", "rc4"] | 103 self.cipherNames = CIPHER_NAMES |
| 79 self.cipherImplementations = ["cryptlib", "openssl", "pycrypto", | 104 self.macNames = MAC_NAMES |
| 80 "python"] | 105 self.cipherImplementations = CIPHER_IMPLEMENTATIONS |
| 81 self.certificateTypes = ["x509", "cryptoID"] | 106 self.certificateTypes = CERTIFICATE_TYPES |
| 82 self.minVersion = (3,0) | 107 self.minVersion = (3,0) |
| 83 self.maxVersion = (3,2) | 108 self.maxVersion = (3,2) |
| 109 self.useExperimentalTackExtension = False |
| 84 | 110 |
| 85 #Filters out options that are not supported | 111 # Validates the min/max fields, and certificateTypes |
| 112 # Filters out unsupported cipherNames and cipherImplementations |
| 86 def _filter(self): | 113 def _filter(self): |
| 87 other = HandshakeSettings() | 114 other = HandshakeSettings() |
| 88 other.minKeySize = self.minKeySize | 115 other.minKeySize = self.minKeySize |
| 89 other.maxKeySize = self.maxKeySize | 116 other.maxKeySize = self.maxKeySize |
| 90 other.cipherNames = self.cipherNames | 117 other.cipherNames = self.cipherNames |
| 118 other.macNames = self.macNames |
| 91 other.cipherImplementations = self.cipherImplementations | 119 other.cipherImplementations = self.cipherImplementations |
| 92 other.certificateTypes = self.certificateTypes | 120 other.certificateTypes = self.certificateTypes |
| 93 other.minVersion = self.minVersion | 121 other.minVersion = self.minVersion |
| 94 other.maxVersion = self.maxVersion | 122 other.maxVersion = self.maxVersion |
| 95 | 123 |
| 96 if not cipherfactory.tripleDESPresent: | 124 if not cipherfactory.tripleDESPresent: |
| 97 other.cipherNames = [e for e in self.cipherNames if e != "3des"] | 125 other.cipherNames = [e for e in self.cipherNames if e != "3des"] |
| 98 if len(other.cipherNames)==0: | 126 if len(other.cipherNames)==0: |
| 99 raise ValueError("No supported ciphers") | 127 raise ValueError("No supported ciphers") |
| 100 | |
| 101 try: | |
| 102 import cryptoIDlib | |
| 103 except ImportError: | |
| 104 other.certificateTypes = [e for e in self.certificateTypes \ | |
| 105 if e != "cryptoID"] | |
| 106 if len(other.certificateTypes)==0: | 128 if len(other.certificateTypes)==0: |
| 107 raise ValueError("No supported certificate types") | 129 raise ValueError("No supported certificate types") |
| 108 | 130 |
| 109 if not cryptomath.cryptlibpyLoaded: | |
| 110 other.cipherImplementations = [e for e in \ | |
| 111 self.cipherImplementations if e != "cryptlib"] | |
| 112 if not cryptomath.m2cryptoLoaded: | 131 if not cryptomath.m2cryptoLoaded: |
| 113 other.cipherImplementations = [e for e in \ | 132 other.cipherImplementations = \ |
| 114 other.cipherImplementations if e != "openssl"] | 133 [e for e in other.cipherImplementations if e != "openssl"] |
| 115 if not cryptomath.pycryptoLoaded: | 134 if not cryptomath.pycryptoLoaded: |
| 116 other.cipherImplementations = [e for e in \ | 135 other.cipherImplementations = \ |
| 117 other.cipherImplementations if e != "pycrypto"] | 136 [e for e in other.cipherImplementations if e != "pycrypto"] |
| 118 if len(other.cipherImplementations)==0: | 137 if len(other.cipherImplementations)==0: |
| 119 raise ValueError("No supported cipher implementations") | 138 raise ValueError("No supported cipher implementations") |
| 120 | 139 |
| 121 if other.minKeySize<512: | 140 if other.minKeySize<512: |
| 122 raise ValueError("minKeySize too small") | 141 raise ValueError("minKeySize too small") |
| 123 if other.minKeySize>16384: | 142 if other.minKeySize>16384: |
| 124 raise ValueError("minKeySize too large") | 143 raise ValueError("minKeySize too large") |
| 125 if other.maxKeySize<512: | 144 if other.maxKeySize<512: |
| 126 raise ValueError("maxKeySize too small") | 145 raise ValueError("maxKeySize too small") |
| 127 if other.maxKeySize>16384: | 146 if other.maxKeySize>16384: |
| 128 raise ValueError("maxKeySize too large") | 147 raise ValueError("maxKeySize too large") |
| 129 for s in other.cipherNames: | 148 for s in other.cipherNames: |
| 130 if s not in ("aes256", "aes128", "rc4", "3des"): | 149 if s not in CIPHER_NAMES: |
| 131 raise ValueError("Unknown cipher name: '%s'" % s) | 150 raise ValueError("Unknown cipher name: '%s'" % s) |
| 132 for s in other.cipherImplementations: | 151 for s in other.cipherImplementations: |
| 133 if s not in ("cryptlib", "openssl", "python", "pycrypto"): | 152 if s not in CIPHER_IMPLEMENTATIONS: |
| 134 raise ValueError("Unknown cipher implementation: '%s'" % s) | 153 raise ValueError("Unknown cipher implementation: '%s'" % s) |
| 135 for s in other.certificateTypes: | 154 for s in other.certificateTypes: |
| 136 if s not in ("x509", "cryptoID"): | 155 if s not in CERTIFICATE_TYPES: |
| 137 raise ValueError("Unknown certificate type: '%s'" % s) | 156 raise ValueError("Unknown certificate type: '%s'" % s) |
| 138 | 157 |
| 139 if other.minVersion > other.maxVersion: | 158 if other.minVersion > other.maxVersion: |
| 140 raise ValueError("Versions set incorrectly") | 159 raise ValueError("Versions set incorrectly") |
| 141 | 160 |
| 142 if not other.minVersion in ((3,0), (3,1), (3,2)): | 161 if not other.minVersion in ((3,0), (3,1), (3,2)): |
| 143 raise ValueError("minVersion set incorrectly") | 162 raise ValueError("minVersion set incorrectly") |
| 144 | 163 |
| 145 if not other.maxVersion in ((3,0), (3,1), (3,2)): | 164 if not other.maxVersion in ((3,0), (3,1), (3,2)): |
| 146 raise ValueError("maxVersion set incorrectly") | 165 raise ValueError("maxVersion set incorrectly") |
| 147 | 166 |
| 148 return other | 167 return other |
| 149 | 168 |
| 150 def _getCertificateTypes(self): | 169 def _getCertificateTypes(self): |
| 151 l = [] | 170 l = [] |
| 152 for ct in self.certificateTypes: | 171 for ct in self.certificateTypes: |
| 153 if ct == "x509": | 172 if ct == "x509": |
| 154 l.append(CertificateType.x509) | 173 l.append(CertificateType.x509) |
| 155 elif ct == "cryptoID": | |
| 156 l.append(CertificateType.cryptoID) | |
| 157 else: | 174 else: |
| 158 raise AssertionError() | 175 raise AssertionError() |
| 159 return l | 176 return l |
| OLD | NEW |