def test_legacy_non_primary_key_fails(self):
   builder = keyset_builder.new_keyset_builder()
   old_template = keyset_builder.legacy_template(jwt.jwt_es256_template())
   _ = builder.add_new_key(old_template)
   current_key_id = builder.add_new_key(jwt.jwt_es256_template())
   builder.set_primary_key(current_key_id)
   handle = builder.keyset_handle()
   with self.assertRaises(tink.TinkError):
     handle.primitive(jwt.JwtPublicKeySign)
   with self.assertRaises(tink.TinkError):
     handle.public_keyset_handle().primitive(jwt.JwtPublicKeyVerify)
    def test_verify_with_other_key_fails(self):
        handle = tink.new_keyset_handle(jwt.jwt_es256_template())
        sign = handle.primitive(jwt.JwtPublicKeySign)
        raw_jwt = jwt.new_raw_jwt(issuer='issuer', without_expiration=True)
        compact = sign.sign_and_encode(raw_jwt)

        other_handle = tink.new_keyset_handle(jwt.jwt_es256_template())
        other_verify = other_handle.public_keyset_handle().primitive(
            jwt.JwtPublicKeyVerify)
        with self.assertRaises(tink.TinkError):
            other_verify.verify_and_decode(
                compact,
                jwt.new_validator(expected_issuer='issuer',
                                  allow_missing_expiration=True))
Ejemplo n.º 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)
Ejemplo n.º 4
0
  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)
