Exemple #1
0
 def test_jwt_mac_sets_custom_kid_for_raw_keys(self, template_name):
     keyset = generate_jwt_mac_keyset_with_custom_kid(
         template_name=template_name, custom_kid='my kid')
     raw_jwt = jwt.new_raw_jwt(without_expiration=True)
     for lang in SUPPORTED_LANGUAGES:
         jwt_mac = testing_servers.jwt_mac(lang, keyset.SerializeToString())
         compact = jwt_mac.compute_mac_and_encode(raw_jwt)
         self.assertEqual(decode_kid(compact), 'my kid')
Exemple #2
0
 def test_jwt_mac_does_not_sets_kid_for_raw_templates(self, template_name):
   key_template = supported_key_types.KEY_TEMPLATE[template_name]
   keyset = testing_servers.new_keyset('cc', key_template)
   raw_jwt = jwt.new_raw_jwt(without_expiration=True)
   for lang in SUPPORTED_LANGUAGES:
     jwt_mac = testing_servers.jwt_mac(lang, keyset)
     compact = jwt_mac.compute_mac_and_encode(raw_jwt)
     self.assertIsNone(decode_kid(compact))
Exemple #3
0
 def test_verify_nonempty_crit_header_invalid(self, lang):
   # See https://tools.ietf.org/html/rfc7515#section-4.1.11
   token = generate_token(
       '{"alg":"HS256","crit":["http://example.invalid/UNDEFINED"],'
       '"http://example.invalid/UNDEFINED":true}', '{"jti":"123"}')
   jwt_mac = testing_servers.jwt_mac(lang, KEYSET)
   with self.assertRaises(tink.TinkError):
     jwt_mac.verify_mac_and_decode(token, EMPTY_VALIDATOR)
Exemple #4
0
 def test_verify_token_with_too_many_recursions_fails(self, lang):
   # num_recursions has been chosen such that parsing of this token fails
   # in all languages. We want to make sure that the algorithm does not
   # hang or crash in this case, but only returns a parsing error.
   num_recursions = 10000
   payload = ('{"a":' * num_recursions) + '""' + ('}' * num_recursions)
   token = generate_token('{"alg":"HS256"}', payload)
   jwt_mac = testing_servers.jwt_mac(lang, KEYSET)
   with self.assertRaises(tink.TinkError):
     jwt_mac.verify_mac_and_decode(token, EMPTY_VALIDATOR)
Exemple #5
0
    def test_verify_audience_string(self, lang):
        token = generate_token('{"alg":"HS256"}', '{"aud":"joe"}')
        jwt_mac = testing_servers.jwt_mac(lang, KEYSET)

        val1 = jwt.new_validator(audience='joe')
        jwt_mac.verify_mac_and_decode(token, val1)

        val3 = EMPTY_VALIDATOR
        with self.assertRaises(tink.TinkError):
            jwt_mac.verify_mac_and_decode(token, val3)
Exemple #6
0
    def test_jwt_mac_without_primary(self, key_template_name, lang):
        """Unsets the primary key and tries to create and verify JWT MACs."""
        template = supported_key_types.KEY_TEMPLATE[key_template_name]
        keyset = testing_servers.new_keyset(lang, template)
        jwt_mac = testing_servers.jwt_mac(lang, keyset)

        now = datetime.datetime.now(tz=datetime.timezone.utc)
        raw_jwt = jwt.new_raw_jwt(issuer='issuer',
                                  expiration=now +
                                  datetime.timedelta(seconds=100))
        token = jwt_mac.compute_mac_and_encode(raw_jwt)

        jwt_mac_without_primary = testing_servers.jwt_mac(
            lang, unset_primary(keyset))
        with self.assertRaises(tink.TinkError):
            jwt_mac_without_primary.compute_mac_and_encode(raw_jwt)

        validator = jwt.new_validator(expected_issuer='issuer', fixed_now=now)
        with self.assertRaises(tink.TinkError):
            jwt_mac_without_primary.verify_mac_and_decode(token, validator)
