예제 #1
0
class MacTest(parameterized.TestCase):
    @parameterized.parameters(
        supported_key_types.test_cases(supported_key_types.MAC_KEY_TYPES))
    def test_encrypt_decrypt(self, key_template_name, supported_langs):
        key_template = supported_key_types.KEY_TEMPLATE[key_template_name]
        keyset_handle = testing_servers.new_keyset_handle('java', key_template)
        supported_macs = [
            testing_servers.mac(lang, keyset_handle)
            for lang in supported_langs
        ]
        unsupported_macs = [
            testing_servers.mac(lang, keyset_handle)
            for lang in testing_servers.LANGUAGES
            if lang not in supported_langs
        ]
        for p in supported_macs:
            data = (
                b'This is some data to be authenticated using key_template '
                b'%s in %s.' %
                (key_template_name.encode('utf8'), p.lang.encode('utf8')))
            mac_value = p.compute_mac(data)
            for p2 in supported_macs:
                self.assertIsNone(p2.verify_mac(mac_value, data))
            for p2 in unsupported_macs:
                with self.assertRaises(tink.TinkError):
                    p2.verify_mac(mac_value, data)
        for p in unsupported_macs:
            with self.assertRaises(tink.TinkError):
                p.compute_mac(data)
예제 #2
0
class AeadPythonTest(parameterized.TestCase):
    @parameterized.parameters(
        supported_key_types.test_cases(supported_key_types.AEAD_KEY_TYPES))
    def test_encrypt_decrypt(self, key_template_name, supported_langs):
        key_template = supported_key_types.KEY_TEMPLATE[key_template_name]
        # use java to generate keys, as it supports all key types.
        keyset_handle = testing_servers.new_keyset_handle('java', key_template)
        supported_aeads = [
            testing_servers.aead(lang, keyset_handle)
            for lang in supported_langs
        ]
        unsupported_aeads = [
            testing_servers.aead(lang, keyset_handle)
            for lang in testing_servers.LANGUAGES
            if lang not in supported_langs
        ]
        for p in supported_aeads:
            plaintext = (
                b'This is some plaintext message to be encrypted using key_template '
                b'%s using %s for encryption.' %
                (key_template_name.encode('utf8'), p.lang.encode('utf8')))
            associated_data = (
                b'Some associated data for %s using %s for encryption.' %
                (key_template_name.encode('utf8'), p.lang.encode('utf8')))
            ciphertext = p.encrypt(plaintext, associated_data)
            for p2 in supported_aeads:
                output = p2.decrypt(ciphertext, associated_data)
                self.assertEqual(output, plaintext)
            for p2 in unsupported_aeads:
                with self.assertRaises(tink.TinkError):
                    p2.decrypt(ciphertext, associated_data)
        for p in unsupported_aeads:
            with self.assertRaises(tink.TinkError):
                p.encrypt(b'plaintext', b'associated_data')
예제 #3
0
 def test_test_cases(self):
     self.assertEqual(
         list(
             supported_key_types.test_cases(
                 ['AesEaxKey', 'ChaCha20Poly1305Key'])),
         [('AES128_EAX', ['cc', 'java', 'python']),
          ('AES256_EAX', ['cc', 'java', 'python']),
          ('CHACHA20_POLY1305', ['java', 'go'])])
