Ejemplo n.º 1
0
    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_raw_key_with_custom_kid_header(self, template):
    # normal key with output prefix RAW
    handle = tink.new_keyset_handle(template)
    raw_jwt = jwt.new_raw_jwt(issuer='issuer', without_expiration=True)
    validator = jwt.new_validator(
        expected_issuer='issuer', allow_missing_expiration=True)

    sign = handle.primitive(jwt.JwtPublicKeySign)
    token = sign.sign_and_encode(raw_jwt)
    verify = handle.public_keyset_handle().primitive(jwt.JwtPublicKeyVerify)
    verify.verify_and_decode(token, validator)

    _, json_header, _, _ = _jwt_format.split_signed_compact(token)
    self.assertNotIn('kid', _json_util.json_loads(json_header))

    # key with a custom_kid set
    custom_kid_handle = _set_custom_kid(handle, custom_kid=LONG_CUSTOM_KID)
    custom_kid_sign = custom_kid_handle.primitive(jwt.JwtPublicKeySign)
    token_with_kid = custom_kid_sign.sign_and_encode(raw_jwt)
    custom_kid_verify = custom_kid_handle.public_keyset_handle().primitive(
        jwt.JwtPublicKeyVerify)
    custom_kid_verify.verify_and_decode(token_with_kid, validator)

    _, header_with_kid, _, _ = _jwt_format.split_signed_compact(token_with_kid)
    self.assertEqual(_json_util.json_loads(header_with_kid)['kid'],
                     LONG_CUSTOM_KID)

    # The primitive with a custom_kid set accepts tokens without kid header.
    custom_kid_verify.verify_and_decode(token, validator)

    # The primitive without a custom_kid set ignores the kid header.
    verify.verify_and_decode(token_with_kid, validator)

    # key with a different custom_kid set
    other_handle = _set_custom_kid(handle, custom_kid='other kid')
    other_verify = other_handle.public_keyset_handle().primitive(
        jwt.JwtPublicKeyVerify)
    # Fails because the kid value do not match.
    with self.assertRaises(tink.TinkError):
      other_verify.verify_and_decode(token_with_kid, validator)

    tink_handle = _change_output_prefix_to_tink(custom_kid_handle)
    tink_sign = tink_handle.primitive(jwt.JwtPublicKeySign)
    tink_verify = tink_handle.public_keyset_handle().primitive(
        jwt.JwtPublicKeyVerify)
    # Having custom_kid set with output prefix TINK is not allowed.
    with self.assertRaises(tink.TinkError):
      tink_sign.sign_and_encode(raw_jwt)
    with self.assertRaises(tink.TinkError):
      tink_verify.verify_and_decode(token, validator)
    with self.assertRaises(tink.TinkError):
      tink_verify.verify_and_decode(token_with_kid, validator)
Ejemplo n.º 3
0
    def test_signed_compact_create_split_with_kid(self):
        raw_jwt = _raw_jwt.raw_jwt_from_json(None, '{"iss":"joe"}')
        signature = _jwt_format.decode_signature(
            b'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk')
        unsigned_compact = _jwt_format.create_unsigned_compact(
            'RS256', 'AZxkm2U', raw_jwt)
        signed_compact = _jwt_format.create_signed_compact(
            unsigned_compact, signature)
        un_comp, hdr, pay, sig = _jwt_format.split_signed_compact(
            signed_compact)

        self.assertEqual(
            unsigned_compact,
            b'eyJraWQiOiJBWnhrbTJVIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJqb2UifQ')
        self.assertEqual(
            signed_compact,
            'eyJraWQiOiJBWnhrbTJVIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJqb2UifQ'
            '.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk')
        self.assertEqual(un_comp, unsigned_compact)
        self.assertEqual(sig, signature)
        self.assertEqual(hdr, '{"kid":"AZxkm2U","alg":"RS256"}')
        header = _json_util.json_loads(hdr)
        _jwt_format.validate_header(header, 'RS256')
        self.assertEqual(pay, '{"iss":"joe"}')
        self.assertIsNone(_jwt_format.get_type_header(header))
Ejemplo n.º 4
0
 def test_split_signed_compact_success(self):
     un_comp, hdr, pay, sig = _jwt_format.split_signed_compact(
         'e30.e30.YWJj')
     self.assertEqual(un_comp, b'e30.e30')
     self.assertEqual(sig, b'abc')
     self.assertEqual(hdr, '{}')
     self.assertEqual(pay, '{}')