Exemple #7
0
 def test_jwt_mac_fails_for_tink_keys_with_custom_kid(self, template_name):
   keyset = generate_jwt_mac_keyset_with_custom_kid(
       template_name=template_name, custom_kid='my kid')
   raw_jwt = jwt.new_raw_jwt(without_expiration=True)
   for lang in SUPPORTED_LANGUAGES:
     with self.assertRaises(
         tink.TinkError,
         msg=('%s supports JWT mac keys with TINK output prefix type '
              'and custom_kid set unexpectedly') % lang):
       jwt_mac = testing_servers.jwt_mac(lang, keyset.SerializeToString())
       jwt_mac.compute_mac_and_encode(raw_jwt)
Exemple #8
0
  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)
Exemple #9
0
 def test_compute_verify_jwt_mac(self, key_template_name):
     supported_langs = supported_key_types.SUPPORTED_LANGUAGES_BY_TEMPLATE_NAME[
         key_template_name]
     self.assertNotEmpty(supported_langs)
     key_template = supported_key_types.KEY_TEMPLATE[key_template_name]
     # Take the first supported language to generate the keyset.
     keyset = testing_servers.new_keyset(supported_langs[0], key_template)
     supported_jwt_macs = [
         testing_servers.jwt_mac(lang, keyset) for lang in supported_langs
     ]
     unsupported_jwt_macs = [
         testing_servers.jwt_mac(lang, keyset)
         for lang in SUPPORTED_LANGUAGES if lang not in supported_langs
     ]
     now = datetime.datetime.now(tz=datetime.timezone.utc)
     raw_jwt = jwt.new_raw_jwt(issuer='issuer',
                               expiration=now +
                               datetime.timedelta(seconds=100))
     for p in supported_jwt_macs:
         compact = p.compute_mac_and_encode(raw_jwt)
         validator = jwt.new_validator(expected_issuer='issuer',
                                       fixed_now=now)
         for p2 in supported_jwt_macs:
             verified_jwt = p2.verify_mac_and_decode(compact, validator)
             self.assertEqual(verified_jwt.issuer(), 'issuer')
         for p2 in unsupported_jwt_macs:
             with self.assertRaises(
                     tink.TinkError,
                     msg=
                     '%s supports verify_mac_and_decode with %s unexpectedly'
                     % (p2.lang, key_template_name)):
                 p2.verify_mac_and_decode(compact, validator)
     for p in unsupported_jwt_macs:
         with self.assertRaises(
                 tink.TinkError,
                 msg=
                 '%s supports compute_mac_and_encode with %s unexpectedly' %
             (p.lang, key_template_name)):
             p.compute_mac_and_encode(raw_jwt)
Exemple #10
0
  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)