예제 #4
0
class JsonTest(parameterized.TestCase):
    def test_is_equal_keyset(self):
        keyset1 = tink_pb2.Keyset()
        key11 = keyset1.key.add()
        key11.key_id = 21
        key12 = keyset1.key.add()
        key12.key_id = 42
        keyset2 = tink_pb2.Keyset()
        key21 = keyset2.key.add()
        key21.key_id = 42
        key22 = keyset2.key.add()
        key22.key_id = 21
        self.assertTrue(
            _is_equal_keyset(keyset1.SerializeToString(),
                             keyset2.SerializeToString()))

    def test_is_not_equal_keyset(self):
        keyset1 = tink_pb2.Keyset()
        key11 = keyset1.key.add()
        key11.key_id = 21
        key12 = keyset1.key.add()
        key12.key_id = 42
        keyset2 = tink_pb2.Keyset()
        key3 = keyset2.key.add()
        key3.key_id = 21
        self.assertFalse(
            _is_equal_keyset(keyset1.SerializeToString(),
                             keyset2.SerializeToString()))

    def assertEqualKeyset(self, keyset1: bytes, keyset2: bytes):
        if not _is_equal_keyset(keyset1, keyset2):
            self.fail('these keysets are not equal: \n%s\n \n%s\n' %
                      (_keyset_proto(keyset1), _keyset_proto(keyset2)))

    @parameterized.parameters(
        supported_key_types.test_cases(supported_key_types.ALL_KEY_TYPES))
    def test_to_from_json(self, key_template_name, supported_langs):
        self.assertNotEmpty(supported_langs)
        key_template = supported_key_types.KEY_TEMPLATE[key_template_name]
        # Take the first supported language to generate the keyset.
        keyset = testing_servers.new_keyset(supported_langs[0], key_template)
        for to_lang in supported_langs:
            json_keyset = testing_servers.keyset_to_json(to_lang, keyset)
            for from_lang in supported_langs:
                keyset2 = testing_servers.keyset_from_json(
                    from_lang, json_keyset)
                self.assertEqualKeyset(keyset, keyset2)
예제 #5
0
class HybridEncryptionTest(parameterized.TestCase):
    @parameterized.parameters(
        supported_key_types.test_cases(
            supported_key_types.HYBRID_PRIVATE_KEY_TYPES))
    def test_encrypt_decrypt(self, key_template_name, supported_langs):
        self.assertNotEmpty(supported_langs)
        key_template = supported_key_types.KEY_TEMPLATE[key_template_name]
        # Take the first supported language to generate the private keyset.
        private_keyset = testing_servers.new_keyset(supported_langs[0],
                                                    key_template)
        supported_decs = [
            testing_servers.hybrid_decrypt(lang, private_keyset)
            for lang in supported_langs
        ]
        unsupported_decs = [
            testing_servers.hybrid_decrypt(lang, private_keyset)
            for lang in SUPPORTED_LANGUAGES if lang not in supported_langs
        ]
        public_keyset = testing_servers.public_keyset('java', private_keyset)
        supported_encs = [
            testing_servers.hybrid_encrypt(lang, public_keyset)
            for lang in supported_langs
        ]
        unsupported_encs = [
            testing_servers.hybrid_encrypt(lang, public_keyset)
            for lang in testing_servers.LANGUAGES
            if lang not in supported_langs
        ]
        for enc in supported_encs:
            plaintext = (
                b'This is some plaintext message to be encrypted using key_template '
                b'%s in %s.' %
                (key_template_name.encode('utf8'), enc.lang.encode('utf8')))
            context_info = (
                b'Some context info for %s using %s for encryption.' %
                (key_template_name.encode('utf8'), enc.lang.encode('utf8')))
            ciphertext = enc.encrypt(plaintext, context_info)
            for dec in supported_decs:
                output = dec.decrypt(ciphertext, context_info)
                self.assertEqual(output, plaintext)
            for dec in unsupported_decs:
                with self.assertRaises(tink.TinkError):
                    dec.decrypt(ciphertext, context_info)
        for enc in unsupported_encs:
            with self.assertRaises(tink.TinkError):
                enc.encrypt(b'plaintext', b'context_info')