Ejemplo n.º 5
0
    def test_ps256_key_with_a_custom_kid_header(self):
        keyset_handle = tink.new_keyset_handle(
            jwt.raw_jwt_ps256_2048_f4_template())

        # Add a custom kid to the key in keyset_handle
        value = keyset_handle._keyset.key[0].key_data.value
        pss_key = jwt_rsa_ssa_pss_pb2.JwtRsaSsaPssPrivateKey.FromString(value)
        pss_key.public_key.custom_kid.value = 'my kid'
        keyset_handle._keyset.key[
            0].key_data.value = pss_key.SerializeToString()

        sign = keyset_handle.primitive(jwt.JwtPublicKeySign)

        raw_jwt = jwt.new_raw_jwt(issuer='issuer', without_expiration=True)
        signed_compact = sign.sign_and_encode(raw_jwt)

        _, json_header, _, _ = _jwt_format.split_signed_compact(signed_compact)
        header = _jwt_format.json_loads(json_header)
        self.assertEqual(header['kid'], 'my kid')

        # Now, change the output prefix type to TINK. This should fail.
        keyset_handle._keyset.key[0].output_prefix_type = tink_pb2.TINK
        with self.assertRaises(tink.TinkError):
            tink_sign = keyset_handle.primitive(jwt.JwtPublicKeySign)
            tink_sign.sign_and_encode(raw_jwt)
Ejemplo n.º 6
0
    def test_raw_output_prefix_type_encodes_a_custom_kid_header(self):
        # normal HMAC jwt_mac with output prefix RAW
        handle = tink.new_keyset_handle(jwt.raw_jwt_hs256_template())
        raw_jwt = jwt.new_raw_jwt(issuer='issuer', without_expiration=True)
        validator = jwt.new_validator(expected_issuer='issuer',
                                      allow_missing_expiration=True)

        jwt_mac = handle.primitive(jwt.JwtMac)
        token = jwt_mac.compute_mac_and_encode(raw_jwt)
        jwt_mac.verify_mac_and_decode(token, validator)

        _, json_header, _, _ = _jwt_format.split_signed_compact(token)
        self.assertNotIn('kid', _json_util.json_loads(json_header))

        # HMAC jwt_mac with a custom_kid set
        custom_kid_handle = _set_custom_kid(handle, custom_kid='my kid')
        custom_kid_jwt_mac = custom_kid_handle.primitive(jwt.JwtMac)
        token_with_kid = custom_kid_jwt_mac.compute_mac_and_encode(raw_jwt)
        custom_kid_jwt_mac.verify_mac_and_decode(token_with_kid, validator)

        _, header_with_kid, _, _ = _jwt_format.split_signed_compact(
            token_with_kid)
        self.assertEqual(
            _json_util.json_loads(header_with_kid)['kid'], 'my kid')

        # Even when custom_kid is set, its not required to be set in the header.
        custom_kid_jwt_mac.verify_mac_and_decode(token, validator)
        # An additional kid header is ignored.
        jwt_mac.verify_mac_and_decode(token_with_kid, validator)

        other_handle = _set_custom_kid(handle, custom_kid='other kid')
        other_jwt_mac = other_handle.primitive(jwt.JwtMac)
        with self.assertRaises(tink.TinkError):
            # The custom_kid does not match the kid header.
            other_jwt_mac.verify_mac_and_decode(token_with_kid, validator)

        tink_handle = _change_output_prefix_to_tink(custom_kid_handle)
        tink_jwt_mac = tink_handle.primitive(jwt.JwtMac)
        # having custom_kid set with output prefix TINK is not allowed
        with self.assertRaises(tink.TinkError):
            tink_jwt_mac.compute_mac_and_encode(raw_jwt)
        with self.assertRaises(tink.TinkError):
            tink_jwt_mac.verify_mac_and_decode(token, validator)
        with self.assertRaises(tink.TinkError):
            tink_jwt_mac.verify_mac_and_decode(token_with_kid, validator)
Ejemplo n.º 7
0
    def test_tink_output_prefix_type_encodes_a_kid_header(self):
        keyset_handle = tink.new_keyset_handle(jwt_es256_tink_template())
        sign = keyset_handle.primitive(jwt.JwtPublicKeySign)

        raw_jwt = jwt.new_raw_jwt(issuer='issuer', without_expiration=True)
        signed_compact = sign.sign_and_encode(raw_jwt)

        _, json_header, _, _ = _jwt_format.split_signed_compact(signed_compact)
        header = _jwt_format.json_loads(json_header)
        self.assertIn('kid', header)
