check that installed certificates are for the domains we are using the certificates for
This commit is contained in:
parent
3d4eadd436
commit
59a9d02fa5
2 changed files with 38 additions and 3 deletions
|
@ -108,7 +108,7 @@ def buy_ssl_certificate(api_key, domain, command, env):
|
|||
|
||||
# Check before we overwrite something we shouldn't.
|
||||
if os.path.exists(ssl_certificate):
|
||||
cert_status = check_certificate(ssl_certificate)
|
||||
cert_status = check_certificate(None, ssl_certificate)
|
||||
if cert_status != "SELF-SIGNED":
|
||||
print("Please back up and delete the file %s so I can save your new certificate." % ssl_certificate)
|
||||
sys.exit(1)
|
||||
|
|
|
@ -223,7 +223,7 @@ def check_ssl_cert(domain, env):
|
|||
|
||||
# Check that the certificate is good.
|
||||
|
||||
cert_status = check_certificate(ssl_certificate)
|
||||
cert_status = check_certificate(domain, ssl_certificate)
|
||||
|
||||
if cert_status == "SELF-SIGNED":
|
||||
fingerprint = shell('check_output', [
|
||||
|
@ -265,9 +265,44 @@ def check_ssl_cert(domain, env):
|
|||
print(cert_status)
|
||||
print("")
|
||||
|
||||
def check_certificate(ssl_certificate):
|
||||
def check_certificate(domain ,ssl_certificate):
|
||||
# Use openssl verify to check the status of a certificate.
|
||||
|
||||
# First check that the certificate is for the right domain. The domain
|
||||
# must be found in the Subject Common Name (CN) or be one of the
|
||||
# Subject Alternative Names.
|
||||
cert_dump = shell('check_output', [
|
||||
"openssl", "x509",
|
||||
"-in", ssl_certificate,
|
||||
"-noout", "-text", "-nameopt", "rfc2253",
|
||||
])
|
||||
cert_dump = cert_dump.split("\n")
|
||||
certificate_names = set()
|
||||
while len(cert_dump) > 0:
|
||||
line = cert_dump.pop(0)
|
||||
|
||||
# Grab from the Subject Common Name. We include the indentation
|
||||
# at the start of the line in case maybe the cert includes the
|
||||
# common name of some other referenced entity (which would be
|
||||
# indented, I hope).
|
||||
m = re.match(" Subject: CN=([^,]+)", line)
|
||||
if m:
|
||||
certificate_names.add(m.group(1))
|
||||
|
||||
# Grab from the Subject Alternative Name, which is a comma-delim
|
||||
# list of names, like DNS:mydomain.com, DNS:otherdomain.com.
|
||||
m = re.match(" X509v3 Subject Alternative Name:", line)
|
||||
if m:
|
||||
names = re.split(",\s*", cert_dump.pop(0).strip())
|
||||
for n in names:
|
||||
m = re.match("DNS:(.*)", n)
|
||||
if m:
|
||||
certificate_names.add(m.group(1))
|
||||
|
||||
if domain is not None and domain not in certificate_names:
|
||||
return "This certificate is for the wrong domain names. It is for %s." % \
|
||||
", ".join(sorted(certificate_names))
|
||||
|
||||
# In order to verify with openssl, we need to split out any
|
||||
# intermediary certificates in the chain (if any) from our
|
||||
# certificate (at the top). They need to be passed separately.
|
||||
|
|
Loading…
Reference in a new issue