예제 #6
0
class StreamingAeadPythonTest(parameterized.TestCase):

  @parameterized.parameters(
      supported_key_types.test_cases(
          supported_key_types.STREAMING_AEAD_KEY_TYPES))
  def test_encrypt_decrypt(self, key_template_name, supported_langs):
    self.assertNotEmpty(supported_langs)
    key_template = supported_key_types.KEY_TEMPLATE[key_template_name]
    # Take the first supported language to generate the keyset.
    keyset = testing_servers.new_keyset(supported_langs[0], key_template)
    supported_streaming_aeads = [
        testing_servers.streaming_aead(lang, keyset) for lang in supported_langs
    ]
    unsupported_streaming_aeads = [
        testing_servers.streaming_aead(lang, keyset)
        for lang in SUPPORTED_LANGUAGES
        if lang not in supported_langs
    ]
    for p in supported_streaming_aeads:
      plaintext = (
          b'This is some plaintext message to be encrypted using key_template '
          b'%s using %s for encryption.'
          % (key_template_name.encode('utf8'), p.lang.encode('utf8')))
      associated_data = (
          b'Some associated data for %s using %s for encryption.' %
          (key_template_name.encode('utf8'), p.lang.encode('utf8')))
      plaintext_stream = io.BytesIO(plaintext)
      ciphertext_result_stream = p.new_encrypting_stream(
          plaintext_stream, associated_data)
      ciphertext = ciphertext_result_stream.read()
      for p2 in supported_streaming_aeads:
        ciphertext_stream = io.BytesIO(ciphertext)
        decrypted_stream = p2.new_decrypting_stream(
            ciphertext_stream, associated_data)
        self.assertEqual(decrypted_stream.read(), plaintext)
      for p2 in unsupported_streaming_aeads:
        with self.assertRaises(tink.TinkError):
          ciphertext_stream = io.BytesIO(ciphertext)
          decrypted_stream = p2.new_decrypting_stream(
              ciphertext_stream, associated_data)
    for p in unsupported_streaming_aeads:
      with self.assertRaises(tink.TinkError):
        plaintext_stream = io.BytesIO(b'plaintext')
        ciphertext_result_stream = p.new_encrypting_stream(
            plaintext_stream, b'associated_data')
class SignaturePythonTest(parameterized.TestCase):
    @parameterized.parameters(
        supported_key_types.test_cases(supported_key_types.SIGNATURE_KEY_TYPES)
    )
    def test_encrypt_decrypt(self, key_template_name, supported_langs):
        self.assertNotEmpty(supported_langs)
        key_template = supported_key_types.KEY_TEMPLATE[key_template_name]
        # Take the first supported language to generate the private keyset.
        private_keyset = testing_servers.new_keyset(supported_langs[0],
                                                    key_template)
        supported_signers = [
            testing_servers.public_key_sign(lang, private_keyset)
            for lang in supported_langs
        ]
        unsupported_signers = [
            testing_servers.public_key_sign(lang, private_keyset)
            for lang in SUPPORTED_LANGUAGES if lang not in supported_langs
        ]
        public_keyset = testing_servers.public_keyset('java', private_keyset)
        supported_verifiers = [
            testing_servers.public_key_verify(lang, public_keyset)
            for lang in supported_langs
        ]
        unsupported_verifiers = [
            testing_servers.public_key_verify(lang, public_keyset)
            for lang in testing_servers.LANGUAGES
            if lang not in supported_langs
        ]
        for signer in supported_signers:
            message = (
                b'A message to be signed using key_template %s in %s.' %
                (key_template_name.encode('utf8'), signer.lang.encode('utf8')))
            sign = signer.sign(message)
            for verifier in supported_verifiers:
                self.assertIsNone(verifier.verify(sign, message))
            for verifier in unsupported_verifiers:
                with self.assertRaises(tink.TinkError):
                    verifier.verify(sign, message)
        for signer in unsupported_signers:
            with self.assertRaises(tink.TinkError):
                _ = signer.sign(message)
예제 #8
0
class DeterministicAeadTest(parameterized.TestCase):

  @parameterized.parameters(
      supported_key_types.test_cases(supported_key_types.DAEAD_KEY_TYPES))
  def test_encrypt_decrypt(self, key_template_name, supported_langs):
    key_template = supported_key_types.KEY_TEMPLATE[key_template_name]
    keyset_handle = testing_servers.new_keyset_handle('java', key_template)
    supported_daeads = [
        testing_servers.deterministic_aead(lang, keyset_handle)
        for lang in supported_langs
    ]
    self.assertNotEmpty(supported_daeads)
    unsupported_daeads = [
        testing_servers.deterministic_aead(lang, keyset_handle)
        for lang in testing_servers.LANGUAGES
        if lang not in supported_langs
    ]
    plaintext = (
        b'This is some plaintext message to be encrypted using '
        b'key_template %s.' % key_template_name.encode('utf8'))
    associated_data = (
        b'Some associated data for %s.' % key_template_name.encode('utf8'))
    ciphertext = None
    for p in supported_daeads:
      if ciphertext:
        self.assertEqual(
            ciphertext,
            p.encrypt_deterministically(plaintext, associated_data))
      else:
        ciphertext = p.encrypt_deterministically(plaintext, associated_data)
    for p2 in supported_daeads:
      output = p2.decrypt_deterministically(ciphertext, associated_data)
      self.assertEqual(output, plaintext)
    for p2 in unsupported_daeads:
      with self.assertRaises(tink.TinkError):
        p2.decrypt_deterministically(ciphertext, associated_data)
    for p in unsupported_daeads:
      with self.assertRaises(tink.TinkError):
        p.encrypt_deterministically(b'plaintext', b'associated_data')
