Example #1
0
    def test_delete_chained_service_key(self):
        # No Authorization header should yield a 400
        self.deleteResponse('key_server.delete_service_key',
                            expected_code=400,
                            service='sample_service',
                            kid='kid1')

        # Generate two keys.
        private_key, _ = model.service_keys.generate_service_key(
            'sample_service', None, kid='kid123')
        model.service_keys.generate_service_key('sample_service',
                                                None,
                                                kid='kid321')

        # Mint a JWT with our test payload
        token = jwt.encode(self._get_test_jwt_payload(),
                           private_key.exportKey('PEM'),
                           'RS256',
                           headers={'kid': 'kid123'})

        # Using the credentials of our second key, attempt tp delete our unapproved key
        self.deleteResponse('key_server.delete_service_key',
                            headers={'Authorization': 'Bearer %s' % token},
                            expected_code=403,
                            service='sample_service',
                            kid='kid321')

        # Approve the second key.
        model.service_keys.approve_service_key(
            'kid123', ServiceKeyApprovalType.SUPERUSER, approver=1)

        # Using the credentials of our approved key, delete our unapproved key
        with assert_action_logged('service_key_delete'):
            self.deleteEmptyResponse(
                'key_server.delete_service_key',
                headers={'Authorization': 'Bearer %s' % token},
                expected_code=204,
                service='sample_service',
                kid='kid321')

        # Attempt to delete a key signed by a key from a different service
        bad_token = jwt.encode(self._get_test_jwt_payload(),
                               private_key.exportKey('PEM'),
                               'RS256',
                               headers={'kid': 'kid5'})
        self.deleteResponse('key_server.delete_service_key',
                            headers={'Authorization': 'Bearer %s' % bad_token},
                            expected_code=403,
                            service='sample_service',
                            kid='kid123')

        # Delete a self-signed, approved key
        with assert_action_logged('service_key_delete'):
            self.deleteEmptyResponse(
                'key_server.delete_service_key',
                headers={'Authorization': 'Bearer %s' % token},
                expected_code=204,
                service='sample_service',
                kid='kid123')
Example #2
0
    def test_delete_unapproved_service_key(self):
        # No Authorization header should yield a 400
        self.deleteResponse(
            "key_server.delete_service_key", expected_code=400, service="sample_service", kid="kid1"
        )

        # Generate an unapproved key.
        private_key, _ = model.service_keys.generate_service_key(
            "sample_service", None, kid="unapprovedkeyhere"
        )

        # Mint a JWT with our test payload
        token = jwt.encode(
            self._get_test_jwt_payload(),
            private_key.private_bytes(
                encoding=serialization.Encoding.PEM,
                format=serialization.PrivateFormat.TraditionalOpenSSL,
                encryption_algorithm=serialization.NoEncryption(),
            ),
            "RS256",
            headers={"kid": "unapprovedkeyhere"},
        )

        # Delete our unapproved key with itself.
        with assert_action_logged("service_key_delete"):
            self.deleteEmptyResponse(
                "key_server.delete_service_key",
                headers={"Authorization": "Bearer %s" % token.decode("ascii")},
                expected_code=204,
                service="sample_service",
                kid="unapprovedkeyhere",
            )
Example #3
0
    def test_delete_unapproved_service_key(self):
        # No Authorization header should yield a 400
        self.deleteResponse('key_server.delete_service_key',
                            expected_code=400,
                            service='sample_service',
                            kid='kid1')

        # Generate an unapproved key.
        private_key, _ = model.service_keys.generate_service_key(
            'sample_service', None, kid='unapprovedkeyhere')

        # Mint a JWT with our test payload
        token = jwt.encode(self._get_test_jwt_payload(),
                           private_key.exportKey('PEM'),
                           'RS256',
                           headers={'kid': 'unapprovedkeyhere'})

        # Delete our unapproved key with itself.
        with assert_action_logged('service_key_delete'):
            self.deleteEmptyResponse(
                'key_server.delete_service_key',
                headers={'Authorization': 'Bearer %s' % token},
                expected_code=204,
                service='sample_service',
                kid='unapprovedkeyhere')
