1# Copyright 2022 Google LLC 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15"""Tests for create_test_key.""" 16 17from absl.testing import absltest 18from absl.testing import parameterized 19from tink import aead 20from tink import daead 21from tink import hybrid 22from tink import jwt 23from tink import mac 24from tink import prf 25from tink import signature 26from tink import streaming_aead 27 28from tink.proto import aes_gcm_pb2 29from tink.proto import tink_pb2 30import tink_config 31from util import key_util 32from util import test_keys 33from util import utilities 34 35 36def _do_not_use_stored_key(_: tink_pb2.KeyTemplate) -> bool: 37 return False 38 39 40def _use_stored_key(_: tink_pb2.KeyTemplate) -> bool: 41 return True 42 43 44def setUpModule(): 45 aead.register() 46 daead.register() 47 hybrid.register() 48 jwt.register_jwt_mac() 49 jwt.register_jwt_signature() 50 mac.register() 51 prf.register() 52 signature.register() 53 streaming_aead.register() 54 55 56class CreateTestKeyTest(parameterized.TestCase): 57 58 def test_get_new_aes_gcm_key(self): 59 """Tests that AES GCM Keys can be generated on the fly.""" 60 template = aead.aead_key_templates.AES128_GCM 61 key = test_keys.new_or_stored_key(template, test_keys.TestKeysContainer(), 62 _do_not_use_stored_key) 63 self.assertEqual(key.key_data.type_url, 64 'type.googleapis.com/google.crypto.tink.AesGcmKey') 65 parsed_key = aes_gcm_pb2.AesGcmKey() 66 parsed_key.ParseFromString(key.key_data.value) 67 self.assertLen(parsed_key.key_value, 16) 68 69 def test_get_precomputed_aes_gcm_key(self): 70 """Tests a key in the container will be retrieved if needed.""" 71 72 # First, create a template and a key manually 73 template = aead.aead_key_templates.AES128_GCM 74 key = test_keys.new_or_stored_key(template, test_keys.TestKeysContainer(), 75 _do_not_use_stored_key) 76 # Insert the key into a container 77 container_with_aes_gcm_key = test_keys.TestKeysContainer() 78 container_with_aes_gcm_key.add_key( 79 key_util.text_format(template), key_util.text_format(key)) 80 key_from_create = test_keys.new_or_stored_key(template, 81 container_with_aes_gcm_key, 82 _use_stored_key) 83 # It suffices to compare the key material to check if the keys are the same 84 self.assertEqual(key.key_data.value, key_from_create.key_data.value) 85 86 def test_get_non_existing_precomputed_aes_gcm_key(self): 87 """Tests a key in the container will be retrieved if needed.""" 88 89 template = aead.aead_key_templates.AES128_GCM 90 container = test_keys.TestKeysContainer() 91 with self.assertRaises(ValueError): 92 test_keys.new_or_stored_key(template, container, _use_stored_key) 93 94 def test_get_keyset_new_aes_gcm_key(self): 95 """Tests that AES GCM Keys can be generated on the fly.""" 96 template = aead.aead_key_templates.AES128_GCM 97 serialized_keyset = test_keys.new_or_stored_keyset( 98 template, 99 test_keys.TestKeysContainer(), 100 _do_not_use_stored_key) 101 keyset = tink_pb2.Keyset.FromString(serialized_keyset) 102 self.assertLen(keyset.key, 1) 103 self.assertEqual(keyset.primary_key_id, keyset.key[0].key_id) 104 self.assertEqual(keyset.key[0].key_data.type_url, 105 'type.googleapis.com/google.crypto.tink.AesGcmKey') 106 parsed_key = aes_gcm_pb2.AesGcmKey() 107 parsed_key.ParseFromString(keyset.key[0].key_data.value) 108 self.assertLen(parsed_key.key_value, 16) 109 110 def test_get_keyset_precomputed_aes_gcm_key(self): 111 """Tests a key in the container will be retrieved if needed.""" 112 113 # First, create a template and a key manually 114 template = aead.aead_key_templates.AES128_GCM 115 key = test_keys.new_or_stored_key(template, test_keys.TestKeysContainer(), 116 _do_not_use_stored_key) 117 # Insert the key into a container 118 container_with_aes_gcm_key = test_keys.TestKeysContainer() 119 container_with_aes_gcm_key.add_key( 120 key_util.text_format(template), key_util.text_format(key)) 121 serialized_keyset = test_keys.new_or_stored_keyset( 122 template, container_with_aes_gcm_key, _use_stored_key) 123 keyset = tink_pb2.Keyset.FromString(serialized_keyset) 124 # It suffices to compare the key material to check if the keys are the same 125 self.assertLen(keyset.key, 1) 126 self.assertEqual(keyset.primary_key_id, keyset.key[0].key_id) 127 self.assertEqual(keyset.key[0].key_data.type_url, 128 'type.googleapis.com/google.crypto.tink.AesGcmKey') 129 self.assertEqual(key.key_data.value, keyset.key[0].key_data.value) 130 131 def test_get_keyset_non_existing_precomputed_aes_gcm_key(self): 132 """Tests a key in the container will be retrieved if needed.""" 133 134 template = aead.aead_key_templates.AES128_GCM 135 container = test_keys.TestKeysContainer() 136 with self.assertRaises(ValueError): 137 test_keys.new_or_stored_keyset(template, container, _use_stored_key) 138 139 def test_key_from_test_keys_db_get_chacha_key(self): 140 """Tests that with only one arguments we get keys from _test_keys_db.py.""" 141 142 parsed_template = tink_pb2.KeyTemplate() 143 key_util.parse_text_format( 144 serialized=r"""type_url: "type.googleapis.com/google.crypto.tink.ChaCha20Poly1305Key" 145# value: [type.googleapis.com/google.crypto.tink.ChaCha20Poly1305KeyFormat] { 146# } 147value: "" 148output_prefix_type: RAW""", 149 msg=parsed_template) 150 key = test_keys.new_or_stored_key(parsed_template) 151 # The same value as in _test_keys_db for the raw key. 152 self.assertEqual( 153 key.key_data.value, 154 b'\022 \372\022\371\335\313\301\314\253\r\364\376\341o\242\375\000p\317,t\326\373U\332\267\342\212\210\2160\3611' 155 ) 156 157 def test_keyset_from_test_keys_db_get_chacha_key(self): 158 """Tests that with only one arguments we get keys from _test_keys_db.py.""" 159 160 parsed_template = tink_pb2.KeyTemplate() 161 key_util.parse_text_format( 162 serialized=r"""type_url: "type.googleapis.com/google.crypto.tink.ChaCha20Poly1305Key" 163# value: [type.googleapis.com/google.crypto.tink.ChaCha20Poly1305KeyFormat] { 164# } 165value: "" 166output_prefix_type: RAW""", 167 msg=parsed_template) 168 serialized_keyset = test_keys.new_or_stored_keyset(parsed_template) 169 keyset = tink_pb2.Keyset.FromString(serialized_keyset) 170 self.assertLen(keyset.key, 1) 171 # The same value as in _test_keys_db for the raw key. 172 self.assertEqual( 173 keyset.key[0].key_data.value, 174 b'\022 \372\022\371\335\313\301\314\253\r\364\376\341o\242\375\000p\317,t\326\373U\332\267\342\212\210\2160\3611' 175 ) 176 177 @parameterized.parameters([ 178 aead.Aead, daead.DeterministicAead, streaming_aead.StreamingAead, 179 hybrid.HybridDecrypt, hybrid.HybridEncrypt, mac.Mac, 180 signature.PublicKeySign, signature.PublicKeyVerify, prf.PrfSet, 181 jwt.JwtMac, jwt.JwtPublicKeySign, jwt.JwtPublicKeyVerify 182 ]) 183 def test_create_test_keys_for_primitive(self, primitive): 184 keyset = test_keys.some_keyset_for_primitive(primitive) 185 key_types = utilities.key_types_in_keyset(keyset) 186 for key_type in key_types: 187 self.assertIn(key_type, tink_config.key_types_for_primitive(primitive)) 188 189if __name__ == '__main__': 190 absltest.main() 191