예제 #9
0
파일: prf_set_test.py 프로젝트: vihcle/tink
class PrfSetPythonTest(parameterized.TestCase):
    @parameterized.parameters(
        supported_key_types.test_cases(supported_key_types.PRF_KEY_TYPES))
    def test_unsupported(self, key_template_name, supported_langs):
        self.assertNotEmpty(supported_langs)
        keyset = gen_keyset(key_template_name)
        unsupported_languages = [
            lang for lang in SUPPORTED_LANGUAGES if lang not in supported_langs
        ]
        for lang in unsupported_languages:
            p = testing_servers.prf_set(lang, keyset)
            with self.assertRaises(tink.TinkError):
                p.primary().compute(b'input_data', output_length=16)

    @parameterized.parameters(
        supported_key_types.test_cases(supported_key_types.PRF_KEY_TYPES))
    def test_supported(self, key_template_name, supported_langs):
        self.assertNotEmpty(supported_langs)
        keyset = gen_keyset(key_template_name)
        input_data = b'This is some input data.'
        outputs = []
        for lang in supported_langs:
            p = testing_servers.prf_set(lang, keyset)
            outputs.append(p.primary().compute(input_data, 16))
        self.assertLen(outputs, len(supported_langs))
        self.assertLen(outputs[0], 16)
        self.assertLen(set(outputs), 1)

    @parameterized.parameters(test_cases_with_output_length())
    def test_compute_consistent_for_output_length(self, key_template_name,
                                                  output_length,
                                                  supported_langs):
        # This test checks that for a given output_length, either all
        # implementations fail or all produce the same value.
        self.assertNotEmpty(supported_langs)
        keyset = gen_keyset(key_template_name)
        input_data = b'This is some input data.'
        errors = {}
        outputs = {}
        for lang in supported_langs:
            try:
                p = testing_servers.prf_set(lang, keyset)
                outputs[lang] = p.primary().compute(input_data, output_length)
            except tink.TinkError as e:
                errors[lang] = e
        inconsistent_errors = bool(errors) and bool(outputs)
        inconsistent_output_values = len(set(outputs.values())) > 1
        if inconsistent_errors or inconsistent_output_values:
            self.fail(
                'The PRF for template %s and output_length=%d is inconsistent: '
                'outputs = %s, errors = %s.' %
                (key_template_name, output_length, outputs, errors))

    @parameterized.parameters(SUPPORTED_LANGUAGES)
    def test_multiple_prfs(self, lang):
        keyset = gen_keyset_with_2_prfs()
        input_data = b'This is some input data.'
        output_length = 15
        p = testing_servers.prf_set(lang, keyset)
        primary_output = p.primary().compute(input_data, output_length)
        primary_id = p.primary_id()
        all_outputs = {
            key_id: f.compute(input_data, output_length)
            for key_id, f in p.all().items()
        }
        self.assertLen(all_outputs, 2)
        self.assertEqual(all_outputs[primary_id], primary_output)
예제 #10
0
파일: prf_set_test.py 프로젝트: vihcle/tink
def test_cases_with_output_length():
    for key_template_name, supported_langs in supported_key_types.test_cases(
            supported_key_types.PRF_KEY_TYPES):
        for output_length in OUTPUT_LENGTHS:
            yield (key_template_name, output_length, supported_langs)
