Beispiel #1
0
  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(
        expected_issuer='issuer',
        expected_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(
        expected_audience='wrong_audience', fixed_now=now)
    with self.assertRaises(tink.TinkError):
      jwt_mac_primitive.verify_mac_and_decode(compact, validator2)
Beispiel #2
0
  def test_generate_compute_verify_mac(self):
    keyset_servicer = services.KeysetServicer()
    jwt_servicer = jwt_service.JwtServicer()

    template = jwt.jwt_hs256_template().SerializeToString()
    gen_request = testing_api_pb2.KeysetGenerateRequest(template=template)
    gen_response = keyset_servicer.Generate(gen_request, self._ctx)
    self.assertEqual(gen_response.WhichOneof('result'), 'keyset')
    keyset = gen_response.keyset

    comp_request = testing_api_pb2.JwtSignRequest(keyset=keyset)
    comp_request.raw_jwt.issuer.value = 'issuer'
    comp_request.raw_jwt.subject.value = 'subject'
    comp_request.raw_jwt.custom_claims['myclaim'].bool_value = True
    comp_request.raw_jwt.expiration.seconds = 1334
    comp_request.raw_jwt.expiration.nanos = 123000000

    comp_response = jwt_servicer.ComputeMacAndEncode(comp_request, self._ctx)
    self.assertEqual(comp_response.WhichOneof('result'), 'signed_compact_jwt')
    signed_compact_jwt = comp_response.signed_compact_jwt
    verify_request = testing_api_pb2.JwtVerifyRequest(
        keyset=keyset, signed_compact_jwt=signed_compact_jwt)
    verify_request.validator.expected_issuer.value = 'issuer'
    verify_request.validator.expected_subject.value = 'subject'
    verify_request.validator.now.seconds = 1234
    verify_response = jwt_servicer.VerifyMacAndDecode(verify_request, self._ctx)
    self.assertEqual(verify_response.WhichOneof('result'), 'verified_jwt')
    self.assertEqual(verify_response.verified_jwt.issuer.value, 'issuer')
    self.assertEqual(verify_response.verified_jwt.subject.value, 'subject')
    self.assertEqual(verify_response.verified_jwt.expiration.seconds, 1334)
    self.assertEqual(verify_response.verified_jwt.expiration.nanos, 0)
Beispiel #3
0
class JwtKeyTemplatesTest(parameterized.TestCase):
    @parameterized.parameters([
        ('JWT_HS256', jwt.jwt_hs256_template()),
        ('JWT_HS384', jwt.jwt_hs384_template()),
        ('JWT_HS512', jwt.jwt_hs512_template()),
        ('JWT_ES256', jwt.jwt_es256_template()),
        ('JWT_ES384', jwt.jwt_es384_template()),
        ('JWT_ES512', jwt.jwt_es512_template()),
        ('JWT_RS256_2048_F4', jwt.jwt_rs256_2048_f4_template()),
        ('JWT_RS256_3072_F4', jwt.jwt_rs256_3072_f4_template()),
        ('JWT_RS384_3072_F4', jwt.jwt_rs384_3072_f4_template()),
        ('JWT_RS512_4096_F4', jwt.jwt_rs512_4096_f4_template()),
        ('JWT_PS256_2048_F4', jwt.jwt_ps256_2048_f4_template()),
        ('JWT_PS256_3072_F4', jwt.jwt_ps256_3072_f4_template()),
        ('JWT_PS384_3072_F4', jwt.jwt_ps384_3072_f4_template()),
        ('JWT_PS512_4096_F4', jwt.jwt_ps512_4096_f4_template()),
    ])
    def test_template(self, template_name, template):
        self.assertEqual(template,
                         helper.template_from_testdata(template_name, 'jwt'))

    @parameterized.named_parameters(('0', 0, b'\x00'),
                                    ('256', 256, b'\x01\x00'),
                                    ('65537', 65537, b'\x01\x00\x01'))
    def test_num_to_bytes(self, number, expected):
        self.assertEqual(jwt._jwt_key_templates._num_to_bytes(number),
                         expected)
Beispiel #4
0
    def test_generate_compute_verify_mac_without_expiration(self):
        keyset_servicer = services.KeysetServicer()
        jwt_servicer = jwt_service.JwtServicer()

        template = jwt.jwt_hs256_template().SerializeToString()
        gen_request = testing_api_pb2.KeysetGenerateRequest(template=template)
        gen_response = keyset_servicer.Generate(gen_request, self._ctx)
        self.assertEqual(gen_response.WhichOneof('result'), 'keyset')
        keyset = gen_response.keyset

        comp_request = testing_api_pb2.JwtSignRequest(keyset=keyset)
        comp_request.raw_jwt.issuer.value = 'issuer'

        comp_response = jwt_servicer.ComputeMacAndEncode(
            comp_request, self._ctx)
        self.assertEqual(comp_response.WhichOneof('result'),
                         'signed_compact_jwt')
        signed_compact_jwt = comp_response.signed_compact_jwt
        verify_request = testing_api_pb2.JwtVerifyRequest(
            keyset=keyset, signed_compact_jwt=signed_compact_jwt)
        verify_request.validator.expected_issuer.value = 'issuer'
        verify_request.validator.allow_missing_expiration = True
        verify_response = jwt_servicer.VerifyMacAndDecode(
            verify_request, self._ctx)
        print(verify_response.err)
        self.assertEqual(verify_response.WhichOneof('result'), 'verified_jwt')
        self.assertEqual(verify_response.verified_jwt.issuer.value, 'issuer')
Beispiel #5
0
 def test_legacy_non_primary_key_fails(self):
   builder = keyset_builder.new_keyset_builder()
   old_template = _create_jwt_hmac_template(jwt_hmac_pb2.HS256, 32,
                                            tink_pb2.LEGACY)
   _ = builder.add_new_key(old_template)
   current_key_id = builder.add_new_key(jwt.jwt_hs256_template())
   builder.set_primary_key(current_key_id)
   handle = builder.keyset_handle()
   with self.assertRaises(tink.TinkError):
     handle.primitive(jwt.JwtMac)
Beispiel #6
0
class JwtKeyTemplatesTest(parameterized.TestCase):
    @parameterized.parameters([
        ('JWT_HS256', jwt.jwt_hs256_template()),
        ('JWT_HS384', jwt.jwt_hs384_template()),
        ('JWT_HS512', jwt.jwt_hs512_template()),
        ('JWT_ES256', jwt.jwt_es256_template()),
        ('JWT_ES384', jwt.jwt_es384_template()),
        ('JWT_ES512', jwt.jwt_es512_template()),
        ('JWT_RS256_2048_F4', jwt.jwt_rs256_2048_f4_template()),
        ('JWT_RS256_3072_F4', jwt.jwt_rs256_3072_f4_template()),
        ('JWT_RS384_3072_F4', jwt.jwt_rs384_3072_f4_template()),
        ('JWT_RS512_4096_F4', jwt.jwt_rs512_4096_f4_template()),
        ('JWT_PS256_2048_F4', jwt.jwt_ps256_2048_f4_template()),
        ('JWT_PS256_3072_F4', jwt.jwt_ps256_3072_f4_template()),
        ('JWT_PS384_3072_F4', jwt.jwt_ps384_3072_f4_template()),
        ('JWT_PS512_4096_F4', jwt.jwt_ps512_4096_f4_template()),
    ])
    def test_template(self, template_name, template):
        self.assertEqual(template,
                         helper.template_from_testdata(template_name, 'jwt'))

    @parameterized.named_parameters(('0', 0, b'\x00'),
                                    ('256', 256, b'\x01\x00'),
                                    ('65537', 65537, b'\x01\x00\x01'))
    def test_num_to_bytes(self, number, expected):
        self.assertEqual(jwt._jwt_key_templates._num_to_bytes(number),
                         expected)

    @parameterized.named_parameters([
        ('JWT_HS256', jwt.jwt_hs256_template()),
        ('JWT_HS384', jwt.jwt_hs384_template()),
        ('JWT_HS512', jwt.jwt_hs512_template()),
    ])
    def test_mac_success(self, key_template):
        keyset_handle = tink.new_keyset_handle(key_template)
        jwt_hmac = keyset_handle.primitive(jwt.JwtMac)
        token = jwt.new_raw_jwt(issuer='issuer', subject='subject')
        compact = jwt_hmac.compute_mac_and_encode(token)
        output_token = jwt_hmac.verify_mac_and_decode(compact,
                                                      jwt.new_validator())
        self.assertEqual(output_token.issuer(), token.issuer())
        self.assertEqual(output_token.subject(), token.subject())
Beispiel #7
0
     signature.signature_key_templates.RSA_SSA_PKCS1_3072_SHA256_F4,
 'RSA_SSA_PKCS1_4096_SHA512_F4':
     signature.signature_key_templates.RSA_SSA_PKCS1_4096_SHA512_F4,
 'RSA_SSA_PSS_3072_SHA256_SHA256_32_F4':
     signature.signature_key_templates.RSA_SSA_PSS_3072_SHA256_SHA256_32_F4,
 'RSA_SSA_PSS_4096_SHA512_SHA512_64_F4':
     signature.signature_key_templates.RSA_SSA_PSS_4096_SHA512_SHA512_64_F4,
 'AES_CMAC_PRF':
     prf.prf_key_templates.AES_CMAC,
 'HMAC_PRF_SHA256':
     prf.prf_key_templates.HMAC_SHA256,
 'HMAC_PRF_SHA512':
     prf.prf_key_templates.HMAC_SHA512,
 'HKDF_PRF_SHA256':
     prf.prf_key_templates.HKDF_SHA256,
 'JWT_HS256': jwt.jwt_hs256_template(),
 'JWT_HS256_RAW': jwt.raw_jwt_hs256_template(),
 'JWT_HS384': jwt.jwt_hs384_template(),
 'JWT_HS384_RAW': jwt.raw_jwt_hs384_template(),
 'JWT_HS512': jwt.jwt_hs512_template(),
 'JWT_HS512_RAW': jwt.raw_jwt_hs512_template(),
 'JWT_ES256': jwt.jwt_es256_template(),
 'JWT_ES256_RAW': jwt.raw_jwt_es256_template(),
 'JWT_ES384': jwt.jwt_es384_template(),
 'JWT_ES384_RAW': jwt.raw_jwt_es384_template(),
 'JWT_ES512': jwt.jwt_es512_template(),
 'JWT_ES512_RAW': jwt.raw_jwt_es512_template(),
 'JWT_RS256_2048_F4': jwt.jwt_rs256_2048_f4_template(),
 'JWT_RS256_2048_F4_RAW': jwt.raw_jwt_rs256_2048_f4_template(),
 'JWT_RS256_3072_F4': jwt.jwt_rs256_3072_f4_template(),
 'JWT_RS256_3072_F4_RAW': jwt.raw_jwt_rs256_3072_f4_template(),
class JwtKeyTemplatesTest(parameterized.TestCase):
    @parameterized.named_parameters([
        ('JWT_HS256', jwt.jwt_hs256_template()),
        ('JWT_HS256_RAW', jwt.raw_jwt_hs256_template()),
        ('JWT_HS384', jwt.jwt_hs384_template()),
        ('JWT_HS384_RAW', jwt.raw_jwt_hs384_template()),
        ('JWT_HS512', jwt.jwt_hs512_template()),
        ('JWT_HS512_RAW', jwt.raw_jwt_hs512_template()),
    ])
    def test_mac_success(self, key_template):
        keyset_handle = tink.new_keyset_handle(key_template)
        jwt_hmac = keyset_handle.primitive(jwt.JwtMac)
        token = jwt.new_raw_jwt(issuer='issuer',
                                subject='subject',
                                without_expiration=True)
        compact = jwt_hmac.compute_mac_and_encode(token)
        output_token = jwt_hmac.verify_mac_and_decode(
            compact,
            jwt.new_validator(expected_issuer='issuer',
                              allow_missing_expiration=True))
        self.assertEqual(output_token.issuer(), token.issuer())
        self.assertEqual(output_token.subject(), token.subject())

    @parameterized.named_parameters([
        ('JWT_ES256', jwt.jwt_es256_template()),
        ('JWT_ES256_RAW', jwt.raw_jwt_es256_template()),
        ('JWT_ES384', jwt.jwt_es384_template()),
        ('JWT_ES384_RAW', jwt.raw_jwt_es384_template()),
        ('JWT_ES512', jwt.jwt_es512_template()),
        ('JWT_ES512_RAW', jwt.raw_jwt_es512_template()),
        ('JWT_RS256_2048_F4', jwt.jwt_rs256_2048_f4_template()),
        ('JWT_RS256_2048_F4_RAW', jwt.raw_jwt_rs256_2048_f4_template()),
        ('JWT_RS256_3072_F4', jwt.jwt_rs256_3072_f4_template()),
        ('JWT_RS256_3072_F4_RAW', jwt.raw_jwt_rs256_3072_f4_template()),
        ('JWT_RS384_3072_F4', jwt.jwt_rs384_3072_f4_template()),
        ('JWT_RS384_3072_F4_RAW', jwt.raw_jwt_rs384_3072_f4_template()),
        ('JWT_RS512_4096_F4', jwt.jwt_rs512_4096_f4_template()),
        ('JWT_RS512_4096_F4_RAW', jwt.raw_jwt_rs512_4096_f4_template()),
        ('JWT_PS256_2048_F4', jwt.jwt_ps256_2048_f4_template()),
        ('JWT_PS256_2048_F4_RAW', jwt.raw_jwt_ps256_2048_f4_template()),
        ('JWT_PS256_3072_F4', jwt.jwt_ps256_3072_f4_template()),
        ('JWT_PS256_3072_F4_RAW', jwt.raw_jwt_ps256_3072_f4_template()),
        ('JWT_PS384_3072_F4', jwt.jwt_ps384_3072_f4_template()),
        ('JWT_PS384_3072_F4_RAW', jwt.raw_jwt_ps384_3072_f4_template()),
        ('JWT_PS512_4096_F4', jwt.jwt_ps512_4096_f4_template()),
        ('JWT_PS512_4096_F4_RAW', jwt.raw_jwt_ps512_4096_f4_template()),
    ])
    def test_new_keydata_primitive_success(self, template):
        private_handle = tink.new_keyset_handle(template)
        sign = private_handle.primitive(jwt.JwtPublicKeySign)
        verify = private_handle.public_keyset_handle().primitive(
            jwt.JwtPublicKeyVerify)
        raw_jwt = jwt.new_raw_jwt(issuer='issuer',
                                  subject='subject',
                                  without_expiration=True)
        compact = sign.sign_and_encode(raw_jwt)
        verified_jwt = verify.verify_and_decode(
            compact,
            jwt.new_validator(expected_issuer='issuer',
                              allow_missing_expiration=True))
        self.assertEqual(verified_jwt.issuer(), 'issuer')
        self.assertEqual(verified_jwt.subject(), 'subject')
Beispiel #9
0
 'RSA_SSA_PKCS1_4096_SHA512_F4':
 signature.signature_key_templates.RSA_SSA_PKCS1_4096_SHA512_F4,
 'RSA_SSA_PSS_3072_SHA256_SHA256_32_F4':
 signature.signature_key_templates.RSA_SSA_PSS_3072_SHA256_SHA256_32_F4,
 'RSA_SSA_PSS_4096_SHA512_SHA512_64_F4':
 signature.signature_key_templates.RSA_SSA_PSS_4096_SHA512_SHA512_64_F4,
 'AES_CMAC_PRF':
 prf.prf_key_templates.AES_CMAC,
 'HMAC_SHA256_PRF':
 prf.prf_key_templates.HMAC_SHA256,
 'HMAC_SHA512_PRF':
 prf.prf_key_templates.HMAC_SHA512,
 'HKDF_SHA256':
 prf.prf_key_templates.HKDF_SHA256,
 'JWT_HS256':
 jwt.jwt_hs256_template(),
 'JWT_HS256_RAW':
 jwt.raw_jwt_hs256_template(),
 'JWT_HS384':
 jwt.jwt_hs384_template(),
 'JWT_HS384_RAW':
 jwt.raw_jwt_hs384_template(),
 'JWT_HS512':
 jwt.jwt_hs512_template(),
 'JWT_HS512_RAW':
 jwt.raw_jwt_hs512_template(),
 'JWT_ES256':
 jwt.jwt_es256_template(),
 'JWT_ES256_RAW':
 jwt.raw_jwt_es256_template(),
 'JWT_ES384':
Beispiel #10
0
class JwtHmacKeyManagerTest(parameterized.TestCase):
    def test_basic(self):
        key_manager = _jwt_hmac_key_manager.MacCcToPyJwtMacKeyManager()
        self.assertEqual(key_manager.primitive_class(), jwt.JwtMac)
        self.assertEqual(key_manager.key_type(),
                         'type.googleapis.com/google.crypto.tink.JwtHmacKey')

    @parameterized.named_parameters([
        ('JWT_HS256', jwt.jwt_hs256_template()),
        ('JWT_HS384', jwt.jwt_hs384_template()),
        ('JWT_HS512', jwt.jwt_hs512_template()),
    ])
    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(issuer='issuer')
        signed_compact = jwt_hmac.compute_mac_and_encode(raw_jwt)

        verified_jwt = jwt_hmac.verify_mac_and_decode(
            signed_compact, jwt.new_validator(fixed_now=DATETIME_1970))
        self.assertEqual(verified_jwt.issuer(), 'issuer')

    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))

    @parameterized.named_parameters([
        ('invalid_header_typ',
         'eyJ0eXAiOiJKV0QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLCJleHAiOjEzMDA'
         '4MTkzODEsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.m6sYAmMakslu'
         'W4deYZS0HaBKbMrfa6kBy6IRr1Vy5Gg'),
        ('modified_signature',
         'eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleH'
         'AiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.'
         'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXi'),
        ('modified_payload',
         'eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLCJleHAiOj'
         'EzMDA4MTkzODEsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.'
         'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk'),
        ('modified_header',
         'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleH'
         'AiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.'
         'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk'),
        ('extra .', 'eyJhbGciOiJIUzI1NiJ9.e30.abc.'),
        ('invalid_header_encoding', 'eyJhbGciOiJIUzI1NiJ9?.e30.abc'),
        ('invalid_payload_encoding', 'eyJhbGciOiJIUzI1NiJ9.e30?.abc'),
        ('invalid_mac_encoding', 'eyJhbGciOiJIUzI1NiJ9.e30.abc?'),
        ('no_mac', 'eyJhbGciOiJIUzI1NiJ9.e30'),
    ])
    def test_invalid_signed_compact(self, invalid_signed_compact):
        jwt_hmac = create_fixed_jwt_hmac()
        validator = jwt.new_validator(issuer='joe', fixed_now=DATETIME_1970)

        with self.assertRaises(tink.TinkError):
            jwt_hmac.verify_mac_and_decode(invalid_signed_compact, validator)
