Example #1
0
    def test_perform_and_cleanup(self, mock_revert, mock_restart, mock_http_perform,
        mock_tls_perform):
        # Only tests functionality specific to configurator.perform
        # Note: As more challenges are offered this will have to be expanded
        achall1 = achallenges.KeyAuthorizationAnnotatedChallenge(
            challb=messages.ChallengeBody(
                chall=challenges.TLSSNI01(token=b"kNdwjwOeX0I_A8DXt9Msmg"),
                uri="https://ca.org/chall0_uri",
                status=messages.Status("pending"),
            ), domain="localhost", account_key=self.rsa512jwk)
        achall2 = achallenges.KeyAuthorizationAnnotatedChallenge(
            challb=messages.ChallengeBody(
                chall=challenges.HTTP01(token=b"m8TdO1qik4JVFtgPPurJmg"),
                uri="https://ca.org/chall1_uri",
                status=messages.Status("pending"),
            ), domain="example.com", account_key=self.rsa512jwk)

        expected = [
            achall1.response(self.rsa512jwk),
            achall2.response(self.rsa512jwk),
        ]

        mock_tls_perform.return_value = expected[:1]
        mock_http_perform.return_value = expected[1:]
        responses = self.config.perform([achall1, achall2])

        self.assertEqual(mock_tls_perform.call_count, 1)
        self.assertEqual(mock_http_perform.call_count, 1)
        self.assertEqual(responses, expected)

        self.config.cleanup([achall1, achall2])
        self.assertEqual(0, self.config._chall_out) # pylint: disable=protected-access
        self.assertEqual(mock_revert.call_count, 1)
        self.assertEqual(mock_restart.call_count, 2)
Example #2
0
    def setUp(self):
        kwargs = {
            "chall": acme_util.HTTP01,
            "uri": "uri",
            "status": messages.STATUS_INVALID,
            "error": messages.Error.with_code("tls", detail="detail"),
        }

        # Prevent future regressions if the error type changes
        self.assertTrue(kwargs["error"].description is not None)

        http_01 = messages.ChallengeBody(**kwargs)  # pylint: disable=star-args

        kwargs["chall"] = acme_util.TLSSNI01
        tls_sni_01 = messages.ChallengeBody(**kwargs)  # pylint: disable=star-args

        self.authzr1 = mock.MagicMock()
        self.authzr1.body.identifier.value = 'example.com'
        self.authzr1.body.challenges = [http_01, tls_sni_01]

        kwargs["error"] = messages.Error(typ="dnssec", detail="detail")
        tls_sni_01_diff = messages.ChallengeBody(**kwargs)  # pylint: disable=star-args

        self.authzr2 = mock.MagicMock()
        self.authzr2.body.identifier.value = 'foo.bar'
        self.authzr2.body.challenges = [tls_sni_01_diff]
Example #3
0
    def setUp(self):
        kwargs = {
            "chall": acme_util.HTTP01,
            "uri": "uri",
            "status": messages.STATUS_INVALID,
            "error": messages.Error(typ="urn:acme:error:tls", detail="detail"),
        }

        # Prevent future regressions if the error type changes
        self.assertTrue(kwargs["error"].description is not None)

        self.http01 = achallenges.KeyAuthorizationAnnotatedChallenge(
            # pylint: disable=star-args
            challb=messages.ChallengeBody(**kwargs),
            domain="example.com",
            account_key="key")

        kwargs["chall"] = acme_util.TLSSNI01
        self.tls_sni_same = achallenges.KeyAuthorizationAnnotatedChallenge(
            # pylint: disable=star-args
            challb=messages.ChallengeBody(**kwargs),
            domain="example.com",
            account_key="key")

        kwargs["error"] = messages.Error(typ="dnssec", detail="detail")
        self.tls_sni_diff = achallenges.KeyAuthorizationAnnotatedChallenge(
            # pylint: disable=star-args
            challb=messages.ChallengeBody(**kwargs),
            domain="foo.bar",
            account_key="key")
    def test_perform(self, mock_restart, mock_dvsni_perform):
        # Only tests functionality specific to configurator.perform
        # Note: As more challenges are offered this will have to be expanded
        auth_key = le_util.Key(self.rsa256_file, self.rsa256_pem)
        achall1 = achallenges.DVSNI(challb=messages.ChallengeBody(
            chall=challenges.DVSNI(r="foo", nonce="bar"),
            uri="https://ca.org/chall0_uri",
            status=messages.Status("pending"),
        ),
                                    domain="localhost",
                                    key=auth_key)
        achall2 = achallenges.DVSNI(challb=messages.ChallengeBody(
            chall=challenges.DVSNI(r="abc", nonce="def"),
            uri="https://ca.org/chall1_uri",
            status=messages.Status("pending"),
        ),
                                    domain="example.com",
                                    key=auth_key)

        dvsni_ret_val = [
            challenges.DVSNIResponse(s="irrelevant"),
            challenges.DVSNIResponse(s="arbitrary"),
        ]

        mock_dvsni_perform.return_value = dvsni_ret_val
        responses = self.config.perform([achall1, achall2])

        self.assertEqual(mock_dvsni_perform.call_count, 1)
        self.assertEqual(responses, dvsni_ret_val)
        self.assertEqual(mock_restart.call_count, 1)
    def setUp(self):
        kwargs = {
            "chall": acme_util.HTTP01,
            "uri": "uri",
            "status": messages.STATUS_INVALID,
            "error": messages.Error(typ="tls", detail="detail"),
        }

        self.http01 = achallenges.KeyAuthorizationAnnotatedChallenge(
            # pylint: disable=star-args
            challb=messages.ChallengeBody(**kwargs),
            domain="example.com",
            account_key="key")

        kwargs["chall"] = acme_util.DVSNI
        self.dvsni_same = achallenges.DVSNI(
            # pylint: disable=star-args
            challb=messages.ChallengeBody(**kwargs),
            domain="example.com",
            account_key="key")

        kwargs["error"] = messages.Error(typ="dnssec", detail="detail")
        self.dvsni_diff = achallenges.DVSNI(
            # pylint: disable=star-args
            challb=messages.ChallengeBody(**kwargs),
            domain="foo.bar",
            account_key="key")
