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