def test_parse_and_validate_invalid_parameters(test_input_token, test_input_jwt_bundle, test_input_audience, expected): with pytest.raises(ArgumentError) as exception: JwtSvid.parse_and_validate(test_input_token, test_input_jwt_bundle, test_input_audience) assert str(exception.value) == expected
def test_parse_and_validate_invalid_missing_kid(): key_id = 'kid10' token = create_jwt(kid=key_id) with pytest.raises(AuthorityNotFoundError) as exception: JwtSvid.parse_and_validate(token, JWT_BUNDLE, ['spire']) assert str( exception.value) == 'Key (' + key_id + ') not found in authorities.'
def test_parse_and_validate_invalid_kid_mismatch(): rsa_key2 = rsa.generate_private_key(public_exponent=65537, key_size=2048) jwt_bundle = JwtBundle( DEFAULT_TRUST_DOMAIN, { 'kid1': DEFAULT_KEY.public_key(), 'kid10': rsa_key2.public_key() }, ) token = create_jwt(kid='kid10') with pytest.raises(InvalidTokenError) as exception: JwtSvid.parse_and_validate(token, jwt_bundle, ['spire']) assert str(exception.value) == 'Signature verification failed.'
def test_parse_and_validate_valid_token_RSA(): token = create_jwt() jwt_svid = JwtSvid.parse_and_validate(token, JWT_BUNDLE, ['spire']) assert jwt_svid.audience == DEFAULT_AUDIENCE assert str(jwt_svid.spiffe_id) == DEFAULT_SPIFFE_ID assert jwt_svid.expiry == DEFAULT_EXPIRY assert jwt_svid.token == token
def validate_jwt_svid(self, token: str, audience: str) -> JwtSvid: """Validates the JWT-SVID token. The parsed and validated JWT-SVID is returned. Args: token: JWT to validate. audience: Audience to validate against. Returns: JwtSvid: If the token and audience could be validated. Raises: ArgumentError: In case token or audience is empty. ValidateJwtSvidError: In case an error occurs calling the Workload API or in case the response from the Workload API cannot be processed. """ if not token: raise ArgumentError('Token cannot be empty') if not audience: raise ArgumentError('Audience cannot be empty') self._spiffe_workload_api_stub.ValidateJWTSVID( request=workload_pb2.ValidateJWTSVIDRequest( audience=audience, svid=token, )) return JwtSvid.parse_insecure(token, [audience])
def fetch_jwt_svid(self, audiences: List[str], subject: Optional[SpiffeId] = None) -> JwtSvid: """Fetches a SPIFFE JWT-SVID. Args: audiences: List of audiences for the JWT SVID. subject: SPIFFE ID subject for the JWT. Returns: JwtSvid: Instance of JwtSvid object. Raises: ArgumentError: In case audience is empty. FetchJwtSvidError: In case there is an error in fetching the JWT-SVID from the Workload API. """ if not audiences: raise ArgumentError('Parameter audiences cannot be empty') response = self._spiffe_workload_api_stub.FetchJWTSVID( request=workload_pb2.JWTSVIDRequest( audience=audiences, spiffe_id=str(subject), )) if len(response.svids) == 0: raise FetchJwtSvidError('JWT SVID response is empty') svid = response.svids[0].svid return JwtSvid.parse_insecure(svid, audiences)
def validate_jwt_svid(self, token: str, audience: str) -> JwtSvid: """Validates the JWT-SVID token. The parsed and validated JWT-SVID is returned. Args: token: JWT to validate. audience: Audience to validate against. Returns: JwtSvid: If the token and audience could be validated. ArgumentError: In case token or audience is empty. """ if not token: raise ArgumentError('Token cannot be empty') if not audience: raise ArgumentError('Audience cannot be empty') try: request = workload_pb2.ValidateJWTSVIDRequest( audience=audience, svid=token, ) self._spiffe_workload_api_stub.ValidateJWTSVID(request) except Exception as e: raise ValidateJwtSvidError(str(e)) return JwtSvid.parse_insecure(token, [audience])
def test_parse_and_validate_valid_token_EC(): ec_key = ec.generate_private_key(ec.SECP384R1(), default_backend()) jwt_bundle = JwtBundle(DEFAULT_TRUST_DOMAIN, {'kid_ec': ec_key.public_key()}) ec_key_pem, _ = get_keys_pems(ec_key) token = create_jwt(ec_key_pem, 'kid_ec', alg='ES512') jwt_svid = JwtSvid.parse_and_validate(token, jwt_bundle, ['spire']) assert jwt_svid.audience == DEFAULT_AUDIENCE assert str(jwt_svid.spiffe_id) == DEFAULT_SPIFFE_ID assert jwt_svid.expiry == DEFAULT_EXPIRY assert jwt_svid.token == token
def test_parse_and_validate_valid_token_multiple_keys_bundle(): ec_key = ec.generate_private_key(ec.SECP521R1(), default_backend()) jwt_bundle = JwtBundle( DEFAULT_TRUST_DOMAIN, { 'kid_rsa': DEFAULT_KEY.public_key(), 'kid_ec': ec_key.public_key() }, ) ec_key_pem, _ = get_keys_pems(ec_key) token = create_jwt(ec_key_pem, kid='kid_ec', alg='ES512') jwt_svid1 = JwtSvid.parse_and_validate(token, jwt_bundle, ['spire']) assert jwt_svid1.audience == DEFAULT_AUDIENCE assert str(jwt_svid1.spiffe_id) == DEFAULT_SPIFFE_ID assert jwt_svid1.expiry == DEFAULT_EXPIRY assert jwt_svid1.token == token token2 = create_jwt(kid='kid_rsa') jwt_svid2 = JwtSvid.parse_and_validate(token2, jwt_bundle, ['spire']) assert jwt_svid2.audience == DEFAULT_AUDIENCE assert str(jwt_svid2.spiffe_id) == DEFAULT_SPIFFE_ID assert jwt_svid2.expiry == DEFAULT_EXPIRY assert jwt_svid2.token == token2
def fetch_jwt_svid(self, audiences: List[str], subject: Optional[SpiffeId] = None) -> JwtSvid: """Fetches a SPIFFE JWT-SVID. Args: audiences: List of audiences for the JWT SVID. subject: SPIFFE ID subject for the JWT. Returns: JwtSvid: Instance of JwtSvid object. Raises: ArgumentError: In case audience is empty. FetchJwtSvidError: In case there is an error in fetching the JWTSVID from the Workload API. """ if not audiences: raise ArgumentError('Parameter audiences cannot be empty') try: response = self._call_fetch_jwt_svids(audiences, str(subject)) svid = response.svids[0].svid return JwtSvid.parse_insecure(svid, audiences) except JwtSvidError as e: raise FetchJwtSvidError(str(e))
def test_invalid_input_parse_insecure(test_input_token, test_input_audience, expected): with pytest.raises(ValueError) as exception: JwtSvid.parse_insecure(test_input_token, test_input_audience) assert str(exception.value) == expected
def test_valid_parse_insecure(test_input_token, test_input_audience, expected): result = JwtSvid.parse_insecure(test_input_token, test_input_audience) assert result.token == test_input_token assert str(result.spiffeId) == expected
def test_invalid_token_parse_insecure(test_input_token, test_input_audience): with pytest.raises(InvalidTokenError): JwtSvid.parse_insecure(test_input_token, test_input_audience)
def test_parse_and_validate_invalid_missing_sub(): token = create_jwt(spiffe_id='') with pytest.raises(InvalidTokenError) as exception: JwtSvid.parse_and_validate(token, JWT_BUNDLE, ['spire']) assert str(exception.value) == 'SPIFFE ID cannot be empty.'