summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/test_acme_dns_tiny.py132
-rwxr-xr-xtests/test_script.sh9
2 files changed, 141 insertions, 0 deletions
diff --git a/tests/test_acme_dns_tiny.py b/tests/test_acme_dns_tiny.py
new file mode 100644
index 0000000..9a2562d
--- /dev/null
+++ b/tests/test_acme_dns_tiny.py
@@ -0,0 +1,132 @@
+#!python3
+
+
+import collections
+import os
+import sys
+import tempfile
+import pytest
+
+
+# append cwd to module importable paths (pytest-3 should be executed from main
+# directory).
+sys.path.append(os.path.realpath("."))
+import acme_dns_tiny
+
+
+DOMAIN = os.getenv('TEST_DOMAIN')
+ACME_STAGING_DIRECTORY = \
+ 'https://acme-staging-v02.api.letsencrypt.org/directory'
+CONTACT = os.getenv('TEST_CONTACT') # form: mailto:name@domain
+
+
+def test_sanity_env():
+ assert DOMAIN
+ assert CONTACT
+
+
+@pytest.fixture(scope='module')
+def casemap(tmpdir_factory):
+
+ tmpdir = tmpdir_factory.mktemp("data")
+
+ def _gen_key(name, size):
+ path = str(tmpdir.join(name))
+ acme_dns_tiny.openssl(['genrsa', '-out', path, str(size)])
+ return path
+
+ account_key = _gen_key('account_key', 4096)
+ domain_key = _gen_key('domain_key', 4096)
+ weak_account_key = _gen_key('weak_account_key', 1024)
+ weak_domain_key = _gen_key('weak_domain_key', 1024)
+
+ default_args = {
+ '--acme-directory': ACME_STAGING_DIRECTORY,
+ '--script': 'tests/test_script.sh',
+ '--account-key': account_key,
+ #'--ttl': 60, # already the default
+ '--ttl': None,
+ '--contact': None,
+ #'--contact': [CONTACT], # not supported by staging directory
+ '--verbose': None,
+ '--quiet': None,
+ }
+
+ def _csr(name, domain_key, subj=f'/CN={DOMAIN}'):
+ path = str(tmpdir.join(name))
+ acme_dns_tiny.openssl([
+ 'req', '-new', '-key', domain_key, '-subj', subj, '-out', path
+ ])
+ return {**default_args, '--csr': path}
+
+ def _san_csr(name, subj='/', san=None):
+ path = str(tmpdir.join(name))
+ with tempfile.NamedTemporaryFile('w', encoding='utf8') as conf, \
+ open('/etc/ssl/openssl.cnf', 'r', encoding='utf8') as orig:
+ conf.write(orig.read())
+ conf.write(f'\n[SAN]\nsubjectAltName={san}\n')
+ conf.flush()
+ acme_dns_tiny.openssl([
+ 'req', '-new', '-key', domain_key, '-subj', subj,
+ '-reqexts', 'SAN', '-config', conf.name, '-out', path
+ ])
+ return {**default_args, '--csr': path}
+
+ return {
+ # single domain
+ 'single': _csr('csr_single', domain_key),
+
+ # single, but weak account key used
+ 'weakaccountkey': {
+ **_csr('csr_simple', domain_key),
+ '--account-key': weak_account_key,
+ },
+
+ # single, but weak domain key used to sign csr
+ 'weakdomainkey': _csr('csr_weakdomain', weak_domain_key),
+
+ # single, csr wrongly signed by account key
+ 'csrbyaccount': _csr('csr_byaccount', account_key),
+
+ # wildcard domain in CN
+ 'wildcard': _csr('csr_wildcard', domain_key, f'/CN=*.{DOMAIN}'),
+
+ # san only
+ 'sanonly': _san_csr('csr_sanonly',
+ san=f'DNS:{DOMAIN},DNS:www.{DOMAIN}'),
+
+ # san and cn
+ 'san': _san_csr('csr_san', subj=f'/CN={DOMAIN}',
+ san=f'DNS:www.{DOMAIN}'),
+
+ # san wildcard (domain + *.domain, contrary to wildcard in cn)
+ 'wildcardsan': _san_csr('csr_wildcardsan',
+ san=f'DNS:{DOMAIN},DNS:*.{DOMAIN}')
+ }
+
+
+def assert_certificate_chain(captured):
+ #assert not captured.err
+ certlist = captured.out.split('-----BEGIN CERTIFICATE-----')
+ assert len(certlist) == 3
+ assert certlist[0] == ''
+ assert '-----END CERTIFICATE-----\n' in certlist[1]
+ assert '-----END CERTIFICATE-----\n' in certlist[2]
+ textchain = acme_dns_tiny.openssl(['x509', '-text', '-noout'],
+ stdin=captured.out)
+ assert 'Issuer' in textchain
+
+
+def test_success(capsys, casemap):
+ for name in ('single', 'wildcard', 'sanonly', 'san', 'wildcardsan'):
+ print(f'test_success case: {name}', file=sys.stderr)
+ acme_dns_tiny.main(casemap[name])
+ captured = capsys.readouterr()
+ assert_certificate_chain(captured)
+
+
+def test_assert(casemap):
+ for name in ('weakaccountkey', 'weakdomainkey', 'csrbyaccount'):
+ print(f'test_assert case: {name}', file=sys.stderr)
+ with pytest.raises(ValueError):
+ acme_dns_tiny.main(casemap[name])
diff --git a/tests/test_script.sh b/tests/test_script.sh
new file mode 100755
index 0000000..dbd6812
--- /dev/null
+++ b/tests/test_script.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+ssh -i "${TEST_SSHKEY}" "${TEST_USER}@${TEST_DNSSERVER}" : <<EOF
+{
+ "action": "$1",
+ "zone": "$2",
+ "challenge": "$3"
+}
+EOF