def test_encrypt_decrypt(self, key_template_name): supported_langs = supported_key_types.SUPPORTED_LANGUAGES_BY_TEMPLATE_NAME[ key_template_name] 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, msg= 'Language %s supports streaming AEAD decryption with %s ' 'unexpectedly' % (p2.lang, key_template_name)): 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, msg='Language %s supports streaming AEAD encryption with %s ' 'unexpectedly' % (p.lang, key_template_name)): plaintext_stream = io.BytesIO(b'plaintext') ciphertext_result_stream = p.new_encrypting_stream( plaintext_stream, b'associated_data')
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 = testing_servers.new_keyset('java', 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')
def test_streaming_aead(self, lang): keyset = testing_servers.new_keyset( lang, streaming_aead.streaming_aead_key_templates.AES128_GCM_HKDF_4KB) plaintext = b'The quick brown fox jumps over the lazy dog' plaintext_stream = io.BytesIO(plaintext) associated_data = b'associated_data' streaming_aead_primitive = testing_servers.streaming_aead(lang, keyset) ciphertext_stream = streaming_aead_primitive.new_encrypting_stream( plaintext_stream, associated_data) output_stream = streaming_aead_primitive.new_decrypting_stream( ciphertext_stream, associated_data) self.assertEqual(output_stream.read(), plaintext) with self.assertRaises(tink.TinkError): streaming_aead_primitive.new_decrypting_stream(io.BytesIO(b'foo'), associated_data)
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)