Example #6
0
    def test_perform(self, mock_restart, mock_dvsni_perform):
        # Only tests functionality specific to configurator.perform
        # Note: As more challenges are offered this will have to be expanded
        achall1 = achallenges.KeyAuthorizationAnnotatedChallenge(
            challb=messages.ChallengeBody(
                chall=challenges.TLSSNI01(token="kNdwjwOeX0I_A8DXt9Msmg"),
                uri="https://ca.org/chall0_uri",
                status=messages.Status("pending"),
            ),
            domain="localhost",
            account_key=self.rsa512jwk)
        achall2 = achallenges.KeyAuthorizationAnnotatedChallenge(
            challb=messages.ChallengeBody(
                chall=challenges.TLSSNI01(token="m8TdO1qik4JVFtgPPurJmg"),
                uri="https://ca.org/chall1_uri",
                status=messages.Status("pending"),
            ),
            domain="example.com",
            account_key=self.rsa512jwk)

        dvsni_ret_val = [
            achall1.response(self.rsa512jwk),
            achall2.response(self.rsa512jwk),
        ]

        mock_dvsni_perform.return_value = dvsni_ret_val
        responses = self.config.perform([achall1, achall2])

        self.assertEqual(mock_dvsni_perform.call_count, 1)
        self.assertEqual(responses, dvsni_ret_val)
        self.assertEqual(mock_restart.call_count, 1)
Example #7
0
    def setUp(self):
        from letsencrypt import achallenges

        kwargs = {
            "chall" : acme_util.SIMPLE_HTTP,
            "uri": "uri",
            "status": messages.STATUS_INVALID,
            "error": messages.Error(typ="tls", detail="detail"),
        }

        self.simple_http = achallenges.SimpleHTTP(
            challb=messages.ChallengeBody(**kwargs),# pylint: disable=star-args
            domain="example.com",
            account_key="key")

        kwargs["chall"] = acme_util.DVSNI
        self.dvsni_same = achallenges.DVSNI(
            challb=messages.ChallengeBody(**kwargs),# pylint: disable=star-args
            domain="example.com",
            account_key="key")

        kwargs["error"] = messages.Error(typ="dnssec", detail="detail")
        self.dvsni_diff = achallenges.DVSNI(
            challb=messages.ChallengeBody(**kwargs),# pylint: disable=star-args
            domain="foo.bar",
            account_key="key")
