From 669e889e6fbc9a8405f4c8a751ccebe2c1990faa Mon Sep 17 00:00:00 2001 From: James Lu Date: Sat, 30 Jan 2016 23:04:13 -0800 Subject: [PATCH] Support configurable SSL fingerprint hash types (Closes #157) --- classes.py | 52 ++++++++++++++++++++++++++++++------------------ example-conf.yml | 11 ++++++++-- 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/classes.py b/classes.py index ff78ff5..e388a9b 100644 --- a/classes.py +++ b/classes.py @@ -206,26 +206,40 @@ class Irc(): # self-sign their certificates anyways. if self.ssl and checks_ok: peercert = self.socket.getpeercert(binary_form=True) - sha1fp = hashlib.sha1(peercert).hexdigest() - expected_fp = self.serverdata.get('ssl_fingerprint') - if expected_fp: - if sha1fp != expected_fp: - # SSL Fingerprint doesn't match; break. - log.error('(%s) Uplink\'s SSL certificate ' - 'fingerprint (SHA1) does not match the ' - 'one configured: expected %r, got %r; ' - 'disconnecting...', self.name, - expected_fp, sha1fp) - checks_ok = False - else: - log.info('(%s) Uplink SSL certificate fingerprint ' - '(SHA1) verified: %r', self.name, sha1fp) + + # Hash type is configurable using the ssl_fingerprint_type + # value, and defaults to sha256. + hashtype = self.serverdata.get('ssl_fingerprint_type', 'sha256').lower() + + try: + hashfunc = getattr(hashlib, hashtype) + except AttributeError: + log.error('(%s) Unsupported SSL certificate fingerprint type %r given, disconnecting...', + self.name, hashtype) + checks_ok = False else: - log.info('(%s) Uplink\'s SSL certificate fingerprint ' - 'is %r. You can enhance the security of your ' - 'link by specifying this in a "ssl_fingerprint"' - ' option in your server block.', self.name, - sha1fp) + fp = hashfunc(peercert).hexdigest() + expected_fp = self.serverdata.get('ssl_fingerprint') + + if expected_fp and checks_ok: + if fp != expected_fp: + # SSL Fingerprint doesn't match; break. + log.error('(%s) Uplink\'s SSL certificate ' + 'fingerprint (%s) does not match the ' + 'one configured: expected %r, got %r; ' + 'disconnecting...', self.name, hashtype, + expected_fp, fp) + checks_ok = False + else: + log.info('(%s) Uplink SSL certificate fingerprint ' + '(%s) verified: %r', self.name, hashtype, + fp) + else: + log.info('(%s) Uplink\'s SSL certificate fingerprint (%s)' + 'is %r. You can enhance the security of your ' + 'link by specifying this in a "ssl_fingerprint"' + ' option in your server block.', self.name, + hashtype, fp) if checks_ok: # All our checks passed, get the protocol module to connect diff --git a/example-conf.yml b/example-conf.yml index 7e7dbdd..9a0358a 100644 --- a/example-conf.yml +++ b/example-conf.yml @@ -127,8 +127,15 @@ servers: # ssl_keyfile: pylink-key.pem # Optionally, you can set this option to verify the SSL certificate - # fingerprint (SHA1) of your uplink. - # ssl_fingerprint: "e0fee1adf795c84eec4735f039503eb18d9c35cc" + # fingerprint of your uplink. + #ssl_fingerprint: "e0fee1adf795c84eec4735f039503eb18d9c35cc" + + # This sets the hash type for the fingerprint (md5, sha1, sha256, etc.) + # Valid values include md5 and sha1-sha512, though others may be + # supported depending on your system: see + # https://docs.python.org/3/library/hashlib.html + # This setting defaults to sha256. + #ssl_fingerprint_type: sha256 ts6net: ip: ::1