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 @type defaultCurve: str 146 @ivar defaultCurve: curve that will be used by server in case the client 147 did not advertise support for any curves. It does not have to be the 148 first curve for eccCurves and may be distinct from curves from that list. 149 """
150 - def __init__(self):
151 self.minKeySize = 1023 152 self.maxKeySize = 8193 153 self.cipherNames = list(CIPHER_NAMES) 154 self.macNames = list(MAC_NAMES) 155 self.keyExchangeNames = list(KEY_EXCHANGE_NAMES) 156 self.cipherImplementations = list(CIPHER_IMPLEMENTATIONS) 157 self.certificateTypes = list(CERTIFICATE_TYPES) 158 self.minVersion = (3, 1) 159 self.maxVersion = (3, 3) 160 self.useExperimentalTackExtension = False 161 self.sendFallbackSCSV = False 162 self.useEncryptThenMAC = True 163 self.rsaSigHashes = list(RSA_SIGNATURE_HASHES) 164 self.rsaSchemes = list(RSA_SCHEMES) 165 self.eccCurves = list(CURVE_NAMES) 166 self.usePaddingExtension = True 167 self.useExtendedMasterSecret = True 168 self.requireExtendedMasterSecret = False 169 self.dhParams = None 170 self.dhGroups = list(ALL_DH_GROUP_NAMES) 171 self.defaultCurve = "secp256r1"
172 173 @staticmethod
174 - def _sanityCheckKeySizes(other):
175 """Check if key size limits are sane""" 176 if other.minKeySize < 512: 177 raise ValueError("minKeySize too small") 178 if other.minKeySize > 16384: 179 raise ValueError("minKeySize too large") 180 if other.maxKeySize < 512: 181 raise ValueError("maxKeySize too small") 182 if other.maxKeySize > 16384: 183 raise ValueError("maxKeySize too large") 184 if other.maxKeySize < other.minKeySize: 185 raise ValueError("maxKeySize smaller than minKeySize")
186 187 @staticmethod
189 """Check if specified cryptographic primitive names are known""" 190 unknownCiphers = [val for val in other.cipherNames \ 191 if val not in ALL_CIPHER_NAMES] 192 if unknownCiphers: 193 raise ValueError("Unknown cipher name: %s" % unknownCiphers) 194 195 unknownMacs = [val for val in other.macNames \ 196 if val not in ALL_MAC_NAMES] 197 if unknownMacs: 198 raise ValueError("Unknown MAC name: %s" % unknownMacs) 199 200 unknownKex = [val for val in other.keyExchangeNames \ 201 if val not in KEY_EXCHANGE_NAMES] 202 if unknownKex: 203 raise ValueError("Unknown key exchange name: %s" % unknownKex) 204 205 unknownImpl = [val for val in other.cipherImplementations \ 206 if val not in CIPHER_IMPLEMENTATIONS] 207 if unknownImpl: 208 raise ValueError("Unknown cipher implementation: %s" % \ 209 unknownImpl) 210 211 unknownType = [val for val in other.certificateTypes \ 212 if val not in CERTIFICATE_TYPES] 213 if unknownType: 214 raise ValueError("Unknown certificate type: %s" % unknownType) 215 216 unknownCurve = [val for val in other.eccCurves \ 217 if val not in ALL_CURVE_NAMES] 218 if unknownCurve: 219 raise ValueError("Unknown ECC Curve name: {0}".format(unknownCurve)) 220 221 if other.defaultCurve not in ALL_CURVE_NAMES: 222 raise ValueError("Unknown default ECC Curve name: {0}" 223 .format(other.defaultCurve)) 224 225 unknownSigHash = [val for val in other.rsaSigHashes \ 226 if val not in ALL_RSA_SIGNATURE_HASHES] 227 if unknownSigHash: 228 raise ValueError("Unknown RSA signature hash: '{0}'".\ 229 format(unknownSigHash)) 230 231 unknownRSAPad = [val for val in other.rsaSchemes 232 if val not in RSA_SCHEMES] 233 if unknownRSAPad: 234 raise ValueError("Unknown RSA padding mode: '{0}'".\ 235 format(unknownRSAPad)) 236 237 unknownDHGroup = [val for val in other.dhGroups 238 if val not in ALL_DH_GROUP_NAMES] 239 if unknownDHGroup: 240 raise ValueError("Unknown FFDHE group name: '{0}'" 241 .format(unknownDHGroup))
242 243 @staticmethod
245 """Check if set protocol version are sane""" 246 if other.minVersion > other.maxVersion: 247 raise ValueError("Versions set incorrectly") 248 if other.minVersion not in ((3, 0), (3, 1), (3, 2), (3, 3)): 249 raise ValueError("minVersion set incorrectly") 250 if other.maxVersion not in ((3, 0), (3, 1), (3, 2), (3, 3)): 251 raise ValueError("maxVersion set incorrectly")
252 253 @staticmethod
254 - def _sanityCheckExtensions(other):
255 """Check if set extension settings are sane""" 256 if other.useEncryptThenMAC not in (True, False): 257 raise ValueError("useEncryptThenMAC can only be True or False") 258 259 if other.useExtendedMasterSecret not in (True, False): 260 raise ValueError("useExtendedMasterSecret must be True or False") 261 if other.requireExtendedMasterSecret not in (True, False): 262 raise ValueError("requireExtendedMasterSecret must be True " 263 "or False") 264 if other.requireExtendedMasterSecret and \ 265 not other.useExtendedMasterSecret: 266 raise ValueError("requireExtendedMasterSecret requires " 267 "useExtendedMasterSecret") 268 269 if other.usePaddingExtension not in (True, False): 270 raise ValueError("usePaddingExtension must be True or False")
271
272 - def validate(self):
273 """ 274 Validate the settings, filter out unsupported ciphersuites and return 275 a copy of object. Does not modify the original object. 276 277 @rtype: HandshakeSettings 278 @return: a self-consistent copy of settings 279 @raise ValueError: when settings are invalid, insecure or unsupported. 280 """ 281 other = HandshakeSettings() 282 other.minKeySize = self.minKeySize 283 other.maxKeySize = self.maxKeySize 284 other.cipherNames = self.cipherNames 285 other.macNames = self.macNames 286 other.keyExchangeNames = self.keyExchangeNames 287 other.cipherImplementations = self.cipherImplementations 288 other.certificateTypes = self.certificateTypes 289 other.minVersion = self.minVersion 290 other.maxVersion = self.maxVersion 291 other.sendFallbackSCSV = self.sendFallbackSCSV 292 other.useEncryptThenMAC = self.useEncryptThenMAC 293 other.usePaddingExtension = self.usePaddingExtension 294 other.rsaSigHashes = self.rsaSigHashes 295 other.rsaSchemes = self.rsaSchemes 296 other.eccCurves = self.eccCurves 297 other.useExtendedMasterSecret = self.useExtendedMasterSecret 298 other.requireExtendedMasterSecret = self.requireExtendedMasterSecret 299 other.dhParams = self.dhParams 300 other.dhGroups = self.dhGroups 301 other.defaultCurve = self.defaultCurve 302 303 if not cipherfactory.tripleDESPresent: 304 other.cipherNames = [i for i in self.cipherNames if i != "3des"] 305 if len(other.cipherNames) == 0: 306 raise ValueError("No supported ciphers") 307 if len(other.certificateTypes) == 0: 308 raise ValueError("No supported certificate types") 309 310 if not cryptomath.m2cryptoLoaded: 311 other.cipherImplementations = \ 312 [e for e in other.cipherImplementations if e != "openssl"] 313 if not cryptomath.pycryptoLoaded: 314 other.cipherImplementations = \ 315 [e for e in other.cipherImplementations if e != "pycrypto"] 316 if len(other.cipherImplementations) == 0: 317 raise ValueError("No supported cipher implementations") 318 319 self._sanityCheckKeySizes(other) 320 321 self._sanityCheckPrimitivesNames(other) 322 323 self._sanityCheckProtocolVersions(other) 324 325 self._sanityCheckExtensions(other) 326 327 if other.maxVersion < (3,3): 328 # No sha-2 and AEAD pre TLS 1.2 329 other.macNames = [e for e in self.macNames if \ 330 e == "sha" or e == "md5"] 331 332 if len(other.rsaSigHashes) == 0 and other.maxVersion >= (3, 3): 333 raise ValueError("TLS 1.2 requires signature algorithms to be set") 334 335 if other.dhParams and (len(other.dhParams) != 2 or 336 not isinstance(other.dhParams[0], int_types) or 337 not isinstance(other.dhParams[1], int_types)): 338 raise ValueError("DH parameters need to be a tuple of integers") 339 340 return other
341
342 - def getCertificateTypes(self):
343 """Get list of certificate types as IDs""" 344 ret = [] 345 for ct in self.certificateTypes: 346 if ct == "x509": 347 ret.append(CertificateType.x509) 348 else: 349 raise AssertionError() 350 return ret
351