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, int_types 
 14   
 15  CIPHER_NAMES = ["chacha20-poly1305", 
 16                  "aes256gcm", "aes128gcm", 
 17                  "aes256", "aes128", 
 18                  "3des"] 
 19  ALL_CIPHER_NAMES = CIPHER_NAMES + ["chacha20-poly1305_draft00", 
 20                                     "rc4", "null"] 
 21  MAC_NAMES = ["sha", "sha256", "sha384", "aead"] # Don't allow "md5" by default. 
 22  ALL_MAC_NAMES = MAC_NAMES + ["md5"] 
 23  KEY_EXCHANGE_NAMES = ["rsa", "dhe_rsa", "ecdhe_rsa", "srp_sha", "srp_sha_rsa", 
 24                        "ecdh_anon", "dh_anon"] 
 25  CIPHER_IMPLEMENTATIONS = ["openssl", "pycrypto", "python"] 
 26  CERTIFICATE_TYPES = ["x509"] 
 27  RSA_SIGNATURE_HASHES = ["sha512", "sha384", "sha256", "sha224", "sha1"] 
 28  ALL_RSA_SIGNATURE_HASHES = RSA_SIGNATURE_HASHES + ["md5"] 
 29  RSA_SCHEMES = ["pss", "pkcs1"] 
 30  # while secp521r1 is the most secure, it's also much slower than the others 
 31  # so place it as the last one 
 32  CURVE_NAMES = ["secp384r1", "secp256r1", "secp521r1"] 
 33  ALL_CURVE_NAMES = CURVE_NAMES + ["secp256k1"] 
 34  if ecdsaAllCurves: 
 35      ALL_CURVE_NAMES += ["secp224r1", "secp192r1"] 
 36  ALL_DH_GROUP_NAMES = ["ffdhe2048", "ffdhe3072", "ffdhe4096", "ffdhe6144", 
 37                        "ffdhe8192"] 