Beispiel #11
0
    def test_key_rotation(self):
        old_key_tmpl = jwt.jwt_hs256_template()
        new_key_tmpl = jwt.jwt_hs384_template()
        builder = keyset_builder.new_keyset_builder()
        older_key_id = builder.add_new_key(old_key_tmpl)

        builder.set_primary_key(older_key_id)
        jwtmac1 = builder.keyset_handle().primitive(jwt.JwtMac)

        newer_key_id = builder.add_new_key(new_key_tmpl)
        jwtmac2 = builder.keyset_handle().primitive(jwt.JwtMac)

        builder.set_primary_key(newer_key_id)
        jwtmac3 = builder.keyset_handle().primitive(jwt.JwtMac)

        builder.disable_key(older_key_id)
        jwtmac4 = builder.keyset_handle().primitive(jwt.JwtMac)

        raw_jwt = jwt.new_raw_jwt(issuer='a')
        validator = jwt.JwtValidator()

        self.assertNotEqual(older_key_id, newer_key_id)
        # 1 uses the older key. So 1, 2 and 3 can verify the mac, but not 4.
        compact1 = jwtmac1.compute_mac_and_encode(raw_jwt)
        self.assertEqual(
            jwtmac1.verify_mac_and_decode(compact1, validator).issuer(), 'a')
        self.assertEqual(
            jwtmac2.verify_mac_and_decode(compact1, validator).issuer(), 'a')
        self.assertEqual(
            jwtmac3.verify_mac_and_decode(compact1, validator).issuer(), 'a')
        with self.assertRaises(tink.TinkError):
            jwtmac4.verify_mac_and_decode(compact1, validator)

        # 2 uses the older key. So 1, 2 and 3 can verify the mac, but not 4.
        compact2 = jwtmac2.compute_mac_and_encode(raw_jwt)
        self.assertEqual(
            jwtmac1.verify_mac_and_decode(compact2, validator).issuer(), 'a')
        self.assertEqual(
            jwtmac2.verify_mac_and_decode(compact2, validator).issuer(), 'a')
        self.assertEqual(
            jwtmac3.verify_mac_and_decode(compact2, validator).issuer(), 'a')
        with self.assertRaises(tink.TinkError):
            jwtmac4.verify_mac_and_decode(compact2, validator)

        # 3 uses the newer key. So 2, 3 and 4 can verify the mac, but not 1.
        compact3 = jwtmac3.compute_mac_and_encode(raw_jwt)
        with self.assertRaises(tink.TinkError):
            jwtmac1.verify_mac_and_decode(compact3, validator)
        self.assertEqual(
            jwtmac2.verify_mac_and_decode(compact3, validator).issuer(), 'a')
        self.assertEqual(
            jwtmac3.verify_mac_and_decode(compact3, validator).issuer(), 'a')
        self.assertEqual(
            jwtmac4.verify_mac_and_decode(compact3, validator).issuer(), 'a')

        # 4 uses the newer key. So 2, 3 and 4 can verify the mac, but not 1.
        compact4 = jwtmac4.compute_mac_and_encode(raw_jwt)
        with self.assertRaises(tink.TinkError):
            jwtmac1.verify_mac_and_decode(compact4, validator)
        self.assertEqual(
            jwtmac2.verify_mac_and_decode(compact4, validator).issuer(), 'a')
        self.assertEqual(
            jwtmac3.verify_mac_and_decode(compact4, validator).issuer(), 'a')
        self.assertEqual(
            jwtmac4.verify_mac_and_decode(compact4, validator).issuer(), 'a')
