commit 71938dcd6216564ace1a57be32ec41c1c4492d66
Author: Captain_Trojan <sejakm@students.zcu.cz>
Date:   Fri Apr 30 19:39:01 2021 +0200

    Re #8705 - Added tests, changed usages (dict -> list).

diff --git a/tests/integration_tests/rest_api/certificates_test.py b/tests/integration_tests/rest_api/certificates_test.py
index 4f31502..a7526d9 100644
--- a/tests/integration_tests/rest_api/certificates_test.py
+++ b/tests/integration_tests/rest_api/certificates_test.py
@@ -15,12 +15,7 @@ def make_root_ca(server, title="Root CA s.r.o."):
             "ST": "Pilsen Region",
             "emailAddress": "root@ca.com"
         },
-        "usage": {
-            "CA": True,
-            "SSL": True,
-            "authentication": True,
-            "digitalSignature": True
-        },
+        "usage": ["CA", "SSL", "authentication", "digitalSignature"],
         "validityDays": 30
     })
 
@@ -37,38 +32,28 @@ def make_inter_ca(server, parent, title="Intermediate CA s.r.o."):
             "ST": "Pilsen Region",
             "emailAddress": "inter@ca.com"
         },
-        "usage": {
-            "CA": True,
-            "SSL": True,
-            "authentication": True,
-            "digitalSignature": True
-        },
+        "usage": ["CA", "SSL", "authentication", "digitalSignature"],
         "validityDays": 30
     })
 
 
 def make_end_cert(server, parent, title="End certificate s.r.o.", usage=None):
     if usage is None:
-        usage = {
-            "CA": False,
-            "SSL": True,
-            "authentication": True,
-            "digitalSignature": True
-        }
+        usage = ["SSL", "authentication", "digitalSignature"]
 
     return server.post("/api/certificates", content_type="application/json", json={
-        "CA": parent,
-        "subject": {
-            "C": "CZ",
-            "CN": title,
-            "L": "Pilsen",
-            "O": title,
-            "OU": "IT department",
-            "ST": "Pilsen Region",
-            "emailAddress": "end@ca.com"
-        },
-        "usage": usage,
-        "validityDays": 30
+    "CA": parent,
+    "subject": {
+        "C": "CZ",
+        "CN": title,
+        "L": "Pilsen",
+        "O": title,
+        "OU": "IT department",
+        "ST": "Pilsen Region",
+        "emailAddress": "end@ca.com"
+    },
+    "usage": usage,
+    "validityDays": 30
     })
 
 
@@ -188,12 +173,7 @@ def test_invalid_params_4(server):
             "ST": "Pilsen",
             "emailAddress": "root@ca.com"
         },
-        "usage": {
-            "CA": True,
-            "SSL": True,
-            "authentication": True,
-            "digitalSignature": True
-        },
+        "usage": ["CA", "SSL", "authentication", "digitalSignature"],
         "validityDays": 30
     })
 
@@ -308,12 +288,7 @@ def test_list_of_certificates(server):
 
 
 def test_sign_by_non_ca(server):
-    ret = make_end_cert(server, 2, "Fake intermediate cert s.r.o.", usage={
-        "CA": False,
-        "SSL": True,
-        "authentication": True,
-        "digitalSignature": True
-    })
+    ret = make_end_cert(server, 2, "Fake intermediate cert s.r.o.", usage=["SSL", "authentication", "digitalSignature"])
 
     assert ret.status_code == 201
 
@@ -324,12 +299,7 @@ def test_sign_by_non_ca(server):
     assert "success" in d
     assert d["success"]
 
-    ret = make_end_cert(server, 8, "End certificate signed by end certificate s.r.o.", usage={
-        "CA": False,
-        "SSL": True,
-        "authentication": False,
-        "digitalSignature": False
-    })
+    ret = make_end_cert(server, 8, "End certificate signed by end certificate s.r.o.", usage=["SSL"])
 
     # TODO discussion -> assert ret.status_code == 400
     assert ret.status_code == 201
@@ -462,12 +432,7 @@ def test_get_details(server):
             "ST": "Pilsen Region",
             "emailAddress": "end@ca.com"
         },
