From 13fb63b12fc92eb5230a8d200844cb3e4755d531 Mon Sep 17 00:00:00 2001 From: Alberto Sottile Date: Sun, 3 Feb 2019 21:19:10 +0100 Subject: [PATCH] TLS: client-server implementation with self-issued certs on IPv4 --- server.crt | 41 +++++++++++++++++------------------------ server.key | 27 --------------------------- server.pem | 46 ++++++++++++++++++++++++++++++++++++++++++++++ syncplay/client.py | 11 ++++++++--- syncplayServer.py | 19 +++++-------------- 5 files changed, 76 insertions(+), 68 deletions(-) delete mode 100644 server.key create mode 100644 server.pem diff --git a/server.crt b/server.crt index b302fd6..d93e114 100644 --- a/server.crt +++ b/server.crt @@ -1,26 +1,19 @@ -----BEGIN CERTIFICATE----- -MIIEcjCCA1qgAwIBAgIJAJe1HOCC73ylMA0GCSqGSIb3DQEBCwUAMHExCzAJBgNV -BAYTAlBMMQ0wCwYDVQQIDAROb25lMQ0wCwYDVQQHDAROb25lMREwDwYDVQQKDAhT -eW5jcGxheTERMA8GA1UEAwwIU3luY3BsYXkxHjAcBgkqhkiG9w0BCQEWD2RldkBz -eW5jcGxheS5wbDAeFw0xOTAyMDMxNTM2MDdaFw0yMDAyMDMxNTM2MDdaMHExCzAJ -BgNVBAYTAlBMMQ0wCwYDVQQIDAROb25lMQ0wCwYDVQQHDAROb25lMREwDwYDVQQK -DAhTeW5jcGxheTERMA8GA1UEAwwIU3luY3BsYXkxHjAcBgkqhkiG9w0BCQEWD2Rl -dkBzeW5jcGxheS5wbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM7S -L3L0Mhf+5pMnSRUGQnxN89o+7aKtQ7Lf/rIGrFFjLNOOcTeWuod/x/MjDw5sP7HP -xQFb0/pAdm7VS5L/GJpWBQiHvB3VndyZ3CazQRs2NOus9CLBtoMh480dz/oiqed+ -XxkhD3hVyRDSkqz+QPNwj5b64FhYo9ocnOZwKJ3KvWBPDPV1wzIiCBh7YB2V/78f -K4qHaX6QVUvruxwpHp/Iw+JMHACBTRND5gXGo7vb/6g8AnKmypy+nS0iFbNasq5p -G5UFFb6T9jcQ7OfHvPOa9b3wFD/R3bi+dOyboST/BUd5j1+sJhrvEGI+fK6zIA11 -uwOasVEekv5I/z2jtG8CAwEAAaOCAQswggEHMIGNBgNVHSMEgYUwgYKhdaRzMHEx -CzAJBgNVBAYTAlBMMQ0wCwYDVQQIDAROb25lMQ0wCwYDVQQHDAROb25lMREwDwYD -VQQKDAhTeW5jcGxheTERMA8GA1UEAwwIU3luY3BsYXkxHjAcBgkqhkiG9w0BCQEW -D2RldkBzeW5jcGxheS5wbIIJAJe1HOCC73ylMAkGA1UdEwQCMAAwCwYDVR0PBAQD -AgTwMF0GA1UdEQRWMFSCUjxzcGVjaWZ5LXRoZS1zYW1lLWNvbW1vbi1uYW1lLXRo -YXQteW91LXVzZWQtd2hpbGUtZ2VuZXJhdGluZy1jc3ItaW4tdGhlLWxhc3Qtc3Rl -cD4wDQYJKoZIhvcNAQELBQADggEBAI+jWXb3nRYS1aOUduiF7VAVIaouYRPgkdb8 -p/W0S36KZ7jJXIQurXxx2znjtdC60qwBjJSqLnI1D6lWP6SdX8LMCNmJjtO/dZaX -zoTDqBEcjXp7Up17Zi2liCtYNYAFDdEX9wWMhrg26gY/IccBwm2wKD+B6MfOBTJc -/DRrp4cf/XcUCoNRCmU6JDFABKc63fK2Tr3ClTrXq2qYTaR4xIVu6EUAJGE+zMja -rOT4vXzvAPPHCf03uYCm8jagoxX9Qi7NyAWnyJOgO0DNnhKyxe1MZEkQV1X8m1ko -BVdikLM5hUHIzI2+5Q7o4jr2CHb5oL5OF4PUypwfeRe+PzoI9qs= +MIIDDjCCAfYCCQCi9L0SyIknmTANBgkqhkiG9w0BAQsFADBJMQswCQYDVQQGEwJQ +TDETMBEGA1UECAwKU29tZS1TdGF0ZTERMA8GA1UECgwIU3luY3BsYXkxEjAQBgNV +BAMMCWxvY2FsaG9zdDAeFw0xOTAyMDMxOTA0MTFaFw0yMTExMjMxOTA0MTFaMEkx +CzAJBgNVBAYTAlBMMRMwEQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQKDAhTeW5j +cGxheTESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxdnxzQ2ddPWLBHzHRlc2uGCML6MtPdTW5mOzQbj+jxHqhcJszIo4 +5/ZoqCX11tgQ69cJphTmg0Pjd89xTiqQBOf/qD3kSycds6j26H4oiIsuvOCaa5LN +lE5jAGZQWWRrnAqXJgbnQZgW+2a8bhJGCospRRIK+h48FDazOwEoNHjmPC7DHWrt +HlU/BbuzGPLhekKzR7LTD8/32+4g1e2LMMEv22LYrN2cRpZqb8wXYgjsMRc7aqAA +NS7x0tspBhBfCigDLd4i+SuKPGkyI118uss7eKx7MDgmQp1vUiTOkKphgT1S/a7m +4EJ3xO+75WjIQ4bJPmLbdLWMKOXi2t7PVQIDAQABMA0GCSqGSIb3DQEBCwUAA4IB +AQCADrdRY64VpPeM8c9MCn7jXDR0B7xjwoQkiyFvISCRiWZwX8QE2atjZ6jGnuB3 +LBattjmjHcCNwLEvc5dZT0ioeiAvNdEbcMitYS7d2x3QIQ2n2zpSMp3speAv7mdG +YkC/oE7bbORBksjsxLCAOPOrDYijyTwDN0oTkDcuhkdztbO5Frp/5vA/i/U29Sxv +ebbJ0JXl8LJKzJqslyRv6sVxsNFH0foX7rwbXzciO4TscHHrFDZwNBhjWYPITJ7J +BBgr8Cs9ZbKFQ7+o1bUob7B8n2tKtVxAHfTQfBe68ZlcdTHfFririLjhRDVXSAFw +8ZZzQoma7VJ/1l8jcoWhdfOe -----END CERTIFICATE----- diff --git a/server.key b/server.key deleted file mode 100644 index 4b08fd3..0000000 --- a/server.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpgIBAAKCAQEAztIvcvQyF/7mkydJFQZCfE3z2j7toq1Dst/+sgasUWMs045x -N5a6h3/H8yMPDmw/sc/FAVvT+kB2btVLkv8YmlYFCIe8HdWd3JncJrNBGzY066z0 -IsG2gyHjzR3P+iKp535fGSEPeFXJENKSrP5A83CPlvrgWFij2hyc5nAoncq9YE8M -9XXDMiIIGHtgHZX/vx8riodpfpBVS+u7HCken8jD4kwcAIFNE0PmBcaju9v/qDwC -cqbKnL6dLSIVs1qyrmkblQUVvpP2NxDs58e885r1vfAUP9HduL507JuhJP8FR3mP -X6wmGu8QYj58rrMgDXW7A5qxUR6S/kj/PaO0bwIDAQABAoIBAQCdeVQ/hseNlbwi -V0tCAt4kn4YIqtltf9eIHx1il8okvgqnmlGCLfYgrZ6k9hDEvo9Q6A3sluq0JNkI -UseUST+GY/C5KgCGBtyH127U2K+99Gwe9jV9MVmyRt+YkhaFMleDt6jZDV8mFMtf -T7X2mjECKrZqEuM24WcA78BXhRan7RMl77ZQFrFNn+TccFItNUoeP75vD+5aLeH+ -ovWbMM3EaSFMPKoOZ3yJ78IEtD1B61DLOjZNlYsli7phmJR0veb8GHhllDovZ6ru -d5k56r5AqFLSV5Xp29Z0+8mbVOjlgDZ5EYYdyyo0KKX3sADtR2f2/ktIZuFPQFsC -nXbKnRVhAoGBAPeI9ft1B5htUdukb7IUcrdLoPv2cl9uw7e/kUemTO51Uk3QSnex -LUYe5JHoQDBdG7tN88xJLzp/ybH8+SublSrwnF7lqs+TRE3NGI05SIprpMIV2dAo -A+/6icg2jqeGt7ZZv2Ge9VzcxuxwmO5hkx51OlulBuEzdzGOfr/KdZ1jAoGBANXk -y4iQ145V1EkelwZZtMfZH8PZXp7ZVdF2vWG4HDV5frOwIanVtm5VEOW683gJsDnk -9+emRtzd0bm5wjy0K784VWzY/JODzxTgkaBgb1qxoHJv8xdzyo/F3n5WjalOnDQ5 -Y2uBDRj9tMKcZGX9yfnDik4ostT9KRUfy+xhXlCFAoGBAJhw2EvLfqn4aPkDA2aA -AUWwZavF0hnDdPSsHSQq3iXcSptxMusTSfZtAAZ7KUyfinyHPSUJzPQRzny2dhzM -68hN9X7boZ3D68SeEgimxm24bPa5zjHK8uHPQRrzvladOHYsPxg3dJODw13I2eW0 -YY3YU+AseVgnAbibMKOcY2JRAoGBAM4m91iHqYpBBRr4Rb1UJp5bkXcVAVJ+zGzX -Uc5mQaH0mH6dasSi+3K5wFB68IAoblZObfUx2Ki1jpbACAqz6Foj9Im1VTLkXmmT -zCfT6l9yRd8mMRjQfFI39qqzx1OANaNMEJujxTjqBhdv3oBCrDFzGtEb/sizu63l -eIk6i0l1AoGBAPRicQrL3fQ0Ig7O6Oc59Rs2I2FCioGTm4m6PMJzhTQQIkaBHxco -Vd8wWQCbZDdP/8o0uh/qvBey0fuGp9ff0k4rOUJtHTI0YlzdJzAEVyuPt+Z+heXc -KSsqIL/+WFL8pNO0wX0dycVEwSZnZ45wBskTGFZjv9c4Q0rdQBru9QWd ------END RSA PRIVATE KEY----- diff --git a/server.pem b/server.pem new file mode 100644 index 0000000..2b12284 --- /dev/null +++ b/server.pem @@ -0,0 +1,46 @@ +-----BEGIN CERTIFICATE----- +MIIDDjCCAfYCCQCi9L0SyIknmTANBgkqhkiG9w0BAQsFADBJMQswCQYDVQQGEwJQ +TDETMBEGA1UECAwKU29tZS1TdGF0ZTERMA8GA1UECgwIU3luY3BsYXkxEjAQBgNV +BAMMCWxvY2FsaG9zdDAeFw0xOTAyMDMxOTA0MTFaFw0yMTExMjMxOTA0MTFaMEkx +CzAJBgNVBAYTAlBMMRMwEQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQKDAhTeW5j +cGxheTESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxdnxzQ2ddPWLBHzHRlc2uGCML6MtPdTW5mOzQbj+jxHqhcJszIo4 +5/ZoqCX11tgQ69cJphTmg0Pjd89xTiqQBOf/qD3kSycds6j26H4oiIsuvOCaa5LN +lE5jAGZQWWRrnAqXJgbnQZgW+2a8bhJGCospRRIK+h48FDazOwEoNHjmPC7DHWrt +HlU/BbuzGPLhekKzR7LTD8/32+4g1e2LMMEv22LYrN2cRpZqb8wXYgjsMRc7aqAA +NS7x0tspBhBfCigDLd4i+SuKPGkyI118uss7eKx7MDgmQp1vUiTOkKphgT1S/a7m +4EJ3xO+75WjIQ4bJPmLbdLWMKOXi2t7PVQIDAQABMA0GCSqGSIb3DQEBCwUAA4IB +AQCADrdRY64VpPeM8c9MCn7jXDR0B7xjwoQkiyFvISCRiWZwX8QE2atjZ6jGnuB3 +LBattjmjHcCNwLEvc5dZT0ioeiAvNdEbcMitYS7d2x3QIQ2n2zpSMp3speAv7mdG +YkC/oE7bbORBksjsxLCAOPOrDYijyTwDN0oTkDcuhkdztbO5Frp/5vA/i/U29Sxv +ebbJ0JXl8LJKzJqslyRv6sVxsNFH0foX7rwbXzciO4TscHHrFDZwNBhjWYPITJ7J +BBgr8Cs9ZbKFQ7+o1bUob7B8n2tKtVxAHfTQfBe68ZlcdTHfFririLjhRDVXSAFw +8ZZzQoma7VJ/1l8jcoWhdfOe +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAxdnxzQ2ddPWLBHzHRlc2uGCML6MtPdTW5mOzQbj+jxHqhcJs +zIo45/ZoqCX11tgQ69cJphTmg0Pjd89xTiqQBOf/qD3kSycds6j26H4oiIsuvOCa +a5LNlE5jAGZQWWRrnAqXJgbnQZgW+2a8bhJGCospRRIK+h48FDazOwEoNHjmPC7D +HWrtHlU/BbuzGPLhekKzR7LTD8/32+4g1e2LMMEv22LYrN2cRpZqb8wXYgjsMRc7 +aqAANS7x0tspBhBfCigDLd4i+SuKPGkyI118uss7eKx7MDgmQp1vUiTOkKphgT1S +/a7m4EJ3xO+75WjIQ4bJPmLbdLWMKOXi2t7PVQIDAQABAoIBAFz8ZlE58eOzNyff +wQRFHvmenqQQ68Vgj7Nt7iSYXkM9Z1yAGQQ0fjQ+scc9OAJGQAWnZeiBcCkHMhPw +Ec9r343+v0AB/pZ3htUWNxzjlgc+arPoV4rxTt9By/O3IlIxCQYoUAtWOT+xzDNR +gIO24OY5qybEKRaOOSxC3Q+BJrUpvIMEf93w7YQQ5SqulcmSYsIK25t+ACdXAlkX +KpvszojDU+qfUH7Uz8/yvFcbZ8LeDdrv1Wcedx15VUIcrU+D9DBYK1NOFW2vuPJT +DJZOQFXMTxg6kSED0O8a4Z3VhaPEBiGdN4KOIkC1tUj8i+BM441Jg4nme8OLX/Vm +NGftpm0CgYEA93w8P6gp1wnO7R56FdRoL9nhfgoMQroqNMqHdoGlWPFZNDqtvbFW +vjhg1v98T8mBvQMsfLruUuDDykacOdDyHRAbPQ+gICUjRXDFgu+GhHcIRn3dcZli +cSRka/JsuqCuTFnIoa981IYEllAQTZ+3w+qR8d+BkoR7K55v5aRxNCsCgYEAzKiM +8u1W3d6/E6EgaiSVOuCwOB85zbQH1t1s6wQoD34u+CEKyW3/WCkZuNMlE6J8luwt +HfXilFq9ZfAdyxN/DhHIygulbIbGwtzYFI6rEmU3zL1bX27ZWStjuDUyWf3zX4T2 +9vlBf9CwJWeotaKl+Or2aeGAiNP5830WIpikyn8CgYEA8AjjNqqXyiWNOZaxurKF +SsP8XQ7JzX5aqVE2Cc683INZjbrMAIwcIer0ohKyM4CyAO0vHNsBhAjUXUAXDkyG +R4HzqUmaeRMMHrG+H7zJr3jz4cr6GNA4FpzBeaFrq6dk5lC+s3NNk6NYl6GX7nHW +/oJogzvQpJcyD6Bfz0+rLHkCgYBr0uFvm1uIyTIiRWGuileVDYvKBamOlqsKqN4Z +c7cncnOMhtwIA8vjxsOmfJesII9DdGrQvhsBzky6yCbqNvtZjkUbLceZxegyAehV +7FR0/J7JX3okbWJVeGaxRlWg1ArE6Gi09d1sWaZ0Doj0KR0IZ8IrRoNRk1y8y8o9 +r+4iQQKBgDyuv6nz4xV3GrW6ohVcCRg8R4yZmb65A4guxZIwMh3nbf+rHWO3RTxd +LMiCLSW3Py2xsxiMa5ICEm75Hke8+KHwRBL7SK1eqaFrdhzvTALQp0IfBu1/t7bR +5bJVa6EL55eNA0LcOZqX36rDYzpzZjaf46XNzshZ/p0X7NryEhNl +-----END RSA PRIVATE KEY----- diff --git a/syncplay/client.py b/syncplay/client.py index 0758e2e..99cbd18 100755 --- a/syncplay/client.py +++ b/syncplay/client.py @@ -11,8 +11,9 @@ import time from copy import deepcopy from functools import wraps -from twisted.internet.endpoints import HostnameEndpoint +from twisted.internet.endpoints import HostnameEndpoint, wrapClientTLS from twisted.internet.protocol import ClientFactory +from twisted.internet.ssl import Certificate, optionsForClientTLS from twisted.internet import reactor, task, defer, threads from twisted.application.internet import ClientService @@ -703,7 +704,11 @@ class SyncplayClient(object): if '[' in host: host = host.strip('[]') port = int(port) - self._endpoint = HostnameEndpoint(reactor, host, port) + with open('server.crt') as cert_file: + trust_root = Certificate.loadPEM(cert_file.read()) + self._wrapped = HostnameEndpoint(reactor, host, port) + self._contextFactory = optionsForClientTLS(hostname=host, trustRoot=trust_root) + self._endpoint = wrapClientTLS(self._contextFactory, self._wrapped) def retry(retries): self._lastGlobalUpdate = None @@ -719,7 +724,7 @@ class SyncplayClient(object): self.reconnecting = True return(0.1 * (2 ** min(retries, 5))) - self._reconnectingService = ClientService(self._endpoint, self.protocolFactory , retryPolicy=retry) + self._reconnectingService = ClientService(self._endpoint, self.protocolFactory, retryPolicy=retry) waitForConnection = self._reconnectingService.whenConnected(failAfterFailures=1) self._reconnectingService.startService() diff --git a/syncplayServer.py b/syncplayServer.py index e3eca96..053c93b 100755 --- a/syncplayServer.py +++ b/syncplayServer.py @@ -15,22 +15,14 @@ except AttributeError: from OpenSSL import crypto from twisted.internet import reactor, ssl -from twisted.internet.endpoints import TCP4ServerEndpoint, SSL4ServerEndpoint, TCP6ServerEndpoint +from twisted.internet.endpoints import SSL4ServerEndpoint, TCP6ServerEndpoint from syncplay.server import SyncFactory, ConfigurationGetter -with open('server.crt', 'r') as f: - cert_data = f.read() -with open('server.key', 'r') as f: - key_data = f.read() +with open('server.pem') as f: + certData = f.read() -cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert_data) -key = crypto.load_privatekey(crypto.FILETYPE_PEM, key_data) -options = ssl.CertificateOptions( - privateKey=key, - certificate=cert, - acceptableProtocols=[b'h2'], -) +certificate = ssl.PrivateCertificate.loadPEM(certData).options() if __name__ == '__main__': argsGetter = ConfigurationGetter() @@ -47,8 +39,7 @@ if __name__ == '__main__': args.max_username_length, args.stats_db_file ) - #endpoint4 = TCP4ServerEndpoint(reactor, int(args.port)) - endpoint4 = SSL4ServerEndpoint(reactor, int(args.port), options) + endpoint4 = SSL4ServerEndpoint(reactor, int(args.port), certificate) endpoint4.listen(factory) #endpoint6 = TCP6ServerEndpoint(reactor, int(args.port)) #endpoint6.listen(factory)