Ejemplo n.º 8
0
 def verify_mac_and_decode(
     self, compact: Text,
     validator: _jwt_validator.JwtValidator) -> _verified_jwt.VerifiedJwt:
   """Verifies, validates and decodes a MACed compact JWT token."""
   parts = _jwt_format.split_signed_compact(compact)
   unsigned_compact, json_header, json_payload, mac = parts
   self._verify_mac(mac, unsigned_compact)
   _jwt_format.validate_header(json_header, self._algorithm)
   raw_jwt = _raw_jwt.RawJwt.from_json_payload(json_payload)
   _jwt_validator.validate(validator, raw_jwt)
   return _verified_jwt.VerifiedJwt._create(raw_jwt)  # pylint: disable=protected-access
  def test_only_tink_output_prefix_type_encodes_a_kid_header(self):
    handle = tink.new_keyset_handle(jwt.raw_jwt_es256_template())
    sign = handle.primitive(jwt.JwtPublicKeySign)
    verify = handle.public_keyset_handle().primitive(jwt.JwtPublicKeyVerify)

    tink_handle = _change_output_prefix_to_tink(handle)
    tink_sign = tink_handle.primitive(jwt.JwtPublicKeySign)
    tink_verify = tink_handle.public_keyset_handle().primitive(
        jwt.JwtPublicKeyVerify)

    raw_jwt = jwt.new_raw_jwt(issuer='issuer', without_expiration=True)

    token = sign.sign_and_encode(raw_jwt)
    token_with_kid = tink_sign.sign_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)

    verify.verify_and_decode(token, validator)
    tink_verify.verify_and_decode(token_with_kid, validator)

    other_handle = _change_key_id(tink_handle)
    other_verify = other_handle.public_keyset_handle().primitive(
        jwt.JwtPublicKeyVerify)

    verify.verify_and_decode(token_with_kid, validator)
    # For output prefix type TINK, the kid header is required.
    with self.assertRaises(tink.TinkError):
      tink_verify.verify_and_decode(token, validator)
    # This should fail because value of the kid header is wrong.
    with self.assertRaises(tink.TinkError):
      other_verify.verify_and_decode(token_with_kid, validator)
Ejemplo n.º 10
0
 def verify_mac_and_decode_with_kid(
         self, compact: str, validator: _jwt_validator.JwtValidator,
         kid: Optional[str]) -> _verified_jwt.VerifiedJwt:
     """Verifies, validates and decodes a MACed compact JWT token."""
     parts = _jwt_format.split_signed_compact(compact)
     unsigned_compact, json_header, json_payload, mac = parts
     self._verify_mac(mac, unsigned_compact)
     header = _json_util.json_loads(json_header)
     _jwt_format.validate_header(header=header,
                                 algorithm=self._algorithm,
                                 tink_kid=kid,
                                 custom_kid=self._custom_kid)
     raw_jwt = _raw_jwt.raw_jwt_from_json(
         _jwt_format.get_type_header(header), json_payload)
     _jwt_validator.validate(validator, raw_jwt)
     return _verified_jwt.VerifiedJwt._create(raw_jwt)  # pylint: disable=protected-access
Ejemplo n.º 11
0
    def test_signed_compact_create_split(self):
        payload = '{"iss":"joe"}'
        signature = _jwt_format.decode_signature(
            b'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk')
        unsigned_compact = _jwt_format.create_unsigned_compact(
            'RS256', payload)
        signed_compact = _jwt_format.create_signed_compact(
            unsigned_compact, signature)
        un_comp, hdr, pay, sig = _jwt_format.split_signed_compact(
            signed_compact)

        self.assertEqual(unsigned_compact,
                         b'eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJqb2UifQ')
        self.assertEqual(
            signed_compact, 'eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJqb2UifQ.'
            'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk')
        self.assertEqual(un_comp, unsigned_compact)
        self.assertEqual(sig, signature)
        self.assertEqual(hdr, '{"alg":"RS256"}')
        _jwt_format.validate_header(hdr, 'RS256')
        self.assertEqual(pay, payload)
Ejemplo n.º 12
0
  def test_signed_compact_create_split(self):
    payload = '{"iss":"joe"}'
    signature = _jwt_format.decode_signature(
        b'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk')
    unsigned_compact = _jwt_format.create_unsigned_compact(
        'RS256', 'JWT', None, payload)
    signed_compact = _jwt_format.create_signed_compact(unsigned_compact,
                                                       signature)
    un_comp, hdr, pay, sig = _jwt_format.split_signed_compact(signed_compact)

    self.assertEqual(
        unsigned_compact,
        b'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJqb2UifQ')
    self.assertEqual(
        signed_compact, 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.'
        'eyJpc3MiOiJqb2UifQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk')
    self.assertEqual(un_comp, unsigned_compact)
    self.assertEqual(sig, signature)
    self.assertEqual(hdr, '{"alg":"RS256","typ":"JWT"}')
    header = _jwt_format.json_loads(hdr)
    _jwt_format.validate_header(header, 'RS256')
    self.assertEqual(pay, payload)
    self.assertEqual(_jwt_format.get_type_header(header), 'JWT')