Example #4
0
    def test_delete_unapproved_service_key(self):
        # No Authorization header should yield a 400
        self.deleteResponse("key_server.delete_service_key",
                            expected_code=400,
                            service="sample_service",
                            kid="kid1")

        # Generate an unapproved key.
        private_key, _ = model.service_keys.generate_service_key(
            "sample_service", None, kid="unapprovedkeyhere")

        # Mint a JWT with our test payload
        token = jwt.encode(
            self._get_test_jwt_payload(),
            private_key.exportKey("PEM"),
            "RS256",
            headers={"kid": "unapprovedkeyhere"},
        )

        # Delete our unapproved key with itself.
        with assert_action_logged("service_key_delete"):
            self.deleteEmptyResponse(
                "key_server.delete_service_key",
                headers={"Authorization": "Bearer %s" % token.decode("ascii")},
                expected_code=204,
                service="sample_service",
                kid="unapprovedkeyhere",
            )
Example #5
0
    def test_attempt_delete_service_key_with_expired_key(self):
        # Generate two keys, approving the first.
        private_key, _ = model.service_keys.generate_service_key(
            "sample_service", None, kid="first"
        )
        model.service_keys.approve_service_key(
            "first", ServiceKeyApprovalType.SUPERUSER, approver=1
        )
        model.service_keys.generate_service_key("sample_service", None, kid="second")

        # Mint a JWT with our test payload
        token = jwt.encode(
            self._get_test_jwt_payload(),
            private_key.private_bytes(
                encoding=serialization.Encoding.PEM,
                format=serialization.PrivateFormat.TraditionalOpenSSL,
                encryption_algorithm=serialization.NoEncryption(),
            ),
            "RS256",
            headers={"kid": "first"},
        )

        # Set the expiration of the first to now - some time.
        model.service_keys.set_key_expiration("first", datetime.utcnow() - timedelta(seconds=100))

        # Using the credentials of our second key, attempt to delete our unapproved key
        self.deleteResponse(
            "key_server.delete_service_key",
            headers={"Authorization": "Bearer %s" % token.decode("ascii")},
            expected_code=403,
            service="sample_service",
            kid="second",
        )

        # Set the expiration to the future and delete the key.
        model.service_keys.set_key_expiration("first", datetime.utcnow() + timedelta(seconds=100))

        with assert_action_logged("service_key_delete"):
            self.deleteEmptyResponse(
                "key_server.delete_service_key",
                headers={"Authorization": "Bearer %s" % token.decode("ascii")},
                expected_code=204,
                service="sample_service",
                kid="second",
            )
Example #6
0
    def test_attempt_delete_service_key_with_expired_key(self):
        # Generate two keys, approving the first.
        private_key, _ = model.service_keys.generate_service_key(
            'sample_service', None, kid='first')
        model.service_keys.approve_service_key(
            'first', ServiceKeyApprovalType.SUPERUSER, approver=1)
        model.service_keys.generate_service_key('sample_service',
                                                None,
                                                kid='second')

        # Mint a JWT with our test payload
        token = jwt.encode(self._get_test_jwt_payload(),
                           private_key.exportKey('PEM'),
                           'RS256',
                           headers={'kid': 'first'})

        # Set the expiration of the first to now - some time.
        model.service_keys.set_key_expiration(
            'first',
            datetime.utcnow() - timedelta(seconds=100))

        # Using the credentials of our second key, attempt to delete our unapproved key
        self.deleteResponse('key_server.delete_service_key',
                            headers={'Authorization': 'Bearer %s' % token},
                            expected_code=403,
                            service='sample_service',
                            kid='second')

        # Set the expiration to the future and delete the key.
        model.service_keys.set_key_expiration(
            'first',
            datetime.utcnow() + timedelta(seconds=100))

        with assert_action_logged('service_key_delete'):
            self.deleteEmptyResponse(
                'key_server.delete_service_key',
                headers={'Authorization': 'Bearer %s' % token},
                expected_code=204,
                service='sample_service',
                kid='second')