-        "usage": {
-            "CA": False,
-            "SSL": True,
-            "authentication": False,
-            "digitalSignature": True
-        },
+        "usage": ["SSL", "digitalSignature"],
         "validityDays": 30
     }
     ret = server.post("/api/certificates", content_type="application/json", json=original)
@@ -498,7 +463,8 @@ def test_get_details(server):
 
     assert original["CA"] == new["CA"]
     assert original["subject"] == new["subject"]
-    assert original["usage"] == new["usage"]
+    a = [k in original["usage"] for k, v in new["usage"].items() if v]
+    assert all(a)
     assert new["status"] == "valid"
 
 
@@ -621,12 +587,7 @@ def test_set_certificate_status(server):
             "O": "Revoked organization",
             "OU": "Revocation dep"
         },
-        "usage": {
-            "CA": False,
-            "SSL": False,
-            "authentication": False,
-            "digitalSignature": True
-        },
+        "usage": ["digitalSignature"],
         "validityDays": 60
     }
     created_ret = server.post("/api/certificates", content_type="application/json", json=certificate)
@@ -867,12 +828,7 @@ def test_certificate_status_information_revoked(server):
             "O": "Revoked organization",
             "OU": "Revocation dep"
         },
-        "usage": {
-            "CA": False,
-            "SSL": False,
-            "authentication": False,
-            "digitalSignature": True
-        },
+        "usage": ["digitalSignature"],
         "validityDays": 60
     }
     created_ret = server.post("/api/certificates", content_type="application/json", json=certificate)
@@ -930,12 +886,7 @@ def test_certificate_status_information_expired(server):
             "O": "Revoked organization",
             "OU": "Revocation dep"
         },
-        "usage": {
-            "CA": False,
-            "SSL": False,
-            "authentication": False,
-            "digitalSignature": True
-        },
+        "usage": ["digitalSignature"],
         "validityDays": 0
     }
     created_ret = server.post("/api/certificates", content_type="application/json", json=certificate)
@@ -958,3 +909,221 @@ def test_certificate_status_information_expired(server):
     assert "success" in ret.json
     assert ret.json["success"]
     assert ret.json["data"]["status"] == "expired"