Ejemplo n.º 13
0
    def test_raw_output_prefix_type_encodes_a_custom_kid_header(self):
        keyset_handle = tink.new_keyset_handle(jwt.raw_jwt_hs256_template())

        # Add a custom kid to the key in keyset_handle
        value = keyset_handle._keyset.key[0].key_data.value
        hmac_key = jwt_hmac_pb2.JwtHmacKey.FromString(value)
        hmac_key.custom_kid.value = 'my kid'
        keyset_handle._keyset.key[
            0].key_data.value = hmac_key.SerializeToString()

        jwt_mac = keyset_handle.primitive(jwt.JwtMac)

        raw_jwt = jwt.new_raw_jwt(issuer='issuer', without_expiration=True)
        signed_compact = jwt_mac.compute_mac_and_encode(raw_jwt)

        _, json_header, _, _ = _jwt_format.split_signed_compact(signed_compact)
        header = _jwt_format.json_loads(json_header)
        self.assertEqual(header['kid'], 'my kid')

        # Now, change the output prefix type to TINK. This should fail.
        keyset_handle._keyset.key[0].output_prefix_type = tink_pb2.TINK
        with self.assertRaises(tink.TinkError):
            tink_jwt_mac = keyset_handle.primitive(jwt.JwtMac)
            tink_jwt_mac.compute_mac_and_encode(raw_jwt)
Ejemplo n.º 14
0
 def test_split_signed_compact_with_invalid_utf8_in_header(self):
     encoded_header = _jwt_format.base64_encode(
         b'{"alg":"RS256", "bad":"\xc2"}')
     token = (encoded_header + b'.e30.YWJj').decode('utf8')
     with self.assertRaises(_jwt_error.JwtInvalidError):
         _jwt_format.split_signed_compact(token)
Ejemplo n.º 15
0
 def test_split_signed_compact_with_bad_characters_fails(self):
     with self.assertRaises(_jwt_error.JwtInvalidError):
         _jwt_format.split_signed_compact('{e30.e30.YWJj')
     with self.assertRaises(_jwt_error.JwtInvalidError):
         _jwt_format.split_signed_compact(' e30.e30.YWJj')
     with self.assertRaises(_jwt_error.JwtInvalidError):
         _jwt_format.split_signed_compact('e30. e30.YWJj')
     with self.assertRaises(_jwt_error.JwtInvalidError):
         _jwt_format.split_signed_compact('e30.e30.YWJj ')
     with self.assertRaises(_jwt_error.JwtInvalidError):
         _jwt_format.split_signed_compact('e30.e30.\nYWJj')
     with self.assertRaises(_jwt_error.JwtInvalidError):
         _jwt_format.split_signed_compact('e30.\re30.YWJj')
     with self.assertRaises(_jwt_error.JwtInvalidError):
         _jwt_format.split_signed_compact('e30$.e30.YWJj')
     with self.assertRaises(_jwt_error.JwtInvalidError):
         _jwt_format.split_signed_compact('e30.$e30.YWJj')
     with self.assertRaises(_jwt_error.JwtInvalidError):
         _jwt_format.split_signed_compact('e30.e30.YWJj$')
     with self.assertRaises(_jwt_error.JwtInvalidError):
         _jwt_format.split_signed_compact('e30.e30.YWJj\ud83c')
Ejemplo n.º 16
0
 def test_split_signed_compact_with_bad_format_fails(self):
     with self.assertRaises(_jwt_error.JwtInvalidError):
         _jwt_format.split_signed_compact('e30.e30.YWJj.abc')
     with self.assertRaises(_jwt_error.JwtInvalidError):
         _jwt_format.split_signed_compact('e30.e30.YWJj.')
     with self.assertRaises(_jwt_error.JwtInvalidError):
         _jwt_format.split_signed_compact('.e30.e30.YWJj')
     with self.assertRaises(_jwt_error.JwtInvalidError):
         _jwt_format.split_signed_compact('.e30.e30.')
     with self.assertRaises(_jwt_error.JwtInvalidError):
         _jwt_format.split_signed_compact('e30')
     with self.assertRaises(_jwt_error.JwtInvalidError):
         _jwt_format.split_signed_compact('')
Ejemplo n.º 17
0
 def test_split_empty_signed_compact(self):
     un_comp, hdr, pay, sig = _jwt_format.split_signed_compact('..')
     self.assertEqual(un_comp, b'.')
     self.assertEmpty(sig)
     self.assertEmpty(hdr)
     self.assertEmpty(pay)