Example #7
0
    def test_put_service_key(self):
        # No Authorization header should yield a 400
        self.putResponse('key_server.put_service_key',
                         service='sample_service',
                         kid='kid420',
                         expected_code=400)

        # Mint a JWT with our test payload
        private_key = RSA.generate(2048)
        jwk = RSAKey(key=private_key.publickey()).serialize()
        payload = self._get_test_jwt_payload()
        token = jwt.encode(payload, private_key.exportKey('PEM'), 'RS256')

        # Invalid service name should yield a 400.
        self.putResponse('key_server.put_service_key',
                         service='sample service',
                         kid='kid420',
                         headers={
                             'Authorization': 'Bearer %s' % token,
                             'Content-Type': 'application/json',
                         },
                         data=jwk,
                         expected_code=400)

        # Publish a new key
        with assert_action_logged('service_key_create'):
            self.putResponse('key_server.put_service_key',
                             service='sample_service',
                             kid='kid420',
                             headers={
                                 'Authorization': 'Bearer %s' % token,
                                 'Content-Type': 'application/json',
                             },
                             data=jwk,
                             expected_code=202)

        # Ensure that the key exists but is unapproved.
        self.getResponse('key_server.get_service_key',
                         service='sample_service',
                         kid='kid420',
                         expected_code=409)

        # Attempt to rotate the key. Since not approved, it will fail.
        token = jwt.encode(payload,
                           private_key.exportKey('PEM'),
                           'RS256',
                           headers={'kid': 'kid420'})
        self.putResponse('key_server.put_service_key',
                         service='sample_service',
                         kid='kid6969',
                         headers={
                             'Authorization': 'Bearer %s' % token,
                             'Content-Type': 'application/json',
                         },
                         data=jwk,
                         expected_code=403)

        # Approve the key.
        model.service_keys.approve_service_key(
            'kid420', ServiceKeyApprovalType.SUPERUSER, approver=1)

        # Rotate that new key
        with assert_action_logged('service_key_rotate'):
            token = jwt.encode(payload,
                               private_key.exportKey('PEM'),
                               'RS256',
                               headers={'kid': 'kid420'})
            self.putResponse('key_server.put_service_key',
                             service='sample_service',
                             kid='kid6969',
                             headers={
                                 'Authorization': 'Bearer %s' % token,
                                 'Content-Type': 'application/json',
                             },
                             data=jwk,
                             expected_code=200)

        # Rotation should only work when signed by the previous key
        private_key = RSA.generate(2048)
        jwk = RSAKey(key=private_key.publickey()).serialize()
        token = jwt.encode(payload,
                           private_key.exportKey('PEM'),
                           'RS256',
                           headers={'kid': 'kid420'})
        self.putResponse('key_server.put_service_key',
                         service='sample_service',
                         kid='kid6969',
                         headers={
                             'Authorization': 'Bearer %s' % token,
                             'Content-Type': 'application/json',
                         },
                         data=jwk,
                         expected_code=403)