38 39 -class HandshakeSettings(object):
40 """This class encapsulates various parameters that can be used with 41 a TLS handshake. 42 @sort: minKeySize, maxKeySize, cipherNames, macNames, certificateTypes, 43 minVersion, maxVersion 44 45 @type minKeySize: int 46 @ivar minKeySize: The minimum bit length for asymmetric keys. 47 48 If the other party tries to use SRP, RSA, or Diffie-Hellman 49 parameters smaller than this length, an alert will be 50 signalled. The default is 1023. 51 52 @type maxKeySize: int 53 @ivar maxKeySize: The maximum bit length for asymmetric keys. 54 55 If the other party tries to use SRP, RSA, or Diffie-Hellman 56 parameters larger than this length, an alert will be signalled. 57 The default is 8193. 58 59 @type cipherNames: list 60 @ivar cipherNames: The allowed ciphers. 61 62 The allowed values in this list are 'aes256', 'aes128', '3des', and 63 'rc4'. If these settings are used with a client handshake, they 64 determine the order of the ciphersuites offered in the ClientHello 65 message. 66 67 If these settings are used with a server handshake, the server will 68 choose whichever ciphersuite matches the earliest entry in this 69 list. 70 71 NOTE: If '3des' is used in this list, but TLS Lite can't find an 72 add-on library that supports 3DES, then '3des' will be silently 73 removed. 74 75 The default value is ['rc4', 'aes256', 'aes128', '3des']. 76 77 @type macNames: list 78 @ivar macNames: The allowed MAC algorithms. 79 80 The allowed values in this list are 'sha' and 'md5'. 81 82 The default value is ['sha']. 83 84 85 @type certificateTypes: list 86 @ivar certificateTypes: The allowed certificate types. 87 88 The only allowed certificate type is 'x509'. This list is only used with a 89 client handshake. The client will advertise to the server which certificate 90 types are supported, and will check that the server uses one of the 91 appropriate types. 92 93 94 @type minVersion: tuple 95 @ivar minVersion: The minimum allowed SSL/TLS version. 96 97 This variable can be set to (3,0) for SSL 3.0, (3,1) for TLS 1.0, (3,2) for 98 TLS 1.1, or (3,3) for TLS 1.2. If the other party wishes to use a lower 99 version, a protocol_version alert will be signalled. The default is (3,1). 100 101 @type maxVersion: tuple 102 @ivar maxVersion: The maximum allowed SSL/TLS version. 103 104 This variable can be set to (3,0) for SSL 3.0, (3,1) for TLS 1.0, (3,2) for 105 TLS 1.1, or (3,3) for TLS 1.2. If the other party wishes to use a higher 106 version, a protocol_version alert will be signalled. The default is (3,3). 107 (WARNING: Some servers may (improperly) reject clients which offer support 108 for TLS 1.1. In this case, try lowering maxVersion to (3,1)). 109 110 @type useExperimentalTackExtension: bool 111 @ivar useExperimentalTackExtension: Whether to enabled TACK support. 112 113 Note that TACK support is not standardized by IETF and uses a temporary 114 TLS Extension number, so should NOT be used in production software. 115 116 @type sendFallbackSCSV: bool 117 @ivar sendFallbackSCSV: Whether to, as a client, send FALLBACK_SCSV. 118 119 @type rsaSigHashes: list 120 @ivar rsaSigHashes: List of hashes supported (and advertised as such) for 121 TLS 1.2 signatures over Server Key Exchange or Certificate Verify with 122 RSA signature algorithm. 123 124 The list is sorted from most wanted to least wanted algorithm. 125 126 The allowed hashes are: "md5", "sha1", "sha224", "sha256", 127 "sha384" and "sha512". The default list does not include md5. 128 129 @type eccCurves: list 130 @ivar eccCurves: List of named curves that are to be supported 131 132 @type useEncryptThenMAC: bool 133 @ivar useEncryptThenMAC: whether to support the encrypt then MAC extension 134 from RFC 7366. True by default. 135 136 @type useExtendedMasterSecret: bool 137 @ivar useExtendedMasterSecret: whether to support the extended master 138 secret calculation from RFC 7627. True by default. 139 140 @type requireExtendedMasterSecret: bool 141 @ivar requireExtendedMasterSecret: whether to require negotiation of 142 extended master secret calculation for successful connection. Requires 143 useExtendedMasterSecret to be set to true. False by default. 144 """
145 - def __init__(self):
146 self.minKeySize = 1023 147 self.maxKeySize = 8193 148 self.cipherNames = list(CIPHER_NAMES) 149 self.macNames = list(MAC_NAMES) 150 self.keyExchangeNames = list(KEY_EXCHANGE_NAMES) 151 self.cipherImplementations = list(CIPHER_IMPLEMENTATIONS) 152 self.certificateTypes = list(CERTIFICATE_TYPES) 153 self.minVersion = (3, 1) 154 self.maxVersion = (3, 3) 155 self.useExperimentalTackExtension = False 156 self.sendFallbackSCSV = False 157 self.useEncryptThenMAC = True 158 self.rsaSigHashes = list(RSA_SIGNATURE_HASHES) 159 self.rsaSchemes = list(RSA_SCHEMES) 160 self.eccCurves = list(CURVE_NAMES) 161 self.usePaddingExtension = True 162 self.useExtendedMasterSecret = True 163 self.requireExtendedMasterSecret = False 164 self.dhParams = None 165 self.dhGroups = list(ALL_DH_GROUP_NAMES)
166 167 @staticmethod
168 - def _sanityCheckKeySizes(other):
169 """Check if key size limits are sane""" 170 if other.minKeySize < 512: 171 raise ValueError("minKeySize too small") 172 if other.minKeySize > 16384: 173 raise ValueError("minKeySize too large") 174 if other.maxKeySize < 512: 175 raise ValueError("maxKeySize too small") 176 if other.maxKeySize > 16384: 177 raise ValueError("maxKeySize too large") 178 if other.maxKeySize < other.minKeySize: 179 raise ValueError("maxKeySize smaller than minKeySize")
180 181 @staticmethod
183 """Check if specified cryptographic primitive names are known""" 184 unknownCiphers = [val for val in other.cipherNames \ 185 if val not in ALL_CIPHER_NAMES] 186 if unknownCiphers: 187 raise ValueError("Unknown cipher name: %s" % unknownCiphers) 188 189 unknownMacs = [val for val in other.macNames \ 190 if val not in ALL_MAC_NAMES] 191 if unknownMacs: 192 raise ValueError("Unknown MAC name: %s" % unknownMacs) 193 194 unknownKex = [val for val in other.keyExchangeNames \ 195 if val not in KEY_EXCHANGE_NAMES] 196 if unknownKex: 197 raise ValueError("Unknown key exchange name: %s" % unknownKex) 198 199 unknownImpl = [val for val in other.cipherImplementations \ 200 if val not in CIPHER_IMPLEMENTATIONS] 201 if unknownImpl: 202 raise ValueError("Unknown cipher implementation: %s" % \ 203 unknownImpl) 204 205 unknownType = [val for val in other.certificateTypes \ 206 if val not in CERTIFICATE_TYPES] 207 if unknownType: 208 raise ValueError("Unknown certificate type: %s" % unknownType) 209 210 unknownCurve = [val for val in other.eccCurves \ 211 if val not in ALL_CURVE_NAMES] 212 if unknownCurve: 213 raise ValueError("Unknown ECC Curve name: {0}".format(unknownCurve)) 214 215 unknownSigHash = [val for val in other.rsaSigHashes \ 216 if val not in ALL_RSA_SIGNATURE_HASHES] 217 if unknownSigHash: 218 raise ValueError("Unknown RSA signature hash: '{0}'".\ 219 format(unknownSigHash)) 220 221 unknownRSAPad = [val for val in other.rsaSchemes 222 if val not in RSA_SCHEMES] 223 if unknownRSAPad: 224 raise ValueError("Unknown RSA padding mode: '{0}'".\ 225 format(unknownRSAPad)) 226 227 unknownDHGroup = [val for val in other.dhGroups 228 if val not in ALL_DH_GROUP_NAMES] 229 if unknownDHGroup: 230 raise ValueError("Unknown FFDHE group name: '{0}'" 231 .format(unknownDHGroup))
232 233 @staticmethod
235 """Check if set protocol version are sane""" 236 if other.minVersion > other.maxVersion: 237 raise ValueError("Versions set incorrectly") 238 if other.minVersion not in ((3, 0), (3, 1), (3, 2), (3, 3)): 239 raise ValueError("minVersion set incorrectly") 240 if other.maxVersion not in ((3, 0), (3, 1), (3, 2), (3, 3)): 241 raise ValueError("maxVersion set incorrectly")
242 243 @staticmethod
244 - def _sanityCheckExtensions(other):
245 """Check if set extension settings are sane""" 246 if other.useEncryptThenMAC not in (True, False): 247 raise ValueError("useEncryptThenMAC can only be True or False") 248 249 if other.useExtendedMasterSecret not in (True, False): 250 raise ValueError("useExtendedMasterSecret must be True or False") 251 if other.requireExtendedMasterSecret not in (True, False): 252 raise ValueError("requireExtendedMasterSecret must be True " 253 "or False") 254 if other.requireExtendedMasterSecret and \ 255 not other.useExtendedMasterSecret: 256 raise ValueError("requireExtendedMasterSecret requires " 257 "useExtendedMasterSecret") 258 259 if other.usePaddingExtension not in (True, False): 260 raise ValueError("usePaddingExtension must be True or False")
261
262 - def validate(self):
263 """ 264 Validate the settings, filter out unsupported ciphersuites and return 265 a copy of object. Does not modify the original object. 266 267 @rtype: HandshakeSettings 268 @return: a self-consistent copy of settings 269 @raise ValueError: when settings are invalid, insecure or unsupported. 270 """ 271 other = HandshakeSettings() 272 other.minKeySize = self.minKeySize 273 other.maxKeySize = self.maxKeySize 274 other.cipherNames = self.cipherNames 275 other.macNames = self.macNames 276 other.keyExchangeNames = self.keyExchangeNames 277 other.cipherImplementations = self.cipherImplementations 278 other.certificateTypes = self.certificateTypes 279 other.minVersion = self.minVersion 280 other.maxVersion = self.maxVersion 281 other.sendFallbackSCSV = self.sendFallbackSCSV 282 other.useEncryptThenMAC = self.useEncryptThenMAC 283 other.usePaddingExtension = self.usePaddingExtension 284 other.rsaSigHashes = self.rsaSigHashes 285 other.rsaSchemes = self.rsaSchemes 286 other.eccCurves = self.eccCurves 287 other.useExtendedMasterSecret = self.useExtendedMasterSecret 288 other.requireExtendedMasterSecret = self.requireExtendedMasterSecret 289 other.dhParams = self.dhParams 290 other.dhGroups = self.dhGroups 291 292 if not cipherfactory.tripleDESPresent: 293 other.cipherNames = [i for i in self.cipherNames if i != "3des"] 294 if len(other.cipherNames) == 0: 295 raise ValueError("No supported ciphers") 296 if len(other.certificateTypes) == 0: 297 raise ValueError("No supported certificate types") 298 299 if not cryptomath.m2cryptoLoaded: 300 other.cipherImplementations = \ 301 [e for e in other.cipherImplementations if e != "openssl"] 302 if not cryptomath.pycryptoLoaded: 303 other.cipherImplementations = \ 304 [e for e in other.cipherImplementations if e != "pycrypto"] 305 if len(other.cipherImplementations) == 0: 306 raise ValueError("No supported cipher implementations") 307 308 self._sanityCheckKeySizes(other) 309 310 self._sanityCheckPrimitivesNames(other) 311 312 self._sanityCheckProtocolVersions(other) 313 314 self._sanityCheckExtensions(other) 315 316 if other.maxVersion < (3,3): 317 # No sha-2 and AEAD pre TLS 1.2 318 other.macNames = [e for e in self.macNames if \ 319 e == "sha" or e == "md5"] 320 321 if len(other.rsaSigHashes) == 0 and other.maxVersion >= (3, 3): 322 raise ValueError("TLS 1.2 requires signature algorithms to be set") 323 324 if other.dhParams and (len(other.dhParams) != 2 or 325 not isinstance(other.dhParams[0], int_types) or 326 not isinstance(other.dhParams[1], int_types)): 327 raise ValueError("DH parameters need to be a tuple of integers") 328 329 return other
330
331 - def getCertificateTypes(self):
332 """Get list of certificate types as IDs""" 333 ret = [] 334 for ct in self.certificateTypes: 335 if ct == "x509": 336 ret.append(CertificateType.x509) 337 else: 338 raise AssertionError() 339 return ret
340