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