def test_obtain_certificate_get_order_no_retryable_domains(self, mock_crypto_util): from acme import messages csr = util.CSR(form="pem", file=mock.sentinel.csr_file, data=CSR_SAN) key = util.CSR(form="pem", file=mock.sentinel.key_file, data=CSR_SAN) mock_crypto_util.generate_csr.return_value = csr mock_crypto_util.generate_key.return_value = key self._set_mock_from_fullchain(mock_crypto_util.cert_and_chain_from_fullchain) self._mock_obtain_certificate() authzr = self._authzr_from_domains(self.eg_domains) self.eg_order.authorizations = authzr self.client.auth_handler.handle_authorizations.return_value = authzr identifier1 = messages.Identifier(typ=messages.IDENTIFIER_FQDN, value='example.com') identifier2 = messages.Identifier(typ=messages.IDENTIFIER_FQDN, value='www.example.com') subproblem1 = messages.Error.with_code('caa', detail='bar', title='title', identifier=identifier1) subproblem2 = messages.Error.with_code('caa', detail='bar', title='title', identifier=identifier2) error_with_subproblems = messages.Error.with_code('malformed', detail='foo', title='title', subproblems=[subproblem1, subproblem2]) self.client.acme.new_order.side_effect = error_with_subproblems self.config.allow_subset_of_names = True self.assertRaises(messages.Error, self.client.obtain_certificate, self.eg_domains) self.assertEqual(self.client.auth_handler.handle_authorizations.call_count, 0) self.assertEqual(self.acme.new_order.call_count, 1) self.assertEqual(mock_crypto_util.generate_key.call_count, 1) self.assertEqual(mock_crypto_util.cert_and_chain_from_fullchain.call_count, 0)
def setUp(self): self.response = mock.MagicMock( ok=True, status_code=http_client.OK, headers={}, links={}) self.net = mock.MagicMock() self.net.post.return_value = self.response self.net.get.return_value = self.response self.identifier = messages.Identifier( typ=messages.IDENTIFIER_FQDN, value='example.com') # Registration self.contact = ('mailto:[email protected]', 'tel:+12025551212') reg = messages.Registration( contact=self.contact, key=KEY.public_key()) self.new_reg = messages.NewRegistration(**dict(reg)) self.regr = messages.RegistrationResource( body=reg, uri='https://www.letsencrypt-demo.org/acme/reg/1') # Authorization authzr_uri = 'https://www.letsencrypt-demo.org/acme/authz/1' challb = messages.ChallengeBody( uri=(authzr_uri + '/1'), status=messages.STATUS_VALID, chall=challenges.DNS(token=jose.b64decode( 'evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA'))) self.challr = messages.ChallengeResource( body=challb, authzr_uri=authzr_uri) self.authz = messages.Authorization( identifier=messages.Identifier( typ=messages.IDENTIFIER_FQDN, value='example.com'), challenges=(challb,), combinations=None) self.authzr = messages.AuthorizationResource( body=self.authz, uri=authzr_uri)
def new_order(self, csr_pem): """Request a new Order object from the server. :param str csr_pem: A CSR in PEM format. :returns: The newly created order. :rtype: OrderResource """ csr = OpenSSL.crypto.load_certificate_request( OpenSSL.crypto.FILETYPE_PEM, csr_pem) # pylint: disable=protected-access dnsNames = crypto_util._pyopenssl_cert_or_req_all_names(csr) ipNames = crypto_util._pyopenssl_cert_or_req_san_ip(csr) # ipNames is now []string identifiers = [] for name in dnsNames: identifiers.append( messages.Identifier(typ=messages.IDENTIFIER_FQDN, value=name)) for ips in ipNames: identifiers.append( messages.Identifier(typ=messages.IDENTIFIER_IP, value=ips)) order = messages.NewOrder(identifiers=identifiers) response = self._post(self.directory['newOrder'], order) body = messages.Order.from_json(response.json()) authorizations = [] # pylint has trouble understanding our josepy based objects which use # things like custom metaclass logic. body.authorizations should be a # list of strings containing URLs so let's disable this check here. for url in body.authorizations: # pylint: disable=not-an-iterable authorizations.append( self._authzr_from_response(self._post_as_get(url), uri=url)) return messages.OrderResource(body=body, uri=response.headers.get('Location'), authorizations=authorizations, csr_pem=csr_pem)
def setUp(self): self.response = mock.MagicMock(ok=True, status_code=http_client.OK, headers={}, links={}) self.net = mock.MagicMock() self.net.post.return_value = self.response self.net.get.return_value = self.response self.directory = messages.Directory({ messages.NewRegistration: 'https://www.letsencrypt-demo.org/acme/new-reg', messages.Revocation: 'https://www.letsencrypt-demo.org/acme/revoke-cert', }) from acme.client import Client self.client = Client(directory=self.directory, key=KEY, alg=jose.RS256, net=self.net) self.identifier = messages.Identifier(typ=messages.IDENTIFIER_FQDN, value='example.com') # Registration self.contact = ('mailto:[email protected]', 'tel:+12025551212') reg = messages.Registration(contact=self.contact, key=KEY.public_key()) self.new_reg = messages.NewRegistration(**dict(reg)) self.regr = messages.RegistrationResource( body=reg, uri='https://www.letsencrypt-demo.org/acme/reg/1', new_authzr_uri='https://www.letsencrypt-demo.org/acme/new-reg', terms_of_service='https://www.letsencrypt-demo.org/tos') # Authorization authzr_uri = 'https://www.letsencrypt-demo.org/acme/authz/1' challb = messages.ChallengeBody( uri=(authzr_uri + '/1'), status=messages.STATUS_VALID, chall=challenges.DNS(token=jose.b64decode( 'evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA'))) self.challr = messages.ChallengeResource(body=challb, authzr_uri=authzr_uri) self.authz = messages.Authorization(identifier=messages.Identifier( typ=messages.IDENTIFIER_FQDN, value='example.com'), challenges=(challb, ), combinations=None) self.authzr = messages.AuthorizationResource( body=self.authz, uri=authzr_uri, new_cert_uri='https://www.letsencrypt-demo.org/acme/new-cert') # Request issuance self.certr = messages.CertificateResource( body=messages_test.CERT, authzrs=(self.authzr, ), uri='https://www.letsencrypt-demo.org/acme/cert/1', cert_chain_uri='https://www.letsencrypt-demo.org/ca')
def setUp(self): self.verify_ssl = mock.MagicMock() self.wrap_in_jws = mock.MagicMock(return_value=mock.sentinel.wrapped) from acme.client import Client self.net = Client( new_reg_uri='https://www.letsencrypt-demo.org/acme/new-reg', key=KEY, alg=jose.RS256, verify_ssl=self.verify_ssl) self.nonce = jose.b64encode('Nonce') self.net._nonces.add(self.nonce) # pylint: disable=protected-access self.response = mock.MagicMock(ok=True, status_code=httplib.OK) self.response.headers = {} self.response.links = {} self.post = mock.MagicMock(return_value=self.response) self.get = mock.MagicMock(return_value=self.response) self.identifier = messages.Identifier(typ=messages.IDENTIFIER_FQDN, value='example.com') # Registration self.contact = ('mailto:[email protected]', 'tel:+12025551212') reg = messages.Registration(contact=self.contact, key=KEY.public(), recovery_token='t') self.regr = messages.RegistrationResource( body=reg, uri='https://www.letsencrypt-demo.org/acme/reg/1', new_authzr_uri='https://www.letsencrypt-demo.org/acme/new-reg', terms_of_service='https://www.letsencrypt-demo.org/tos') # Authorization authzr_uri = 'https://www.letsencrypt-demo.org/acme/authz/1' challb = messages.ChallengeBody(uri=(authzr_uri + '/1'), status=messages.STATUS_VALID, chall=challenges.DNS(token='foo')) self.challr = messages.ChallengeResource(body=challb, authzr_uri=authzr_uri) self.authz = messages.Authorization(identifier=messages.Identifier( typ=messages.IDENTIFIER_FQDN, value='example.com'), challenges=(challb, ), combinations=None) self.authzr = messages.AuthorizationResource( body=self.authz, uri=authzr_uri, new_cert_uri='https://www.letsencrypt-demo.org/acme/new-cert') # Request issuance self.certr = messages.CertificateResource( body=messages_test.CERT, authzrs=(self.authzr, ), uri='https://www.letsencrypt-demo.org/acme/cert/1', cert_chain_uri='https://www.letsencrypt-demo.org/ca')
def test_identifier(self): """Test the identifier property.""" self.assertEqual( self.auth1.identifier, messages.Identifier(typ=messages.IDENTIFIER_FQDN, value=self.auth1.value)) self.assertEqual( self.auth2.identifier, messages.Identifier(typ=messages.IDENTIFIER_FQDN, value=self.auth2.value))
def setUp(self): super(ClientV2Test, self).setUp() self.directory = DIRECTORY_V2 from acme.client import ClientV2 self.client = ClientV2(self.directory, self.net) self.new_reg = self.new_reg.update(terms_of_service_agreed=True) self.authzr_uri2 = 'https://www.letsencrypt-demo.org/acme/authz/2' self.authz2 = self.authz.update(identifier=messages.Identifier( typ=messages.IDENTIFIER_FQDN, value='www.example.com'), status=messages.STATUS_PENDING) self.authzr2 = messages.AuthorizationResource( body=self.authz2, uri=self.authzr_uri2) self.order = messages.Order( identifiers=(self.authz.identifier, self.authz2.identifier), status=messages.STATUS_PENDING, authorizations=(self.authzr.uri, self.authzr_uri2), finalize='https://www.letsencrypt-demo.org/acme/acct/1/order/1/finalize') self.orderr = messages.OrderResource( body=self.order, uri='https://www.letsencrypt-demo.org/acme/acct/1/order/1', authorizations=[self.authzr, self.authzr2], csr_pem=CSR_SAN_PEM)
def new_order(self, csr_pem): """Request a new Order object from the server. :param str csr_pem: A CSR in PEM format. :returns: The newly created order. :rtype: OrderResource """ csr = OpenSSL.crypto.load_certificate_request( OpenSSL.crypto.FILETYPE_PEM, csr_pem) # pylint: disable=protected-access dnsNames = crypto_util._pyopenssl_cert_or_req_all_names(csr) identifiers = [] for name in dnsNames: identifiers.append( messages.Identifier(typ=messages.IDENTIFIER_FQDN, value=name)) order = messages.NewOrder(identifiers=identifiers) response = self._post(self.directory['newOrder'], order) body = messages.Order.from_json(response.json()) authorizations = [] for url in body.authorizations: authorizations.append( self._authzr_from_response(self._post_as_get(url), uri=url)) return messages.OrderResource(body=body, uri=response.headers.get('Location'), authorizations=authorizations, csr_pem=csr_pem)
def new_order(self, csr_pem): """Request a new Order object from the server. :param str csr_pem: A CSR in PEM format. :returns: The newly created order. :rtype: OrderResource """ csr = cryptography.x509.load_pem_x509_csr( csr_pem, cryptography.hazmat.backends.default_backend()) san_extension = next( ext for ext in csr.extensions if ext.oid == cryptography.x509.oid.ExtensionOID.SUBJECT_ALTERNATIVE_NAME) dnsNames = san_extension.value.get_values_for_type( cryptography.x509.DNSName) identifiers = [] for name in dnsNames: identifiers.append( messages.Identifier(typ=messages.IDENTIFIER_FQDN, value=name)) order = messages.NewOrder(identifiers=identifiers) response = self.net.post(self.directory['newOrder'], order) body = messages.Order.from_json(response.json()) authorizations = [] for url in body.authorizations: authorizations.append(self._authzr_from_response( self.net.get(url))) return messages.OrderResource(body=body, uri=response.headers.get('Location'), authorizations=authorizations, csr_pem=csr_pem)
def test_add_authorizations(self): """Test the add_authorizations method.""" identifier = messages.Identifier(typ=messages.IDENTIFIER_FQDN, value='example.com') auths = self.order1.add_authorizations([identifier]) self.assertEqual(auths[0].type, 'dns') self.assertEqual(auths[0].value, 'example.com') msg = r'^UNIQUE constraint failed: django_ca_acmeauthorization\.order_id, django_ca_acmeauthorization\.type, django_ca_acmeauthorization\.value$' # NOQA: E501 with transaction.atomic(), self.assertRaisesRegex(IntegrityError, msg): self.order1.add_authorizations([identifier])
def fqdn_identifier(fqdn): """ Construct an identifier from an FQDN. Trivial implementation, just saves on typing. :param str fqdn: The domain name. :return: The identifier. :rtype: `~acme.messages.Identifier` """ return messages.Identifier(typ=messages.IDENTIFIER_FQDN, value=fqdn)
def request_domain_challenges(self, domain, new_authz_uri): """Request challenges for domain names. This is simply a convenience function that wraps around `request_challenges`, but works with domain names instead of generic identifiers. :param str domain: Domain name to be challenged. :param str new_authzr_uri: new-authorization URI :returns: Authorization Resource. :rtype: `.AuthorizationResource` """ return self.request_challenges(messages.Identifier( typ=messages.IDENTIFIER_FQDN, value=domain), new_authz_uri)
def request_domain_challenges(self, domain, new_authzr_uri=None): """Request challenges for domain names. This is simply a convenience function that wraps around `request_challenges`, but works with domain names instead of generic identifiers. See ``request_challenges`` for more documentation. :param str domain: Domain name to be challenged. :param str new_authzr_uri: Deprecated. Do not use. :returns: Authorization Resource. :rtype: `.AuthorizationResource` :raises errors.WildcardUnsupportedError: if a wildcard is requested """ return self.request_challenges(messages.Identifier( typ=messages.IDENTIFIER_FQDN, value=domain), new_authzr_uri)
def gen_authzr(authz_status: messages.Status, domain: str, challs: Iterable[challenges.Challenge], statuses: Iterable[messages.Status], combos: bool = True) -> messages.AuthorizationResource: """Generate an authorization resource. :param authz_status: Status object :type authz_status: :class:`acme.messages.Status` :param list challs: Challenge objects :param list statuses: status of each challenge object :param bool combos: Whether or not to add combinations """ challbs = tuple( chall_to_challb(chall, status) for chall, status in zip(challs, statuses)) authz_kwargs = { "identifier": messages.Identifier(typ=messages.IDENTIFIER_FQDN, value=domain), "challenges": challbs, } if combos: authz_kwargs.update({"combinations": gen_combos(challbs)}) if authz_status == messages.STATUS_VALID: authz_kwargs.update({ "status": authz_status, "expires": datetime.datetime.now() + datetime.timedelta(days=31), }) else: authz_kwargs.update({ "status": authz_status, }) return messages.AuthorizationResource( uri="https://trusted.ca/new-authz-resource", body=messages.Authorization(**authz_kwargs))
def test_obtain_certificate_get_order_partial_success(self, mock_remove, mock_crypto_util): from acme import messages csr = util.CSR(form="pem", file=mock.sentinel.csr_file, data=CSR_SAN) key = util.CSR(form="pem", file=mock.sentinel.key_file, data=CSR_SAN) mock_crypto_util.generate_csr.return_value = csr mock_crypto_util.generate_key.return_value = key self._set_mock_from_fullchain(mock_crypto_util.cert_and_chain_from_fullchain) self._mock_obtain_certificate() authzr = self._authzr_from_domains(self.eg_domains) self.eg_order.authorizations = authzr self.client.auth_handler.handle_authorizations.return_value = authzr identifier = messages.Identifier(typ=messages.IDENTIFIER_FQDN, value='example.com') subproblem = messages.Error.with_code('caa', detail='bar', title='title', identifier=identifier) error_with_subproblems = messages.Error.with_code('malformed', detail='foo', title='title', subproblems=[subproblem]) self.client.acme.new_order.side_effect = [error_with_subproblems, mock.DEFAULT] self.config.allow_subset_of_names = True with test_util.patch_display_util(): result = self.client.obtain_certificate(self.eg_domains) self.assertEqual( result, (mock.sentinel.cert, mock.sentinel.chain, key, csr)) self.assertEqual(self.client.auth_handler.handle_authorizations.call_count, 1) self.assertEqual(self.acme.new_order.call_count, 2) successful_domains = [d for d in self.eg_domains if d != 'example.com'] self.assertEqual(mock_crypto_util.generate_key.call_count, 2) mock_crypto_util.generate_csr.assert_has_calls([ mock.call(key, self.eg_domains, self.config.csr_dir, self.config.must_staple, self.config.strict_permissions), mock.call(key, successful_domains, self.config.csr_dir, self.config.must_staple, self.config.strict_permissions)]) self.assertEqual(mock_remove.call_count, 2) self.assertEqual(mock_crypto_util.cert_and_chain_from_fullchain.call_count, 1)
def request_cert(domain): domain = domain.lower() print("Generating user key") user_key = josepy.JWKRSA( key=rsa.generate_private_key( public_exponent=65537, key_size=KEY_SIZE, backend=default_backend() ) ) print("Connecting to Let's Encrypt on {}".format(DIRECTORY_URL)) acme = client.Client(DIRECTORY_URL, user_key) print("Registering") regr = acme.register() print("Agreeing to ToS") acme.agree_to_tos(regr) print("Requesting challenges") authzr = acme.request_challenges( identifier=messages.Identifier(typ=messages.IDENTIFIER_FQDN, value=domain) ) print("Looking for HTTP challenge") challenge = get_http_challenge(authzr) print("You need to set up the challenge response.") print("URL: http://{}{}".format(domain, challenge.chall.path)) print("Content: {}".format(challenge.chall.validation(user_key))) response = challenge.chall.response(user_key) while not response.simple_verify(challenge.chall, domain, user_key.public_key()): raw_input("It doesn't look like it's set up yet; press return when it is.") print("Authorizing -- here goes...") auth_response = acme.answer_challenge(challenge, challenge.chall.response(user_key)) print("Response was {}".format(auth_response)) print("Waiting for authorization to become valid") while True: print("Polling") authzr, authzr_response = acme.poll(authzr) challenge = get_http_challenge(authzr) if challenge.status.name == "valid": break print("HTTP challenge is currently {}".format(challenge)) time.sleep(1) print("Auth valid") print("Generating CSR") certificate_key = crypto.PKey() certificate_key.generate_key(crypto.TYPE_RSA, 2048) csr = crypto.X509Req() csr.get_subject().CN = domain csr.set_pubkey(certificate_key) csr.sign(certificate_key, "sha256") print("Requesting certificate") certificate_response = acme.request_issuance(josepy.util.ComparableX509(csr), [authzr]) print("Got it!") print("Fetching chain") chain = acme.fetch_chain(certificate_response) print("Done!") print("Here are the details:") print("Private key:") print(crypto.dump_privatekey(FILETYPE_PEM, certificate_key)) print("Combined cert:") print(crypto.dump_certificate(FILETYPE_PEM, certificate_response.body.wrapped)) for cert in chain: print(crypto.dump_certificate(FILETYPE_PEM, cert.wrapped))
NEW_REG_URL = 'https://www.letsencrypt-demo.org/acme/new-reg' BITS = 2048 # minimum for Boulder DOMAIN = 'example1.com' # example.com is ignored by Boulder key = jose.JWKRSA.load( Crypto.PublicKey.RSA.generate(BITS).exportKey(format="PEM")) acme = client.Client(NEW_REG_URL, key) regr = acme.register(contact=()) logging.info('Auto-accepting TOS: %s', regr.terms_of_service) acme.update_registration( regr.update(body=regr.body.update(agreement=regr.terms_of_service))) logging.debug(regr) authzr = acme.request_challenges(identifier=messages.Identifier( typ=messages.IDENTIFIER_FQDN, value=DOMAIN), new_authzr_uri=regr.new_authzr_uri) logging.debug(authzr) authzr, authzr_response = acme.poll(authzr) csr = M2Crypto.X509.load_request_string( pkg_resources.resource_string('acme.jose', os.path.join('testdata', 'csr.der')), M2Crypto.X509.FORMAT_DER) try: acme.request_issuance(csr, (authzr, )) except messages.Error as error: print("This script is doomed to fail as no authorization " "challenges are ever solved. Error from server: {0}".format(error))
DOMAIN = 'example1.com' # example.com is ignored by Boulder # generate_private_key requires cryptography>=0.5 key = jose.JWKRSA(key=rsa.generate_private_key( public_exponent=65537, key_size=BITS, backend=default_backend())) acme = client.Client(NEW_REG_URL, key) regr = acme.register() logging.info('Auto-accepting TOS: %s', regr.terms_of_service) acme.update_registration(regr.update( body=regr.body.update(agreement=regr.terms_of_service))) logging.debug(regr) authzr = acme.request_challenges( identifier=messages.Identifier(typ=messages.IDENTIFIER_FQDN, value=DOMAIN), new_authzr_uri=regr.new_authzr_uri) logging.debug(authzr) authzr, authzr_response = acme.poll(authzr) csr = OpenSSL.crypto.load_certificate_request( OpenSSL.crypto.FILETYPE_ASN1, pkg_resources.resource_string( 'acme', os.path.join('testdata', 'csr.der'))) try: acme.request_issuance(csr, (authzr,)) except messages.Error as error: print ("This script is doomed to fail as no authorization " "challenges are ever solved. Error from server: {0}".format(error))
def run_acme_reg_to_finish(domain, regr_uri, accnt_key, site_key, csr, tmp_chall_dict, directory_url): accnt_key = jose.JWKRSA(key=accnt_key) acme = client.Client(directory_url, accnt_key) msg = messages.RegistrationResource(uri=regr_uri) regr = acme.query_registration(msg) log.info('Auto-accepting TOS: %s from: %s', regr.terms_of_service, directory_url) acme.agree_to_tos(regr) authzr = acme.request_challenges( identifier=messages.Identifier(typ=messages.IDENTIFIER_FQDN, value=domain)) log.debug('Created auth client %s', authzr) def get_http_challenge(x, y): return y if isinstance(y.chall, challenges.HTTP01) else x challb = reduce(get_http_challenge, authzr.body.challenges, None) chall_tok = challb.chall.validation(accnt_key) v = chall_tok.split('.')[0] log.info('Exposing challenge on %s', v) tmp_chall_dict.set(v, ChallTok(chall_tok)) test_path = 'http://localhost:8082{}'.format(challb.path) local_req = Request(test_path, headers={'Host': domain}) log.debug('Testing local url path: %s', test_path) try: resp = urlopen(local_req) t = resp.read().decode('utf-8').strip() if t != chall_tok: raise ValueError except (IOError, ValueError): log.info('Resolving challenge locally failed. ACME request will fail. %s', test_path) raise cr = acme.answer_challenge(challb, challb.chall.response(accnt_key)) log.debug('Acme CA responded to challenge request with: %s', cr) try: # Wrap this step and log the failure particularly here because this is # the expected point of failure for applications that are not reachable # from the public internet. cert_res, _ = acme.poll_and_request_issuance(jose.util.ComparableX509(csr), (authzr,)) # NOTE pylint disabled due to spurious reporting. See docs: # https://letsencrypt.readthedocs.io/projects/acme/en/latest/api/jose/util.html#acme.jose.util.ComparableX509 # pylint: disable=no-member cert_str = cert_res.body._dump(FILETYPE_PEM) except messages.Error as error: log.err("Failed in request issuance step %s", error) raise chain_certs = acme.fetch_chain(cert_res) # The chain certs returned by the LE CA will always have at least one # intermediate cert. Other certificate authorities that run ACME may # behave differently, but we aren't using them. chain_str = dump_certificate(FILETYPE_PEM, chain_certs[0]) # pylint: disable=no-member expr_date = convert_asn1_date(cert_res.body.wrapped.get_notAfter()) log.info('Retrieved cert using ACME that expires on %s', expr_date) return cert_str, chain_str
def _update(self): if not self.dom_key or not self.dom_csr: self.state = 'cert' return if not self.key: self.state = 'priv_key' return k = self._deserialize_key(self.key) acme = client.Client(DIRECTORY_URL, k) authzr = acme.request_challenges(identifier=messages.Identifier( typ=messages.IDENTIFIER_FQDN, value=self.name)) challb = self._supported_challb(authzr) if not challb: _logger.warning( _("Didn't find any http01 challenge. Just try again.")) _logger.warning(authzr) raise exceptions.Warning( _("Didn't find any http01 challenge. Just try again.")) response, self.challenge_validation = challb.response_and_validation(k) self.challenge_path = challb.path.split('/')[-1] challenge = Challenge() challenge.set_challenge(self.challenge_path, self.challenge_validation) _logger.info("Need to response %s on url %s", self.challenge_validation, self.challenge_path) # write data to file, because it seems that the data is not written to the database bevor # the controller requests it. So the controller loads it from the file: #challenge_file = os.path.join(get_challenge_dir(), self.challenge_path) #f = open(challenge_file, 'w') #f.write(self.challenge_validation) #_logger.info("saved %s to '%s'", self.challenge_validation, challenge_file) #self.dom_verified = response.simple_verify( # challb.chall, self.name, acme.key.public_key()) #f.close() #if not self.dom_verified: # _logger.warning('%s was not successfully self-verified. ' # 'CA is likely to fail as well!', self.name) # raise exceptions.Warning(_("%s was not successfully self-verified. CA is likely to fail as well!"% self.name)) #else: # _logger.info('%s was successfully self-verified', self.name) # os.unlink(challenge_file) # _logger.info("unlinked %s", challenge_file) # authzr, authzr_response = acme.poll(authzr) acme.answer_challenge(challb, response) csr = OpenSSL.crypto.load_certificate_request( OpenSSL.crypto.FILETYPE_PEM, self.dom_csr) certr, authzr = acme.poll_and_request_issuance( jose.util.ComparableX509(csr), (authzr, )) self.cert = OpenSSL.crypto.dump_certificate( OpenSSL.crypto.FILETYPE_PEM, certr.body) if self.cert: expire_time = time.strptime(certr.body.get_notAfter(), "%Y%m%d%H%M%SZ") self.expires = time.strftime(DEFAULT_SERVER_DATETIME_FORMAT, expire_time) return self.cert