Ejemplo n.º 5
0
  def test_generate_compute_verify_signature(self):
    keyset_servicer = services.KeysetServicer()
    jwt_servicer = jwt_service.JwtServicer()

    template = jwt.jwt_es256_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')
    private_keyset = gen_response.keyset

    comp_request = testing_api_pb2.JwtSignRequest(keyset=private_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_response = jwt_servicer.PublicKeySignAndEncode(comp_request, self._ctx)
    self.assertEqual(comp_response.WhichOneof('result'), 'signed_compact_jwt')
    signed_compact_jwt = comp_response.signed_compact_jwt

    pub_request = testing_api_pb2.KeysetPublicRequest(
        private_keyset=private_keyset)
    pub_response = keyset_servicer.Public(pub_request, self._ctx)
    self.assertEqual(pub_response.WhichOneof('result'), 'public_keyset')
    public_keyset = pub_response.public_keyset

    verify_request = testing_api_pb2.JwtVerifyRequest(
        keyset=public_keyset, signed_compact_jwt=signed_compact_jwt)
    verify_request.validator.expected_issuer.value = 'issuer'
    verify_request.validator.expected_subject.value = 'subject'
    verify_request.validator.allow_missing_expiration = True
    verify_response = jwt_servicer.PublicKeyVerifyAndDecode(
        verify_request, self._ctx)
    self.assertEqual(verify_response.WhichOneof('result'), 'verified_jwt')
    self.assertEqual(verify_response.verified_jwt.issuer.value, 'issuer')
 def test_create_sign_primitive_with_invalid_algorithm_fails(self):
     handle = tink.new_keyset_handle(jwt.jwt_es256_template())
     key = jwt_ecdsa_pb2.JwtEcdsaPrivateKey.FromString(
         handle._keyset.key[0].key_data.value)
     key.public_key.algorithm = jwt_ecdsa_pb2.ES_UNKNOWN
     handle._keyset.key[0].key_data.value = key.SerializeToString()
     with self.assertRaises(tink.TinkError):
         handle.primitive(jwt.JwtPublicKeySign)
 def test_interesting_error(self):
   private_handle = tink.new_keyset_handle(jwt.jwt_es256_template())
   sign = private_handle.primitive(jwt.JwtPublicKeySign)
   verify = private_handle.public_keyset_handle().primitive(
       jwt.JwtPublicKeyVerify)
   raw_jwt = jwt.new_raw_jwt(issuer='issuer', without_expiration=True)
   compact = sign.sign_and_encode(raw_jwt)
   with self.assertRaisesRegex(jwt.JwtInvalidError,
                               'invalid JWT; expected issuer'):
     verify.verify_and_decode(compact, jwt.new_validator(
         expected_issuer='unknown', allow_missing_expiration=True))
    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_create_sign_verify_with_type_header(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(type_header='typeHeader',
                                  issuer='joe',
                                  without_expiration=True)
        signed_compact = sign.sign_and_encode(raw_jwt)

        validator = jwt.new_validator(expected_type_header='typeHeader',
                                      expected_issuer='joe',
                                      allow_missing_expiration=True)
        verified_jwt = verify.verify_and_decode(signed_compact, validator)
        self.assertEqual(verified_jwt.type_header(), 'typeHeader')
Ejemplo n.º 10
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())
Ejemplo n.º 11
0
  def test_jwt_public_key_sign_export_import_verify(self, lang):
    private_keyset = testing_servers.new_keyset(lang, jwt.jwt_es256_template())
    public_keyset = testing_servers.public_keyset(lang, private_keyset)

    # sign and export public key
    signer = testing_servers.jwt_public_key_sign(lang, private_keyset)
    now = datetime.datetime.now(tz=datetime.timezone.utc)
    token = jwt.new_raw_jwt(
        jwt_id='jwt_id', expiration=now + datetime.timedelta(seconds=100))
    compact = signer.sign_and_encode(token)
    public_jwk_set = testing_servers.jwk_set_from_keyset(lang, public_keyset)

    # verify using public_jwk_set
    imported_public_keyset = testing_servers.jwk_set_to_keyset(
        lang, public_jwk_set)

    verifier = testing_servers.jwt_public_key_verify(lang,
                                                     imported_public_keyset)
    validator = jwt.new_validator(fixed_now=now)
    verified_jwt = verifier.verify_and_decode(compact, validator)
    self.assertEqual(verified_jwt.jwt_id(), 'jwt_id')
Ejemplo n.º 12
0
     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(),
 '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(),
Ejemplo n.º 13
0
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')
Ejemplo n.º 14
0
 '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':
 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':
Ejemplo n.º 15
0
 def test_jwt_mac_from_keyset_without_primary_fails(self):
   builder = keyset_builder.new_keyset_builder()
   builder.add_new_key(jwt.jwt_es256_template())
   with self.assertRaises(tink.TinkError):
     builder.keyset_handle()
Ejemplo n.º 16
0
class JwtSignatureWrapperTest(parameterized.TestCase):

  def test_interesting_error(self):
    private_handle = tink.new_keyset_handle(jwt.jwt_es256_template())
    sign = private_handle.primitive(jwt.JwtPublicKeySign)
    verify = private_handle.public_keyset_handle().primitive(
        jwt.JwtPublicKeyVerify)
    raw_jwt = jwt.new_raw_jwt(issuer='issuer', without_expiration=True)
    compact = sign.sign_and_encode(raw_jwt)
    with self.assertRaisesRegex(jwt.JwtInvalidError,
                                'invalid JWT; expected issuer'):
      verify.verify_and_decode(compact, jwt.new_validator(
          expected_issuer='unknown', allow_missing_expiration=True))

  @parameterized.parameters([
      (jwt.raw_jwt_es256_template(), jwt.raw_jwt_es256_template()),
      (jwt.raw_jwt_es256_template(), jwt.jwt_es256_template()),
      (jwt.jwt_es256_template(), jwt.raw_jwt_es256_template()),
      (jwt.jwt_es256_template(), jwt.jwt_es256_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)
    handle1 = builder.keyset_handle()
    sign1 = handle1.primitive(jwt.JwtPublicKeySign)
    verify1 = handle1.public_keyset_handle().primitive(jwt.JwtPublicKeyVerify)

    newer_key_id = builder.add_new_key(new_key_tmpl)
    handle2 = builder.keyset_handle()
    sign2 = handle2.primitive(jwt.JwtPublicKeySign)
    verify2 = handle2.public_keyset_handle().primitive(jwt.JwtPublicKeyVerify)

    builder.set_primary_key(newer_key_id)
    handle3 = builder.keyset_handle()
    sign3 = handle3.primitive(jwt.JwtPublicKeySign)
    verify3 = handle3.public_keyset_handle().primitive(jwt.JwtPublicKeyVerify)

    builder.disable_key(older_key_id)
    handle4 = builder.keyset_handle()
    sign4 = handle4.primitive(jwt.JwtPublicKeySign)
    verify4 = handle4.public_keyset_handle().primitive(jwt.JwtPublicKeyVerify)

    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 signature, but not 4.
    compact1 = sign1.sign_and_encode(raw_jwt)
    self.assertEqual(
        verify1.verify_and_decode(compact1, validator).issuer(), 'a')
    self.assertEqual(
        verify2.verify_and_decode(compact1, validator).issuer(), 'a')
    self.assertEqual(
        verify3.verify_and_decode(compact1, validator).issuer(), 'a')
    with self.assertRaises(tink.TinkError):
      verify4.verify_and_decode(compact1, validator)

    # 2 uses the older key. So 1, 2 and 3 can verify the signature, but not 4.
    compact2 = sign2.sign_and_encode(raw_jwt)
    self.assertEqual(
        verify1.verify_and_decode(compact2, validator).issuer(), 'a')
    self.assertEqual(
        verify2.verify_and_decode(compact2, validator).issuer(), 'a')
    self.assertEqual(
        verify3.verify_and_decode(compact2, validator).issuer(), 'a')
    with self.assertRaises(tink.TinkError):
      verify4.verify_and_decode(compact2, validator)

    # 3 uses the newer key. So 2, 3 and 4 can verify the signature, but not 1.
    compact3 = sign3.sign_and_encode(raw_jwt)
    with self.assertRaises(tink.TinkError):
      verify1.verify_and_decode(compact3, validator)
    self.assertEqual(
        verify2.verify_and_decode(compact3, validator).issuer(), 'a')
    self.assertEqual(
        verify3.verify_and_decode(compact3, validator).issuer(), 'a')
    self.assertEqual(
        verify4.verify_and_decode(compact3, validator).issuer(), 'a')

    # 4 uses the newer key. So 2, 3 and 4 can verify the signature, but not 1.
    compact4 = sign4.sign_and_encode(raw_jwt)
    with self.assertRaises(tink.TinkError):
      verify1.verify_and_decode(compact4, validator)
    self.assertEqual(
        verify2.verify_and_decode(compact4, validator).issuer(), 'a')
    self.assertEqual(
        verify3.verify_and_decode(compact4, validator).issuer(), 'a')
    self.assertEqual(
        verify4.verify_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_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)

  @parameterized.named_parameters([
      ('JWT_ES256_RAW', jwt.raw_jwt_es256_template()),
      ('JWT_RS256_RAW', jwt.raw_jwt_rs256_2048_f4_template()),
      ('JWT_PS256_RAW', jwt.raw_jwt_ps256_3072_f4_template()),
  ])
  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)

  def test_legacy_template_fails(self):
    template = keyset_builder.legacy_template(jwt.jwt_es256_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.JwtPublicKeySign)
    with self.assertRaises(tink.TinkError):
      handle.public_keyset_handle().primitive(jwt.JwtPublicKeyVerify)

  def test_legacy_non_primary_key_fails(self):
    builder = keyset_builder.new_keyset_builder()
    old_template = keyset_builder.legacy_template(jwt.jwt_es256_template())
    _ = builder.add_new_key(old_template)
    current_key_id = builder.add_new_key(jwt.jwt_es256_template())
    builder.set_primary_key(current_key_id)
    handle = builder.keyset_handle()
    with self.assertRaises(tink.TinkError):
      handle.primitive(jwt.JwtPublicKeySign)
    with self.assertRaises(tink.TinkError):
      handle.public_keyset_handle().primitive(jwt.JwtPublicKeyVerify)

  def test_jwt_mac_from_keyset_without_primary_fails(self):
    builder = keyset_builder.new_keyset_builder()
    builder.add_new_key(jwt.jwt_es256_template())
    with self.assertRaises(tink.TinkError):
      builder.keyset_handle()
Ejemplo n.º 17
0
class JwtSignatureWrapperTest(parameterized.TestCase):

    # TODO(juerg): Add tests with TINK templates

    def test_interesting_error(self):
        private_handle = tink.new_keyset_handle(jwt.jwt_es256_template())
        sign = private_handle.primitive(jwt.JwtPublicKeySign)
        verify = private_handle.public_keyset_handle().primitive(
            jwt.JwtPublicKeyVerify)
        raw_jwt = jwt.new_raw_jwt(issuer='issuer', without_expiration=True)
        compact = sign.sign_and_encode(raw_jwt)
        with self.assertRaisesRegex(jwt.JwtInvalidError,
                                    'invalid JWT; expected issuer'):
            verify.verify_and_decode(
                compact,
                jwt.new_validator(expected_issuer='unknown',
                                  allow_missing_expiration=True))

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

        builder.set_primary_key(older_key_id)
        handle1 = builder.keyset_handle()
        sign1 = handle1.primitive(jwt.JwtPublicKeySign)
        verify1 = handle1.public_keyset_handle().primitive(
            jwt.JwtPublicKeyVerify)

        newer_key_id = builder.add_new_key(new_key_tmpl)
        handle2 = builder.keyset_handle()
        sign2 = handle2.primitive(jwt.JwtPublicKeySign)
        verify2 = handle2.public_keyset_handle().primitive(
            jwt.JwtPublicKeyVerify)

        builder.set_primary_key(newer_key_id)
        handle3 = builder.keyset_handle()
        sign3 = handle3.primitive(jwt.JwtPublicKeySign)
        verify3 = handle3.public_keyset_handle().primitive(
            jwt.JwtPublicKeyVerify)

        builder.disable_key(older_key_id)
        handle4 = builder.keyset_handle()
        sign4 = handle4.primitive(jwt.JwtPublicKeySign)
        verify4 = handle4.public_keyset_handle().primitive(
            jwt.JwtPublicKeyVerify)

        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 signature, but not 4.
        compact1 = sign1.sign_and_encode(raw_jwt)
        self.assertEqual(
            verify1.verify_and_decode(compact1, validator).issuer(), 'a')
        self.assertEqual(
            verify2.verify_and_decode(compact1, validator).issuer(), 'a')
        self.assertEqual(
            verify3.verify_and_decode(compact1, validator).issuer(), 'a')
        with self.assertRaises(tink.TinkError):
            verify4.verify_and_decode(compact1, validator)

        # 2 uses the older key. So 1, 2 and 3 can verify the signature, but not 4.
        compact2 = sign2.sign_and_encode(raw_jwt)
        self.assertEqual(
            verify1.verify_and_decode(compact2, validator).issuer(), 'a')
        self.assertEqual(
            verify2.verify_and_decode(compact2, validator).issuer(), 'a')
        self.assertEqual(
            verify3.verify_and_decode(compact2, validator).issuer(), 'a')
        with self.assertRaises(tink.TinkError):
            verify4.verify_and_decode(compact2, validator)

        # 3 uses the newer key. So 2, 3 and 4 can verify the signature, but not 1.
        compact3 = sign3.sign_and_encode(raw_jwt)
        with self.assertRaises(tink.TinkError):
            verify1.verify_and_decode(compact3, validator)
        self.assertEqual(
            verify2.verify_and_decode(compact3, validator).issuer(), 'a')
        self.assertEqual(
            verify3.verify_and_decode(compact3, validator).issuer(), 'a')
        self.assertEqual(
            verify4.verify_and_decode(compact3, validator).issuer(), 'a')

        # 4 uses the newer key. So 2, 3 and 4 can verify the signature, but not 1.
        compact4 = sign4.sign_and_encode(raw_jwt)
        with self.assertRaises(tink.TinkError):
            verify1.verify_and_decode(compact4, validator)
        self.assertEqual(
            verify2.verify_and_decode(compact4, validator).issuer(), 'a')
        self.assertEqual(
            verify3.verify_and_decode(compact4, validator).issuer(), 'a')
        self.assertEqual(
            verify4.verify_and_decode(compact4, validator).issuer(), 'a')

    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)

    def test_es256_key_with_custom_kid_header(self):
        keyset_handle = tink.new_keyset_handle(jwt.raw_jwt_es256_template())

        # Add a custom kid to the key in keyset_handle
        value = keyset_handle._keyset.key[0].key_data.value
        ecdsa_key = jwt_ecdsa_pb2.JwtEcdsaPrivateKey.FromString(value)
        ecdsa_key.public_key.custom_kid.value = 'my kid'
        keyset_handle._keyset.key[
            0].key_data.value = ecdsa_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)

    def test_rs256_key_with_custom_kid_header(self):
        keyset_handle = tink.new_keyset_handle(
            jwt.raw_jwt_rs256_2048_f4_template())

        # Add a custom kid to the key in keyset_handle
        value = keyset_handle._keyset.key[0].key_data.value
        pkcs1_key = jwt_rsa_ssa_pkcs1_pb2.JwtRsaSsaPkcs1PrivateKey.FromString(
            value)
        pkcs1_key.public_key.custom_kid.value = 'my kid'
        keyset_handle._keyset.key[
            0].key_data.value = pkcs1_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)

    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)

    def test_legacy_template_fails(self):
        template = _create_jwt_ecdsa_template(jwt_ecdsa_pb2.ES256,
                                              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.JwtPublicKeySign)
        with self.assertRaises(tink.TinkError):
            handle.public_keyset_handle().primitive(jwt.JwtPublicKeyVerify)

    def test_legacy_non_primary_key_fails(self):
        builder = keyset_builder.new_keyset_builder()
        old_template = _create_jwt_ecdsa_template(jwt_ecdsa_pb2.ES256,
                                                  tink_pb2.LEGACY)
        _ = builder.add_new_key(old_template)
        current_key_id = builder.add_new_key(jwt.jwt_es256_template())
        builder.set_primary_key(current_key_id)
        handle = builder.keyset_handle()
        with self.assertRaises(tink.TinkError):
            handle.primitive(jwt.JwtPublicKeySign)
        with self.assertRaises(tink.TinkError):
            handle.public_keyset_handle().primitive(jwt.JwtPublicKeyVerify)