Exemple #11
0
    def test_verify_issued_at(self, lang):
        token = generate_token('{"alg":"HS256"}', '{"jti":"123", "iat":1234}')
        jwt_mac = testing_servers.jwt_mac(lang, KEYSET)

        # same time as issued-at fine.
        validator_same_time = jwt.new_validator(
            expect_issued_in_the_past=True,
            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(
            expect_issued_in_the_past=True,
            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)

        # ten second before but without expect_issued_in_the_past is fine
        validator_without_iat_validation = jwt.new_validator(
            allow_missing_expiration=True,
            fixed_now=datetime.datetime.fromtimestamp(1224,
                                                      datetime.timezone.utc))
        jwt_mac.verify_mac_and_decode(token, validator_without_iat_validation)

        # 3 seconds too early with 3 seconds clock skew is fine
        validator_ok_with_clockskew = jwt.new_validator(
            expect_issued_in_the_past=True,
            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(
            expect_issued_in_the_past=True,
            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)
Exemple #12
0
    def test_verify_subject(self, lang):
        token = generate_token('{"alg":"HS256"}', '{"sub":"joe"}')
        jwt_mac = testing_servers.jwt_mac(lang, KEYSET)

        val1 = jwt.new_validator(subject='joe')
        jwt_mac.verify_mac_and_decode(token, val1)

        val2 = EMPTY_VALIDATOR
        jwt_mac.verify_mac_and_decode(token, val2)

        val3 = jwt.new_validator(subject='Joe')
        with self.assertRaises(tink.TinkError):
            jwt_mac.verify_mac_and_decode(token, val3)

        val4 = jwt.new_validator(subject='joe ')
        with self.assertRaises(tink.TinkError):
            jwt_mac.verify_mac_and_decode(token, val4)
Exemple #13
0
  def test_verify_typ_header(self, lang):
    token = generate_token(
        '{"typ":"typeHeader", "alg":"HS256"}', '{"jti":"123"}')
    jwt_mac = testing_servers.jwt_mac(lang, KEYSET)

    validator_with_correct_type_header = jwt.new_validator(
        expected_type_header='typeHeader', allow_missing_expiration=True)
    jwt_mac.verify_mac_and_decode(token, validator_with_correct_type_header)

    validator_with_missing_type_header = jwt.new_validator(
        allow_missing_expiration=True)
    with self.assertRaises(tink.TinkError):
      jwt_mac.verify_mac_and_decode(token, validator_with_missing_type_header)

    validator_that_ignores_type_header = jwt.new_validator(
        ignore_type_header=True, allow_missing_expiration=True)
    jwt_mac.verify_mac_and_decode(token, validator_that_ignores_type_header)

    validator_with_wrong_type_header = jwt.new_validator(
        expected_type_header='typeHeader', allow_missing_expiration=True)
    jwt_mac.verify_mac_and_decode(token, validator_with_wrong_type_header)
Exemple #14
0
    def test_verify_float_expiration(self, lang):
        token = generate_token('{"alg":"HS256"}',
                               '{"iss":"joe", "exp":1234.5}')
        jwt_mac = testing_servers.jwt_mac(lang, KEYSET)

        # same time is expired.
        val1 = jwt.new_validator(fixed_now=datetime.datetime.fromtimestamp(
            1234.5, datetime.timezone.utc))
        with self.assertRaises(tink.TinkError):
            jwt_mac.verify_mac_and_decode(token, val1)

        # a fraction of a second after is expired.
        val1 = jwt.new_validator(fixed_now=datetime.datetime.fromtimestamp(
            1234.75, 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(
            1234.25, datetime.timezone.utc))
        jwt_mac.verify_mac_and_decode(token, val2)
Exemple #15
0
    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)
Exemple #16
0
 def test_verify_token_with_many_recursions(self, lang):
   num_recursions = 10
   payload = ('{"a":' * num_recursions) + '""' + ('}' * num_recursions)
   token = generate_token('{"alg":"HS256"}', payload)
   jwt_mac = testing_servers.jwt_mac(lang, KEYSET)
   jwt_mac.verify_mac_and_decode(token, EMPTY_VALIDATOR)
Exemple #17
0
  def test_verify_token_with_empty_audiences(self, lang):
    token = generate_token('{"alg":"HS256"}', '{"aud":[]}')
    jwt_mac = testing_servers.jwt_mac(lang, KEYSET)

    with self.assertRaises(tink.TinkError):
      jwt_mac.verify_mac_and_decode(token, EMPTY_VALIDATOR)
Exemple #18
0
 def test_verify_invalid_utf8_in_payload(self, lang):
   token = generate_token_from_bytes(b'{"alg":"HS256"}', b'{"jti":"joe\xc2"}')
   jwt_mac = testing_servers.jwt_mac(lang, KEYSET)
   with self.assertRaises(tink.TinkError):
     jwt_mac.verify_mac_and_decode(token, EMPTY_VALIDATOR)
Exemple #19
0
  def test_verify_issuer_with_wrong_type(self, lang):
    token = generate_token('{"alg":"HS256"}', '{"iss":123}')
    jwt_mac = testing_servers.jwt_mac(lang, KEYSET)

    with self.assertRaises(tink.TinkError):
      jwt_mac.verify_mac_and_decode(token, EMPTY_VALIDATOR)
Exemple #20
0
 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))
