Changeset - ae6e41dde81c
[Not reviewed]
0 5 0
Branko Majic (branko) - 6 years ago 2018-04-14 00:05:27
branko@majic.rs
GC-22: Updated renew command to replace existing private key with CSR if passed-in:

- Added functional test which covers renewal of server and client
certificates using CSR when previous certificate was issued using
private key.
- Replaced the private key with CSR when renewing certificate using
CSR in case where previous certificate was issued with private key.
- Updated signature for renew command to accept path to custom CSR.
- Updated existing unit tests for new renew command signature.
- Added unit tests covering new functionality.
5 files changed with 227 insertions and 21 deletions:
0 comments (0 inline, 0 general)
functional_tests/test_csr.py
Show inline comments
 
@@ -211,3 +211,107 @@ def test_renew_certificate_originally_issued_with_csr(tmpdir):
 
    assert client_new_stored_csr == client_old_stored_csr
 
    assert client_new_certificate != client_old_certificate
 
    assert client_csr_public_key == client_certificate_public_key
 

	
 

	
 
def test_renew_certificate_originally_issued_with_private_key_using_csr(tmpdir):
 
    # John has an existing project where he has generated a server and
 
    # client private key with corresponding CSR.
 
    tmpdir.chdir()
 
    run_command("openssl", "req", "-new", "-newkey", "rsa:2048", "-nodes", "-keyout", "myserver.key.pem",
 
                "-subj", "/CN=myserver", "-out", "mycustomserver.csr.pem")
 
    run_command("openssl", "req", "-new", "-newkey", "rsa:2048", "-nodes", "-keyout", "myclient.key.pem",
 
                "-subj", "/CN=myclient", "-out", "mycustomclient.csr.pem")
 

	
 
    # He wants to grab some certificates for those, so he goes ahead
 
    # and initialised the CA hierarchy.
 
    tmpdir.chdir()
 
    run_command("gimmecert", "init")
 

	
 
    # He proceeds to issue a server and client certificate.
 
    run_command("gimmecert", "server", "myserver")
 
    run_command("gimmecert", "client", "myclient")
 

	
 
    # Very quickly John realises that he has mistakenly forgotten to
 
    # pass-in the relevant CSRs, and that Gimmecert has generated
 
    # private keys locally and issued certificates for them.
 
    assert tmpdir.join('.gimmecert', 'server', 'myserver.key.pem').check(file=1)
 
    assert not tmpdir.join('.gimmecert', 'server', 'myserver.csr.pem').check(file=1)
 
    assert tmpdir.join('.gimmecert', 'client', 'myclient.key.pem').check(file=1)
 
    assert not tmpdir.join('.gimmecert', 'client', 'myclient.csr.pem').check(file=1)
 

	
 
    # John has a look at generated artefacts.
 
    server_old_certificate = tmpdir.join(".gimmecert", "server", "myserver.cert.pem").read()
 
    server_old_certificate_public_key, _, _ = run_command("openssl", "x509", "-noout", "-pubkey", "-in", ".gimmecert/server/myserver.cert.pem")
 

	
 
    client_old_certificate = tmpdir.join(".gimmecert", "client", "myclient.cert.pem").read()
 
    client_old_certificate_public_key, _, _ = run_command("openssl", "x509", "-noout", "-pubkey", "-in", ".gimmecert/client/myclient.cert.pem")
 

	
 
    # He also has a look at the CSRs he generated for both server and
 
    # client.
 
    server_csr_public_key, _, _ = run_command("openssl", "req", "-noout", "-pubkey", "-in", "mycustomserver.csr.pem")
 
    server_csr = tmpdir.join("mycustomserver.csr.pem").read()
 

	
 
    client_csr_public_key, _, _ = run_command("openssl", "req", "-noout", "-pubkey", "-in", "mycustomclient.csr.pem")
 
    client_csr = tmpdir.join("mycustomclient.csr.pem").read()
 

	
 
    # He goes ahead and renews the server certificate first,
 
    # passing-in the CSR this time around.
 
    stdout, stderr, exit_code = run_command("gimmecert", "renew", "--csr", "mycustomserver.csr.pem", "server", "myserver")
 

	
 
    # No errors are shown, and John is informed about generated
 
    # artefacts, and that the private key has been removed and
 
    # replaced with the CSR.
 
    assert exit_code == 0
 
    assert stderr == ""
 
    assert "Renewed certificate for server myserver." in stdout
 
    assert "Private key used for issuance of previous certificate has been removed, and replaced with the passed-in CSR." in stdout
 
    assert ".gimmecert/server/myserver.csr.pem" in stdout
 
    assert ".gimmecert/server/myserver.cert.pem" in stdout
 
    assert ".gimmecert/server/myserver.key.pem" not in stdout
 

	
 
    # John has a look at generated artefacts.
 
    server_stored_csr = tmpdir.join(".gimmecert", "server", "myserver.csr.pem").read()
 
    server_stored_csr_public_key, _, _ = run_command("openssl", "req", "-noout", "-pubkey", "-in", ".gimmecert/server/myserver.csr.pem")
 

	
 
    server_new_certificate = tmpdir.join(".gimmecert", "server", "myserver.cert.pem").read()
 
    server_new_certificate_public_key, _, _ = run_command("openssl", "x509", "-noout", "-pubkey", "-in", ".gimmecert/server/myserver.cert.pem")
 

	
 
    # John notices that, for start, the private key has indeed been
 
    # removed from the filesystem, that the content of the certificate
 
    # has changed, that the passed-in CSR has been stored, and that
 
    # public key from the certificate matches the public key in CSR.
 
    assert not tmpdir.join(".gimmecert", "server", "myserver.key.pem").check()
 
    assert server_new_certificate != server_old_certificate
 
    assert server_stored_csr == server_csr
 
    assert server_new_certificate_public_key == server_csr_public_key
 

	
 
    # John renews the client certificate afterwards, passing-in the
 
    # CSR this time around.
 
    stdout, stderr, exit_code = run_command("gimmecert", "renew", "--csr", "mycustomclient.csr.pem", "client", "myclient")
 

	
 
    # No errors are shown, and John is informed about generated
 
    # artefacts, and that the private key has been removed and
 
    # replaced with the CSR.
 
    assert exit_code == 0
 
    assert stderr == ""
 
    assert "Renewed certificate for client myclient." in stdout
 
    assert "Private key used for issuance of previous certificate has been removed, and replaced with the passed-in CSR." in stdout
 
    assert ".gimmecert/client/myclient.csr.pem" in stdout
 
    assert ".gimmecert/client/myclient.cert.pem" in stdout
 
    assert ".gimmecert/client/myclient.key.pem" not in stdout
 

	
 
    # John has a look at generated artefacts.
 
    client_stored_csr = tmpdir.join(".gimmecert", "client", "myclient.csr.pem").read()
 
    client_stored_csr_public_key, _, _ = run_command("openssl", "req", "-noout", "-pubkey", "-in", ".gimmecert/client/myclient.csr.pem")
 

	
 
    client_new_certificate = tmpdir.join(".gimmecert", "client", "myclient.cert.pem").read()
 
    client_new_certificate_public_key, _, _ = run_command("openssl", "x509", "-noout", "-pubkey", "-in", ".gimmecert/client/myclient.cert.pem")
 

	
 
    # John notices that, for start, the private key has indeed been
 
    # removed from the filesystem, that the content of the certificate
 
    # has changed, that the passed-in CSR has been stored, and that
 
    # public key from the certificate matches the public key in CSR.
 
    assert not tmpdir.join(".gimmecert", "client", "myclient.key.pem").check()
 
    assert client_new_certificate != client_old_certificate
 
    assert client_stored_csr == client_csr
 
    assert client_new_certificate_public_key == client_csr_public_key
