Mercurial > hg
comparison mercurial/sslutil.py @ 29554:4a7b0c696fbc
sslutil: implement wrapserversocket()
wrapsocket() is heavily tailored towards client use. In preparation
for converting the built-in server to use sslutil (as opposed to
the ssl module directly), we add wrapserversocket() for wrapping
a socket to be used on servers.
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Thu, 14 Jul 2016 20:14:19 -0700 |
parents | 5f8b36d5a6ec |
children | 53de8255ec4e |
comparison
equal
deleted
inserted
replaced
29553:cd3e58862cab | 29554:4a7b0c696fbc |
---|---|
323 'ui': ui, | 323 'ui': ui, |
324 } | 324 } |
325 | 325 |
326 return sslsocket | 326 return sslsocket |
327 | 327 |
328 def wrapserversocket(sock, ui, certfile=None, keyfile=None, cafile=None, | |
329 requireclientcert=False): | |
330 """Wrap a socket for use by servers. | |
331 | |
332 ``certfile`` and ``keyfile`` specify the files containing the certificate's | |
333 public and private keys, respectively. Both keys can be defined in the same | |
334 file via ``certfile`` (the private key must come first in the file). | |
335 | |
336 ``cafile`` defines the path to certificate authorities. | |
337 | |
338 ``requireclientcert`` specifies whether to require client certificates. | |
339 | |
340 Typically ``cafile`` is only defined if ``requireclientcert`` is true. | |
341 """ | |
342 if modernssl: | |
343 # We /could/ use create_default_context() here since it doesn't load | |
344 # CAs when configured for client auth. | |
345 sslcontext = SSLContext(ssl.PROTOCOL_SSLv23) | |
346 # SSLv2 and SSLv3 are broken. Ban them outright. | |
347 sslcontext.options |= OP_NO_SSLv2 | OP_NO_SSLv3 | |
348 # Prevent CRIME | |
349 sslcontext.options |= getattr(ssl, 'OP_NO_COMPRESSION', 0) | |
350 # Improve forward secrecy. | |
351 sslcontext.options |= getattr(ssl, 'OP_SINGLE_DH_USE', 0) | |
352 sslcontext.options |= getattr(ssl, 'OP_SINGLE_ECDH_USE', 0) | |
353 | |
354 # Use the list of more secure ciphers if found in the ssl module. | |
355 if util.safehasattr(ssl, '_RESTRICTED_SERVER_CIPHERS'): | |
356 sslcontext.options |= getattr(ssl, 'OP_CIPHER_SERVER_PREFERENCE', 0) | |
357 sslcontext.set_ciphers(ssl._RESTRICTED_SERVER_CIPHERS) | |
358 else: | |
359 sslcontext = SSLContext(ssl.PROTOCOL_TLSv1) | |
360 | |
361 if requireclientcert: | |
362 sslcontext.verify_mode = ssl.CERT_REQUIRED | |
363 else: | |
364 sslcontext.verify_mode = ssl.CERT_NONE | |
365 | |
366 if certfile or keyfile: | |
367 sslcontext.load_cert_chain(certfile=certfile, keyfile=keyfile) | |
368 | |
369 if cafile: | |
370 sslcontext.load_verify_locations(cafile=cafile) | |
371 | |
372 return sslcontext.wrap_socket(sock, server_side=True) | |
373 | |
328 class wildcarderror(Exception): | 374 class wildcarderror(Exception): |
329 """Represents an error parsing wildcards in DNS name.""" | 375 """Represents an error parsing wildcards in DNS name.""" |
330 | 376 |
331 def _dnsnamematch(dn, hostname, maxwildcards=1): | 377 def _dnsnamematch(dn, hostname, maxwildcards=1): |
332 """Match DNS names according RFC 6125 section 6.4.3. | 378 """Match DNS names according RFC 6125 section 6.4.3. |