def answer_challenges(operation_id: int, **kwargs): db = kwargs["db"] operation = Operation.query.get(operation_id) service_instance = operation.service_instance acme_user = service_instance.acme_user time.sleep(int(config.DNS_PROPAGATION_SLEEP_TIME)) account_key = serialization.load_pem_private_key( acme_user.private_key_pem.encode(), password=None, backend=default_backend() ) wrapped_account_key = josepy.JWKRSA(key=account_key) registration = json.loads(acme_user.registration_json) net = client.ClientNetwork( wrapped_account_key, user_agent="cloud.gov external domain broker", account=registration, ) directory = messages.Directory.from_json(net.get(config.ACME_DIRECTORY).json()) client_acme = client.ClientV2(directory, net=net) for challenge in service_instance.challenges: challenge_body = messages.ChallengeBody.from_json( json.loads(challenge.body_json) ) challenge_response = challenge_body.response(wrapped_account_key) # Let the CA server know that we are ready for the challenge. client_acme.answer_challenge(challenge_body, challenge_response) challenge.answered = True db.session.add(challenge) db.session.commit()
def main(): if sys.argv[1] == 'staging': directory = 'https://acme-staging.api.letsencrypt.org/directory' else: directory = 'https://acme-v01.api.letsencrypt.org/directory' key = josepy.JWKRSA(key=serialization.load_pem_private_key( sys.stdin.read(), password=None, backend=default_backend()) ) net = acme_client.ClientNetwork(key) client = acme_client.Client( directory=directory, key=key, net=net ) new_reg = messages.NewRegistration.from_data( email=sys.argv[2] ) acct = None try: regr = client.register(new_reg) except errors.ConflictError as e: acct = e.location print(json.dumps({'body': {}, 'uri': acct}))
def new_account(self): """ Registers a new ACME account at the set ACME `directory` URL. By running this method, you are agreeing to the ACME servers terms of use.\n - :return [`none`]: the account and account_key properties will be updated with the new account registration.\n - :raises `InvalidDirectory`: if this object does not contain a valid ACME directory URL.\n - :raises `InvalidEmail`: if this object does not contain a valid email address to use during registration.\n\n ## Example\n ```python >>> client.new_account() ``` """ self.__validate_directory__() self.__validate_email__() # Generate a new RSA2048 account key rsa_key = rsa.generate_private_key(public_exponent=65537, key_size=2048, backend=(default_backend())) self.account_key = jose.JWKRSA(key=rsa_key) # Initialize our ACME client object self.__net__ = client.ClientNetwork(self.account_key, user_agent='simple_acme_dns/1.0.0') self.__directory__ = messages.Directory.from_json(self.__net__.get(self.directory).json()) self.__client__ = client.ClientV2(self.__directory__, net=self.__net__) # Complete registration registration = messages.NewRegistration.from_data(email=self.email, terms_of_service_agreed=True) self.account = self.__client__.new_account(registration)
def test_revoke_by_privkey(): client = chisel2.make_client(None) domains = [random_domain()] key = OpenSSL.crypto.PKey() key.generate_key(OpenSSL.crypto.TYPE_RSA, 2048) key_pem = OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, key) csr_pem = chisel2.make_csr(domains) order = client.new_order(csr_pem) cleanup = chisel2.do_http_challenges(client, order.authorizations) try: order = client.poll_and_finalize(order) finally: cleanup() # Create a new client with the JWK as the cert private key jwk = josepy.JWKRSA(key=key) net = acme_client.ClientNetwork(key, user_agent="Boulder integration tester") directory = Directory.from_json(net.get(chisel2.DIRECTORY_V2).json()) new_client = acme_client.ClientV2(directory, net) cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, order.fullchain_pem) client.revoke(josepy.ComparableX509(cert), 0)
def test_revoke_by_privkey(): client = make_client(None) domains = [random_domain()] key = OpenSSL.crypto.PKey() key.generate_key(OpenSSL.crypto.TYPE_RSA, 2048) key_pem = OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, key) csr_pem = acme_crypto_util.make_csr(key_pem, domains, False) order = client.new_order(csr_pem) cleanup = do_http_challenges(client, order.authorizations) try: order = client.poll_order_and_request_issuance(order) finally: cleanup() # Create a new client with the JWK as the cert private key jwk = jose.JWKRSA(key=key) net = acme_client.ClientNetwork(key, acme_version=2, user_agent="Boulder integration tester") new_client = acme_client.Client(os.getenv( 'DIRECTORY', 'http://localhost:4001/directory'), key=jwk, net=net, acme_version=2) cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, order.fullchain_pem) client.revoke(jose.ComparableX509(cert), 0)
def setup_acme_client(self, authority): if not authority.options: raise InvalidAuthority("Invalid authority. Options not set") options = {} for option in json.loads(authority.options): options[option["name"]] = option.get("value") email = options.get('email', current_app.config.get('ACME_EMAIL')) tel = options.get('telephone', current_app.config.get('ACME_TEL')) directory_url = options.get('acme_url', current_app.config.get('ACME_DIRECTORY_URL')) existing_key = options.get('acme_private_key', current_app.config.get('ACME_PRIVATE_KEY')) existing_regr = options.get('acme_regr', current_app.config.get('ACME_REGR')) if existing_key and existing_regr: # Reuse the same account for each certificate issuance key = jose.JWK.json_loads(existing_key) regr = messages.RegistrationResource.json_loads(existing_regr) current_app.logger.debug("Connecting with directory at {0}".format(directory_url)) net = ClientNetwork(key, account=regr) client = BackwardsCompatibleClientV2(net, key, directory_url) return client, {} else: # Create an account for each certificate issuance key = jose.JWKRSA(key=generate_private_key('RSA2048')) current_app.logger.debug("Connecting with directory at {0}".format(directory_url)) net = ClientNetwork(key, account=None) client = BackwardsCompatibleClientV2(net, key, directory_url) registration = client.new_account_and_tos(messages.NewRegistration.from_data(email=email)) current_app.logger.debug("Connected: {0}".format(registration.uri)) return client, registration
def _load_account_key(self) -> None: """Load or create account key.""" key = None if self.path_account_key.exists(): _LOGGER.debug("Load account keyfile: %s", self.path_account_key) pem = self.path_account_key.read_bytes() key = serialization.load_pem_private_key(pem, password=None, backend=default_backend()) else: _LOGGER.debug("Create new RSA keyfile: %s", self.path_account_key) key = rsa.generate_private_key( public_exponent=65537, key_size=ACCOUNT_KEY_SIZE, backend=default_backend(), ) # Store it to file pem = key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption(), ) self.path_account_key.write_bytes(pem) self.path_account_key.chmod(0o600) self._account_jwk = jose.JWKRSA(key=jose.ComparableRSAKey(key))
def __create_client(self, key): key = jose.JWKRSA(key=key) net = acme.client.ClientNetwork(key, user_agent=ACME.USER_AGENT) directory = acme.messages.Directory.from_json( net.get(ACME.ACME_ENDPOINT).json()) client = acme.client.ClientV2(directory, net=net) return client
def test_revoke_by_privkey(): client = chisel2.make_client(None) domains = [random_domain()] key = OpenSSL.crypto.PKey() key.generate_key(OpenSSL.crypto.TYPE_RSA, 2048) key_pem = OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, key) csr_pem = chisel2.make_csr(domains) order = client.new_order(csr_pem) cleanup = chisel2.do_http_challenges(client, order.authorizations) try: order = client.poll_and_finalize(order) finally: cleanup() # Create a new client with the JWK as the cert private key jwk = josepy.JWKRSA(key=key) net = acme_client.ClientNetwork(key, user_agent="Boulder integration tester") directory = Directory.from_json(net.get(chisel2.DIRECTORY_V2).json()) new_client = acme_client.ClientV2(directory, net) cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, order.fullchain_pem) reset_akamai_purges() client.revoke(josepy.ComparableX509(cert), 0) cert_file_pem = os.path.join(tempdir, "revokeme.pem") with open(cert_file_pem, "w") as f: f.write( OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, cert).decode()) ee_ocsp_url = "http://localhost:4002" verify_ocsp(cert_file_pem, "test/test-ca2.pem", ee_ocsp_url, "revoked") verify_akamai_purge()
def generateCertificate(domain, notification_email, directory_url=DIRECTORY_URL_PROD, cert_dir=None, debug=None): # Create account key acc_key = jose.JWKRSA( key=rsa.generate_private_key(public_exponent=65537, key_size=ACC_KEY_BITS, backend=default_backend())) # Create client configured to use our ACME server and trust our root cert net = client.ClientNetwork(acc_key, user_agent=USER_AGENT) if debug == True: directory_url = DIRECTORY_URL_STAGING directory = messages.Directory.from_json(net.get(directory_url).json()) client_acme = client.ClientV2(directory, net=net) # Register account and accept TOS regr = client_acme.new_account( messages.NewRegistration.from_data(email=notification_email, terms_of_service_agreed=True)) # Create domain private key and CSR pkey_pem, csr_pem = new_csr(domain) # Issue certificate orderr = client_acme.new_order(csr_pem) # Select HTTP-01 within offered challenges by the CA server challb = select_http01_chall(orderr) # The certificate is ready to be used in the variable "fullchain_pem". fullchain_pem = perform_http01(client_acme, challb, orderr) # Store the certificates if cert_dir is None: cert_dir = CERT_DIR cert_domain_dir = "{}/{}".format(cert_dir, domain) if not os.path.exists(cert_domain_dir): os.makedirs(cert_domain_dir) key_file = "{}/dsiprouter.key".format(cert_domain_dir) cert_file = "{}/dsiprouter.crt".format(cert_domain_dir) with os.fdopen(os.open(key_file, os.O_WRONLY | os.O_CREAT, 0o640), 'w') as keyfile: keyfile.write(pkey_pem.decode('utf-8')) with os.fdopen(os.open(cert_file, os.O_WRONLY | os.O_CREAT, 0o640), 'w') as certfile: certfile.write(fullchain_pem) # Change owner to root:kamailio so that Kamailio can load the configurations change_owner(cert_domain_dir, "root", "kamailio") change_owner(key_file, "root", "kamailio") change_owner(cert_file, "root", "kamailio") return pkey_pem.decode('utf-8'), fullchain_pem
def create_user(operation_id: int, **kwargs): db = kwargs["db"] acme_user = ACMEUser() operation = Operation.query.get(operation_id) service_instance = operation.service_instance service_instance.acme_user = acme_user key = josepy.JWKRSA( key=rsa.generate_private_key( public_exponent=65537, key_size=2048, backend=default_backend() ) ) private_key_pem_in_binary = key.key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.TraditionalOpenSSL, encryption_algorithm=serialization.NoEncryption(), ) acme_user.private_key_pem = private_key_pem_in_binary.decode("utf-8") net = client.ClientNetwork(key, user_agent="cloud.gov external domain broker") directory = messages.Directory.from_json(net.get(config.ACME_DIRECTORY).json()) client_acme = client.ClientV2(directory, net=net) acme_user.email = "*****@*****.**" registration = client_acme.new_account( messages.NewRegistration.from_data( email=acme_user.email, terms_of_service_agreed=True ) ) acme_user.registration_json = registration.json_dumps() acme_user.uri = registration.uri db.session.add(operation) db.session.add(service_instance) db.session.add(acme_user) db.session.commit()
def uninitialized_client(key=None): if key is None: key = josepy.JWKRSA( key=rsa.generate_private_key(65537, 2048, default_backend())) net = acme_client.ClientNetwork(key, user_agent="Boulder integration tester") directory = messages.Directory.from_json(net.get(DIRECTORY_V2).json()) return acme_client.ClientV2(directory, net)
def create_v2_client(directory_url, accnt_key): """Creates an ACME v2 Client for making requests to Let's Encrypt with""" accnt_key = josepy.JWKRSA(key=accnt_key) net = client.ClientNetwork(accnt_key, user_agent="GlobaLeaks Let's Encrypt Client") directory = messages.Directory.from_json(net.get(directory_url).json()) return client.ClientV2(directory, net)
def _key_generate(self): """ generate key """ self.logger.debug('CAhandler._key_generate({0})'.format(self.key_size)) user_key = josepy.JWKRSA( key=rsa.generate_private_key(public_exponent=65537, key_size=self.key_size, backend=default_backend())) return user_key
def create_acme_client(self, email=None): key = josepy.JWKRSA(key=rsa.generate_private_key(65537, 2048, default_backend())) net = acme_client.ClientNetwork(key, user_agent="Callback Catcher Client") directory = messages.Directory.from_json(net.get(LETSENCRYPTDIRECTORY).json()) client = acme_client.ClientV2(directory, net) tos = client.directory.meta.terms_of_service client.net.account = client.new_account(messages.NewRegistration.from_data(email=email, terms_of_service_agreed=True)) return client
def answer_challenges(operation_id: int, **kwargs): operation = Operation.query.get(operation_id) service_instance = operation.service_instance acme_user = service_instance.acme_user operation.step_description = "Answering Lets Encrypt challenges" flag_modified(operation, "step_description") db.session.add(operation) db.session.commit() challenges = service_instance.new_certificate.challenges.all() unanswered = [challenge for challenge in challenges if not challenge.answered] if not unanswered: return time.sleep(int(config.DNS_PROPAGATION_SLEEP_TIME)) account_key = serialization.load_pem_private_key( acme_user.private_key_pem.encode(), password=None, backend=default_backend() ) wrapped_account_key = josepy.JWKRSA(key=account_key) registration = json.loads(acme_user.registration_json) net = client.ClientNetwork( wrapped_account_key, user_agent="cloud.gov external domain broker", account=registration, ) directory = messages.Directory.from_json(net.get(config.ACME_DIRECTORY).json()) client_acme = AcmeClient(directory, net=net) for challenge in unanswered: if json.loads(challenge.body_json)["status"] == "valid": # this covers an edge case where we run an update # shortly after initial provisioning or renewal # it arguably makes more sense to do when we get the challenges # but doing so makes testing worlds harder challenge.answered = True db.session.add(challenge) db.session.commit() continue challenge_body = messages.ChallengeBody.from_json( json.loads(challenge.body_json) ) challenge_response = challenge_body.response(wrapped_account_key) # Let the CA server know that we are ready for the challenge. response = client_acme.answer_challenge(challenge_body, challenge_response) print(response) if response.body.error is not None: # log the error for now. We haven't reproduced this locally, so we can't act on it yet # but it would be interesting in the real world logger.error( f"challenge for instance {service_instance.id} errored. Error: {response.body.error}" ) challenge.answered = True db.session.add(challenge) db.session.commit()
def _generate_keypair(cls): """ generate the jwk keypair for the key request :return: the JWKRSA object """ rsa_key = generate_private_key(public_exponent=65537, key_size=4096, backend=default_backend()) return josepy.JWKRSA(key=josepy.ComparableRSAKey(rsa_key))
def _create_acme_client(self) -> acme_client.ClientV2: net = acme_client.ClientNetwork(key=josepy.JWKRSA( key=rsa.generate_private_key( public_exponent=ACME_RSA_PUBLIC_EXPONENT, key_size=ACME_RSA_KEY_SIZE, backend=default_backend(), ))) directory = acme_messages.Directory.from_json( net.get(self.options.acme_directory_url).json()) return acme_client.ClientV2(directory=directory, net=net)
def get_or_gen_key(ctx, account_key_path, new_account_key_size): account_key_path = os.path.expanduser(account_key_path) if os.path.exists(account_key_path): logger.debug('opening existing account key %s', account_key_path) with open(account_key_path, 'rb') as key_file: key_contents = key_file.read() try: try: account_key = jose.JWKRSA( key=serialization.load_pem_private_key( key_contents, None, default_backend())) except TypeError: # password required password = click.prompt('Password for %s' % account_key_path, hide_input=True, default=None) key = serialization.load_pem_private_key( key_contents, password.encode('utf-8'), default_backend()) account_key = jose.JWKRSA(key=key) except ValueError as e: logger.error('could not open key %s: %s', account_key_path, e) ctx.exit(1) else: logger.warning('no account key found; creating a new %d bit key in %s', new_account_key_size, account_key_path) account_key = jose.JWKRSA( key=rsa.generate_private_key(public_exponent=65537, key_size=new_account_key_size, backend=default_backend())) try: os.makedirs(os.path.dirname(account_key_path), 0o750) except os.error: pass # dir already exists encryption_algorithm = ask_for_password_or_no_crypto(account_key_path) with open(account_key_path, 'wb') as key_file: key_file.write( account_key.key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=encryption_algorithm)) return account_key
def make_client(email=None): """Build an acme.Client and register a new account with a random key.""" key = josepy.JWKRSA(key=rsa.generate_private_key(65537, 2048, default_backend())) net = acme_client.ClientNetwork(key, user_agent="Boulder integration tester") client = acme_client.Client(DIRECTORY, key=key, net=net) account = client.register(messages.NewRegistration.from_data(email=email)) client.agree_to_tos(account) client.account = account return client
def __init__(self, account_id=None): if account_id: self.account = Account.query.get(account_id) self.key = jose.JWKRSA( key=crypto.load_private_key(self.account.key.encode("utf8"))) regr = RegistrationResource.from_json( json.loads(self.account.contents)) net = ClientNetwork(self.key, account=regr) self.client = BackwardsCompatibleClientV2( net, self.key, self.account.directory_uri) else: print("Setup ACME Account")
def wildcard_revoke(cert_pem,account): #Check if registrar exists if account not in os.listdir(REG_DIRECTORY): print "This account does not exists, register it first with new_account.py" sys.exit(1) #Load files from disk with open(REG_DIRECTORY + "/" + account + "/private.key", "rb") as key_file: privkey = serialization.load_pem_private_key( key_file.read(), password=None, backend=default_backend() ) with open(REG_DIRECTORY + "/" + account + "/reguri.txt", "r") as reguri_file: reg_uri = reguri_file.read() #Compose registration resource (regr) key = jose.JWKRSA(key=privkey) regr = messages.RegistrationResource( body=messages.Registration( key=key.public_key()), uri = reg_uri) #Init ACME net = ClientNetwork(key) directory = net.get(DIRECTORY_URL).json() acme = client.ClientV2(directory, net) #Check if registration is valid if acme.query_registration(regr).body.status == u'valid': print "Registration valid" else: print "Registration invalid" sys.exit(1) #Deserialize key from variable cert = jose.ComparableX509(OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert_pem)) #Try to revoke cert, return false on error or revoked-already state try: revokation = acme.revoke(cert,1) except messages.Error,acme_exc: if str(acme_exc) == str("urn:ietf:params:acme:error:alreadyRevoked :: Certificate already revoked"): return ["Certificate already revoked",False] else: return [acme_exc, False]
def initiate_challenges(operation_id: int, **kwargs): operation = Operation.query.get(operation_id) service_instance = operation.service_instance acme_user = service_instance.acme_user certificate = service_instance.new_certificate operation.step_description = "Initiating Lets Encrypt challenges" flag_modified(operation, "step_description") db.session.add(operation) db.session.commit() if certificate.order_json is not None: return account_key = serialization.load_pem_private_key( acme_user.private_key_pem.encode(), password=None, backend=default_backend() ) wrapped_account_key = josepy.JWKRSA(key=account_key) registration = json.loads(acme_user.registration_json) net = client.ClientNetwork( wrapped_account_key, user_agent="cloud.gov external domain broker", account=registration, ) directory = messages.Directory.from_json(net.get(config.ACME_DIRECTORY).json()) client_acme = AcmeClient(directory, net=net) order = client_acme.new_order(certificate.csr_pem.encode()) order_json = json.dumps(order.to_json()) certificate.order_json = json.dumps(order.to_json()) for domain in service_instance.domain_names: challenge_body = dns_challenge(order, domain) ( challenge_response, challenge_validation_contents, ) = challenge_body.response_and_validation(wrapped_account_key) challenge = Challenge() challenge.body_json = challenge_body.json_dumps() challenge.domain = domain challenge.certificate = certificate challenge.validation_domain = challenge_body.validation_domain_name(domain) challenge.validation_contents = challenge_validation_contents db.session.add(challenge) db.session.commit()
def create_registration(): global privkey, regr privkey = rsa.generate_private_key(public_exponent=65537, key_size=BITS, backend=default_backend()) key = jose.JWKRSA(key=privkey) net = ClientNetwork(key) directory = net.get(DIRECTORY_URL).json() acme = client.ClientV2(directory, net) regbody = dict( messages.Registration(contact=('mailto:[email protected]', ), terms_of_service_agreed=True, key=key.public_key())) #NEED TO SAVE REGBODY VARIABLE TO FILE regr = acme.new_account(messages.NewRegistration(**regbody))
def make_client(email=None): """Build an acme.Client and register a new account with a random key.""" key = josepy.JWKRSA(key=rsa.generate_private_key(65537, 2048, default_backend())) net = acme_client.ClientNetwork(key, acme_version=2, user_agent="Boulder integration tester") client = acme_client.Client(DIRECTORY, key=key, net=net, acme_version=2) tos = client.directory.meta.terms_of_service if tos == ACCEPTABLE_TOS: net.account = client.register(messages.NewRegistration.from_data(email=email, terms_of_service_agreed=True)) else: raise Exception("Unrecognized terms of service URL %s" % tos) return client
def createAccount(user, dir_url, email): acc_key = jose.JWKRSA(key=rsa.generate_private_key(public_exponent=65537, key_size=2048, backend=default_backend()) ) # Register account and accept TOS net = client.ClientNetwork(acc_key, user_agent=user) directory = messages.Directory.from_json(net.get(dir_url).json()) client_acme = client.ClientV2(directory, net=net) #Terms of Service URL is in client_acme.directory.meta.terms_of_service # Registration Resource: regr # Creates account with contact information. email = (email) regr = client_acme.new_account(messages.NewRegistration.from_data(email=email, terms_of_service_agreed=True)) return client_acme
def __init__(self, configuration, test=False): if test: self.key = None else: with open(configuration.cm_key, "r") as key_file: private_key = serialization.load_pem_private_key( key_file.read(), password=None, backend=default_backend() ) self.key = jose.JWKRSA(key=private_key) user_agent = 'bigacme (https://github.com/magnuswatn/bigacme/)' network = client.ClientNetwork(self.key, user_agent=user_agent) network.session.proxies = {'https': configuration.ca_proxy} acme_client = client.Client(directory=configuration.ca, key=self.key, net=network) self.client = acme_client
def get_client(): global __cached_client_acme if __cached_client_acme: return __cached_client_acme account_pkey = loadFile("le/account.pem") account_data = None if account_pkey: account_data = loadFile("le/account.json") acc_key_pkey = None if account_pkey: acc_key_pkey = serialization.load_pem_private_key( data=account_pkey, password=None, backend=default_backend()) else: acc_key_pkey = rsa.generate_private_key(public_exponent=65537, key_size=KEY_BITS, backend=default_backend()) account_pkey = acc_key_pkey.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption()) acc_key = jose.JWKRSA(key=acc_key_pkey) net = client.ClientNetwork(acc_key, user_agent=USER_AGENT) directory = messages.Directory.from_json(net.get(DIRECTORY_URL).json()) client_acme = client.ClientV2(directory, net=net) if account_data != None: client_acme.net.account = messages.RegistrationResource.json_loads( account_data) try: if not client_acme.net.account: email = ('*****@*****.**') regr = client_acme.new_account( messages.NewRegistration.from_data( email=email, terms_of_service_agreed=True)) storeFile("le/account.json", regr.json_dumps().encode()) storeFile("le/account.pem", account_pkey) except errors.ConflictError: raise # TODO: Maybe handle? This happens when an account has been made with a key already __cached_client_acme = client_acme return client_acme
def _create_acc_key(): """Generate RSA Key Default key_size is 3072, but MUST be at least 2048. Certificate Authorities like Let's Encrypt can’t provide EdDSA certificates yet, so this rules-out using ed25519 keys. See: https://letsencrypt.org/docs/glossary/#def-EdDSA and https://community.letsencrypt.org/t/support-ed25519-and-ed448/69868 """ key_size = config.rsa_key_size or DEFAULT_KEY_SIZE le_acc_key = jose.JWKRSA( key=rsa.generate_private_key(public_exponent=PUBLIC_EXPONENT, key_size=key_size, backend=default_backend())) return le_acc_key
def setup_acme_client(): email = current_app.config.get('ACME_EMAIL') tel = current_app.config.get('ACME_TEL') directory_url = current_app.config.get('ACME_DIRECTORY_URL') contact = ('mailto:{}'.format(email), 'tel:{}'.format(tel)) key = jose.JWKRSA(key=generate_private_key('RSA2048')) current_app.logger.debug( "Connecting with directory at {0}".format(directory_url)) client = Client(directory_url, key) registration = client.register( messages.NewRegistration.from_data(email=email)) current_app.logger.debug("Connected: {0}".format(registration.uri)) client.agree_to_tos(registration) return client, registration