Files
@ 5e176c2a3067
Branch filter:
Location: gimmecert/tests/test_storage.py - annotation
5e176c2a3067
9.0 KiB
text/x-python
GC-37: Parametrise a couple of storage test functions to cover ECDSA as well.
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 | 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 84ba90064e85 9f09715ce550 7a2919409da2 7a2919409da2 7a2919409da2 9f09715ce550 9f09715ce550 71e316da896f 9f09715ce550 a7af49f9e2c3 a7af49f9e2c3 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 7a2919409da2 a6b448968a50 9f09715ce550 9f09715ce550 5e176c2a3067 5e176c2a3067 5e176c2a3067 5e176c2a3067 5e176c2a3067 9f09715ce550 9f09715ce550 5e176c2a3067 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 5e176c2a3067 5e176c2a3067 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 89d391511fdb 89d391511fdb 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 9f09715ce550 71e316da896f 71e316da896f 71e316da896f 71e316da896f de1cc2505a56 71e316da896f 71e316da896f 71e316da896f 1b16b8ce67df 1b16b8ce67df 71e316da896f 71e316da896f 988ac40d5cec 988ac40d5cec 988ac40d5cec 988ac40d5cec 988ac40d5cec 988ac40d5cec 988ac40d5cec 988ac40d5cec 988ac40d5cec 988ac40d5cec 988ac40d5cec 988ac40d5cec 988ac40d5cec 988ac40d5cec 7a2919409da2 7a2919409da2 a7af49f9e2c3 a7af49f9e2c3 a7af49f9e2c3 a7af49f9e2c3 a7af49f9e2c3 7a2919409da2 a7af49f9e2c3 7a2919409da2 7a2919409da2 7a2919409da2 7a2919409da2 7a2919409da2 7a2919409da2 7a2919409da2 a7af49f9e2c3 7a2919409da2 7a2919409da2 7a2919409da2 5e176c2a3067 5e176c2a3067 5e176c2a3067 5e176c2a3067 5e176c2a3067 7a2919409da2 5e176c2a3067 7a2919409da2 7a2919409da2 7a2919409da2 7a2919409da2 5e176c2a3067 7a2919409da2 7a2919409da2 7a2919409da2 7a2919409da2 7a2919409da2 7a2919409da2 7a2919409da2 7a2919409da2 89d391511fdb 7a2919409da2 7a2919409da2 7a2919409da2 7a2919409da2 7a2919409da2 7a2919409da2 7a2919409da2 7a2919409da2 7a2919409da2 a7af49f9e2c3 a7af49f9e2c3 a7af49f9e2c3 a7af49f9e2c3 5e176c2a3067 5e176c2a3067 7a2919409da2 a7af49f9e2c3 7a2919409da2 7a2919409da2 7a2919409da2 7a2919409da2 7a2919409da2 7a2919409da2 7a2919409da2 7a2919409da2 7a2919409da2 7a2919409da2 a7af49f9e2c3 7a2919409da2 7a2919409da2 a7af49f9e2c3 7a2919409da2 7a2919409da2 a7af49f9e2c3 7a2919409da2 7a2919409da2 a7af49f9e2c3 7a2919409da2 7a2919409da2 647208f5016b 647208f5016b 647208f5016b 647208f5016b 647208f5016b 89d391511fdb 647208f5016b 647208f5016b 647208f5016b 647208f5016b 647208f5016b 647208f5016b 647208f5016b 647208f5016b 647208f5016b 647208f5016b 647208f5016b 647208f5016b 647208f5016b 647208f5016b 89d391511fdb 647208f5016b 647208f5016b 647208f5016b 647208f5016b 647208f5016b 647208f5016b 647208f5016b 647208f5016b | # -*- 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
|