예제 #11
0
파일: aead_test.py 프로젝트: vihcle/tink
class AeadPythonTest(parameterized.TestCase):
    @parameterized.parameters(
        supported_key_types.test_cases(supported_key_types.AEAD_KEY_TYPES))
    def test_encrypt_decrypt(self, key_template_name, supported_langs):
        self.assertNotEmpty(supported_langs)
        key_template = supported_key_types.KEY_TEMPLATE[key_template_name]
        # Take the first supported language to generate the keyset.
        keyset = testing_servers.new_keyset(supported_langs[0], key_template)
        supported_aeads = [
            testing_servers.aead(lang, keyset) for lang in supported_langs
        ]
        unsupported_aeads = [
            testing_servers.aead(lang, keyset) for lang in SUPPORTED_LANGUAGES
            if lang not in supported_langs
        ]
        for p in supported_aeads:
            plaintext = (
                b'This is some plaintext message to be encrypted using key_template '
                b'%s using %s for encryption.' %
                (key_template_name.encode('utf8'), p.lang.encode('utf8')))
            associated_data = (
                b'Some associated data for %s using %s for encryption.' %
                (key_template_name.encode('utf8'), p.lang.encode('utf8')))
            ciphertext = p.encrypt(plaintext, associated_data)
            for p2 in supported_aeads:
                output = p2.decrypt(ciphertext, associated_data)
                self.assertEqual(output, plaintext)
            for p2 in unsupported_aeads:
                with self.assertRaises(tink.TinkError):
                    p2.decrypt(ciphertext, associated_data)
        for p in unsupported_aeads:
            with self.assertRaises(tink.TinkError):
                p.encrypt(b'plaintext', b'associated_data')

    @parameterized.parameters(key_rotation_test_cases())
    def test_key_rotation(self, enc_lang, dec_lang, old_key_tmpl,
                          new_key_tmpl):
        # Do a key rotation from an old key generated from old_key_tmpl to a new
        # key generated from new_key_tmpl. Encryption and decryption are done
        # in languages enc_lang and dec_lang.
        builder = keyset_builder.new_keyset_builder()
        older_key_id = builder.add_new_key(old_key_tmpl)
        builder.set_primary_key(older_key_id)
        enc_aead1 = testing_servers.aead(enc_lang, builder.keyset())
        dec_aead1 = testing_servers.aead(dec_lang, builder.keyset())
        newer_key_id = builder.add_new_key(new_key_tmpl)
        enc_aead2 = testing_servers.aead(enc_lang, builder.keyset())
        dec_aead2 = testing_servers.aead(dec_lang, builder.keyset())

        builder.set_primary_key(newer_key_id)
        enc_aead3 = testing_servers.aead(enc_lang, builder.keyset())
        dec_aead3 = testing_servers.aead(dec_lang, builder.keyset())

        builder.disable_key(older_key_id)
        enc_aead4 = testing_servers.aead(enc_lang, builder.keyset())
        dec_aead4 = testing_servers.aead(dec_lang, builder.keyset())

        self.assertNotEqual(older_key_id, newer_key_id)
        # 1 encrypts with the older key. So 1, 2 and 3 can decrypt it, but not 4.
        ciphertext1 = enc_aead1.encrypt(b'plaintext', b'ad')
        self.assertEqual(dec_aead1.decrypt(ciphertext1, b'ad'), b'plaintext')
        self.assertEqual(dec_aead2.decrypt(ciphertext1, b'ad'), b'plaintext')
        self.assertEqual(dec_aead3.decrypt(ciphertext1, b'ad'), b'plaintext')
        with self.assertRaises(tink.TinkError):
            _ = dec_aead4.decrypt(ciphertext1, b'ad')

        # 2 encrypts with the older key. So 1, 2 and 3 can decrypt it, but not 4.
        ciphertext2 = enc_aead2.encrypt(b'plaintext', b'ad')
        self.assertEqual(dec_aead1.decrypt(ciphertext2, b'ad'), b'plaintext')
        self.assertEqual(dec_aead2.decrypt(ciphertext2, b'ad'), b'plaintext')
        self.assertEqual(dec_aead3.decrypt(ciphertext2, b'ad'), b'plaintext')
        with self.assertRaises(tink.TinkError):
            _ = dec_aead4.decrypt(ciphertext2, b'ad')

        # 3 encrypts with the newer key. So 2, 3 and 4 can decrypt it, but not 1.
        ciphertext3 = enc_aead3.encrypt(b'plaintext', b'ad')
        with self.assertRaises(tink.TinkError):
            _ = dec_aead1.decrypt(ciphertext3, b'ad')
        self.assertEqual(dec_aead2.decrypt(ciphertext3, b'ad'), b'plaintext')
        self.assertEqual(dec_aead3.decrypt(ciphertext3, b'ad'), b'plaintext')
        self.assertEqual(dec_aead4.decrypt(ciphertext3, b'ad'), b'plaintext')

        # 4 encrypts with the newer key. So 2, 3 and 4 can decrypt it, but not 1.
        ciphertext4 = enc_aead4.encrypt(b'plaintext', b'ad')
        with self.assertRaises(tink.TinkError):
            _ = dec_aead1.decrypt(ciphertext4, b'ad')
        self.assertEqual(dec_aead2.decrypt(ciphertext4, b'ad'), b'plaintext')
        self.assertEqual(dec_aead3.decrypt(ciphertext4, b'ad'), b'plaintext')
        self.assertEqual(dec_aead4.decrypt(ciphertext4, b'ad'), b'plaintext')
