Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Common Name support has been added for acme.crypto_util.make_csr() #5837

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 9 additions & 4 deletions acme/acme/crypto_util.py
Expand Up @@ -155,23 +155,27 @@ def probe_sni(name, host, port=443, timeout=300,
raise errors.Error(error)
return client_ssl.get_peer_certificate()

def make_csr(private_key_pem, domains, must_staple=False):
"""Generate a CSR containing a list of domains as subjectAltNames.
def make_csr(private_key_pem, subject_alt_names, must_staple=False, common_name=None):
"""Generate a CSR containing a list of subject_alt_names as subjectAltNames
and common_name string as Common Name subject. If common_name is not passed,
first domain from the subject_alt_names will be a Common Name subject by default.

:param buffer private_key_pem: Private key, in PEM PKCS#8 format.
:param list domains: List of DNS names to include in subjectAltNames of CSR.
:param list subject_alt_names: List of DNS names to include in subjectAltNames of CSR.
:param bool must_staple: Whether to include the TLS Feature extension (aka
OCSP Must Staple: https://tools.ietf.org/html/rfc7633).
:param unicode common_name: Common name subject string of CSR.
:returns: buffer PEM-encoded Certificate Signing Request.
"""
private_key = OpenSSL.crypto.load_privatekey(
OpenSSL.crypto.FILETYPE_PEM, private_key_pem)
csr = OpenSSL.crypto.X509Req()
csr.get_subject().CN = common_name or subject_alt_names[0]
extensions = [
OpenSSL.crypto.X509Extension(
b'subjectAltName',
critical=False,
value=', '.join('DNS:' + d for d in domains).encode('ascii')
value=', '.join('DNS:' + d for d in subject_alt_names).encode('ascii')
),
]
if must_staple:
Expand Down Expand Up @@ -303,3 +307,4 @@ def _dump_cert(cert):
# assumes that OpenSSL.crypto.dump_certificate includes ending
# newline character
return b"".join(_dump_cert(cert) for cert in chain)

11 changes: 11 additions & 0 deletions acme/acme/crypto_util_test.py
Expand Up @@ -206,6 +206,17 @@ def test_make_csr(self):
value=b'DNS:a.example, DNS:b.example',
).get_data(),
)
def test_make_csr_empty_common_name(self):
csr_pem = self._call_with_key(["a.example", "b.example"])
csr = OpenSSL.crypto.load_certificate_request(
OpenSSL.crypto.FILETYPE_PEM, csr_pem)
self.assertEquals(csr.get_subject().CN, u'a.example')

def test_make_csr_with_common_name(self):
csr_pem = self._call_with_key(["a.example", "b.example"], common_name=u'b.example')
csr = OpenSSL.crypto.load_certificate_request(
OpenSSL.crypto.FILETYPE_PEM, csr_pem)
self.assertEquals(csr.get_subject().CN, u'b.example')

def test_make_csr_must_staple(self):
csr_pem = self._call_with_key(["a.example"], must_staple=True)
Expand Down