def request_certificate_issuance(client, challgs, csr, logger): # Convert the OpenSSL.crypto.X509Req to a ComparableX509 expected by request_issuance. csr = acme.jose.util.ComparableX509(csr) # Request a certificate using the CSR and some number of domain validation challenges. logger("Requesting a certificate.") try: cert_response = client.request_issuance(csr, challgs) except acme.messages.Error as e: if e.typ == "urn:acme:error:rateLimited": raise RateLimited(e.detail) raise # unhandled # Get the certificate chain. chain = client.fetch_chain(cert_response) # cert_response.body and chain now hold OpenSSL.crypto.X509 objects. # Convert them to PEM format. cert_pem = cert_to_pem(cert_response.body) chain = list(map(cert_to_pem, chain)) return (cert_pem, chain)
def main(): # Set this to the list of domain names for the certificate. The # first will be the "common name" and the rest will be Subject # Alternative Names names. The difference doesn't really matter. # You can have just a single domain here. domains = ["mailinabox.email", "www.mailinabox.email"] account_key_file = 'le_account.pem' registration_file = "le_registration.json" challenges_file = "le_challenges.jsons" certificate_file = "certificate.crt" def simple_logger(s): print(s) # Create the ACME client, making a new account & registration # if not set up yet. try: (client, regr, account) = create_client(account_key_file, registration_file, simple_logger) except NeedToAgreeToTOS as e: print("agreeing to TOS", e.url) (client, regr, account) = create_client(account_key_file, registration_file, simple_logger, agree_to_tos_url=e.url) # Submit domain validation. challgs = [] for domain in domains: try: challg = submit_domain_validation(client, regr, account, challenges_file, domain, simple_logger) challgs.append(challg) except NeedToInstallFile as e: print("Install a file") print("Location:", e.url) print("Content Type:", e.content_type) print("Contents:", e.contents) return except WaitABit as e: print ("Try again in %s." % (e.until_when - datetime.datetime.now())) return # Domains are now validated. Generate a CSR. # Since this is an example, we'll generate a private key on the fly. from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives.asymmetric import rsa key = rsa.generate_private_key(public_exponent=65537, key_size=2048, backend=default_backend()) # To save it in PEM format (but for this test we don't need to save it): # # with open(keyfile, 'wb') as f: # f.write(key.private_bytes(encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.TraditionalOpenSSL))) # # If you already have a private key but not a CSR, load it like this: # # with open(keyfile, 'rb') as f: # key = serialization.load_pem_private_key(f.read(), password=None, backend=default_backend()) # Create a CSR, if you don't have one already. csr = generate_csr(domains, key) # Or if you already have a CSR, load it now in PEM format: # # with open(csrfile, 'rb') as f: # csr = f.read() # csr = OpenSSL.crypto.load_certificate_request(OpenSSL.crypto.FILETYPE_PEM, csr) # Request a certificate using the CSR and some number of domain validation challenges. cert_response = client.request_issuance(csr, challgs) # cert_response.body now holds a OpenSSL.crypto.X509 object. Convert it to # PEM format and save: import OpenSSL.crypto cert_pem = OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, cert_response.body) with open(certificate_file, 'wb') as f: f.write(cert_pem)