Beispiel #12
0
class JwtHmacKeyManagerTest(parameterized.TestCase):

  def test_basic(self):
    key_manager = _jwt_hmac_key_manager.MacCcToPyJwtMacKeyManager()
    self.assertEqual(key_manager.primitive_class(), _jwt_mac.JwtMacInternal)
    self.assertEqual(key_manager.key_type(),
                     'type.googleapis.com/google.crypto.tink.JwtHmacKey')

  @parameterized.named_parameters([
      ('JWT_HS256', jwt.jwt_hs256_template()),
      ('JWT_HS384', jwt.jwt_hs384_template()),
      ('JWT_HS512', jwt.jwt_hs512_template()),
  ])
  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)
    signed_compact = jwt_hmac.compute_mac_and_encode_with_kid(raw_jwt, None)

    verified_jwt = jwt_hmac.verify_mac_and_decode(
        signed_compact,
        jwt.new_validator(
            expected_type_header='typeHeader',
            expected_issuer='issuer',
            allow_missing_expiration=True,
            fixed_now=DATETIME_1970))
    self.assertEqual(verified_jwt.type_header(), 'typeHeader')
    self.assertEqual(verified_jwt.issuer(), 'issuer')

  def test_fixed_signed_compact(self):
    signed_compact = (
        'eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleH'
        'AiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.'
        'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk')
    jwt_hmac = create_fixed_jwt_hmac()
    verified_jwt = jwt_hmac.verify_mac_and_decode(
        signed_compact,
        jwt.new_validator(
            expected_type_header='JWT',
            expected_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'))
    self.assertTrue(verified_jwt.type_header(), 'JWT')

    # 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(expected_issuer='jane', fixed_now=DATETIME_1970))

  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_invalid_signed_compact_with_valid_signature(self):
    jwt_hmac = create_fixed_jwt_hmac()
    validator = jwt.new_validator(
        expected_issuer='joe',
        allow_missing_expiration=True,
        fixed_now=DATETIME_1970)

    # token with valid signature but invalid alg header
    token_with_invalid_header = create_signed_token('{"alg":"RS256"}',
                                                    '{"iss":"joe"}')
    with self.assertRaises(tink.TinkError):
      jwt_hmac.verify_mac_and_decode(token_with_invalid_header, validator)

    # token with valid signature but invalid json in payload
    token_with_invalid_payload = create_signed_token('{"alg":"HS256"}',
                                                     '{"iss":"joe"')
    with self.assertRaises(tink.TinkError):
      jwt_hmac.verify_mac_and_decode(token_with_invalid_payload, validator)

  @parameterized.named_parameters([
      ('modified_signature',
       'eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleH'
       'AiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.'
       'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXi'),
      ('modified_payload',
       'eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLCJleHAiOj'
       'EzMDA4MTkzODEsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.'
       'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk'),
      ('modified_header',
       'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleH'
       'AiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.'
       'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk'),
      ('extra .', 'eyJhbGciOiJIUzI1NiJ9.e30.abc.'),
      ('invalid_header_encoding', 'eyJhbGciOiJIUzI1NiJ9?.e30.abc'),
      ('invalid_payload_encoding', 'eyJhbGciOiJIUzI1NiJ9.e30?.abc'),
      ('invalid_mac_encoding', 'eyJhbGciOiJIUzI1NiJ9.e30.abc?'),
      ('no_mac', 'eyJhbGciOiJIUzI1NiJ9.e30'),
  ])
  def test_invalid_signed_compact(self, invalid_signed_compact):
    jwt_hmac = create_fixed_jwt_hmac()
    validator = jwt.new_validator(
        expected_issuer='joe',
        allow_missing_expiration=True,
        fixed_now=DATETIME_1970)

    with self.assertRaises(tink.TinkError):
      jwt_hmac.verify_mac_and_decode(invalid_signed_compact, validator)
Beispiel #13
0
class JwtMacWrapperTest(parameterized.TestCase):

  @parameterized.parameters([
      (jwt.jwt_hs256_template(), jwt.jwt_hs256_template()),
      (jwt.jwt_hs256_template(), jwt_hs256_tink_template()),
      (jwt_hs256_tink_template(), jwt.jwt_hs256_template()),
      (jwt_hs256_tink_template(), jwt_hs256_tink_template()),
  ])
  def test_key_rotation(self, old_key_tmpl, new_key_tmpl):
    builder = keyset_builder.new_keyset_builder()
    older_key_id = builder.add_new_key(old_key_tmpl)

    builder.set_primary_key(older_key_id)
    jwtmac1 = builder.keyset_handle().primitive(jwt.JwtMac)

    newer_key_id = builder.add_new_key(new_key_tmpl)
    jwtmac2 = builder.keyset_handle().primitive(jwt.JwtMac)

    builder.set_primary_key(newer_key_id)
    jwtmac3 = builder.keyset_handle().primitive(jwt.JwtMac)

    builder.disable_key(older_key_id)
    jwtmac4 = builder.keyset_handle().primitive(jwt.JwtMac)

    raw_jwt = jwt.new_raw_jwt(issuer='a', without_expiration=True)
    validator = jwt.new_validator(
        expected_issuer='a', allow_missing_expiration=True)

    self.assertNotEqual(older_key_id, newer_key_id)
    # 1 uses the older key. So 1, 2 and 3 can verify the mac, but not 4.
    compact1 = jwtmac1.compute_mac_and_encode(raw_jwt)
    self.assertEqual(
        jwtmac1.verify_mac_and_decode(compact1, validator).issuer(), 'a')
    self.assertEqual(
        jwtmac2.verify_mac_and_decode(compact1, validator).issuer(), 'a')
    self.assertEqual(
        jwtmac3.verify_mac_and_decode(compact1, validator).issuer(), 'a')
    with self.assertRaises(tink.TinkError):
      jwtmac4.verify_mac_and_decode(compact1, validator)

    # 2 uses the older key. So 1, 2 and 3 can verify the mac, but not 4.
    compact2 = jwtmac2.compute_mac_and_encode(raw_jwt)
    self.assertEqual(
        jwtmac1.verify_mac_and_decode(compact2, validator).issuer(), 'a')
    self.assertEqual(
        jwtmac2.verify_mac_and_decode(compact2, validator).issuer(), 'a')
    self.assertEqual(
        jwtmac3.verify_mac_and_decode(compact2, validator).issuer(), 'a')
    with self.assertRaises(tink.TinkError):
      jwtmac4.verify_mac_and_decode(compact2, validator)

    # 3 uses the newer key. So 2, 3 and 4 can verify the mac, but not 1.
    compact3 = jwtmac3.compute_mac_and_encode(raw_jwt)
    with self.assertRaises(tink.TinkError):
      jwtmac1.verify_mac_and_decode(compact3, validator)
    self.assertEqual(
        jwtmac2.verify_mac_and_decode(compact3, validator).issuer(), 'a')
    self.assertEqual(
        jwtmac3.verify_mac_and_decode(compact3, validator).issuer(), 'a')
    self.assertEqual(
        jwtmac4.verify_mac_and_decode(compact3, validator).issuer(), 'a')

    # 4 uses the newer key. So 2, 3 and 4 can verify the mac, but not 1.
    compact4 = jwtmac4.compute_mac_and_encode(raw_jwt)
    with self.assertRaises(tink.TinkError):
      jwtmac1.verify_mac_and_decode(compact4, validator)
    self.assertEqual(
        jwtmac2.verify_mac_and_decode(compact4, validator).issuer(), 'a')
    self.assertEqual(
        jwtmac3.verify_mac_and_decode(compact4, validator).issuer(), 'a')
    self.assertEqual(
        jwtmac4.verify_mac_and_decode(compact4, validator).issuer(), 'a')

  def test_tink_output_prefix_type_encodes_a_kid_header(self):
    keyset_handle = tink.new_keyset_handle(jwt_hs256_tink_template())
    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.assertIn('kid', header)

  def test_legacy_key_fails(self):
    template = _create_jwt_hmac_template(jwt_hmac_pb2.HS256, 32,
                                         tink_pb2.LEGACY)
    builder = keyset_builder.new_keyset_builder()
    key_id = builder.add_new_key(template)
    builder.set_primary_key(key_id)
    handle = builder.keyset_handle()
    with self.assertRaises(tink.TinkError):
      handle.primitive(jwt.JwtMac)

  def test_legacy_non_primary_key_fails(self):
    builder = keyset_builder.new_keyset_builder()
    old_template = _create_jwt_hmac_template(jwt_hmac_pb2.HS256, 32,
                                             tink_pb2.LEGACY)
    _ = builder.add_new_key(old_template)
    current_key_id = builder.add_new_key(jwt.jwt_hs256_template())
    builder.set_primary_key(current_key_id)
    handle = builder.keyset_handle()
    with self.assertRaises(tink.TinkError):
      handle.primitive(jwt.JwtMac)
Beispiel #14
0
class JwtMacWrapperTest(parameterized.TestCase):
    @parameterized.parameters([
        (jwt.raw_jwt_hs256_template(), jwt.raw_jwt_hs256_template()),
        (jwt.raw_jwt_hs256_template(), jwt.jwt_hs256_template()),
        (jwt.jwt_hs256_template(), jwt.raw_jwt_hs256_template()),
        (jwt.jwt_hs256_template(), jwt.jwt_hs256_template()),
    ])
    def test_key_rotation(self, old_key_tmpl, new_key_tmpl):
        builder = keyset_builder.new_keyset_builder()
        older_key_id = builder.add_new_key(old_key_tmpl)

        builder.set_primary_key(older_key_id)
        jwtmac1 = builder.keyset_handle().primitive(jwt.JwtMac)

        newer_key_id = builder.add_new_key(new_key_tmpl)
        jwtmac2 = builder.keyset_handle().primitive(jwt.JwtMac)

        builder.set_primary_key(newer_key_id)
        jwtmac3 = builder.keyset_handle().primitive(jwt.JwtMac)

        builder.disable_key(older_key_id)
        jwtmac4 = builder.keyset_handle().primitive(jwt.JwtMac)

        raw_jwt = jwt.new_raw_jwt(issuer='a', without_expiration=True)
        validator = jwt.new_validator(expected_issuer='a',
                                      allow_missing_expiration=True)

        self.assertNotEqual(older_key_id, newer_key_id)
        # 1 uses the older key. So 1, 2 and 3 can verify the mac, but not 4.
        compact1 = jwtmac1.compute_mac_and_encode(raw_jwt)
        self.assertEqual(
            jwtmac1.verify_mac_and_decode(compact1, validator).issuer(), 'a')
        self.assertEqual(
            jwtmac2.verify_mac_and_decode(compact1, validator).issuer(), 'a')
        self.assertEqual(
            jwtmac3.verify_mac_and_decode(compact1, validator).issuer(), 'a')
        with self.assertRaises(tink.TinkError):
            jwtmac4.verify_mac_and_decode(compact1, validator)

        # 2 uses the older key. So 1, 2 and 3 can verify the mac, but not 4.
        compact2 = jwtmac2.compute_mac_and_encode(raw_jwt)
        self.assertEqual(
            jwtmac1.verify_mac_and_decode(compact2, validator).issuer(), 'a')
        self.assertEqual(
            jwtmac2.verify_mac_and_decode(compact2, validator).issuer(), 'a')
        self.assertEqual(
            jwtmac3.verify_mac_and_decode(compact2, validator).issuer(), 'a')
        with self.assertRaises(tink.TinkError):
            jwtmac4.verify_mac_and_decode(compact2, validator)

        # 3 uses the newer key. So 2, 3 and 4 can verify the mac, but not 1.
        compact3 = jwtmac3.compute_mac_and_encode(raw_jwt)
        with self.assertRaises(tink.TinkError):
            jwtmac1.verify_mac_and_decode(compact3, validator)
        self.assertEqual(
            jwtmac2.verify_mac_and_decode(compact3, validator).issuer(), 'a')
        self.assertEqual(
            jwtmac3.verify_mac_and_decode(compact3, validator).issuer(), 'a')
        self.assertEqual(
            jwtmac4.verify_mac_and_decode(compact3, validator).issuer(), 'a')

        # 4 uses the newer key. So 2, 3 and 4 can verify the mac, but not 1.
        compact4 = jwtmac4.compute_mac_and_encode(raw_jwt)
        with self.assertRaises(tink.TinkError):
            jwtmac1.verify_mac_and_decode(compact4, validator)
        self.assertEqual(
            jwtmac2.verify_mac_and_decode(compact4, validator).issuer(), 'a')
        self.assertEqual(
            jwtmac3.verify_mac_and_decode(compact4, validator).issuer(), 'a')
        self.assertEqual(
            jwtmac4.verify_mac_and_decode(compact4, validator).issuer(), 'a')

    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_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)

    def test_legacy_key_fails(self):
        template = keyset_builder.legacy_template(jwt.raw_jwt_hs256_template())
        builder = keyset_builder.new_keyset_builder()
        key_id = builder.add_new_key(template)
        builder.set_primary_key(key_id)
        handle = builder.keyset_handle()
        with self.assertRaises(tink.TinkError):
            handle.primitive(jwt.JwtMac)

    def test_legacy_non_primary_key_fails(self):
        builder = keyset_builder.new_keyset_builder()
        old_template = keyset_builder.legacy_template(
            jwt.raw_jwt_hs256_template())
        _ = builder.add_new_key(old_template)
        current_key_id = builder.add_new_key(jwt.jwt_hs256_template())
        builder.set_primary_key(current_key_id)
        handle = builder.keyset_handle()
        with self.assertRaises(tink.TinkError):
            handle.primitive(jwt.JwtMac)

    def test_jwt_mac_from_keyset_without_primary_fails(self):
        builder = keyset_builder.new_keyset_builder()
        builder.add_new_key(jwt.raw_jwt_hs256_template())
        with self.assertRaises(tink.TinkError):
            builder.keyset_handle()