+
+    def test_create_with_key_with_pass_valid(server, cryptography_service):
+        key_pass = "123456Seven"
+        key_pem = cryptography_service.create_private_key(key_pass)
+
+        certificate = {
+            "CA": 1,
+            "subject": {
+                "C": "CZ",
+                "CN": "Rare Name",
+                "L": "Legendary Name",
+                "O": "Obscure Name",
+                "OU": "Original Uniform"
+            },
+            "usage": ["CA", "digitalSignature"],
+            "validityDays": 1,
+            "key": {
+                "password": key_pass,
+                "key_pem": key_pem
+            },
+        }
+        ret = server.post("/api/certificates", content_type="application/json", json=certificate)
+        assert ret.status_code == 201
+
+    def test_create_with_key_with_pass_invalid_1(server, cryptography_service):
+        key_pass = "123456Seven"
+        key_pem = cryptography_service.create_private_key(key_pass)
+
+        certificate = {
+            "CA": 1,
+            "subject": {
+                "C": "CZ",
+                "CN": "Rare Name",
+                "L": "Legendary Name",
+                "O": "Obscure Name",
+                "OU": "Original Uniform"
+            },
+            "usage": ["CA", "digitalSignature"],
+            "validityDays": 1,
+            "key": {
+                "password": "whoopsiedaisy",
+                "key_pem": key_pem
+            },
+        }
+        ret = server.post("/api/certificates", content_type="application/json", json=certificate)
+        assert ret.status_code == 400
+        assert ret.json["data"] == 'The provided passphrase does not match the provided key.'
+        assert not ret.json["success"]
+
+    def test_create_with_key_with_pass_invalid_2(server, cryptography_service):
+        key_pass = "123456Seven"
+
+        certificate = {
+            "CA": 1,
+            "subject": {
+                "C": "CZ",
+                "CN": "Rare Name",
+                "L": "Legendary Name",
+                "O": "Obscure Name",
+                "OU": "Original Uniform"
+            },
+            "usage": ["CA", "digitalSignature"],
+            "validityDays": 1,
+            "key": {
+                "password": key_pass,
+                "key_pem": "hi im garbage and you better pray `server` survives this"
+            },
+        }
+        ret = server.post("/api/certificates", content_type="application/json", json=certificate)
+        assert ret.status_code == 400
+        assert ret.json["data"] == 'The provided passphrase does not match the provided key.'
+        assert not ret.json["success"]
+
+    def test_create_with_key_no_pass(server, cryptography_service):
+        key_pem = cryptography_service.create_private_key()
+
+        certificate = {
+            "CA": 1,
+            "subject": {
+                "C": "CZ",
+                "CN": "Rare Name",
+                "L": "Legendary Name",
+                "O": "Obscure Name",
+                "OU": "Original Uniform"
+            },
+            "usage": ["CA", "digitalSignature"],
+            "validityDays": 1,
+            "key": {
+                "key_pem": key_pem
+            },
+        }
+        ret = server.post("/api/certificates", content_type="application/json", json=certificate)
+        assert ret.status_code == 201
+
+    def test_create_with_key_no_pass_invalid_1(server, cryptography_service):
+        certificate = {
+            "CA": 1,
+            "subject": {
+                "C": "CZ",
+                "CN": "Rare Name",
+                "L": "Legendary Name",
+                "O": "Obscure Name",
+                "OU": "Original Uniform"
+            },
+            "usage": ["CA", "digitalSignature"],
+            "validityDays": 1,
+            "key": {
+                "key_pem": "hi im garbage and you better pray `server` survives this"
+            },
+        }
+        ret = server.post("/api/certificates", content_type="application/json", json=certificate)
+        assert ret.status_code == 400
+        assert not ret.json["success"]
+
+    def test_create_no_key_with_pass(server, cryptography_service):
+        key_pass = "123456Seven"
+
+        certificate = {
+            "CA": 1,
+            "subject": {
+                "C": "CZ",
+                "CN": "Rare Name",
+                "L": "Legendary Name",
+                "O": "Obscure Name",
+                "OU": "Original Uniform"
+            },
+            "usage": ["CA", "digitalSignature"],
+            "validityDays": 1,
+            "key": {
+                "password": key_pass,
+            },
+        }
+        ret = server.post("/api/certificates", content_type="application/json", json=certificate)
+        assert ret.status_code == 201
+        assert ret.json["success"]
+        created_id = ret.json["data"]
+        ret = server.get(f"/api/certificates/{created_id}/privatekey")
+        assert ret.status_code == 200
+        assert ret.json["success"]
+        key_pem = ret.json["data"]
+        assert cryptography_service.verify_key(key_pem, key_pass)
+
+    def test_create_no_key_with_pass_invalid_1(server, cryptography_service):
+        key_pass = "123456Seven"
+
+        certificate = {
+            "CA": 1,
+            "subject": {
+                "C": "CZ",
+                "CN": "Rare Name",
+                "L": "Legendary Name",
+                "O": "Obscure Name",
+                "OU": "Original Uniform"
+            },
+            "usage": ["CA", "digitalSignature"],
+            "validityDays": 1,
+            "key": {
+                "password": key_pass,
+            },
+        }
+        ret = server.post("/api/certificates", content_type="application/json", json=certificate)
+        assert ret.status_code == 201
+        assert ret.json["success"]
+        created_id = ret.json["data"]
+        ret = server.get(f"/api/certificates/{created_id}/privatekey")
+        assert ret.status_code == 200
+        assert ret.json["success"]
+        key_pem = ret.json["data"]
+        assert not cryptography_service.verify_key(key_pem, "iforgotthepassagainimsorryfrowningface")
+
+    def test_create_no_key_no_pass_invalid(server, cryptography_service):
+        certificate = {
+            "CA": 1,
+            "subject": {
+                "C": "CZ",
+                "CN": "Rare Name",
+                "L": "Legendary Name",
+                "O": "Obscure Name",
+                "OU": "Original Uniform"
+            },
+            "usage": ["CA", "digitalSignature"],
+            "validityDays": 1,
+            "key": {
+            }
+        }
+        ret = server.post("/api/certificates", content_type="application/json", json=certificate)
+        assert ret.status_code == 201  # TODO Honza? CertificateController/create_cert
+
+    def test_key_reusal(server, cryptography_service):
+        # key_pass = "1234567Eight"
+        # key_pem = cryptography_service.create_private_key(key_pass)
+        #
+        # certificate = {
+        #     "CA": 1,
+        #     "subject": {
+        #         "C": "CZ",
+        #         "CN": "Rare Name",
+        #         "L": "Legendary awd",
+        #         "O": "Obscure awd",
+        #         "OU": "Original Uniform"
+        #     },
+        #     "usage": ["CA", "digitalSignature"],
+        #     "validityDays": 1,
+        #     "key": {
+        #         "password": key_pass,
+        #         "key_pem": key_pem
+        #     },
+        # }
+        # ret = server.post("/api/certificates", content_type="application/json", json=certificate)
+        # assert ret.staus_code == 201
+        # assert ret.json["success"]
+        # created_id = ret.json["data"]
+        # ret = server.get(f"/api/certificates/{created_id}/privatekey")
+        # assert ret.status_code == 200
+        # assert ret.json["success"]
+        # key_pem = ret.json["data"]
+        # TODO
+        pass
diff --git a/tests/integration_tests/rest_api/conftest.py b/tests/integration_tests/rest_api/conftest.py
index 13f9fa9..9a2963e 100644
--- a/tests/integration_tests/rest_api/conftest.py
+++ b/tests/integration_tests/rest_api/conftest.py
@@ -5,6 +5,7 @@ from injector import Injector
 from app import app as flask_app
 from src.config.configuration import test_configuration_binder
 from src.config.connection_provider import ConnectionProvider
