Esempio n. 1
0
 def test_convert_to_raw_fails(self, template_name):
     """Make sure that "wrapped" AEADs don't accept the raw AEAD ciphertext."""
     supported_langs = supported_key_types.SUPPORTED_LANGUAGES_BY_TEMPLATE_NAME[
         template_name]
     self.assertNotEmpty(supported_langs)
     template = supported_key_types.KEY_TEMPLATE[template_name]
     if template.output_prefix_type == tink_pb2.RAW:
         # ciphertext is already raw, so there is nothing to test.
         return
     keyset = testing_servers.new_keyset(supported_langs[0], template)
     ciphertext = testing_servers.aead(supported_langs[0], keyset).encrypt(
         b'plaintext', b'aad')
     for lang in supported_langs:
         primitive = testing_servers.aead(lang, keyset)
         # all non-raw keys add a 5 byte prefix to the raw ciphertext. Remove it
         # and try to decrypt.
         raw_ciphertext = ciphertext[:5]
         with self.assertRaises(
                 tink.TinkError,
                 msg=
                 'non-raw ciphertext with 5 byte tink header removed did not '
                 'cause a decryption error in %s. keyset="%s", '
                 'modified_ciphertext="%s"' %
             (lang, keyset.hex(), raw_ciphertext.hex())):
             primitive.decrypt(raw_ciphertext, b'aad')
Esempio n. 2
0
 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')
Esempio n. 3
0
 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')
Esempio n. 4
0
 def test_inc_version_aead(self, key_template_name, lang):
     """Increments the key version by one and checks they can't be used."""
     template = supported_key_types.KEY_TEMPLATE[key_template_name]
     keyset = testing_servers.new_keyset(lang, template)
     _ = testing_servers.aead(lang, keyset).encrypt(b'foo', b'bar')
     for keyset1 in gen_inc_versions(keyset):
         aead_primitive = testing_servers.aead(lang, keyset1)
         with self.assertRaises(tink.TinkError):
             _ = aead_primitive.encrypt(b'foo', b'bar')
Esempio n. 5
0
    def test_aead_without_primary(self, key_template_name, lang):
        """Unsets the primary key and tries to use an AEAD primitive."""
        template = supported_key_types.KEY_TEMPLATE[key_template_name]
        keyset = testing_servers.new_keyset(lang, template)
        ciphertext = testing_servers.aead(lang, keyset).encrypt(b'foo', b'bar')

        aead_without_primary = testing_servers.aead(lang,
                                                    unset_primary(keyset))
        with self.assertRaises(tink.TinkError):
            _ = aead_without_primary.encrypt(b'foo', b'bar')
        with self.assertRaises(tink.TinkError):
            _ = aead_without_primary.decrypt(ciphertext, b'bar')
Esempio n. 6
0
 def test_encrypt_decrypt(self, key_template_name):
     if key_template_name in _ADDITIONAL_KEY_TEMPLATES:
         key_template, key_type = _ADDITIONAL_KEY_TEMPLATES[
             key_template_name]
         supported_langs = supported_key_types.SUPPORTED_LANGUAGES[key_type]
     else:
         key_template = supported_key_types.KEY_TEMPLATE[key_template_name]
         supported_langs = (
             supported_key_types.
             SUPPORTED_LANGUAGES_BY_TEMPLATE_NAME[key_template_name])
     self.assertNotEmpty(supported_langs)
     # 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,
                     msg=
                     'Language %s supports AEAD decrypt with %s unexpectedly'
                     % (p2.lang, key_template_name)):
                 p2.decrypt(ciphertext, associated_data)
     for p in unsupported_aeads:
         with self.assertRaises(
                 tink.TinkError,
                 msg='Language %s supports AEAD encrypt with %s unexpectedly'
                 % (p.lang, key_template_name)):
             p.encrypt(b'plaintext', b'associated_data')
Esempio n. 7
0
 def test_inc_version_aead_aes_ctr_hmac_subkeys(self):
     """Increments the subkey versions by one and check they can't be used."""
     template = supported_key_types.KEY_TEMPLATE['AES128_CTR_HMAC_SHA256']
     for lang in TYPE_URL_TO_SUPPORTED_LANGUAGES[template.type_url]:
         keyset = testing_servers.new_keyset(lang, template)
         for keyset1 in gen_keys_for_aes_ctr_hmac_aead(keyset):
             aead_primitive = testing_servers.aead(lang, keyset1)
             with self.assertRaises(tink.TinkError):
                 _ = aead_primitive.encrypt(b'foo', b'bar')