예제 #12
0
파일: mac_test.py 프로젝트: vihcle/tink
class MacTest(parameterized.TestCase):
    @parameterized.parameters(
        supported_key_types.test_cases(supported_key_types.MAC_KEY_TYPES))
    def test_encrypt_decrypt(self, key_template_name, supported_langs):
        self.assertNotEmpty(supported_langs)
        key_template = supported_key_types.KEY_TEMPLATE[key_template_name]
        # Take the first supported language to generate the keyset.
        keyset = testing_servers.new_keyset(supported_langs[0], key_template)
        supported_macs = [
            testing_servers.mac(lang, keyset) for lang in supported_langs
        ]
        unsupported_macs = [
            testing_servers.mac(lang, keyset) for lang in SUPPORTED_LANGUAGES
            if lang not in supported_langs
        ]
        for p in supported_macs:
            data = (
                b'This is some data to be authenticated using key_template '
                b'%s in %s.' %
                (key_template_name.encode('utf8'), p.lang.encode('utf8')))
            mac_value = p.compute_mac(data)
            for p2 in supported_macs:
                self.assertIsNone(p2.verify_mac(mac_value, data))
            for p2 in unsupported_macs:
                with self.assertRaises(tink.TinkError):
                    p2.verify_mac(mac_value, data)
        for p in unsupported_macs:
            with self.assertRaises(tink.TinkError):
                p.compute_mac(data)

    @parameterized.parameters(key_rotation_test_cases())
    def test_key_rotation(self, compute_lang, verify_lang, old_key_tmpl,
                          new_key_tmpl):
        # Do a key rotation from an old key generated from old_key_tmpl to a new
        # key generated from new_key_tmpl. MAC computation and verification are done
        # in languages compute_lang and verify_lang.
        builder = keyset_builder.new_keyset_builder()
        older_key_id = builder.add_new_key(old_key_tmpl)
        builder.set_primary_key(older_key_id)
        compute_mac1 = testing_servers.mac(compute_lang, builder.keyset())
        verify_mac1 = testing_servers.mac(verify_lang, builder.keyset())
        newer_key_id = builder.add_new_key(new_key_tmpl)
        compute_mac2 = testing_servers.mac(compute_lang, builder.keyset())
        verify_mac2 = testing_servers.mac(verify_lang, builder.keyset())

        builder.set_primary_key(newer_key_id)
        compute_mac3 = testing_servers.mac(compute_lang, builder.keyset())
        verify_mac3 = testing_servers.mac(verify_lang, builder.keyset())

        builder.disable_key(older_key_id)
        compute_mac4 = testing_servers.mac(compute_lang, builder.keyset())
        verify_mac4 = testing_servers.mac(verify_lang, builder.keyset())

        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.
        mac_value1 = compute_mac1.compute_mac(b'plaintext')
        verify_mac1.verify_mac(mac_value1, b'plaintext')
        verify_mac2.verify_mac(mac_value1, b'plaintext')
        verify_mac3.verify_mac(mac_value1, b'plaintext')
        with self.assertRaises(tink.TinkError):
            verify_mac4.verify_mac(mac_value1, b'plaintext')

        # 2 uses the older key. So 1, 2 and 3 can verify the mac, but not 4.
        mac_value2 = compute_mac2.compute_mac(b'plaintext')
        verify_mac1.verify_mac(mac_value2, b'plaintext')
        verify_mac2.verify_mac(mac_value2, b'plaintext')
        verify_mac3.verify_mac(mac_value2, b'plaintext')
        with self.assertRaises(tink.TinkError):
            verify_mac4.verify_mac(mac_value2, b'plaintext')

        # 3 uses the newer key. So 2, 3 and 4 can verify the mac, but not 1.
        mac_value3 = compute_mac3.compute_mac(b'plaintext')
        with self.assertRaises(tink.TinkError):
            verify_mac1.verify_mac(mac_value3, b'plaintext')
        verify_mac2.verify_mac(mac_value3, b'plaintext')
        verify_mac3.verify_mac(mac_value3, b'plaintext')
        verify_mac4.verify_mac(mac_value3, b'plaintext')

        # 4 uses the newer key. So 2, 3 and 4 can verify the mac, but not 1.
        mac_value4 = compute_mac4.compute_mac(b'plaintext')
        with self.assertRaises(tink.TinkError):
            verify_mac1.verify_mac(mac_value4, b'plaintext')
        verify_mac2.verify_mac(mac_value4, b'plaintext')
        verify_mac3.verify_mac(mac_value4, b'plaintext')
        verify_mac4.verify_mac(mac_value4, b'plaintext')
