def test_verify_not_before(self, lang): token = generate_token('{"alg":"HS256"}', '{"jti":"123", "nbf":1234}') jwt_mac = testing_servers.jwt_mac(lang, KEYSET) # same time as not-before fine. validator_same_time = jwt.new_validator( allow_missing_expiration=True, fixed_now=datetime.datetime.fromtimestamp(1234, datetime.timezone.utc)) jwt_mac.verify_mac_and_decode(token, validator_same_time) # one second before is not yet valid validator_before = jwt.new_validator( allow_missing_expiration=True, fixed_now=datetime.datetime.fromtimestamp(1233, datetime.timezone.utc)) with self.assertRaises(tink.TinkError): jwt_mac.verify_mac_and_decode(token, validator_before) # 3 seconds too early with 3 seconds clock skew is fine validator_ok_with_clockskew = jwt.new_validator( allow_missing_expiration=True, fixed_now=datetime.datetime.fromtimestamp(1231, datetime.timezone.utc), clock_skew=datetime.timedelta(seconds=3)) jwt_mac.verify_mac_and_decode(token, validator_ok_with_clockskew) # 3 seconds too early with 2 seconds clock skew is not yet valid. validator_too_early_with_clockskew = jwt.new_validator( allow_missing_expiration=True, fixed_now=datetime.datetime.fromtimestamp(1231, datetime.timezone.utc), clock_skew=datetime.timedelta(seconds=2)) with self.assertRaises(tink.TinkError): jwt_mac.verify_mac_and_decode(token, validator_too_early_with_clockskew)
def test_validate_issued_at(self): in_one_minute = (datetime.datetime.now(tz=datetime.timezone.utc) + datetime.timedelta(minutes=1)) one_minute_ago = (datetime.datetime.now(tz=datetime.timezone.utc) - datetime.timedelta(minutes=1)) token_with_issued_at_in_the_future = jwt.new_raw_jwt( issued_at=in_one_minute, without_expiration=True) token_with_issued_at_in_the_past = jwt.new_raw_jwt( issued_at=one_minute_ago, without_expiration=True) token_without_issued_at = jwt.new_raw_jwt(without_expiration=True) validator = jwt.new_validator(allow_missing_expiration=True) _jwt_validator.validate(validator, token_with_issued_at_in_the_future) _jwt_validator.validate(validator, token_with_issued_at_in_the_past) _jwt_validator.validate(validator, token_without_issued_at) issued_at_validator = jwt.new_validator( expect_issued_in_the_past=True, allow_missing_expiration=True) with self.assertRaises(jwt.JwtInvalidError): _jwt_validator.validate(issued_at_validator, token_with_issued_at_in_the_future) _jwt_validator.validate(issued_at_validator, token_with_issued_at_in_the_past) with self.assertRaises(jwt.JwtInvalidError): _jwt_validator.validate(issued_at_validator, token_without_issued_at)
def test_valid_signed_compact(self): jwt_hmac = create_fixed_jwt_hmac() valid_token = create_signed_token('{"alg":"HS256"}', '{"iss":"joe"}') verified = jwt_hmac.verify_mac_and_decode( valid_token, jwt.new_validator( expected_issuer='joe', allow_missing_expiration=True, fixed_now=DATETIME_1970)) self.assertEqual(verified.issuer(), 'joe') token_with_unknown_typ = create_signed_token( '{"alg":"HS256","typ":"unknown"}', '{"iss":"joe"}') verified2 = jwt_hmac.verify_mac_and_decode( token_with_unknown_typ, jwt.new_validator( expected_type_header='unknown', expected_issuer='joe', allow_missing_expiration=True, fixed_now=DATETIME_1970)) self.assertEqual(verified2.issuer(), 'joe') token_with_unknown_kid = create_signed_token( '{"kid":"unknown","alg":"HS256"}', '{"iss":"joe"}') verified2 = jwt_hmac.verify_mac_and_decode( token_with_unknown_kid, jwt.new_validator( expected_issuer='joe', allow_missing_expiration=True, fixed_now=DATETIME_1970)) self.assertEqual(verified2.issuer(), 'joe')
def test_verify_issuer(self, lang): token = generate_token('{"alg":"HS256"}', '{"iss":"joe"}') jwt_mac = testing_servers.jwt_mac(lang, KEYSET) validator_with_correct_issuer = jwt.new_validator( expected_issuer='joe', allow_missing_expiration=True) jwt_mac.verify_mac_and_decode(token, validator_with_correct_issuer) validator_without_issuer = jwt.new_validator(allow_missing_expiration=True) with self.assertRaises(tink.TinkError): jwt_mac.verify_mac_and_decode(token, validator_without_issuer) validator_that_ignores_issuer = jwt.new_validator( ignore_issuer=True, allow_missing_expiration=True) jwt_mac.verify_mac_and_decode(token, validator_that_ignores_issuer) validator_with_wrong_issuer = jwt.new_validator( expected_issuer='Joe', allow_missing_expiration=True) with self.assertRaises(tink.TinkError): jwt_mac.verify_mac_and_decode(token, validator_with_wrong_issuer) val4 = jwt.new_validator( expected_issuer='joe ', allow_missing_expiration=True) with self.assertRaises(tink.TinkError): jwt_mac.verify_mac_and_decode(token, val4)
def test_verify_not_before(self, lang): token = generate_token('{"alg":"HS256"}', '{"iss":"joe", "nbf":1234}') jwt_mac = testing_servers.jwt_mac(lang, KEYSET) # same time as nbf fine. val1 = jwt.new_validator(fixed_now=datetime.datetime.fromtimestamp( 1234, datetime.timezone.utc)) jwt_mac.verify_mac_and_decode(token, val1) # one second before is not yet valid val2 = jwt.new_validator(fixed_now=datetime.datetime.fromtimestamp( 1233, datetime.timezone.utc)) with self.assertRaises(tink.TinkError): jwt_mac.verify_mac_and_decode(token, val2) # 3 seconds too early with 3 seconds clock skew is fine val4 = jwt.new_validator(fixed_now=datetime.datetime.fromtimestamp( 1231, datetime.timezone.utc), clock_skew=datetime.timedelta(seconds=3)) jwt_mac.verify_mac_and_decode(token, val4) # 3 seconds too late with 2 seconds clock skew is fine. val3 = jwt.new_validator(fixed_now=datetime.datetime.fromtimestamp( 1231, datetime.timezone.utc), clock_skew=datetime.timedelta(seconds=2)) with self.assertRaises(tink.TinkError): jwt_mac.verify_mac_and_decode(token, val3)
def test_jwt_mac(self, lang): keyset = testing_servers.new_keyset(lang, jwt.jwt_hs256_template()) jwt_mac_primitive = testing_servers.jwt_mac(lang, keyset) now = datetime.datetime.now(tz=datetime.timezone.utc) token = jwt.new_raw_jwt(issuer='issuer', subject='subject', audiences=['audience1', 'audience2'], jwt_id='jwt_id', expiration=now + datetime.timedelta(seconds=10), custom_claims={ 'switch': True, 'pi': 3.14159 }) compact = jwt_mac_primitive.compute_mac_and_encode(token) validator = jwt.new_validator(audience='audience1', fixed_now=now) # HERE verified_jwt = jwt_mac_primitive.verify_mac_and_decode( compact, validator) self.assertEqual(verified_jwt.issuer(), 'issuer') self.assertEqual(verified_jwt.subject(), 'subject') self.assertEqual(verified_jwt.jwt_id(), 'jwt_id') self.assertEqual(verified_jwt.custom_claim('switch'), True) self.assertEqual(verified_jwt.custom_claim('pi'), 3.14159) validator2 = jwt.new_validator(audience='wrong_audience', fixed_now=now) with self.assertRaises(tink.TinkError): jwt_mac_primitive.verify_mac_and_decode(compact, validator2)
def test_fixed_signed_compact(self): jwt_hmac = create_fixed_jwt_hmac() signed_compact = ( 'eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleH' 'AiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.' 'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk') verified_jwt = jwt_hmac.verify_mac_and_decode( signed_compact, jwt.new_validator(issuer='joe', fixed_now=DATETIME_1970)) self.assertEqual(verified_jwt.issuer(), 'joe') self.assertEqual(verified_jwt.expiration().year, 2011) self.assertCountEqual(verified_jwt.custom_claim_names(), ['http://example.com/is_root']) self.assertTrue( verified_jwt.custom_claim('http://example.com/is_root')) # fails because it is expired with self.assertRaises(tink.TinkError): jwt_hmac.verify_mac_and_decode( signed_compact, jwt.new_validator(fixed_now=DATETIME_2020)) # fails with wrong issuer with self.assertRaises(tink.TinkError): jwt_hmac.verify_mac_and_decode( signed_compact, jwt.new_validator(issuer='jane', fixed_now=DATETIME_1970))
def test_verify_expiration(self, lang): token = generate_token('{"alg":"HS256"}', '{"iss":"joe", "exp":1234}') jwt_mac = testing_servers.jwt_mac(lang, KEYSET) # same time is expired. val1 = jwt.new_validator(fixed_now=datetime.datetime.fromtimestamp( 1234, datetime.timezone.utc)) with self.assertRaises(tink.TinkError): jwt_mac.verify_mac_and_decode(token, val1) # a fraction of a second before is fine val2 = jwt.new_validator(fixed_now=datetime.datetime.fromtimestamp( 1233.75, datetime.timezone.utc)) jwt_mac.verify_mac_and_decode(token, val2) # 3 seconds too late with 3 seconds clock skew is expired. val4 = jwt.new_validator(fixed_now=datetime.datetime.fromtimestamp( 1237, datetime.timezone.utc), clock_skew=datetime.timedelta(seconds=3)) with self.assertRaises(tink.TinkError): jwt_mac.verify_mac_and_decode(token, val4) # 2 seconds too late with 3 seconds clock skew is fine. val3 = jwt.new_validator(fixed_now=datetime.datetime.fromtimestamp( 1236, datetime.timezone.utc), clock_skew=datetime.timedelta(seconds=3)) jwt_mac.verify_mac_and_decode(token, val3)
def test_jwt_public_key_sign_verify(self, lang): key_format = jwt_ecdsa_pb2.JwtEcdsaKeyFormat( algorithm=jwt_ecdsa_pb2.ES256) key_template = tink_pb2.KeyTemplate( type_url='type.googleapis.com/google.crypto.tink.JwtEcdsaPrivateKey', value=key_format.SerializeToString(), output_prefix_type=tink_pb2.RAW) private_keyset = testing_servers.new_keyset(lang, key_template) public_keyset = testing_servers.public_keyset(lang, private_keyset) signer = testing_servers.jwt_public_key_sign(lang, private_keyset) verifier = testing_servers.jwt_public_key_verify(lang, public_keyset) now = datetime.datetime.now(tz=datetime.timezone.utc) token = jwt.new_raw_jwt( issuer='issuer', subject='subject', audiences=['audience1', 'audience2'], jwt_id='jwt_id', expiration=now + datetime.timedelta(seconds=10), custom_claims={'switch': True, 'pi': 3.14159}) compact = signer.sign_and_encode(token) validator = jwt.new_validator(audience='audience1', fixed_now=now) verified_jwt = verifier.verify_and_decode(compact, validator) self.assertEqual(verified_jwt.issuer(), 'issuer') self.assertEqual(verified_jwt.subject(), 'subject') self.assertEqual(verified_jwt.jwt_id(), 'jwt_id') self.assertEqual(verified_jwt.custom_claim('switch'), True) self.assertEqual(verified_jwt.custom_claim('pi'), 3.14159) validator2 = jwt.new_validator(audience='wrong_audience', fixed_now=now) with self.assertRaises(tink.TinkError): verifier.verify_and_decode(compact, validator2)
def test_jwt_mac(self, lang): key_format = jwt_hmac_pb2.JwtHmacKeyFormat( hash_type=common_pb2.SHA256, key_size=32) key_template = tink_pb2.KeyTemplate( type_url='type.googleapis.com/google.crypto.tink.JwtHmacKey', value=key_format.SerializeToString(), output_prefix_type=tink_pb2.RAW) keyset = testing_servers.new_keyset(lang, key_template) jwt_mac_primitive = testing_servers.jwt_mac(lang, keyset) now = datetime.datetime.now(tz=datetime.timezone.utc) token = jwt.new_raw_jwt( issuer='issuer', subject='subject', audiences=['audience1', 'audience2'], jwt_id='jwt_id', expiration=now + datetime.timedelta(seconds=10), custom_claims={'switch': True, 'pi': 3.14159}) compact = jwt_mac_primitive.compute_mac_and_encode(token) validator = jwt.new_validator(audience='audience1', fixed_now=now) verified_jwt = jwt_mac_primitive.verify_mac_and_decode(compact, validator) self.assertEqual(verified_jwt.issuer(), 'issuer') self.assertEqual(verified_jwt.subject(), 'subject') self.assertEqual(verified_jwt.jwt_id(), 'jwt_id') self.assertEqual(verified_jwt.custom_claim('switch'), True) self.assertEqual(verified_jwt.custom_claim('pi'), 3.14159) validator2 = jwt.new_validator(audience='wrong_audience', fixed_now=now) with self.assertRaises(tink.TinkError): jwt_mac_primitive.verify_mac_and_decode(compact, validator2)
def test_verify_expiration(self, lang): token = generate_token('{"alg":"HS256"}', '{"jti":"123", "exp":1234}') jwt_mac = testing_servers.jwt_mac(lang, KEYSET) # same time is expired. validator_with_same_time = jwt.new_validator( fixed_now=datetime.datetime.fromtimestamp(1234, datetime.timezone.utc)) with self.assertRaises(tink.TinkError): jwt_mac.verify_mac_and_decode(token, validator_with_same_time) # a second before is fine validator_before = jwt.new_validator( fixed_now=datetime.datetime.fromtimestamp(1233, datetime.timezone.utc)) jwt_mac.verify_mac_and_decode(token, validator_before) # 3 seconds too late with 3 seconds clock skew is expired. validator_too_late_with_clockskew = jwt.new_validator( fixed_now=datetime.datetime.fromtimestamp(1237, datetime.timezone.utc), clock_skew=datetime.timedelta(seconds=3)) with self.assertRaises(tink.TinkError): jwt_mac.verify_mac_and_decode(token, validator_too_late_with_clockskew) # 2 seconds too late with 3 seconds clock skew is fine. validator_still_ok_with_clockskew = jwt.new_validator( fixed_now=datetime.datetime.fromtimestamp(1236, datetime.timezone.utc), clock_skew=datetime.timedelta(seconds=3)) jwt_mac.verify_mac_and_decode(token, validator_still_ok_with_clockskew)
def test_jwt_public_key_sign_verify(self, lang): private_keyset = testing_servers.new_keyset(lang, jwt.jwt_es256_template()) public_keyset = testing_servers.public_keyset(lang, private_keyset) signer = testing_servers.jwt_public_key_sign(lang, private_keyset) verifier = testing_servers.jwt_public_key_verify(lang, public_keyset) now = datetime.datetime.now(tz=datetime.timezone.utc) token = jwt.new_raw_jwt( issuer='issuer', subject='subject', audiences=['audience1', 'audience2'], jwt_id='jwt_id', expiration=now + datetime.timedelta(seconds=10), custom_claims={'switch': True, 'pi': 3.14159}) compact = signer.sign_and_encode(token) validator = jwt.new_validator( expected_issuer='issuer', expected_audience='audience1', fixed_now=now) verified_jwt = verifier.verify_and_decode(compact, validator) self.assertEqual(verified_jwt.issuer(), 'issuer') self.assertEqual(verified_jwt.subject(), 'subject') self.assertEqual(verified_jwt.jwt_id(), 'jwt_id') self.assertEqual(verified_jwt.custom_claim('switch'), True) self.assertEqual(verified_jwt.custom_claim('pi'), 3.14159) validator2 = jwt.new_validator( expected_audience='wrong_audience', fixed_now=now) with self.assertRaises(tink.TinkError): verifier.verify_and_decode(compact, validator2)
def test_verify_float_not_before(self, lang): token = generate_token('{"alg":"HS256"}', '{"iss":"joe", "nbf":1234.5}') jwt_mac = testing_servers.jwt_mac(lang, KEYSET) val1 = jwt.new_validator( fixed_now=datetime.datetime.fromtimestamp(1234, datetime.timezone.utc)) with self.assertRaises(tink.TinkError): jwt_mac.verify_mac_and_decode(token, val1) val2 = jwt.new_validator( fixed_now=datetime.datetime.fromtimestamp(1235, datetime.timezone.utc)) jwt_mac.verify_mac_and_decode(token, val2)
def test_verify_float_expiration(self, lang): token = generate_token('{"alg":"HS256"}', '{"jti":"123", "exp":1234.5}') jwt_mac = testing_servers.jwt_mac(lang, KEYSET) validate_after = jwt.new_validator( fixed_now=datetime.datetime.fromtimestamp(1235.5, datetime.timezone.utc)) with self.assertRaises(tink.TinkError): jwt_mac.verify_mac_and_decode(token, validate_after) validate_before = jwt.new_validator( fixed_now=datetime.datetime.fromtimestamp(1233.5, datetime.timezone.utc)) jwt_mac.verify_mac_and_decode(token, validate_before)
def test_create_sign_verify(self): handle = tink.new_keyset_handle(jwt.jwt_es256_template()) sign = handle.primitive(jwt.JwtPublicKeySign) verify = handle.public_keyset_handle().primitive( jwt.JwtPublicKeyVerify) raw_jwt = jwt.new_raw_jwt( issuer='joe', expiration=DATETIME_2011, custom_claims={'http://example.com/is_root': True}) signed_compact = sign.sign_and_encode(raw_jwt) validator = jwt.new_validator(expected_issuer='joe', fixed_now=DATETIME_1970) verified_jwt = verify.verify_and_decode(signed_compact, validator) self.assertEqual(verified_jwt.issuer(), 'joe') self.assertEqual(verified_jwt.expiration().year, 2011) self.assertCountEqual(verified_jwt.custom_claim_names(), ['http://example.com/is_root']) self.assertTrue( verified_jwt.custom_claim('http://example.com/is_root')) # fails because it is expired with self.assertRaises(tink.TinkError): verify.verify_and_decode( signed_compact, jwt.new_validator(expected_issuer='joe', fixed_now=DATETIME_2020)) # wrong issuer with self.assertRaises(tink.TinkError): verify.verify_and_decode( signed_compact, jwt.new_validator(expected_issuer='jane', fixed_now=DATETIME_1970)) # invalid format with self.assertRaises(tink.TinkError): verify.verify_and_decode(signed_compact + '.123', validator) # invalid character with self.assertRaises(tink.TinkError): verify.verify_and_decode(signed_compact + '?', validator) # modified signature with self.assertRaises(tink.TinkError): verify.verify_and_decode(signed_compact + 'a', validator) # modified header with self.assertRaises(tink.TinkError): verify.verify_and_decode('a' + signed_compact, validator)
def test_validator_getters(self): fixed_now = datetime.datetime.fromtimestamp(12345, datetime.timezone.utc) clock_skew = datetime.timedelta(minutes=1) validator = jwt.new_validator( expected_type_header='type_header', expected_issuer='issuer', expected_subject='subject', expected_audience='audience', fixed_now=fixed_now, clock_skew=clock_skew) self.assertTrue(validator.has_expected_type_header()) self.assertEqual(validator.expected_type_header(), 'type_header') self.assertTrue(validator.has_expected_issuer()) self.assertEqual(validator.expected_issuer(), 'issuer') self.assertTrue(validator.has_expected_subject()) self.assertEqual(validator.expected_subject(), 'subject') self.assertTrue(validator.has_expected_audience()) self.assertEqual(validator.expected_audience(), 'audience') self.assertFalse(validator.allow_missing_expiration()) self.assertFalse(validator.ignore_issuer()) self.assertFalse(validator.ignore_subject()) self.assertFalse(validator.ignore_audiences()) self.assertTrue(validator.has_fixed_now()) self.assertEqual(validator.fixed_now(), fixed_now) self.assertEqual(validator.clock_skew(), clock_skew)
def test_only_tink_output_prefix_type_encodes_a_kid_header(self): handle = tink.new_keyset_handle(jwt.raw_jwt_hs256_template()) jwt_mac = handle.primitive(jwt.JwtMac) tink_handle = _change_output_prefix_to_tink(handle) tink_jwt_mac = tink_handle.primitive(jwt.JwtMac) raw_jwt = jwt.new_raw_jwt(issuer='issuer', without_expiration=True) token = jwt_mac.compute_mac_and_encode(raw_jwt) token_with_kid = tink_jwt_mac.compute_mac_and_encode(raw_jwt) _, header, _, _ = _jwt_format.split_signed_compact(token) self.assertNotIn('kid', _json_util.json_loads(header)) _, header_with_kid, _, _ = _jwt_format.split_signed_compact( token_with_kid) self.assertIn('kid', _json_util.json_loads(header_with_kid)) validator = jwt.new_validator(expected_issuer='issuer', allow_missing_expiration=True) jwt_mac.verify_mac_and_decode(token, validator) tink_jwt_mac.verify_mac_and_decode(token_with_kid, validator) # With output prefix type RAW, a kid header is ignored jwt_mac.verify_mac_and_decode(token_with_kid, validator) # With output prefix type TINK, a kid header is required. with self.assertRaises(tink.TinkError): tink_jwt_mac.verify_mac_and_decode(token, validator) other_handle = _change_key_id(tink_handle) other_jwt_mac = other_handle.primitive(jwt.JwtMac) # A token with a wrong kid is rejected, even if the signature is ok. with self.assertRaises(tink.TinkError): other_jwt_mac.verify_mac_and_decode(token_with_kid, validator)
def test_validate_not_before_in_the_future_fails(self): in_the_future = (datetime.datetime.now(tz=datetime.timezone.utc) + datetime.timedelta(minutes=1)) token = jwt.new_raw_jwt(not_before=in_the_future) validator = jwt.new_validator() with self.assertRaises(jwt.JwtInvalidError): _jwt_validator.validate(validator, token)
def test_validate_recently_expired_with_clock_skew_success(self): recently_expired = (datetime.datetime.now(tz=datetime.timezone.utc) - datetime.timedelta(minutes=1)) token = jwt.new_raw_jwt(expiration=recently_expired) validator = jwt.new_validator(clock_skew=datetime.timedelta(minutes=2)) # because of clock_skew, the recently expired token is valid _jwt_validator.validate(validator, token)
def test_validate_expired_fails(self): expired = (datetime.datetime.now(tz=datetime.timezone.utc) - datetime.timedelta(minutes=1)) token = jwt.new_raw_jwt(expiration=expired) validator = jwt.new_validator() with self.assertRaises(jwt.JwtInvalidError): _jwt_validator.validate(validator, token)
def test_empty_validator_getters(self): validator = jwt.new_validator() self.assertFalse(validator.has_issuer()) self.assertFalse(validator.has_subject()) self.assertFalse(validator.has_audience()) self.assertFalse(validator.has_fixed_now()) self.assertFalse(validator.clock_skew(), datetime.timedelta())
def test_validate_with_fixed_now_valid_success(self): fixed_now = datetime.datetime.fromtimestamp(12345, datetime.timezone.utc) validator = jwt.new_validator(fixed_now=fixed_now) expiration = fixed_now + datetime.timedelta(minutes=1) not_before = fixed_now - datetime.timedelta(minutes=1) token = jwt.new_raw_jwt(expiration=expiration, not_before=not_before) _jwt_validator.validate(validator, token)
def test_jwt_signature_without_primary(self, key_template_name, lang): """Unsets the primary key and tries to sign and verify JWT signatures.""" template = supported_key_types.KEY_TEMPLATE[key_template_name] private_keyset = testing_servers.new_keyset(lang, template) public_keyset = testing_servers.public_keyset(lang, private_keyset) signer = testing_servers.jwt_public_key_sign(lang, private_keyset) now = datetime.datetime.now(tz=datetime.timezone.utc) raw_jwt = jwt.new_raw_jwt(issuer='issuer', expiration=now + datetime.timedelta(seconds=100)) token = signer.sign_and_encode(raw_jwt) signer_without_primary = testing_servers.jwt_public_key_sign( lang, unset_primary(private_keyset)) with self.assertRaises(tink.TinkError): signer_without_primary.sign_and_encode(raw_jwt) verifier_without_primary = testing_servers.jwt_public_key_verify( lang, unset_primary(public_keyset)) validator = jwt.new_validator(expected_issuer='issuer', fixed_now=now) if lang in ['cc', 'java', 'python']: # C++, Java and Python currently allow this. verifier_without_primary.verify_and_decode(token, validator) else: with self.assertRaises(tink.TinkError): verifier_without_primary.verify_and_decode(token, validator)
def validator_from_proto( proto_validator: testing_api_pb2.JwtValidator) -> jwt.JwtValidator: """Converts a proto JwtValidator into a JwtValidator.""" expected_type_header = None if proto_validator.HasField('expected_type_header'): expected_type_header = proto_validator.expected_type_header.value expected_issuer = None if proto_validator.HasField('expected_issuer'): expected_issuer = proto_validator.expected_issuer.value expected_subject = None if proto_validator.HasField('expected_subject'): expected_subject = proto_validator.expected_subject.value expected_audience = None if proto_validator.HasField('expected_audience'): expected_audience = proto_validator.expected_audience.value fixed_now = None if proto_validator.HasField('now'): fixed_now = _from_timestamp_proto(proto_validator.now) clock_skew = None if proto_validator.HasField('clock_skew'): clock_skew = _from_duration_proto(proto_validator.clock_skew) return jwt.new_validator( expected_type_header=expected_type_header, expected_issuer=expected_issuer, expected_subject=expected_subject, expected_audience=expected_audience, ignore_type_header=proto_validator.ignore_type_header, ignore_issuer=proto_validator.ignore_issuer, ignore_subject=proto_validator.ignore_subject, ignore_audiences=proto_validator.ignore_audience, allow_missing_expiration=proto_validator.allow_missing_expiration, fixed_now=fixed_now, clock_skew=clock_skew)
def test_new_keydata_primitive_success(self, template): key_manager = _jwt_hmac_key_manager.MacCcToPyJwtMacKeyManager() key_data = key_manager.new_key_data(template) jwt_hmac = key_manager.primitive(key_data) raw_jwt = jwt.new_raw_jwt( type_header='typeHeader', issuer='issuer', without_expiration=True) validator = jwt.new_validator( expected_type_header='typeHeader', expected_issuer='issuer', allow_missing_expiration=True, fixed_now=DATETIME_1970) token_with_kid = jwt_hmac.compute_mac_and_encode_with_kid( raw_jwt, kid='kid-123') token_without_kid = jwt_hmac.compute_mac_and_encode_with_kid( raw_jwt, kid=None) # Verification of a token with a kid only fails if the wrong kid is passed. verified_jwt = jwt_hmac.verify_mac_and_decode_with_kid( token_with_kid, validator, kid='kid-123') self.assertEqual(verified_jwt.type_header(), 'typeHeader') self.assertEqual(verified_jwt.issuer(), 'issuer') jwt_hmac.verify_mac_and_decode_with_kid(token_with_kid, validator, kid=None) with self.assertRaises(tink.TinkError): jwt_hmac.verify_mac_and_decode_with_kid( token_with_kid, validator, kid='other-kid') # A token without kid is only valid if no kid is passed. jwt_hmac.verify_mac_and_decode_with_kid( token_without_kid, validator, kid=None) with self.assertRaises(tink.TinkError): jwt_hmac.verify_mac_and_decode_with_kid( token_without_kid, validator, kid='kid-123')
def test_validate_not_before_almost_reached_with_clock_skew_success(self): in_one_minute = (datetime.datetime.now(tz=datetime.timezone.utc) + datetime.timedelta(minutes=1)) token = jwt.new_raw_jwt(not_before=in_one_minute, without_expiration=True) validator = jwt.new_validator( allow_missing_expiration=True, clock_skew=datetime.timedelta(minutes=2)) _jwt_validator.validate(validator, token)
def test_verify_empty_string_issuer(self, lang): token = generate_token('{"alg":"HS256"}', '{"iss":""}') jwt_mac = testing_servers.jwt_mac(lang, KEYSET) jwt_mac.verify_mac_and_decode( token, jwt.new_validator(expected_issuer='', allow_missing_expiration=True))
def main(argv): del argv # Unused. # Initialise Tink try: jwt.register_jwt_signature() except tink.TinkError as e: logging.exception('Error initialising Tink: %s', e) return 1 # Read the keyset into a keyset_handle with open(FLAGS.keyset_path, 'rt') as keyset_file: try: text = keyset_file.read() keyset_handle = cleartext_keyset_handle.read( tink.JsonKeysetReader(text)) except tink.TinkError as e: logging.exception('Error reading keyset: %s', e) return 1 now = datetime.datetime.now(tz=datetime.timezone.utc) if FLAGS.mode == 'sign': # Get the JwtPublicKeySign primitive try: jwt_sign = keyset_handle.primitive(jwt.JwtPublicKeySign) except tink.TinkError as e: logging.exception('Error creating JwtPublicKeySign: %s', e) return 1 # Create token raw_jwt = jwt.new_raw_jwt(subject=FLAGS.subject, expiration=now + datetime.timedelta(seconds=100)) token = jwt_sign.sign_and_encode(raw_jwt) with open(FLAGS.token_path, 'wt') as token_file: token_file.write(token) logging.info('Token has been written to %s', FLAGS.token_path) return 0 # Get the JwtPublicKeyVerify primitive try: jwt_verify = keyset_handle.primitive(jwt.JwtPublicKeyVerify) except tink.TinkError as e: logging.exception('Error creating JwtPublicKeyVerify: %s', e) return 1 # Verify token with open(FLAGS.token_path, 'rt') as token_file: token = token_file.read() validator = jwt.new_validator(expected_subject=FLAGS.subject) try: verified_jwt = jwt_verify.verify_and_decode(token, validator) expires_in = verified_jwt.expiration() - now logging.info('Token is valid and expires in %s seconds', expires_in.seconds) return 0 except tink.TinkError as e: logging.info('JWT verification failed: %s', e) return 1
def test_validate_with_fixed_now_not_yet_valid_fails(self): two_minutes_ago = (datetime.datetime.now(tz=datetime.timezone.utc) - datetime.timedelta(minutes=2)) one_minute_ago = two_minutes_ago + datetime.timedelta(minutes=1) token = jwt.new_raw_jwt(not_before=one_minute_ago) validator = jwt.new_validator(fixed_now=two_minutes_ago) with self.assertRaises(jwt.JwtInvalidError): _jwt_validator.validate(validator, token)
def test_validate_with_fixed_now_expired_fails(self): in_two_minutes = (datetime.datetime.now(tz=datetime.timezone.utc) + datetime.timedelta(minutes=2)) in_one_minute = in_two_minutes - datetime.timedelta(minutes=1) token = jwt.new_raw_jwt(expiration=in_one_minute) validator = jwt.new_validator(fixed_now=in_two_minutes) with self.assertRaises(jwt.JwtInvalidError): _jwt_validator.validate(validator, token)