Files
@ 61cbaabb84d2
Branch filter:
Location: gimmecert/tests/test_storage.py
61cbaabb84d2
9.0 KiB
text/x-python
GC-37: Updated documentation to cover key specification options.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | # -*- coding: utf-8 -*-
#
# Copyright (C) 2018 Branko Majic
#
# This file is part of Gimmecert.
#
# Gimmecert is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Gimmecert is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# Gimmecert. If not, see <http://www.gnu.org/licenses/>.
#
import os
import io
import cryptography
import gimmecert.commands
import gimmecert.crypto
import gimmecert.storage
import gimmecert.utils
import pytest
def test_initialise_storage(tmpdir):
tmpdir.chdir()
gimmecert.storage.initialise_storage(tmpdir.strpath)
assert os.path.exists(tmpdir.join('.gimmecert').strpath)
assert os.path.exists(tmpdir.join('.gimmecert', 'ca').strpath)
assert os.path.exists(tmpdir.join('.gimmecert', 'server').strpath)
assert os.path.exists(tmpdir.join('.gimmecert', 'client').strpath)
@pytest.mark.parametrize("key_specification, key_type_representation", [
[("rsa", 2048), "RSA"],
[("ecdsa", cryptography.hazmat.primitives.asymmetric.ec.SECP192R1), "EC"],
])
def test_write_private_key(tmpdir, key_specification, key_type_representation):
tmpdir.chdir()
private_key = gimmecert.crypto.KeyGenerator(*key_specification)()
key_path = tmpdir.join('test.key.pem').strpath
gimmecert.storage.write_private_key(private_key, key_path)
assert os.path.exists(key_path)
with open(key_path, 'r') as key_file:
content = key_file.read()
assert 'BEGIN %s PRIVATE KEY' % key_type_representation in content
assert 'END %s PRIVATE KEY' % key_type_representation in content
def test_write_certificate(tmpdir):
tmpdir.chdir()
issuer_dn = gimmecert.crypto.get_dn('My test 1')
subject_dn = gimmecert.crypto.get_dn('My test 2')
issuer_private_key = gimmecert.crypto.KeyGenerator('rsa', 2048)()
subject_private_key = gimmecert.crypto.KeyGenerator('rsa', 2048)()
not_before, not_after = gimmecert.crypto.get_validity_range()
certificate = gimmecert.crypto.issue_certificate(issuer_dn, subject_dn, issuer_private_key, subject_private_key.public_key(), not_before, not_after)
certificate_path = tmpdir.join('test.key.pem').strpath
gimmecert.storage.write_certificate(certificate, certificate_path)
assert os.path.exists(certificate_path)
with open(certificate_path, 'r') as certificate_file:
content = certificate_file.read()
assert 'BEGIN CERTIFICATE' in content
assert 'END CERTIFICATE' in content
def test_write_certificate_chain(tmpdir):
output_file = tmpdir.join('chain.cert.pem')
certificate_chain = [certificate for _, certificate in gimmecert.crypto.generate_ca_hierarchy('My Project', 3, gimmecert.crypto.KeyGenerator("rsa", 2048))]
level1_pem, level2_pem, level3_pem = [gimmecert.utils.certificate_to_pem(certificate) for certificate in certificate_chain]
gimmecert.storage.write_certificate_chain(certificate_chain, output_file.strpath)
content = output_file.read(mode='r')
expected_content = "%s\n%s\n%s" % (level1_pem, level2_pem, level3_pem)
assert content == expected_content
def test_is_initialised_returns_true_if_directory_is_initialised(tmpdir):
tmpdir.chdir()
gimmecert.storage.initialise_storage(tmpdir.strpath)
assert gimmecert.storage.is_initialised(tmpdir.strpath) is True
def test_is_initialised_returns_false_if_directory_is_not_initialised(tmpdir):
tmpdir.chdir()
assert gimmecert.storage.is_initialised(tmpdir.strpath) is False
@pytest.mark.parametrize("key_specification, private_key_instance_type", [
[("rsa", 1024), cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey],
[("ecdsa", cryptography.hazmat.primitives.asymmetric.ec.SECP192R1), cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey],
])
def test_read_ca_hierarchy_returns_list_of_ca_private_key_and_certificate_pairs_for_single_ca(tmpdir, key_specification, private_key_instance_type):
tmpdir.chdir()
gimmecert.commands.init(io.StringIO(), io.StringIO(), tmpdir.strpath, 'My Project', 1, key_specification)
ca_hierarchy = gimmecert.storage.read_ca_hierarchy(tmpdir.join('.gimmecert', 'ca').strpath)
assert len(ca_hierarchy) == 1
private_key, certificate = ca_hierarchy[0]
assert isinstance(private_key, private_key_instance_type)
assert isinstance(certificate, cryptography.x509.Certificate)
@pytest.mark.parametrize("key_specification, private_key_instance_type", [
[("rsa", 1024), cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey],
[("ecdsa", cryptography.hazmat.primitives.asymmetric.ec.SECP192R1), cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey],
])
def test_read_private_key_returns_private_key(tmpdir, key_specification, private_key_instance_type):
private_key_path = tmpdir.join('private.key.pem').strpath
private_key = gimmecert.crypto.KeyGenerator(*key_specification)()
gimmecert.storage.write_private_key(private_key, private_key_path)
my_private_key = gimmecert.storage.read_private_key(private_key_path)
assert isinstance(my_private_key, private_key_instance_type)
assert my_private_key.public_key().public_numbers() == private_key.public_key().public_numbers() # Can't compare private keys directly.
def test_read_certificate_returns_certificate(tmpdir):
certificate_path = tmpdir.join('certificate.cert.pem').strpath
dn = gimmecert.crypto.get_dn('mycertificate')
not_before, not_after = gimmecert.crypto.get_validity_range()
private_key = gimmecert.crypto.KeyGenerator('rsa', 2048)()
certificate = gimmecert.crypto.issue_certificate(dn, dn, private_key, private_key.public_key(), not_before, not_after)
gimmecert.storage.write_certificate(certificate, certificate_path)
my_certificate = gimmecert.storage.read_certificate(certificate_path)
assert isinstance(my_certificate, cryptography.x509.Certificate)
assert my_certificate == certificate
@pytest.mark.parametrize("key_specification, private_key_instance_type", [
[("rsa", 1024), cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey],
[("ecdsa", cryptography.hazmat.primitives.asymmetric.ec.SECP192R1), cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey],
])
def test_read_ca_hierarchy_returns_list_of_ca_private_key_and_certificate_pairs_in_hierarchy_order_for_multiple_cas(tmpdir, key_specification,
private_key_instance_type):
tmpdir.chdir()
gimmecert.commands.init(io.StringIO(), io.StringIO(), tmpdir.strpath, 'My Project', 4, key_specification)
ca_hierarchy = gimmecert.storage.read_ca_hierarchy(tmpdir.join('.gimmecert', 'ca').strpath)
assert len(ca_hierarchy) == 4
private_key_1, certificate_1 = ca_hierarchy[0]
private_key_2, certificate_2 = ca_hierarchy[1]
private_key_3, certificate_3 = ca_hierarchy[2]
private_key_4, certificate_4 = ca_hierarchy[3]
assert isinstance(private_key_1, private_key_instance_type)
assert isinstance(certificate_1, cryptography.x509.Certificate)
assert certificate_1.subject == gimmecert.crypto.get_dn("My Project Level 1 CA")
assert isinstance(private_key_2, private_key_instance_type)
assert isinstance(certificate_2, cryptography.x509.Certificate)
assert certificate_2.subject == gimmecert.crypto.get_dn("My Project Level 2 CA")
assert isinstance(private_key_3, private_key_instance_type)
assert isinstance(certificate_3, cryptography.x509.Certificate)
assert certificate_3.subject == gimmecert.crypto.get_dn("My Project Level 3 CA")
assert isinstance(private_key_4, private_key_instance_type)
assert isinstance(certificate_4, cryptography.x509.Certificate)
assert certificate_4.subject == gimmecert.crypto.get_dn("My Project Level 4 CA")
def test_write_csr(tmpdir):
csr_file = tmpdir.join('test.csr.pem')
private_key = gimmecert.crypto.KeyGenerator('rsa', 2048)()
csr = gimmecert.crypto.generate_csr('test', private_key)
gimmecert.storage.write_csr(csr, csr_file.strpath)
csr_file_content = csr_file.read()
assert os.path.exists(csr_file.strpath)
assert csr_file_content.startswith('-----BEGIN CERTIFICATE REQUEST-----')
assert csr_file_content.endswith('-----END CERTIFICATE REQUEST-----\n')
def test_read_csr(tmpdir):
csr_file = tmpdir.join('mycsr.csr.pem')
private_key = gimmecert.crypto.KeyGenerator('rsa', 2048)()
original_csr = gimmecert.crypto.generate_csr('mycsr', private_key)
gimmecert.storage.write_csr(original_csr, csr_file.strpath)
csr = gimmecert.storage.read_csr(csr_file.strpath)
assert isinstance(csr, cryptography.x509.CertificateSigningRequest)
assert csr == original_csr
|