Example #8
0
    def setUp(self):
        from certbot._internal.auth_handler import AuthHandler

        self.mock_auth = mock.MagicMock(spec=plugin_common.Plugin, name="buzz")
        self.mock_auth.name = "buzz"
        self.mock_auth.auth_hint.return_value = "the buzz hint"
        self.handler = AuthHandler(self.mock_auth, mock.MagicMock(), mock.MagicMock(), [])

        kwargs = {
            "chall": acme_util.HTTP01,
            "uri": "uri",
            "status": messages.STATUS_INVALID,
            "error": messages.Error.with_code("tls", detail="detail"),
        }

        # Prevent future regressions if the error type changes
        self.assertIsNotNone(kwargs["error"].description)

        http_01 = messages.ChallengeBody(**kwargs)

        kwargs["chall"] = acme_util.HTTP01
        http_01 = messages.ChallengeBody(**kwargs)

        self.authzr1 = mock.MagicMock()
        self.authzr1.body.identifier.value = 'example.com'
        self.authzr1.body.challenges = [http_01, http_01]

        kwargs["error"] = messages.Error.with_code("dnssec", detail="detail")
        http_01_diff = messages.ChallengeBody(**kwargs)

        self.authzr2 = mock.MagicMock()
        self.authzr2.body.identifier.value = 'foo.bar'
        self.authzr2.body.challenges = [http_01_diff]
Example #9
0
    def test_challenge_unexpected_uri(self):
        """
        ``_check_challenge`` raises `~acme.errors.UnexpectedUpdate` if the
        challenge does not have the expected URI.
        """
        # Crazy dance that was used in previous test.
        url1 = URL.fromText(u'https://example.org/').asURI().asText()
        url2 = URL.fromText(u'https://example.com/').asURI().asText()

        with self.assertRaises(errors.UnexpectedUpdate):
            Client._check_challenge(
                challenge=messages.ChallengeResource(
                    body=messages.ChallengeBody(chall=None, uri=url1)),
                challenge_body=messages.ChallengeBody(chall=None, uri=url2),
            )
Example #10
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 setUp(self):
        self.installer = mock.MagicMock()
        certs = [CERT0_PATH, CERT1_PATH, CERT2_PATH, CERT3_PATH]
        keys = [None, None, CERT2_KEY_PATH, CERT3_KEY_PATH]
        self.installer.get_all_certs_keys.return_value = zip(
            certs, keys, 4 * [None])
        self.proof_of_pos = proof_of_possession.ProofOfPossession(
            self.installer)

        hints = challenges.ProofOfPossession.Hints(
            jwk=jose.JWKRSA(key=CERT3_KEY),
            cert_fingerprints=(),
            certs=(),
            serial_numbers=(),
            subject_key_identifiers=(),
            issuers=(),
            authorized_for=())
        chall = challenges.ProofOfPossession(alg=jose.RS256,
                                             nonce='zczv4HMLVe_0kimJ25Juig',
                                             hints=hints)
        challb = messages.ChallengeBody(chall=chall,
                                        uri="http://example",
                                        status=messages.STATUS_PENDING)
        self.achall = achallenges.ProofOfPossession(challb=challb,
                                                    domain="example.com")
Example #12
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.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')
Example #13
0
    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')
Example #14
0
 def setUp(self):
     from certbot.errors import FailedChallenges
     self.error = FailedChallenges({
         achallenges.DNS(domain="example.com",
                         challb=messages.ChallengeBody(
                             chall=acme_util.DNS01,
                             uri=None,
                             error=messages.Error.with_code(
                                 "tls", detail="detail")))
     })
Example #15
0
 def setUp(self):
     from certbot.errors import FailedChallenges
     self.error = FailedChallenges(
         set([
             achallenges.DNS(domain="example.com",
                             challb=messages.ChallengeBody(
                                 chall=acme_util.DNS,
                                 uri=None,
                                 error=messages.Error(typ="tls",
                                                      detail="detail")))
         ]))
Example #16
0
    def test_unicode(self):
        from certbot.errors import FailedChallenges
        arabic_detail = u'\u0639\u062f\u0627\u0644\u0629'
        arabic_error = FailedChallenges({achallenges.DNS(
            domain="example.com", challb=messages.ChallengeBody(
                chall=acme_util.DNS01, uri=None,
                error=messages.Error.with_code("tls", detail=arabic_detail)))})

        self.assertTrue(str(arabic_error).startswith(
            "Failed authorization procedure. example.com (dns-01): "
            "urn:ietf:params:acme:error:tls"))
Example #17
0
def chall_to_challb(chall: challenges.Challenge, status: messages.Status) -> messages.ChallengeBody:
    """Return ChallengeBody from Challenge."""
    kwargs = {
        "chall": chall,
        "uri": chall.typ + "_uri",
        "status": status,
    }

    if status == messages.STATUS_VALID:
        kwargs.update({"validated": datetime.datetime.now()})

    return messages.ChallengeBody(**kwargs)
