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
|
import unittest, os, sys, tempfile
from subprocess import Popen, PIPE
try:
from StringIO import StringIO # Python 2
except ImportError:
from io import StringIO # Python 3
import acme_tiny
from .monkey import gen_keys
KEYS = gen_keys()
class TestModule(unittest.TestCase):
"Tests for acme_tiny.get_crt()"
def setUp(self):
self.CA = "https://acme-staging.api.letsencrypt.org"
self.tempdir = tempfile.mkdtemp()
self.fuse_proc = Popen(["python", "tests/monkey.py", self.tempdir])
def tearDown(self):
self.fuse_proc.terminate()
self.fuse_proc.wait()
os.rmdir(self.tempdir)
def test_success_cn(self):
""" Successfully issue a certificate via common name """
old_stdout = sys.stdout
sys.stdout = StringIO()
result = acme_tiny.main([
"--account-key", KEYS['account_key'].name,
"--csr", KEYS['domain_csr'].name,
"--acme-dir", self.tempdir,
"--ca", self.CA,
])
sys.stdout.seek(0)
crt = sys.stdout.read().encode("utf8")
sys.stdout = old_stdout
out, err = Popen(["openssl", "x509", "-text", "-noout"], stdin=PIPE,
stdout=PIPE, stderr=PIPE).communicate(crt)
self.assertIn("Issuer: CN=Fake LE Intermediate", out.decode("utf8"))
def test_success_san(self):
""" Successfully issue a certificate via subject alt name """
old_stdout = sys.stdout
sys.stdout = StringIO()
result = acme_tiny.main([
"--account-key", KEYS['account_key'].name,
"--csr", KEYS['san_csr'].name,
"--acme-dir", self.tempdir,
"--ca", self.CA,
])
sys.stdout.seek(0)
crt = sys.stdout.read().encode("utf8")
sys.stdout = old_stdout
out, err = Popen(["openssl", "x509", "-text", "-noout"], stdin=PIPE,
stdout=PIPE, stderr=PIPE).communicate(crt)
self.assertIn("Issuer: CN=Fake LE Intermediate", out.decode("utf8"))
def test_success_cli(self):
""" Successfully issue a certificate via command line interface """
crt, err = Popen([
"python", "acme_tiny.py",
"--account-key", KEYS['account_key'].name,
"--csr", KEYS['domain_csr'].name,
"--acme-dir", self.tempdir,
"--ca", self.CA,
], stdout=PIPE, stderr=PIPE).communicate()
out, err = Popen(["openssl", "x509", "-text", "-noout"], stdin=PIPE,
stdout=PIPE, stderr=PIPE).communicate(crt)
self.assertIn("Issuer: CN=Fake LE Intermediate", out.decode("utf8"))
def test_missing_account_key(self):
""" OpenSSL throws an error when the account key is missing """
try:
result = acme_tiny.main([
"--account-key", "/foo/bar",
"--csr", KEYS['domain_csr'].name,
"--acme-dir", self.tempdir,
"--ca", self.CA,
])
except Exception as e:
result = e
self.assertIsInstance(result, IOError)
self.assertIn("Error opening Private Key", result.args[0])
def test_missing_csr(self):
""" OpenSSL throws an error when the CSR is missing """
try:
result = acme_tiny.main([
"--account-key", KEYS['account_key'].name,
"--csr", "/foo/bar",
"--acme-dir", self.tempdir,
"--ca", self.CA,
])
except Exception as e:
result = e
self.assertIsInstance(result, IOError)
self.assertIn("Error loading /foo/bar", result.args[0])
def test_weak_key(self):
""" Let's Encrypt rejects weak keys """
try:
result = acme_tiny.main([
"--account-key", KEYS['weak_key'].name,
"--csr", KEYS['domain_csr'].name,
"--acme-dir", self.tempdir,
"--ca", self.CA,
])
except Exception as e:
result = e
self.assertIsInstance(result, ValueError)
self.assertIn("Key too small", result.args[0])
def test_invalid_domain(self):
""" Let's Encrypt rejects invalid domains """
try:
result = acme_tiny.main([
"--account-key", KEYS['account_key'].name,
"--csr", KEYS['invalid_csr'].name,
"--acme-dir", self.tempdir,
"--ca", self.CA,
])
except Exception as e:
result = e
self.assertIsInstance(result, ValueError)
self.assertIn("Invalid character in DNS name", result.args[0])
def test_nonexistant_domain(self):
""" Should be unable verify a nonexistent domain """
try:
result = acme_tiny.main([
"--account-key", KEYS['account_key'].name,
"--csr", KEYS['nonexistent_csr'].name,
"--acme-dir", self.tempdir,
"--ca", self.CA,
])
except Exception as e:
result = e
self.assertIsInstance(result, ValueError)
self.assertIn("but couldn't download", result.args[0])
def test_account_key_domain(self):
""" Can't use the account key for the CSR """
try:
result = acme_tiny.main([
"--account-key", KEYS['account_key'].name,
"--csr", KEYS['account_csr'].name,
"--acme-dir", self.tempdir,
"--ca", self.CA,
])
except Exception as e:
result = e
self.assertIsInstance(result, ValueError)
self.assertIn("Certificate public key must be different than account key", result.args[0])
|