From 9a0ff9a3282bd865c1ac4f2af4c90eb1c6169d23 Mon Sep 17 00:00:00 2001
From: Kfir Hadas <sharkykh@gmail.com>
Date: Wed, 24 May 2017 11:41:16 +0300
Subject: [PATCH] Fix #3795 + added test for cert generation (#3796)

* Use bytes instead of unicode

* Test create_https_certificates

May need to install pyOpenSSL on Travis

* Update test case

tox: Install pyOpenSSL
---
 sickbeard/helpers.py   |  4 +--
 tests/helpers_tests.py | 55 +++++++++++++++++++++++++++++++++++++++---
 tox.ini                |  2 ++
 3 files changed, 55 insertions(+), 6 deletions(-)

diff --git a/sickbeard/helpers.py b/sickbeard/helpers.py
index c7f6020d4..ed59353e0 100644
--- a/sickbeard/helpers.py
+++ b/sickbeard/helpers.py
@@ -860,12 +860,12 @@ def create_https_certificates(ssl_cert, ssl_key):
     # Create the CA Certificate
     cakey = createKeyPair(TYPE_RSA, 4096)
     careq = createCertRequest(cakey, CN='Certificate Authority')
-    cacert = createCertificate(careq, (careq, cakey), serial, validity_period, 'sha256')
+    cacert = createCertificate(careq, (careq, cakey), serial, validity_period, b'sha256')
 
     cname = 'SickRage'
     pkey = createKeyPair(TYPE_RSA, 4096)
     req = createCertRequest(pkey, CN=cname)
-    cert = createCertificate(req, (cacert, cakey), serial, validity_period, 'sha256')
+    cert = createCertificate(req, (cacert, cakey), serial, validity_period, b'sha256')
 
     # Save the key and certificate to disk
     try:
diff --git a/tests/helpers_tests.py b/tests/helpers_tests.py
index c655e0478..4adba62c9 100644
--- a/tests/helpers_tests.py
+++ b/tests/helpers_tests.py
@@ -504,12 +504,59 @@ class HelpersEncryptionTests(unittest.TestCase):
     """
     Test encryption and decryption
     """
-    @unittest.skip('Not yet implemented')
     def test_create_https_certificates(self):
         """
-        Test create_https_certificates
-        """
-        pass
+        Test that create_https_certificates successfully generates certificate and private key
+        """
+        try:
+            import OpenSSL
+        except ImportError:
+            self.skipTest('pyOpenSSL is not installed')
+            return False
+
+        base_path = os.path.dirname(__file__)
+        cert_path = os.path.abspath(os.path.join(base_path, 'test.crt'))
+        pkey_path = os.path.abspath(os.path.join(base_path, 'test.key'))
+
+        def removeTestFiles():
+            try:
+                os.remove(cert_path)
+                os.remove(pkey_path)
+            except OSError:
+                pass
+
+        removeTestFiles()  # always remove existing
+        self.assertTrue(helpers.create_https_certificates(cert_path, pkey_path))
+        self.assertTrue(os.path.isfile(cert_path))
+        self.assertTrue(os.path.isfile(pkey_path))
+
+        FILETYPE_PEM = OpenSSL.crypto.FILETYPE_PEM
+        try:
+            with open(cert_path, 'rt') as f:
+                cert = OpenSSL.crypto.load_certificate(FILETYPE_PEM, f.read())
+        except Exception as error:
+            removeTestFiles()
+            self.fail('Unable to load certificate')
+
+        try:
+            with open(pkey_path, 'rt') as f:
+                pkey = OpenSSL.crypto.load_privatekey(FILETYPE_PEM, f.read())
+        except Exception as error:
+            removeTestFiles()
+            self.fail('Unable to load private key')
+
+        context = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_METHOD)
+        context.use_privatekey(pkey)
+        context.use_certificate(cert)
+        failed = False
+        try:
+            context.check_privatekey()
+        except OpenSSL.SSL.Error:
+            failed = True
+        finally:
+            removeTestFiles()
+
+        self.assertFalse(failed, 'private key does not match certificate')
 
     @unittest.skip('Not yet implemented')
     def test_encrypt(self):
diff --git a/tox.ini b/tox.ini
index e059252fd..8b9aed3ae 100644
--- a/tox.ini
+++ b/tox.ini
@@ -14,6 +14,7 @@ deps =
     mock
     vcrpy-unittest
     pytz
+    pyopenssl
 commands =
     /bin/rm -f {toxinidir}/tests/sickbeard.db
     /bin/rm -f {toxinidir}/tests/cache.db
@@ -33,6 +34,7 @@ deps =
     mock
     vcrpy-unittest
     pytz
+    pyopenssl
 commands =
     cmd /c del /f /q {toxinidir}\tests\sickbeard.db {toxinidir}\tests\cache.db {toxinidir}\tests\failed.db 2> nul
     nosetests -c nose.cfg --nocapture
-- 
GitLab