Example #8
0
    def test_delete_chained_service_key(self):
        # No Authorization header should yield a 400
        self.deleteResponse(
            "key_server.delete_service_key", expected_code=400, service="sample_service", kid="kid1"
        )

        # Generate two keys.
        private_key, _ = model.service_keys.generate_service_key(
            "sample_service", None, kid="kid123"
        )
        model.service_keys.generate_service_key("sample_service", None, kid="kid321")

        # Mint a JWT with our test payload
        token = jwt.encode(
            self._get_test_jwt_payload(),
            private_key.private_bytes(
                encoding=serialization.Encoding.PEM,
                format=serialization.PrivateFormat.TraditionalOpenSSL,
                encryption_algorithm=serialization.NoEncryption(),
            ),
            "RS256",
            headers={"kid": "kid123"},
        )

        # Using the credentials of our second key, attempt tp delete our unapproved key
        self.deleteResponse(
            "key_server.delete_service_key",
            headers={"Authorization": "Bearer %s" % token.decode("ascii")},
            expected_code=403,
            service="sample_service",
            kid="kid321",
        )

        # Approve the second key.
        model.service_keys.approve_service_key(
            "kid123", ServiceKeyApprovalType.SUPERUSER, approver=1
        )

        # Using the credentials of our approved key, delete our unapproved key
        with assert_action_logged("service_key_delete"):
            self.deleteEmptyResponse(
                "key_server.delete_service_key",
                headers={"Authorization": "Bearer %s" % token.decode("ascii")},
                expected_code=204,
                service="sample_service",
                kid="kid321",
            )

        # Attempt to delete a key signed by a key from a different service
        bad_token = jwt.encode(
            self._get_test_jwt_payload(),
            private_key.private_bytes(
                encoding=serialization.Encoding.PEM,
                format=serialization.PrivateFormat.TraditionalOpenSSL,
                encryption_algorithm=serialization.NoEncryption(),
            ),
            "RS256",
            headers={"kid": "kid5"},
        )
        self.deleteResponse(
            "key_server.delete_service_key",
            headers={"Authorization": "Bearer %s" % bad_token.decode("ascii")},
            expected_code=403,
            service="sample_service",
            kid="kid123",
        )

        # Delete a self-signed, approved key
        with assert_action_logged("service_key_delete"):
            self.deleteEmptyResponse(
                "key_server.delete_service_key",
                headers={"Authorization": "Bearer %s" % token.decode("ascii")},
                expected_code=204,
                service="sample_service",
                kid="kid123",
            )
Example #9
0
    def test_put_service_key(self):
        # No Authorization header should yield a 400
        self.putResponse(
            "key_server.put_service_key", service="sample_service", kid="kid420", expected_code=400
        )

        # Mint a JWT with our test payload
        jwk = JsonWebKey.generate_key("RSA", 2048, is_private=True)
        private_pem = jwk.get_private_key().private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=serialization.NoEncryption(),
        )

        payload = self._get_test_jwt_payload()
        token = jwt.encode(payload, private_pem, "RS256")

        # Invalid service name should yield a 400.
        self.putResponse(
            "key_server.put_service_key",
            service="sample service",
            kid="kid420",
            headers={
                "Authorization": "Bearer %s" % token.decode("ascii"),
                "Content-Type": "application/json",
            },
            data=jwk.as_dict(),
            expected_code=400,
        )

        # Publish a new key
        with assert_action_logged("service_key_create"):
            self.putResponse(
                "key_server.put_service_key",
                service="sample_service",
                kid="kid420",
                headers={
                    "Authorization": "Bearer %s" % token.decode("ascii"),
                    "Content-Type": "application/json",
                },
                data=jwk.as_dict(),
                expected_code=202,
            )

        # Ensure that the key exists but is unapproved.
        self.getResponse(
            "key_server.get_service_key", service="sample_service", kid="kid420", expected_code=409
        )

        # Attempt to rotate the key. Since not approved, it will fail.
        token = jwt.encode(payload, private_pem, "RS256", headers={"kid": "kid420"})
        self.putResponse(
            "key_server.put_service_key",
            service="sample_service",
            kid="kid6969",
            headers={
                "Authorization": "Bearer %s" % token.decode("ascii"),
                "Content-Type": "application/json",
            },
            data=jwk.as_dict(),
            expected_code=403,
        )

        # Approve the key.
        model.service_keys.approve_service_key(
            "kid420", ServiceKeyApprovalType.SUPERUSER, approver=1
        )

        # Rotate that new key
        with assert_action_logged("service_key_rotate"):
            token = jwt.encode(payload, private_pem, "RS256", headers={"kid": "kid420"})
            self.putResponse(
                "key_server.put_service_key",
                service="sample_service",
                kid="kid6969",
                headers={
                    "Authorization": "Bearer %s" % token.decode("ascii"),
                    "Content-Type": "application/json",
                },
                data=jwk.as_dict(),
                expected_code=200,
            )

        # Rotation should only work when signed by the previous key
        jwk = JsonWebKey.generate_key("RSA", 2048, is_private=True)
        private_pem = jwk.get_private_key().private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=serialization.NoEncryption(),
        )

        token = jwt.encode(payload, private_pem, "RS256", headers={"kid": "kid420"})
        self.putResponse(
            "key_server.put_service_key",
            service="sample_service",
            kid="kid6969",
            headers={
                "Authorization": "Bearer %s" % token.decode("ascii"),
                "Content-Type": "application/json",
            },
            data=jwk.as_dict(),
            expected_code=403,
        )