Ejemplo n.º 18
0
    def test_key_rotation(self, old_key_tmpl, new_key_tmpl):
        old_key_tmpl = jwt.jwt_es256_template()
        new_key_tmpl = jwt.jwt_es384_template()
        builder = keyset_builder.new_keyset_builder()
        older_key_id = builder.add_new_key(old_key_tmpl)

        builder.set_primary_key(older_key_id)
        handle1 = builder.keyset_handle()
        sign1 = handle1.primitive(jwt.JwtPublicKeySign)
        verify1 = handle1.public_keyset_handle().primitive(
            jwt.JwtPublicKeyVerify)

        newer_key_id = builder.add_new_key(new_key_tmpl)
        handle2 = builder.keyset_handle()
        sign2 = handle2.primitive(jwt.JwtPublicKeySign)
        verify2 = handle2.public_keyset_handle().primitive(
            jwt.JwtPublicKeyVerify)

        builder.set_primary_key(newer_key_id)
        handle3 = builder.keyset_handle()
        sign3 = handle3.primitive(jwt.JwtPublicKeySign)
        verify3 = handle3.public_keyset_handle().primitive(
            jwt.JwtPublicKeyVerify)

        builder.disable_key(older_key_id)
        handle4 = builder.keyset_handle()
        sign4 = handle4.primitive(jwt.JwtPublicKeySign)
        verify4 = handle4.public_keyset_handle().primitive(
            jwt.JwtPublicKeyVerify)

        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 signature, but not 4.
        compact1 = sign1.sign_and_encode(raw_jwt)
        self.assertEqual(
            verify1.verify_and_decode(compact1, validator).issuer(), 'a')
        self.assertEqual(
            verify2.verify_and_decode(compact1, validator).issuer(), 'a')
        self.assertEqual(
            verify3.verify_and_decode(compact1, validator).issuer(), 'a')
        with self.assertRaises(tink.TinkError):
            verify4.verify_and_decode(compact1, validator)

        # 2 uses the older key. So 1, 2 and 3 can verify the signature, but not 4.
        compact2 = sign2.sign_and_encode(raw_jwt)
        self.assertEqual(
            verify1.verify_and_decode(compact2, validator).issuer(), 'a')
        self.assertEqual(
            verify2.verify_and_decode(compact2, validator).issuer(), 'a')
        self.assertEqual(
            verify3.verify_and_decode(compact2, validator).issuer(), 'a')
        with self.assertRaises(tink.TinkError):
            verify4.verify_and_decode(compact2, validator)

        # 3 uses the newer key. So 2, 3 and 4 can verify the signature, but not 1.
        compact3 = sign3.sign_and_encode(raw_jwt)
        with self.assertRaises(tink.TinkError):
            verify1.verify_and_decode(compact3, validator)
        self.assertEqual(
            verify2.verify_and_decode(compact3, validator).issuer(), 'a')
        self.assertEqual(
            verify3.verify_and_decode(compact3, validator).issuer(), 'a')
        self.assertEqual(
            verify4.verify_and_decode(compact3, validator).issuer(), 'a')

        # 4 uses the newer key. So 2, 3 and 4 can verify the signature, but not 1.
        compact4 = sign4.sign_and_encode(raw_jwt)
        with self.assertRaises(tink.TinkError):
            verify1.verify_and_decode(compact4, validator)
        self.assertEqual(
            verify2.verify_and_decode(compact4, validator).issuer(), 'a')
        self.assertEqual(
            verify3.verify_and_decode(compact4, validator).issuer(), 'a')
        self.assertEqual(
            verify4.verify_and_decode(compact4, validator).issuer(), 'a')