Changeset - 92e93e67b2b6
[Not reviewed]
0 3 0
Branko Majic (branko) - 4 years ago 2020-07-08 23:53:44
branko@majic.rs
GC-37: Update status command to include relevant/correct information about ECDSA algorithms:

- Updated functional test to include case where CA hierarchy has been
initialised with the ECDSA keys.
- Updated unit tests to include testing of output for entities that
use ECDSA keys.
- Use the key_specification_from_public_key function to obtain
information about key in use (instead of assuming it's RSA).
3 files changed with 51 insertions and 3 deletions:
0 comments (0 inline, 0 general)
functional_tests/test_status.py
Show inline comments
 
@@ -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"
gimmecert/commands.py
Show inline comments
 
@@ -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)
tests/test_commands.py
Show inline comments
 
@@ -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()
0 comments (0 inline, 0 general)