Example #10
0
    def test_put_service_key(self):
        # No Authorization header should yield a 400
        self.putResponse("key_server.put_service_key",
                         service="sample_service",
                         kid="kid420",
                         expected_code=400)

        # Mint a JWT with our test payload
        private_key = RSA.generate(2048)
        jwk = RSAKey(key=private_key.publickey()).serialize()
        payload = self._get_test_jwt_payload()
        token = jwt.encode(payload, private_key.exportKey("PEM"), "RS256")

        # Invalid service name should yield a 400.
        self.putResponse(
            "key_server.put_service_key",
            service="sample service",
            kid="kid420",
            headers={
                "Authorization": "Bearer %s" % token.decode("ascii"),
                "Content-Type": "application/json",
            },
            data=jwk,
            expected_code=400,
        )

        # Publish a new key
        with assert_action_logged("service_key_create"):
            self.putResponse(
                "key_server.put_service_key",
                service="sample_service",
                kid="kid420",
                headers={
                    "Authorization": "Bearer %s" % token.decode("ascii"),
                    "Content-Type": "application/json",
                },
                data=jwk,
                expected_code=202,
            )

        # Ensure that the key exists but is unapproved.
        self.getResponse("key_server.get_service_key",
                         service="sample_service",
                         kid="kid420",
                         expected_code=409)

        # Attempt to rotate the key. Since not approved, it will fail.
        token = jwt.encode(payload,
                           private_key.exportKey("PEM"),
                           "RS256",
                           headers={"kid": "kid420"})
        self.putResponse(
            "key_server.put_service_key",
            service="sample_service",
            kid="kid6969",
            headers={
                "Authorization": "Bearer %s" % token.decode("ascii"),
                "Content-Type": "application/json",
            },
            data=jwk,
            expected_code=403,
        )

        # Approve the key.
        model.service_keys.approve_service_key(
            "kid420", ServiceKeyApprovalType.SUPERUSER, approver=1)

        # Rotate that new key
        with assert_action_logged("service_key_rotate"):
            token = jwt.encode(payload,
                               private_key.exportKey("PEM"),
                               "RS256",
                               headers={"kid": "kid420"})
            self.putResponse(
                "key_server.put_service_key",
                service="sample_service",
                kid="kid6969",
                headers={
                    "Authorization": "Bearer %s" % token.decode("ascii"),
                    "Content-Type": "application/json",
                },
                data=jwk,
                expected_code=200,
            )

        # Rotation should only work when signed by the previous key
        private_key = RSA.generate(2048)
        jwk = RSAKey(key=private_key.publickey()).serialize()
        token = jwt.encode(payload,
                           private_key.exportKey("PEM"),
                           "RS256",
                           headers={"kid": "kid420"})
        self.putResponse(
            "key_server.put_service_key",
            service="sample_service",
            kid="kid6969",
            headers={
                "Authorization": "Bearer %s" % token.decode("ascii"),
                "Content-Type": "application/json",
            },
            data=jwk,
            expected_code=403,
        )