Exemple #21
0
 def test_unknown_typ_header_valid(self, lang):
     token = generate_token('{"typ":"unknown", "alg":"HS256"}',
                            '{"iss":"joe"}')
     jwt_mac = testing_servers.jwt_mac(lang, KEYSET)
     verified_jwt = jwt_mac.verify_mac_and_decode(token, EMPTY_VALIDATOR)
     self.assertEqual(verified_jwt.type_header(), 'unknown')
Exemple #22
0
 def test_large_expiration_is_fine(self, lang):
   token = generate_token('{"alg":"HS256"}', '{"exp":253402300799}')
   jwt_mac = testing_servers.jwt_mac(lang, KEYSET)
   jwt_mac.verify_mac_and_decode(token, EMPTY_VALIDATOR)
Exemple #23
0
 def test_verify_ignores_typ_header(self, lang):
     token = generate_token('{"typ":"unknown", "alg":"HS256"}',
                            '{"iss":"joe"}')
     jwt_mac = testing_servers.jwt_mac(lang, KEYSET)
     jwt_mac.verify_mac_and_decode(token, EMPTY_VALIDATOR)
Exemple #24
0
 def test_verify_unknown_header_valid(self, lang):
   token = generate_token('{"alg":"HS256", "unknown":{"a":"b"}}',
                          '{"jti":"123"}')
   jwt_mac = testing_servers.jwt_mac(lang, KEYSET)
   verified_jwt = jwt_mac.verify_mac_and_decode(token, EMPTY_VALIDATOR)
   self.assertEqual(verified_jwt.jwt_id(), '123')
Exemple #25
0
 def test_verify_valid(self, lang):
     token = generate_token('{"alg":"HS256"}', '{"iss":"joe"}')
     jwt_mac = testing_servers.jwt_mac(lang, KEYSET)
     verified_jwt = jwt_mac.verify_mac_and_decode(token, EMPTY_VALIDATOR)
     self.assertEqual(verified_jwt.issuer(), 'joe')
Exemple #26
0
 def test_verify_empty_crit_header_invalid(self, lang):
     # See https://tools.ietf.org/html/rfc7515#section-4.1.11
     token = generate_token('{"alg":"HS256", "crit":[]}', '{"iss":"joe"}')
     jwt_mac = testing_servers.jwt_mac(lang, KEYSET)
     with self.assertRaises(tink.TinkError):
         jwt_mac.verify_mac_and_decode(token, EMPTY_VALIDATOR)
Exemple #27
0
 def test_too_large_expiration_is_invalid(self, lang):
   token = generate_token('{"alg":"HS256"}', '{"exp":253402300800}')
   jwt_mac = testing_servers.jwt_mac(lang, KEYSET)
   with self.assertRaises(tink.TinkError):
     jwt_mac.verify_mac_and_decode(token, EMPTY_VALIDATOR)
Exemple #28
0
  def test_infinity_expiration_is_invalid(self, lang):
    token = generate_token('{"alg":"HS256"}', '{"jti":"123", "exp":Infinity}')
    jwt_mac = testing_servers.jwt_mac(lang, KEYSET)

    with self.assertRaises(tink.TinkError):
      jwt_mac.verify_mac_and_decode(token, EMPTY_VALIDATOR)
Exemple #29
0
 def test_verify_empty_string_subject(self, lang):
     token = generate_token('{"alg":"HS256"}', '{"sub":""}')
     jwt_mac = testing_servers.jwt_mac(lang, KEYSET)
     jwt_mac.verify_mac_and_decode(token, jwt.new_validator(subject=''))