Example #18
0
def chall_to_challb(chall, status):  # pylint: disable=redefined-outer-name
    """Return ChallengeBody from Challenge."""
    kwargs = {
        "chall": chall,
        "uri": chall.typ + "_uri",
        "status": status,
    }

    if status == messages.STATUS_VALID:
        kwargs.update({"validated": datetime.datetime.now()})

    return messages.ChallengeBody(**kwargs)  # pylint: disable=star-args
Example #19
0
 def request_challenges(self, identifier):
     self._authorizations[identifier] = challenges = OrderedDict()
     for chall_type in self._challenge_types:
         uuid = unicode(uuid4())
         challb = messages.ChallengeBody(chall=chall_type(token=b'token'),
                                         uri=uuid,
                                         status=messages.STATUS_PENDING)
         challenges[chall_type] = uuid
         self._challenges[uuid] = challb
     return succeed(
         messages.AuthorizationResource(body=messages.Authorization(
             identifier=identifier,
             status=messages.STATUS_PENDING,
             challenges=[self._challenges[u] for u in challenges.values()],
             combinations=[[n] for n in range(len(challenges))])))
 def test_perform_bad_challenge(self):
     hints = challenges.ProofOfPossession.Hints(
         jwk=jose.jwk.JWKOct(key=CERT3_KEY),
         cert_fingerprints=(),
         certs=(),
         serial_numbers=(),
         subject_key_identifiers=(),
         issuers=(),
         authorized_for=())
     chall = challenges.ProofOfPossession(alg=jose.HS512,
                                          nonce='zczv4HMLVe_0kimJ25Juig',
                                          hints=hints)
     challb = messages.ChallengeBody(chall=chall,
                                     uri="http://example",
                                     status=messages.STATUS_PENDING)
     self.achall = achallenges.ProofOfPossession(challb=challb,
                                                 domain="example.com")
     self.assertEqual(self.proof_of_pos.perform(self.achall), None)
Example #21
0
def InvalidateAuth(challenge_uri, challenge_token):
	HTTPChallenge = challenges.HTTP01(token=jose.decode_b64jose(challenge_token))
	authorization = HTTPChallenge.validation(KEY)
	HTTPChallengeResponse = challenges.HTTP01Response(key_authorization=authorization)
	challenge_body = messages.ChallengeBody(chall=HTTPChallenge,uri=challenge_uri)
	answer = ACME_CLIENT.answer_challenge(challenge_body,HTTPChallengeResponse)
    def test_perform_and_cleanup(self, request_info):
        # GIVEN a HTTP authnticator challenge
        account_key = jose.JWKRSA.load(
            pkg_resources.resource_string(
                __name__, os.path.join('testdata', 'rsa512_key.pem')))
        token = b"m8TdO1qik4JVFtgPPurJmg"
        domain = "example.com"
        achall = achallenges.KeyAuthorizationAnnotatedChallenge(
            challb=messages.ChallengeBody(
                chall=challenges.HTTP01(token=token),
                uri="https://ca.org/chall1_uri",
                status=messages.Status("pending"),
            ),
            domain=domain,
            account_key=account_key)

        expected = [
            achall.response(account_key),
        ]

        # WHEN the challenge is performed and cleaned up
        responses = self.configurator.perform([achall])

        self.configurator.cleanup([achall])

        # THEN a ACME challenge service is created and
        # then cleaned up in Kong.
        calls = request_info.mock_calls
        requests = self._get_write_requests(calls)

        self.assertEqual(responses, expected)

        acme_service_requests = requests[0:3]
        cleanup_requests = requests[3:]

        service_id = requests[0][1][len("/services/"):]
        plugin_id = requests[1][1][len("/plugins/"):]
        route_id = requests[2][1][len("/routes/"):]

        self.assertEqual(acme_service_requests,
                         [("PUT", "/services/" + service_id, {
                             "name": "certbot-kong_TEMPORARY_ACME_challenge",
                             "url": "http://invalid.example.com"
                         }),
                          ("PUT", "/plugins/" + plugin_id, {
                              "service": {
                                  "id": service_id
                              },
                              "name": "request-termination",
                              "config": {
                                  "status_code": 200,
                                  "content_type": "text/plain",
                                  "body": achall.validation(achall.account_key)
                              }
                          }),
                          ("PUT", "/routes/" + route_id, {
                              "service": {
                                  "id": service_id
                              },
                              "paths": [
                                  "/.well-known/acme-challenge/" +
                                  achall.chall.encode("token")
                              ],
                              "hosts": [domain],
                              "protocols": ["http"]
                          })])

        self.assertEqual(cleanup_requests,
                         [("DELETE", "/routes/" + route_id, None),
                          ("DELETE", "/plugins/" + plugin_id, None),
                          ("DELETE", "/services/" + service_id, None)])