gimmecert/cli.py
Show inline comments
 
@@ -148,14 +148,14 @@ def setup_renew_subcommand_parser(parser, subparsers):
 

	
 
    new_private_key_or_csr_group.add_argument('--new-private-key', '-p', action='store_true', help='''Generate new private key for renewal. \
 
    Default is to keep the existing key. Mutually exclusive with the --csr option.''')
 
    new_private_key_or_csr_group.add_argument('--csr', '-c', type=str, help='''Do not use local private key and public key information from \
 
    new_private_key_or_csr_group.add_argument('--csr', '-c', type=str, default=None, help='''Do not use local private key and public key information from \
 
    existing certificate, and use the passed-in certificate signing request (CSR) instead. If private key exists, it will be removed. \
 
    Mutually exclusive with the --new-private-key option.''')
 

	
 
    def renew_wrapper(args):
 
        project_directory = os.getcwd()
 

	
 
        return renew(sys.stdout, sys.stderr, project_directory, args.entity_type, args.entity_name, args.new_private_key)
 
        return renew(sys.stdout, sys.stderr, project_directory, args.entity_type, args.entity_name, args.new_private_key, args.csr)
 

	
 
    subparser.set_defaults(func=renew_wrapper)
 

	
gimmecert/commands.py
Show inline comments
 
@@ -340,7 +340,7 @@ def client(stdout, stderr, project_directory, entity_name, custom_csr_path):
 
    return ExitCode.SUCCESS
 

	
 

	
 
def renew(stdout, stderr, project_directory, entity_type, entity_name, generate_new_private_key):
 
def renew(stdout, stderr, project_directory, entity_type, entity_name, generate_new_private_key, custom_csr_path):
 
    """
 
    Renews existing certificate, while optionally generating a new
 
    private key in the process. Naming and extensions are preserved.
 
@@ -363,6 +363,9 @@ def renew(stdout, stderr, project_directory, entity_type, entity_name, generate_
 
    :param generate_new_private_key: Specify if a new private key should be generated, or an existing one should be used instead.
 
    :type generate_new_private_key: bool
 

	
 
    :param custom_csr_path: Path to custom certificate signing request to use for issuing client certificate. Set to None or "" to generate private key.
 
    :type custom_csr_path: str or None
 

	
 
    :returns: Status code, one from gimmecert.commands.ExitCode.
 
    :rtype: int
 
    """
 
@@ -398,6 +401,10 @@ def renew(stdout, stderr, project_directory, entity_type, entity_name, generate_
 
        private_key = gimmecert.crypto.generate_private_key()
 
        gimmecert.storage.write_private_key(private_key, private_key_path)
 
        public_key = private_key.public_key()
 
    elif custom_csr_path:
 
        csr = gimmecert.storage.read_csr(custom_csr_path)
 
        gimmecert.storage.write_csr(csr, csr_path)
 
        public_key = csr.public_key()
 
    else:
 
        public_key = old_certificate.public_key()
 

	
 
@@ -405,6 +412,13 @@ def renew(stdout, stderr, project_directory, entity_type, entity_name, generate_
 
    certificate = gimmecert.crypto.renew_certificate(old_certificate, public_key, issuer_private_key, issuer_certificate)
 
    gimmecert.storage.write_certificate(certificate, certificate_path)
 

	
 
    # Replace private key with CSR.
 
    if custom_csr_path and os.path.exists(private_key_path):
 
        os.remove(private_key_path)
 
        private_key_replaced_with_csr = True
 
    else:
 
        private_key_replaced_with_csr = False
 

	
 
    # Type of artefacts reported depending on whether the private key
 
    # or CSR are present.
 
    if generate_new_private_key:
 
@@ -412,6 +426,9 @@ def renew(stdout, stderr, project_directory, entity_type, entity_name, generate_
 
    else:
 
        print("Renewed certificate for %s %s.\n" % (entity_type, entity_name), file=stdout)
 

	
 
    if private_key_replaced_with_csr:
 
        print("Private key used for issuance of previous certificate has been removed, and replaced with the passed-in CSR.", file=stdout)
 

	
 
    # Output information about private key or CSR path.
 
    if os.path.exists(csr_path):
 
        print("{entity_type_titled} CSR: .gimmecert/{entity_type}/{entity_name}.csr.pem"
tests/test_cli.py
Show inline comments
 
@@ -535,7 +535,7 @@ def test_renew_command_invoked_with_correct_parameters_for_server(mock_renew, tm
 

	
 
    gimmecert.cli.main()
 

	
 
    mock_renew.assert_called_once_with(sys.stdout, sys.stderr, tmpdir.strpath, 'server', 'myserver', False)
 
    mock_renew.assert_called_once_with(sys.stdout, sys.stderr, tmpdir.strpath, 'server', 'myserver', False, None)
 

	
 

	
 
@mock.patch('sys.argv', ['gimmecert', 'renew', 'client', 'myclient'])
 
@@ -549,7 +549,7 @@ def test_renew_command_invoked_with_correct_parameters_for_client(mock_renew, tm
 

	
 
    gimmecert.cli.main()
 

	
 
    mock_renew.assert_called_once_with(sys.stdout, sys.stderr, tmpdir.strpath, 'client', 'myclient', False)
 
    mock_renew.assert_called_once_with(sys.stdout, sys.stderr, tmpdir.strpath, 'client', 'myclient', False, None)
 

	
 

	
 
@mock.patch('sys.argv', ['gimmecert', 'renew', '--new-private-key', 'server', 'myserver'])
 
@@ -563,7 +563,7 @@ def test_renew_command_invoked_with_correct_parameters_for_server_with_new_priva
 

	
 
    gimmecert.cli.main()
 

	
 
    mock_renew.assert_called_once_with(sys.stdout, sys.stderr, tmpdir.strpath, 'server', 'myserver', True)
 
    mock_renew.assert_called_once_with(sys.stdout, sys.stderr, tmpdir.strpath, 'server', 'myserver', True, None)
 

	
 

	
 
@mock.patch('sys.argv', ['gimmecert', 'renew', '--new-private-key', 'client', 'myclient'])
 
@@ -577,7 +577,35 @@ def test_renew_command_invoked_with_correct_parameters_for_client_with_new_priva
 

	
 
    gimmecert.cli.main()
 

	
 
    mock_renew.assert_called_once_with(sys.stdout, sys.stderr, tmpdir.strpath, 'client', 'myclient', True)
 
    mock_renew.assert_called_once_with(sys.stdout, sys.stderr, tmpdir.strpath, 'client', 'myclient', True, None)
 

	
 

	
 
@mock.patch('sys.argv', ['gimmecert', 'renew', '--csr', 'mycustom.csr.pem', 'server', 'myserver'])
 
@mock.patch('gimmecert.cli.renew')
 
def test_renew_command_invoked_with_correct_parameters_for_server_with_csr_option(mock_renew, tmpdir):
 
    # This should ensure we don't accidentally create artifacts
 
    # outside of test directory.
 
    tmpdir.chdir()
 

	
 
    mock_renew.return_value = gimmecert.commands.ExitCode.SUCCESS
 

	
 
    gimmecert.cli.main()
 

	
 
    mock_renew.assert_called_once_with(sys.stdout, sys.stderr, tmpdir.strpath, 'server', 'myserver', False, 'mycustom.csr.pem')
 

	
 

	
 
@mock.patch('sys.argv', ['gimmecert', 'renew', '--csr', 'mycustom.csr.pem', 'client', 'myclient'])
 
@mock.patch('gimmecert.cli.renew')
 
def test_renew_command_invoked_with_correct_parameters_for_client_with_csr_option(mock_renew, tmpdir):
 
    # This should ensure we don't accidentally create artifacts
 
    # outside of test directory.
 
    tmpdir.chdir()
 

	
 
    mock_renew.return_value = gimmecert.commands.ExitCode.SUCCESS
 

	
 
    gimmecert.cli.main()
 

	
 
    mock_renew.assert_called_once_with(sys.stdout, sys.stderr, tmpdir.strpath, 'client', 'myclient', False, 'mycustom.csr.pem')
 

	
 

	
 
@mock.patch('sys.argv', ['gimmecert', 'status'])
tests/test_commands.py
Show inline comments
 
@@ -480,7 +480,7 @@ def test_server_reports_success_if_certificate_not_already_issued_but_update_was
 
def test_renew_returns_status_code(tmpdir):
 
    tmpdir.chdir()
 

	
 
    status_code = gimmecert.commands.renew(io.StringIO(), io.StringIO(), tmpdir.strpath, 'server', 'myserver', False)
 
    status_code = gimmecert.commands.renew(io.StringIO(), io.StringIO(), tmpdir.strpath, 'server', 'myserver', False, None)
 

	
 
    assert isinstance(status_code, int)
 

	
 
@@ -490,7 +490,7 @@ def test_renew_reports_error_if_directory_is_not_initialised(tmpdir):
 
    stdout_stream = io.StringIO()
 
    stderr_stream = io.StringIO()
 

	
 
    status_code = gimmecert.commands.renew(stdout_stream, stderr_stream, tmpdir.strpath, 'server', 'myserver', False)
 
    status_code = gimmecert.commands.renew(stdout_stream, stderr_stream, tmpdir.strpath, 'server', 'myserver', False, None)
 

	
 
    stdout = stdout_stream.getvalue()
 
    stderr = stderr_stream.getvalue()
 
@@ -507,7 +507,7 @@ def test_renew_reports_error_if_no_existing_server_certificate_is_present(tmpdir
 
    stdout_stream = io.StringIO()
 
    stderr_stream = io.StringIO()
 

	
 
    status_code = gimmecert.commands.renew(stdout_stream, stderr_stream, tmpdir.strpath, 'server', 'myserver', False)
 
    status_code = gimmecert.commands.renew(stdout_stream, stderr_stream, tmpdir.strpath, 'server', 'myserver', False, None)
 

	
 
    stdout = stdout_stream.getvalue()
 
    stderr = stderr_stream.getvalue()
 
@@ -525,7 +525,7 @@ def test_renew_reports_error_if_no_existing_client_certificate_is_present(tmpdir
 
    stdout_stream = io.StringIO()
 
    stderr_stream = io.StringIO()
 

	
 
    status_code = gimmecert.commands.renew(stdout_stream, stderr_stream, tmpdir.strpath, 'client', 'myclient', False)
 
    status_code = gimmecert.commands.renew(stdout_stream, stderr_stream, tmpdir.strpath, 'client', 'myclient', False, None)
 

	
 
    stdout = stdout_stream.getvalue()
 
    stderr = stderr_stream.getvalue()
 
@@ -545,7 +545,7 @@ def test_renew_reports_success_and_paths_to_server_artifacts(tmpdir):
 
    gimmecert.commands.init(io.StringIO(), io.StringIO(), tmpdir.strpath, tmpdir.basename, depth)
 
    gimmecert.commands.server(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myserver', None, False, None)
 

	
 
    status_code = gimmecert.commands.renew(stdout_stream, stderr_stream, tmpdir.strpath, 'server', 'myserver', False)
 
    status_code = gimmecert.commands.renew(stdout_stream, stderr_stream, tmpdir.strpath, 'server', 'myserver', False, None)
 

	
 
    stdout = stdout_stream.getvalue()
 
    stderr = stderr_stream.getvalue()
 
@@ -567,7 +567,7 @@ def test_renew_reports_success_and_paths_to_client_artifacts(tmpdir):
 
    gimmecert.commands.init(io.StringIO(), io.StringIO(), tmpdir.strpath, tmpdir.basename, depth)
 
    gimmecert.commands.client(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myclient', None)
 

	
 
    status_code = gimmecert.commands.renew(stdout_stream, stderr_stream, tmpdir.strpath, 'client', 'myclient', False)
 
    status_code = gimmecert.commands.renew(stdout_stream, stderr_stream, tmpdir.strpath, 'client', 'myclient', False, None)
 

	
 
    stdout = stdout_stream.getvalue()
 
    stderr = stderr_stream.getvalue()
 
@@ -589,7 +589,7 @@ def test_renew_keeps_server_private_key(tmpdir):
 
    gimmecert.commands.server(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myserver', None, False, None)
 
    private_key_after_issuance = private_key_file.read()
 

	
 
    gimmecert.commands.renew(io.StringIO(), io.StringIO(), tmpdir.strpath, 'server', 'myserver', False)
 
    gimmecert.commands.renew(io.StringIO(), io.StringIO(), tmpdir.strpath, 'server', 'myserver', False, None)
 
    private_key_after_renewal = private_key_file.read()
 

	
 
    assert private_key_after_issuance == private_key_after_renewal
 
@@ -604,7 +604,7 @@ def test_renew_keeps_client_private_key(tmpdir):
 
    gimmecert.commands.client(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myclient', None)
 
    private_key_after_issuance = private_key_file.read()
 

	
 
    gimmecert.commands.renew(io.StringIO(), io.StringIO(), tmpdir.strpath, 'client', 'myclient', False)
 
    gimmecert.commands.renew(io.StringIO(), io.StringIO(), tmpdir.strpath, 'client', 'myclient', False, None)
 
    private_key_after_renewal = private_key_file.read()
 

	
 
    assert private_key_after_issuance == private_key_after_renewal
 
@@ -619,7 +619,7 @@ def test_renew_replaces_server_certificate(tmpdir):
 
    gimmecert.commands.server(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myserver', None, False, None)
 
    certificate_after_issuance = certificate_file.read()
 

	
 
    gimmecert.commands.renew(io.StringIO(), io.StringIO(), tmpdir.strpath, 'server', 'myserver', False)
 
    gimmecert.commands.renew(io.StringIO(), io.StringIO(), tmpdir.strpath, 'server', 'myserver', False, None)
 
    certificate_after_renewal = certificate_file.read()
 

	
 
    assert certificate_after_issuance != certificate_after_renewal
 
@@ -636,7 +636,7 @@ def test_renew_replaces_client_certificate(tmpdir):
 
    gimmecert.commands.client(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myclient', None)
 
    certificate_after_issuance = certificate_file.read()
 

	
 
    gimmecert.commands.renew(io.StringIO(), io.StringIO(), tmpdir.strpath, 'client', 'myclient', False)
 
    gimmecert.commands.renew(io.StringIO(), io.StringIO(), tmpdir.strpath, 'client', 'myclient', False, None)
 
    certificate_after_renewal = certificate_file.read()
 

	
 
    assert certificate_after_issuance != certificate_after_renewal
 
@@ -653,7 +653,7 @@ def test_renew_reports_success_and_paths_to_server_artifacts_with_new_key(tmpdir
 
    gimmecert.commands.init(io.StringIO(), io.StringIO(), tmpdir.strpath, tmpdir.basename, depth)
 
    gimmecert.commands.server(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myserver', None, False, None)
 

	
 
    status_code = gimmecert.commands.renew(stdout_stream, stderr_stream, tmpdir.strpath, 'server', 'myserver', True)
 
    status_code = gimmecert.commands.renew(stdout_stream, stderr_stream, tmpdir.strpath, 'server', 'myserver', True, None)
 

	
 
    stdout = stdout_stream.getvalue()
 
    stderr = stderr_stream.getvalue()
 
@@ -674,7 +674,7 @@ def test_renew_generates_new_private_key_if_requested(tmpdir):
 
    gimmecert.commands.server(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myserver', None, False, None)
 
    private_key_after_issuance = private_key_file.read()
 

	
 
    gimmecert.commands.renew(io.StringIO(), io.StringIO(), tmpdir.strpath, 'server', 'myserver', True)
 
    gimmecert.commands.renew(io.StringIO(), io.StringIO(), tmpdir.strpath, 'server', 'myserver', True, None)
 
    private_key_after_renewal = private_key_file.read()
 

	
 
    assert private_key_after_issuance != private_key_after_renewal
 
@@ -1238,7 +1238,7 @@ def test_renew_reports_success_and_paths_to_server_artifacts_with_csr(tmpdir):
 
    gimmecert.commands.init(io.StringIO(), io.StringIO(), tmpdir.strpath, tmpdir.basename, depth)
 
    gimmecert.commands.server(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myserver', None, False, csr_file.strpath)
 

	
 
    status_code = gimmecert.commands.renew(stdout_stream, stderr_stream, tmpdir.strpath, 'server', 'myserver', False)
 
    status_code = gimmecert.commands.renew(stdout_stream, stderr_stream, tmpdir.strpath, 'server', 'myserver', False, None)
 

	
 
    stdout = stdout_stream.getvalue()
 
    stderr = stderr_stream.getvalue()
 
@@ -1266,7 +1266,7 @@ def test_renew_reports_success_and_paths_to_client_artifacts_with_csr(tmpdir):
 
    gimmecert.commands.init(io.StringIO(), io.StringIO(), tmpdir.strpath, tmpdir.basename, depth)
 
    gimmecert.commands.client(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myclient', csr_file.strpath)
 

	
 
    status_code = gimmecert.commands.renew(stdout_stream, stderr_stream, tmpdir.strpath, 'client', 'myclient', False)
 
    status_code = gimmecert.commands.renew(stdout_stream, stderr_stream, tmpdir.strpath, 'client', 'myclient', False, None)
 

	
 
    stdout = stdout_stream.getvalue()
 
    stderr = stderr_stream.getvalue()
 
@@ -1277,3 +1277,60 @@ def test_renew_reports_success_and_paths_to_client_artifacts_with_csr(tmpdir):
 
    assert ".gimmecert/client/myclient.cert.pem" in stdout
 
    assert ".gimmecert/client/myclient.key.pem" not in stdout
 
    assert stderr == ""
 

	
 

	
 
def test_renew_reports_success_and_paths_to_server_artifacts_with_csr_when_replacing_private_key(tmpdir):
 
    depth = 1
 

	
 
    csr_file = tmpdir.join("mycustom.csr.pem")
 

	
 
    stdout_stream = io.StringIO()
 
    stderr_stream = io.StringIO()
 

	
 
    private_key = gimmecert.crypto.generate_private_key()
 
    csr = gimmecert.crypto.generate_csr("mytest", private_key)
 
    gimmecert.storage.write_csr(csr, csr_file.strpath)
 

	
 
    gimmecert.commands.init(io.StringIO(), io.StringIO(), tmpdir.strpath, tmpdir.basename, depth)
 
    gimmecert.commands.server(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myserver', None, False, None)
 

	
 
    status_code = gimmecert.commands.renew(stdout_stream, stderr_stream, tmpdir.strpath, 'server', 'myserver', False, csr_file.strpath)
 

	
 
    stdout = stdout_stream.getvalue()
 
    stderr = stderr_stream.getvalue()
 

	
 
    assert status_code == gimmecert.commands.ExitCode.SUCCESS
 
    assert "Renewed certificate for server myserver." in stdout
 
    assert "removed" in stdout
 
    assert "replaced" in stdout
 
    assert ".gimmecert/server/myserver.csr.pem" in stdout
 
    assert ".gimmecert/server/myserver.cert.pem" in stdout
 
    assert ".gimmecert/server/myserver.key.pem" not in stdout
 
    assert stderr == ""
 

	
 

	
 
def test_renew_replaces_server_private_key_with_csr(tmpdir):
 
    depth = 1
 

	
 
    custom_csr_file = tmpdir.join("mycustom.csr.pem")
 
    csr_file = tmpdir.join(".gimmecert", "server", "myserver.csr.pem")
 
    private_key_file = tmpdir.join(".gimmecert", "server", "myserver.key.pem")
 

	
 
    custom_csr_private_key = gimmecert.crypto.generate_private_key()
 
    custom_csr = gimmecert.crypto.generate_csr("mycustom", custom_csr_private_key)
 
    gimmecert.storage.write_csr(custom_csr, custom_csr_file.strpath)
 
    custom_csr_file_content = custom_csr_file.read()
 

	
 
    gimmecert.commands.init(io.StringIO(), io.StringIO(), tmpdir.strpath, tmpdir.basename, depth)
 
    gimmecert.commands.server(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myserver', None, False, None)
 

	
 
    assert private_key_file.check(file=1)
 

	
 
    gimmecert.commands.renew(io.StringIO(), io.StringIO(), tmpdir.strpath, 'server', 'myserver', False, custom_csr_file.strpath)
 

	
 
    assert csr_file.check(file=1)
 

	
 
    csr_file_content = csr_file.read()
 

	
 
    assert csr_file_content == custom_csr_file_content
 
    assert not private_key_file.check()
0 comments (0 inline, 0 general)