def create_issuing_service( reactor: IReactorTCP, acme_url: str, account_key_file: str, well_known_resource: IResource, ) -> AcmeIssuingService: """Create an ACME issuing service, and attach it to a web Resource Args: reactor: twisted reactor acme_url: URL to use to request certificates account_key_file: where to store the account key well_known_resource: web resource for .well-known. we will attach a child resource for "acme-challenge". Returns: AcmeIssuingService """ responder = HTTP01Responder() well_known_resource.putChild(b"acme-challenge", responder.resource) store = ErsatzStore() return AcmeIssuingService( cert_store=store, client_creator=(lambda: Client.from_url( reactor=reactor, url=URL.from_text(acme_url), key=load_or_create_client_key(account_key_file), alg=RS256, )), clock=reactor, responders=[responder], )
def make(cls, section_name, node_config, announcement, reactor): configured_issuer = node_config.get_config( section=section_name, option=u"ristretto-issuer-root-url", ).decode("ascii") if announcement is not None: # Don't let us talk to a storage server that has a different idea # about who issues ZKAPs. We should lift this limitation (that is, we # should support as many different issuers as the user likes) in the # future but doing so requires changing how the web interface works # and possibly also the interface for voucher submission. # # If we aren't given an announcement then we're not being used in # the context of a specific storage server so the check is # unnecessary and impossible. announced_issuer = announcement[u"ristretto-issuer-root-url"] if announced_issuer != configured_issuer: raise IssuerConfigurationMismatch(announced_issuer, configured_issuer) return cls( HTTPClient(Agent(reactor)), URL.from_text(configured_issuer), )
interval = timedelta(hours=1) clock.advance(interval.total_seconds()) # It failed again. self.assertThat( controller.get_voucher(voucher).state, MatchesAll( IsInstance(model_Unpaid), MatchesStructure( # At the new time, demonstrating the retry was performed. finished=Equals(datetime_now()), ), ), ) NOWHERE = URL.from_text(u"https://127.0.0.1/") class RistrettoRedeemerTests(TestCase): """ Tests for ``RistrettoRedeemer``. """ def test_interface(self): """ An ``RistrettoRedeemer`` instance provides ``IRedeemer``. """ redeemer = RistrettoRedeemer(stub_agent(), NOWHERE) self.assertThat( redeemer, Provides([IRedeemer]), )
def start_listening(self): # Configure logging for txacme, if you need to debug # from eliot import add_destinations # from eliot.twisted import TwistedDestination # # add_destinations(TwistedDestination()) from txacme.challenges import HTTP01Responder from txacme.service import AcmeIssuingService from txacme.endpoint import load_or_create_client_key from txacme.client import Client from josepy.jwa import RS256 self._store = ErsatzStore() responder = HTTP01Responder() self._issuer = AcmeIssuingService( cert_store=self._store, client_creator=(lambda: Client.from_url( reactor=self.reactor, url=URL.from_text(self.hs.config.acme_url), key=load_or_create_client_key( FilePath(self.hs.config.config_dir_path)), alg=RS256, )), clock=self.reactor, responders=[responder], ) well_known = Resource() well_known.putChild(b'acme-challenge', responder.resource) responder_resource = Resource() responder_resource.putChild(b'.well-known', well_known) responder_resource.putChild(b'check', static.Data(b'OK', b'text/plain')) srv = server.Site(responder_resource) bind_addresses = self.hs.config.acme_bind_addresses for host in bind_addresses: logger.info( "Listening for ACME requests on %s:%i", host, self.hs.config.acme_port, ) try: self.reactor.listenTCP( self.hs.config.acme_port, srv, interface=host, ) except twisted.internet.error.CannotListenError as e: check_bind_error(e, host, bind_addresses) # Make sure we are registered to the ACME server. There's no public API # for this, it is usually triggered by startService, but since we don't # want it to control where we save the certificates, we have to reach in # and trigger the registration machinery ourselves. self._issuer._registered = False yield self._issuer._ensure_registered()