diff --git a/functional_tests/test_status.py b/functional_tests/test_status.py index e0baea26978f4d167584c8b4ef0faa65b16dee2c..bbab0fb1160e635b15611110438e435ebbc83ebd 100644 --- a/functional_tests/test_status.py +++ b/functional_tests/test_status.py @@ -72,6 +72,7 @@ def test_status_on_uninitialised_directory(tmpdir): @pytest.mark.parametrize("ca_key_specification, default_key_representation", [ ("rsa:2048", "2048-bit RSA"), + ("ecdsa:secp521r1", "secp521r1 ECDSA"), ]) def test_status_on_initialised_directory(tmpdir, ca_key_specification, default_key_representation): # John is interested in finding out a bit more about what @@ -86,12 +87,14 @@ def test_status_on_initialised_directory(tmpdir, ca_key_specification, default_k run_command("openssl", "req", "-new", "-newkey", "rsa:2048", "-nodes", "-keyout", "myserver3.key.pem", "-subj", "/CN=myserver3", "-out", "myserver3.csr.pem") run_command('gimmecert', 'server', '--csr', 'myserver3.csr.pem', 'myserver3') + run_command('gimmecert', 'server', 'myserver4', '-k', 'ecdsa:secp256r1') run_command('gimmecert', 'client', 'myclient1', '-k', 'rsa:1024') run_command('gimmecert', 'client', 'myclient2') run_command("openssl", "req", "-new", "-newkey", "rsa:2048", "-nodes", "-keyout", "myclient3.key.pem", "-subj", "/CN=myclient3", "-out", "myclient3.csr.pem") run_command('gimmecert', 'client', '--csr', 'myclient3.csr.pem', 'myclient3') + run_command('gimmecert', 'client', 'myclient4', '-k', 'ecdsa:secp192r1') # John switches to project directory. tmpdir.chdir() @@ -149,6 +152,7 @@ def test_status_on_initialised_directory(tmpdir, ca_key_specification, default_k index_myserver1 = stdout_lines.index("CN=myserver1") # Should not raise index_myserver2 = stdout_lines.index("CN=myserver2") # Should not raise index_myserver3 = stdout_lines.index("CN=myserver3") # Should not raise + index_myserver4 = stdout_lines.index("CN=myserver4") # Should not raise assert stdout_lines[index_myserver1+1].startswith(" Validity: ") assert stdout_lines[index_myserver1+2] == " DNS: myserver1" @@ -168,6 +172,11 @@ def test_status_on_initialised_directory(tmpdir, ca_key_specification, default_k assert stdout_lines[index_myserver3+4] == " CSR: .gimmecert/server/myserver3.csr.pem" assert stdout_lines[index_myserver3+5] == " Certificate: .gimmecert/server/myserver3.cert.pem" + assert stdout_lines[index_myserver4+2] == " DNS: myserver4" + assert stdout_lines[index_myserver4+3] == " Key algorithm: secp256r1 ECDSA" + assert stdout_lines[index_myserver4+4] == " Private key: .gimmecert/server/myserver4.key.pem" + assert stdout_lines[index_myserver4+5] == " Certificate: .gimmecert/server/myserver4.cert.pem" + # For client certificates, John can see that for each certificate # he can see its subject DN and validity. Information for each # client is followed by key algorithm and paths to private key and @@ -175,6 +184,7 @@ def test_status_on_initialised_directory(tmpdir, ca_key_specification, default_k index_myclient1 = stdout_lines.index("CN=myclient1") # Should not raise index_myclient2 = stdout_lines.index("CN=myclient2") # Should not raise index_myclient3 = stdout_lines.index("CN=myclient3") # Should not raise + index_myclient4 = stdout_lines.index("CN=myclient4") # Should not raise assert stdout_lines[index_myclient1+1].startswith(" Validity: ") assert stdout_lines[index_myclient1+2] == " Key algorithm: 1024-bit RSA" @@ -190,3 +200,8 @@ def test_status_on_initialised_directory(tmpdir, ca_key_specification, default_k assert stdout_lines[index_myclient3+2] == " Key algorithm: 2048-bit RSA" assert stdout_lines[index_myclient3+3] == " CSR: .gimmecert/client/myclient3.csr.pem" assert stdout_lines[index_myclient3+4] == " Certificate: .gimmecert/client/myclient3.cert.pem" + + assert stdout_lines[index_myclient4+1].startswith(" Validity: ") + assert stdout_lines[index_myclient4+2] == " Key algorithm: secp192r1 ECDSA" + assert stdout_lines[index_myclient4+3] == " Private key: .gimmecert/client/myclient4.key.pem" + assert stdout_lines[index_myclient4+4] == " Certificate: .gimmecert/client/myclient4.cert.pem" diff --git a/gimmecert/commands.py b/gimmecert/commands.py index 9770551493651c2aef359fa9874f47631f334a61..0552af03051a193b1af84eec588002f44ff8cfb3 100644 --- a/gimmecert/commands.py +++ b/gimmecert/commands.py @@ -542,7 +542,8 @@ def status(stdout, stderr, project_directory): ca_hierarchy = gimmecert.storage.read_ca_hierarchy(os.path.join(project_directory, '.gimmecert', 'ca')) # Derive key specification from the issuing CA certificate. - key_algorithm = gimmecert.crypto.KeyGenerator('rsa', ca_hierarchy[-1][1].public_key().key_size) + key_specification = gimmecert.crypto.key_specification_from_public_key(ca_hierarchy[-1][1].public_key()) + key_algorithm = gimmecert.crypto.KeyGenerator(key_specification[0], key_specification[1]) print("", file=stdout) # Separator print("Default key algorithm: %s" % key_algorithm, file=stdout) @@ -584,7 +585,7 @@ def status(stdout, stderr, project_directory): certificate = gimmecert.storage.read_certificate(os.path.join(project_directory, '.gimmecert', 'server', certificate_file)) private_key_path = os.path.join(project_directory, '.gimmecert', 'server', certificate_file.replace('.cert.pem', '.key.pem')) csr_path = os.path.join(project_directory, '.gimmecert', 'server', certificate_file.replace('.cert.pem', '.csr.pem')) - key_algorithm = str(gimmecert.crypto.KeyGenerator("rsa", certificate.public_key().key_size)) + key_algorithm = str(gimmecert.crypto.KeyGenerator(*gimmecert.crypto.key_specification_from_public_key(certificate.public_key()))) # Separator. print("", file=stdout) @@ -626,7 +627,7 @@ def status(stdout, stderr, project_directory): certificate = gimmecert.storage.read_certificate(os.path.join(project_directory, '.gimmecert', 'client', certificate_file)) private_key_path = os.path.join(project_directory, '.gimmecert', 'client', certificate_file.replace('.cert.pem', '.key.pem')) csr_path = os.path.join(project_directory, '.gimmecert', 'client', certificate_file.replace('.cert.pem', '.csr.pem')) - key_algorithm = str(gimmecert.crypto.KeyGenerator("rsa", certificate.public_key().key_size)) + key_algorithm = str(gimmecert.crypto.KeyGenerator(*gimmecert.crypto.key_specification_from_public_key(certificate.public_key()))) # Separator. print("", file=stdout) diff --git a/tests/test_commands.py b/tests/test_commands.py index 78f24aff469d0647da8f225ba69e1806d86bfb26..d656a5ab951a87871165538bd55f914446ad333c 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -24,6 +24,7 @@ import os import sys import cryptography.x509 +from cryptography.hazmat.primitives.asymmetric import ec import gimmecert.commands import gimmecert.crypto @@ -631,6 +632,7 @@ def test_status_reports_uninitialised_directory(tmpdir): @pytest.mark.parametrize('ca_key_specification,ca_key_representation', [ (('rsa', 1024), '1024-bit RSA'), (('rsa', 2048), '2048-bit RSA'), + (('ecdsa', ec.SECP521R1), 'secp521r1 ECDSA'), ]) def test_status_reports_ca_hierarchy_information(tmpdir, ca_key_specification, ca_key_representation): stdout_stream = io.StringIO() @@ -698,6 +700,9 @@ def test_status_reports_server_certificate_information(tmpdir): with freeze_time('2018-04-01 00:15:00'): gimmecert.commands.server(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myserver3', None, myserver3_csr_file.strpath, None) + with freeze_time('2018-05-01 00:15:00'): + gimmecert.commands.server(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myserver4', None, None, ("ecdsa", ec.SECP256R1)) + with freeze_time('2018-06-01 00:15:00'): status_code = gimmecert.commands.status(stdout_stream, stderr_stream, tmpdir.strpath) @@ -713,6 +718,7 @@ def test_status_reports_server_certificate_information(tmpdir): index_myserver1 = stdout_lines.index("CN=myserver1") # Should not raise index_myserver2 = stdout_lines.index("CN=myserver2") # Should not raise index_myserver3 = stdout_lines.index("CN=myserver3") # Should not raise + index_myserver4 = stdout_lines.index("CN=myserver4") # Should not raise myserver1_validity = stdout_lines[index_myserver1 + 1] myserver1_dns = stdout_lines[index_myserver1 + 2] @@ -732,6 +738,12 @@ def test_status_reports_server_certificate_information(tmpdir): myserver3_csr_path = stdout_lines[index_myserver3 + 4] myserver3_certificate_path = stdout_lines[index_myserver3 + 5] + myserver4_validity = stdout_lines[index_myserver4 + 1] + myserver4_dns = stdout_lines[index_myserver4 + 2] + myserver4_key_algorithm = stdout_lines[index_myserver4 + 3] + myserver4_private_key_path = stdout_lines[index_myserver4 + 4] + myserver4_certificate_path = stdout_lines[index_myserver4 + 5] + assert myserver1_validity == " Validity: 2018-02-01 00:00:00 UTC - 2019-01-01 00:15:00 UTC" assert myserver1_dns == " DNS: myserver1" assert myserver1_key_algorithm == " Key algorithm: 1024-bit RSA" @@ -750,6 +762,12 @@ def test_status_reports_server_certificate_information(tmpdir): assert myserver3_csr_path == " CSR: .gimmecert/server/myserver3.csr.pem" assert myserver3_certificate_path == " Certificate: .gimmecert/server/myserver3.cert.pem" + assert myserver4_validity == " Validity: 2018-05-01 00:00:00 UTC - 2019-01-01 00:15:00 UTC" + assert myserver4_dns == " DNS: myserver4" + assert myserver4_key_algorithm == " Key algorithm: secp256r1 ECDSA" + assert myserver4_private_key_path == " Private key: .gimmecert/server/myserver4.key.pem" + assert myserver4_certificate_path == " Certificate: .gimmecert/server/myserver4.cert.pem" + def test_status_reports_client_certificate_information(tmpdir): stdout_stream = io.StringIO() @@ -772,6 +790,9 @@ def test_status_reports_client_certificate_information(tmpdir): with freeze_time('2018-04-01 00:15:00'): gimmecert.commands.client(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myclient3', myclient3_csr_file.strpath, None) + with freeze_time('2018-05-01 00:15:00'): + gimmecert.commands.client(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myclient4', None, ("ecdsa", ec.SECP384R1)) + with freeze_time('2018-06-01 00:15:00'): status_code = gimmecert.commands.status(stdout_stream, stderr_stream, tmpdir.strpath) @@ -787,6 +808,7 @@ def test_status_reports_client_certificate_information(tmpdir): index_myclient1 = stdout_lines.index("CN=myclient1") # Should not raise index_myclient2 = stdout_lines.index("CN=myclient2") # Should not raise index_myclient3 = stdout_lines.index("CN=myclient3") # Should not raise + index_myclient4 = stdout_lines.index("CN=myclient4") # Should not raise myclient1_validity = stdout_lines[index_myclient1 + 1] myclient1_key_algorithm = stdout_lines[index_myclient1 + 2] @@ -803,6 +825,11 @@ def test_status_reports_client_certificate_information(tmpdir): myclient3_csr_path = stdout_lines[index_myclient3 + 3] myclient3_certificate_path = stdout_lines[index_myclient3 + 4] + myclient4_validity = stdout_lines[index_myclient4 + 1] + myclient4_key_algorithm = stdout_lines[index_myclient4 + 2] + myclient4_private_key_path = stdout_lines[index_myclient4 + 3] + myclient4_certificate_path = stdout_lines[index_myclient4 + 4] + assert myclient1_validity == " Validity: 2018-02-01 00:00:00 UTC - 2019-01-01 00:15:00 UTC" assert myclient1_key_algorithm == " Key algorithm: 1024-bit RSA" assert myclient1_private_key_path == " Private key: .gimmecert/client/myclient1.key.pem" @@ -818,6 +845,11 @@ def test_status_reports_client_certificate_information(tmpdir): assert myclient3_csr_path == " CSR: .gimmecert/client/myclient3.csr.pem" assert myclient3_certificate_path == " Certificate: .gimmecert/client/myclient3.cert.pem" + assert myclient4_validity == " Validity: 2018-05-01 00:00:00 UTC - 2019-01-01 00:15:00 UTC" + assert myclient4_key_algorithm == " Key algorithm: secp384r1 ECDSA" + assert myclient4_private_key_path == " Private key: .gimmecert/client/myclient4.key.pem" + assert myclient4_certificate_path == " Certificate: .gimmecert/client/myclient4.cert.pem" + def test_status_reports_no_server_certificates_were_issued(tmpdir): stdout_stream = io.StringIO()