def test_get_jwt_authority_invalid_input():
    jwt_bundle = JwtBundle(trust_domain, authorities)

    with pytest.raises(ArgumentError) as exception:
        jwt_bundle.get_jwt_authority('')

    assert str(exception.value) == 'key_id cannot be empty.'
def test_get_jwt_authority_empty_authority_dict():
    invalid_authorities = None
    jwt_bundle = JwtBundle(trust_domain, invalid_authorities)

    response = jwt_bundle.get_jwt_authority(key_id='p1')

    assert response is None
示例#3
0
    def parse_and_validate(cls, token: str, jwt_bundle: JwtBundle,
                           audience: List[str]) -> 'JwtSvid':
        """Parses and validates a JWT-SVID token and returns an instance of JwtSvid.

        The JWT-SVID signature is verified using the JWT bundle source.

        Args:
            token: A token as a string that is parsed and validated.
            jwt_bundle: An instance of JwtBundle that provides the JWT authorities to verify the signature.
            audience: A list of strings used to validate the 'aud' claim.

        Returns:
            An instance of JwtSvid with a SPIFFE ID parsed from the 'sub', audience from 'aud', and expiry
            from 'exp' claim.

        Raises:
            JwtSvidError:   When the token expired or the expiration claim is missing,
                            when the algorithm is not supported, when the header 'kid' is missing,
                            when the signature cannot be verified, or
                            when the 'aud' claim has an audience that is not in the audience list provided as parameter.
            ArgumentError:     When the token is blank or cannot be parsed.
            BundleNotFoundError:    If the bundle for the trust domain of the spiffe id from the 'sub'
                                    cannot be found the jwt_bundle_source.
            AuthorityNotFoundError: If the authority cannot be found in the bundle using the value from the 'kid' header.
            InvalidTokenError: In case token is malformed and fails to decode.
        """
        if not token:
            raise ArgumentError(
                INVALID_INPUT_ERROR.format('token cannot be empty'))

        if not jwt_bundle:
            raise ArgumentError(
                INVALID_INPUT_ERROR.format('jwt_bundle cannot be empty'))
        try:
            header_params = jwt.get_unverified_header(token)
            validator = JwtSvidValidator()
            validator.validate_header(header_params)
            key_id = header_params.get('kid')
            signing_key = jwt_bundle.get_jwt_authority(key_id)
            if not signing_key:
                raise AuthorityNotFoundError(key_id)

            public_key_pem = signing_key.public_bytes(
                encoding=serialization.Encoding.PEM,
                format=serialization.PublicFormat.SubjectPublicKeyInfo,
            ).decode('UTF-8')

            claims = jwt.decode(
                token,
                algorithms=header_params.get('alg'),
                key=public_key_pem,
                audience=audience,
                options={
                    'verify_signature': True,
                    'verify_aud': True,
                    'verify_exp': True,
                },
            )

            spiffe_id = SpiffeId.parse(claims.get('sub', None))

            return JwtSvid(spiffe_id, claims['aud'], claims['exp'], claims,
                           token)
        except PyJWTError as err:
            raise InvalidTokenError(str(err))
        except ArgumentError as value_err:
            raise InvalidTokenError(str(value_err))
def test_get_jwt_authority_invalid_key_id_not_found():
    jwt_bundle = JwtBundle(trust_domain, authorities)

    response = jwt_bundle.get_jwt_authority('p0')

    assert response is None
def test_get_jwt_authority_valid_input():
    jwt_bundle = JwtBundle(trust_domain, authorities)

    authority_key = jwt_bundle.get_jwt_authority('kid2')

    assert rsa_key == authority_key