Package tlslite :: Module handshakesettings
[hide private]
[frames] | no frames]

Source Code for Module tlslite.handshakesettings

  1  # Authors:  
  2  #   Trevor Perrin 
  3  #   Dave Baggett (Arcode Corporation) - cleanup handling of constants 
  4  #   Yngve Pettersen (ported by Paul Sokolovsky) - TLS 1.2 
  5  # 
  6  # See the LICENSE file for legal information regarding use of this file. 
  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"] # Don't allow "md5" by default. 
 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  # while secp521r1 is the most secure, it's also much slower than the others 
 29  # so place it as the last one 
 30  CURVE_NAMES = ["secp384r1", "secp256r1", "secp521r1"] 
 31  ALL_CURVE_NAMES = CURVE_NAMES + ["secp256k1"] 
 32  if ecdsaAllCurves: 
 33      ALL_CURVE_NAMES += ["secp224r1", "secp192r1"] 
34 35 -class HandshakeSettings(object):
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 """
128 - def __init__(self):
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
145 - def _sanityCheckKeySizes(other):
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
211 - def validate(self):
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 # No sha-2 and AEAD pre TLS 1.2 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
267 - def getCertificateTypes(self):
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