예제 #13
0
class StreamingAeadPythonTest(parameterized.TestCase):
    @parameterized.parameters(
        supported_key_types.test_cases(
            supported_key_types.STREAMING_AEAD_KEY_TYPES))
    def test_encrypt_decrypt(self, key_template_name, supported_langs):
        self.assertNotEmpty(supported_langs)
        key_template = supported_key_types.KEY_TEMPLATE[key_template_name]
        # Take the first supported language to generate the keyset.
        keyset = testing_servers.new_keyset(supported_langs[0], key_template)
        supported_streaming_aeads = [
            testing_servers.streaming_aead(lang, keyset)
            for lang in supported_langs
        ]
        unsupported_streaming_aeads = [
            testing_servers.streaming_aead(lang, keyset)
            for lang in SUPPORTED_LANGUAGES if lang not in supported_langs
        ]
        for p in supported_streaming_aeads:
            desc = (
                b'This is some plaintext message to be encrypted using key_template '
                b'%s using %s for encryption.' %
                (key_template_name.encode('utf8'), p.lang.encode('utf8')))
            plaintext = desc + LONG_PLAINTEXT
            associated_data = (
                b'Some associated data for %s using %s for encryption.' %
                (key_template_name.encode('utf8'), p.lang.encode('utf8')))
            plaintext_stream = io.BytesIO(plaintext)
            ciphertext_result_stream = p.new_encrypting_stream(
                plaintext_stream, associated_data)
            ciphertext = ciphertext_result_stream.read()
            for p2 in supported_streaming_aeads:
                ciphertext_stream = io.BytesIO(ciphertext)
                decrypted_stream = p2.new_decrypting_stream(
                    ciphertext_stream, associated_data)
                self.assertEqual(decrypted_stream.read(), plaintext)
            for p2 in unsupported_streaming_aeads:
                with self.assertRaises(tink.TinkError):
                    ciphertext_stream = io.BytesIO(ciphertext)
                    decrypted_stream = p2.new_decrypting_stream(
                        ciphertext_stream, associated_data)
        for p in unsupported_streaming_aeads:
            with self.assertRaises(tink.TinkError):
                plaintext_stream = io.BytesIO(b'plaintext')
                ciphertext_result_stream = p.new_encrypting_stream(
                    plaintext_stream, b'associated_data')

    @parameterized.parameters(key_rotation_test_cases())
    def test_key_rotation(self, enc_lang, dec_lang):
        # Do a key rotation from an old key to a new key.
        # Encryption and decryption are done in languages enc_lang and dec_lang.
        builder = keyset_builder.new_keyset_builder()
        older_key_id = builder.add_new_key(
            streaming_aead.streaming_aead_key_templates.AES128_GCM_HKDF_4KB)
        builder.set_primary_key(older_key_id)
        enc1 = testing_servers.streaming_aead(enc_lang, builder.keyset())
        dec1 = testing_servers.streaming_aead(dec_lang, builder.keyset())
        newer_key_id = builder.add_new_key(
            streaming_aead.streaming_aead_key_templates.AES256_GCM_HKDF_4KB)
        enc2 = testing_servers.streaming_aead(enc_lang, builder.keyset())
        dec2 = testing_servers.streaming_aead(dec_lang, builder.keyset())

        builder.set_primary_key(newer_key_id)
        enc3 = testing_servers.streaming_aead(enc_lang, builder.keyset())
        dec3 = testing_servers.streaming_aead(dec_lang, builder.keyset())

        builder.disable_key(older_key_id)
        enc4 = testing_servers.streaming_aead(enc_lang, builder.keyset())
        dec4 = testing_servers.streaming_aead(dec_lang, builder.keyset())

        self.assertNotEqual(older_key_id, newer_key_id)
        # 1 encrypts with the older key. So 1, 2 and 3 can decrypt it, but not 4.
        plaintext = LONG_PLAINTEXT
        ad = b'associated_data'
        ciphertext1 = enc1.new_encrypting_stream(io.BytesIO(plaintext),
                                                 ad).read()
        self.assertEqual(
            dec1.new_decrypting_stream(io.BytesIO(ciphertext1), ad).read(),
            plaintext)
        self.assertEqual(
            dec2.new_decrypting_stream(io.BytesIO(ciphertext1), ad).read(),
            plaintext)
        self.assertEqual(
            dec3.new_decrypting_stream(io.BytesIO(ciphertext1), ad).read(),
            plaintext)
        with self.assertRaises(tink.TinkError):
            _ = dec4.new_decrypting_stream(io.BytesIO(ciphertext1), ad).read()

        # 2 encrypts with the older key. So 1, 2 and 3 can decrypt it, but not 4.
        ciphertext2 = enc2.new_encrypting_stream(io.BytesIO(plaintext),
                                                 ad).read()
        self.assertEqual(
            dec1.new_decrypting_stream(io.BytesIO(ciphertext2), ad).read(),
            plaintext)
        self.assertEqual(
            dec2.new_decrypting_stream(io.BytesIO(ciphertext2), ad).read(),
            plaintext)
        self.assertEqual(
            dec3.new_decrypting_stream(io.BytesIO(ciphertext2), ad).read(),
            plaintext)
        with self.assertRaises(tink.TinkError):
            _ = dec4.new_decrypting_stream(io.BytesIO(ciphertext2), ad).read()

        # 3 encrypts with the newer key. So 2, 3 and 4 can decrypt it, but not 1.
        ciphertext3 = enc3.new_encrypting_stream(io.BytesIO(plaintext),
                                                 ad).read()
        with self.assertRaises(tink.TinkError):
            _ = dec1.new_decrypting_stream(io.BytesIO(ciphertext3), ad).read()
        self.assertEqual(
            dec2.new_decrypting_stream(io.BytesIO(ciphertext3), ad).read(),
            plaintext)
        self.assertEqual(
            dec3.new_decrypting_stream(io.BytesIO(ciphertext3), ad).read(),
            plaintext)
        self.assertEqual(
            dec4.new_decrypting_stream(io.BytesIO(ciphertext3), ad).read(),
            plaintext)

        # 4 encrypts with the newer key. So 2, 3 and 4 can decrypt it, but not 1.
        ciphertext4 = enc4.new_encrypting_stream(io.BytesIO(plaintext),
                                                 ad).read()
        with self.assertRaises(tink.TinkError):
            _ = dec1.new_decrypting_stream(io.BytesIO(ciphertext4), ad).read()
        self.assertEqual(
            dec2.new_decrypting_stream(io.BytesIO(ciphertext4), ad).read(),
            plaintext)
        self.assertEqual(
            dec3.new_decrypting_stream(io.BytesIO(ciphertext4), ad).read(),
            plaintext)
        self.assertEqual(
            dec4.new_decrypting_stream(io.BytesIO(ciphertext4), ad).read(),
            plaintext)