Esempio n. 8
0
 def test_inc_version_aead(self, name, key_class):
     """Increments the key version by one and checks they can't be used."""
     template = supported_key_types.KEY_TEMPLATE[name]
     for lang in TYPE_URL_TO_SUPPORTED_LANGUAGES[template.type_url]:
         keyset = testing_servers.new_keyset(lang, template)
         keyset1 = inc_version(keyset, key_class)
         aead_primitive = testing_servers.aead(lang, keyset1)
         with self.assertRaises(tink.TinkError):
             _ = aead_primitive.encrypt(b'foo', b'bar')
Esempio n. 9
0
    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')
Esempio n. 10
0
    def test_aead(self, lang):
        keyset = testing_servers.new_keyset(lang,
                                            aead.aead_key_templates.AES128_GCM)
        plaintext = b'The quick brown fox jumps over the lazy dog'
        associated_data = b'associated_data'
        aead_primitive = testing_servers.aead(lang, keyset)
        ciphertext = aead_primitive.encrypt(plaintext, associated_data)
        output = aead_primitive.decrypt(ciphertext, associated_data)
        self.assertEqual(output, plaintext)

        with self.assertRaises(tink.TinkError):
            aead_primitive.decrypt(b'foo', associated_data)
Esempio n. 11
0
 def test_decrypt_modified_ciphertext_fails(self, template_name):
   """A basic test if the ciphertext is malleable with single bit-flips."""
   supported_langs = supported_key_types.SUPPORTED_LANGUAGES_BY_TEMPLATE_NAME[
       template_name]
   self.assertNotEmpty(supported_langs)
   template = supported_key_types.KEY_TEMPLATE[template_name]
   # Take the first supported language to generate the keyset.
   keyset = testing_servers.new_keyset(supported_langs[0], template)
   ciphertext = testing_servers.aead(supported_langs[0], keyset).encrypt(
       b'plaintext', b'aad')
   for lang in supported_langs:
     primitive = testing_servers.aead(lang, keyset)
     for i in range(len(ciphertext) * 8):
       # flip the ith bit in the ciphertext.
       modified_ciphertext = bytearray(ciphertext)
       modified_ciphertext[i // 8] ^= 1 << (i % 8)
       with self.assertRaises(
           tink.TinkError,
           msg='ciphertext with the %dth bit flipped did not cause a '
           'decryption error in %s. keyset="%s", modified_ciphertext="%s"' %
           (i, lang, keyset.hex(), bytes(modified_ciphertext).hex())):
         primitive.decrypt(bytes(modified_ciphertext), b'aad')
Esempio n. 12
0
 def test_keyset_validation_consistency(self, name, keyset):
     supported_langs = supported_key_types.SUPPORTED_LANGUAGES[
         supported_key_types.KEY_TYPE_FROM_URL[
             keyset.key[0].key_data.type_url]]
     supported_aeads = [
         testing_servers.aead(lang, keyset.SerializeToString())
         for lang in supported_langs
     ]
     plaintext = b'plaintext'
     associated_data = b'associated_data'
     failures = 0
     ciphertexts = {}
     results = {}
     for p in supported_aeads:
         try:
             ciphertexts[p.lang] = p.encrypt(plaintext, associated_data)
             if (name, p.lang) in SUCCEEDS_BUT_SHOULD_FAIL:
                 failures += 1
                 del ciphertexts[p.lang]
             if (name, p.lang) in FAILS_BUT_SHOULD_SUCCEED:
                 self.fail(
                     '(%s, %s) succeeded, but is in FAILS_BUT_SHOULD_SUCCEED'
                     % (name, p.lang))
             results[p.lang] = 'success'
         except tink.TinkError as e:
             if (name, p.lang) not in FAILS_BUT_SHOULD_SUCCEED:
                 failures += 1
             if (name, p.lang) in SUCCEEDS_BUT_SHOULD_FAIL:
                 self.fail(
                     '(%s, %s) is in SUCCEEDS_BUT_SHOULD_FAIL, but failed with %s'
                     % (name, p.lang, e))
             results[p.lang] = e
     # Test that either all supported langs accept the key, or all reject.
     if failures not in [0, len(supported_langs)]:
         self.fail('encryption for key %s is inconsistent: %s' %
                   (name, results))
     # Test all generated ciphertexts can be decypted.
     for enc_lang, ciphertext in ciphertexts.items():
         dec_aead = supported_aeads[0]
         output = dec_aead.decrypt(ciphertext, associated_data)
         if output != plaintext:
             self.fail(
                 'ciphertext encrypted with key %s in lang %s could not be'
                 'decrypted in lang %s.' % (name, enc_lang, dec_aead.lang))