+from src.services.cryptography import CryptographyService
 
 
 @pytest.fixture(scope="session")
@@ -16,3 +17,8 @@ def server():
     flask_app.testing = True
     with flask_app.test_client() as s:
         yield s
+
+
+@pytest.fixture(scope="session")
+def cryptography_service():
+    return CryptographyService()
\ No newline at end of file
diff --git a/tests/integration_tests/rest_api/crl_ocsp_test.py b/tests/integration_tests/rest_api/crl_ocsp_test.py
index 2dc87b4..1de5ab2 100644
--- a/tests/integration_tests/rest_api/crl_ocsp_test.py
+++ b/tests/integration_tests/rest_api/crl_ocsp_test.py
@@ -16,25 +16,12 @@ def make_root_ca(server, title="Root CA s.r.o."):
             "ST": "Pilsen Region",
             "emailAddress": "root@ca.com"
         },
-        "usage": {
-            "CA": True,
-            "SSL": True,
-            "authentication": True,
-            "digitalSignature": True
-        },
+        "usage": ["CA", "SSL", "authentication", "digitalSignature"],
         "validityDays": 30
     })
 
 
-def make_end_cert(server, parent, title="End certificate s.r.o.", usage=None):
-    if usage is None:
-        usage = {
-            "CA": False,
-            "SSL": True,
-            "authentication": True,
-            "digitalSignature": True
-        }
-
+def make_inter_ca(server, parent, title="Intermediate CA s.r.o."):
     return server.post("/api/certificates", content_type="application/json", json={
         "CA": parent,
         "subject": {
@@ -44,13 +31,33 @@ def make_end_cert(server, parent, title="End certificate s.r.o.", usage=None):
             "O": title,
             "OU": "IT department",
             "ST": "Pilsen Region",
-            "emailAddress": "end@ca.com"
+            "emailAddress": "inter@ca.com"
         },
-        "usage": usage,
+        "usage": ["CA", "SSL", "authentication", "digitalSignature"],
         "validityDays": 30
     })
 
 
+def make_end_cert(server, parent, title="End certificate s.r.o.", usage=None):
+    if usage is None:
+        usage = ["SSL", "authentication", "digitalSignature"]
+
+    return server.post("/api/certificates", content_type="application/json", json={
+    "CA": parent,
+    "subject": {
+        "C": "CZ",
+        "CN": title,
+        "L": "Pilsen",
+        "O": title,
+        "OU": "IT department",
+        "ST": "Pilsen Region",
+        "emailAddress": "end@ca.com"
+    },
+    "usage": usage,
+    "validityDays": 30
+    })
+
+
 def test_crl_endpoint_empty(server):
     ret = make_root_ca(server, title="Root 1")
     data = ret.json
