def test_primitive_fails_on_subclass(self): self.reg.register_key_manager( DummyKeyManager('dummy_type_url', helper.FakeAead)) with self.assertRaisesRegex(core.TinkError, 'uses primitive FakeAead, and not Aead'): self.reg.primitive(tink_pb2.KeyData(type_url='dummy_type_url'), aead.Aead)
def test_text_format_keyset(self): key = tink_pb2.Keyset.Key( key_data=tink_pb2.KeyData( type_url='type.googleapis.com/google.crypto.tink.AesGcmKey', value=b'\032\020Z\027\031\027\362\353\020\320\257p\271^\260\022\344\274', key_material_type=tink_pb2.KeyData.SYMMETRIC), status=tink_pb2.ENABLED, key_id=3588418072, output_prefix_type=tink_pb2.TINK) keyset = tink_pb2.Keyset(primary_key_id=3588418072) keyset.key.append(key) expected = r"""primary_key_id: 3588418072 key { key_data { type_url: "type.googleapis.com/google.crypto.tink.AesGcmKey" # value: [type.googleapis.com/google.crypto.tink.AesGcmKey] { # version: 0 # key_value: "Z\027\031\027\362\353\020\320\257p\271^\260\022\344\274" # } value: "\032\020Z\027\031\027\362\353\020\320\257p\271^\260\022\344\274" key_material_type: SYMMETRIC } status: ENABLED key_id: 3588418072 output_prefix_type: TINK }""" output = key_util.text_format(keyset) self.assertEqual(output, expected) # the output should be in text format, and result in the original template. self.assertEqual( text_format.Parse(output, tink_pb2.Keyset()), keyset)
def test_primitive_fails_on_wrong_primitive(self): self.reg.register_key_manager( DummyKeyManager('dummy_type_url', aead.Aead)) with self.assertRaisesRegex(core.TinkError, 'uses primitive Aead, and not Mac'): self.reg.primitive(tink_pb2.KeyData(type_url='dummy_type_url'), mac.Mac)
def test_public_key_data_success(self): self.reg.register_key_manager(DummyPrivateKeyManager('dummy_type_url')) key_data = tink_pb2.KeyData( type_url='dummy_type_url', key_material_type=tink_pb2.KeyData.ASYMMETRIC_PRIVATE) public_key_data = self.reg.public_key_data(key_data) self.assertEqual(public_key_data.type_url, 'public_dummy_type_url')
def test_public_key_data_fails_for_non_private_key_manager(self): self.reg.register_key_manager(DummyKeyManager('dummy_type_url')) key_data = tink_pb2.KeyData( type_url='dummy_type_url', key_material_type=tink_pb2.KeyData.ASYMMETRIC_PRIVATE) with self.assertRaises(core.TinkError): self.reg.public_key_data(key_data)
def new_key_data(self, key_template: tink_pb2.KeyTemplate) -> tink_pb2.KeyData: data = self._cc_key_manager.new_key_data( key_template.SerializeToString()) key_data = tink_pb2.KeyData() key_data.ParseFromString(data) return key_data
def decrypt(self, ciphertext: bytes, associated_data: bytes) -> bytes: ct_len = len(ciphertext) # Recover DEK length if ct_len < DEK_LEN_BYTES: raise core.TinkError dek_len = struct.unpack('>I', ciphertext[0:DEK_LEN_BYTES])[0] # Basic check if DEK length can be valid. if dek_len > (ct_len - DEK_LEN_BYTES) or dek_len < 0: raise core.TinkError # Decrypt DEK with remote AEAD encrypted_dek_bytes = ciphertext[DEK_LEN_BYTES:DEK_LEN_BYTES + dek_len] dek_bytes = self.remote_aead.decrypt(encrypted_dek_bytes, b'') # Get AEAD primitive based on DEK dek = tink_pb2.KeyData() dek.type_url = self.key_template.type_url dek.value = dek_bytes dek.key_material_type = tink_pb2.KeyData.KeyMaterialType.SYMMETRIC dek_aead = core.Registry.primitive(dek, aead.Aead) # Extract ciphertext payload and decrypt ct_bytes = ciphertext[DEK_LEN_BYTES + dek_len:] return dek_aead.decrypt(ct_bytes, associated_data)
def test_public_key_data_fails_for_non_asymmetric_private_key(self): self.reg.register_key_manager(DummyPrivateKeyManager('dummy_type_url')) key_data = tink_pb2.KeyData( type_url='dummy_type_url', key_material_type=tink_pb2.KeyData.ASYMMETRIC_PUBLIC) with self.assertRaisesRegex(core.TinkError, 'contains a non-private key'): self.reg.public_key_data(key_data)
def native_key_data(proto): """Convert pybind11_protobuf KeyData proto to native Python proto.""" # This function is needed because native_pb.MergeFrom(pybind11_pb) # is not currently supported. if not getattr(proto, '_is_wrapped_c_proto', False): return proto native = tink_pb2.KeyData() native.ParseFromString(proto.SerializeToString()) return native
def test_new_key_data(self): key_template = self.new_jwt_hmac_key_template(common_pb2.SHA256, 32) key_data = tink_pb2.KeyData() key_data.ParseFromString(self.key_manager.new_key_data(key_template)) self.assertEqual(key_data.type_url, self.key_manager.key_type()) key = jwt_hmac_pb2.JwtHmacKey() key.ParseFromString(key_data.value) self.assertEqual(key.version, 0) self.assertEqual(key.hash_type, common_pb2.SHA256) self.assertLen(key.key_value, 32)
def test_new_key_data(self): key_template = self.new_aes_siv_key_template(64) key_data = tink_pb2.KeyData() key_data.ParseFromString(self.key_manager.new_key_data(key_template)) self.assertEqual(key_data.type_url, self.key_manager.key_type()) self.assertEqual(key_data.key_material_type, tink_pb2.KeyData.SYMMETRIC) key = aes_siv_pb2.AesSivKey() key.ParseFromString(key_data.value) self.assertEqual(key.version, 0) self.assertLen(key.key_value, 64)
def test_new_key_data(self): key_template = self.new_hmac_key_template(common_pb2.SHA256, 24, 16) key_data = tink_pb2.KeyData() key_data.ParseFromString(self.key_manager.new_key_data(key_template)) self.assertEqual(key_data.type_url, self.key_manager.key_type()) key = hmac_pb2.HmacKey() key.ParseFromString(key_data.value) self.assertEqual(key.version, 0) self.assertEqual(key.params.hash, common_pb2.SHA256) self.assertEqual(key.params.tag_size, 24) self.assertLen(key.key_value, 16)
def test_new_key_data(self): key_template = self.new_aes_eax_key_template(12, 16) serialized_key_data = self.key_manager.new_key_data(key_template) key_data = tink_pb2.KeyData() key_data.ParseFromString(serialized_key_data) self.assertEqual(key_data.type_url, self.key_manager.key_type()) self.assertEqual(key_data.key_material_type, tink_pb2.KeyData.SYMMETRIC) key = aes_eax_pb2.AesEaxKey() key.ParseFromString(key_data.value) self.assertEqual(key.version, 0) self.assertEqual(key.params.iv_size, 12) self.assertLen(key.key_value, 16)
def _fixed_key_data() -> tink_pb2.KeyData: # test example in https://tools.ietf.org/html/rfc7515#appendix-A.1.1 key_encoded = (b'AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_' b'T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow') padded_key_encoded = key_encoded + b'=' * (-len(key_encoded) % 4) key_value = base64.urlsafe_b64decode(padded_key_encoded) jwt_hmac_key = jwt_hmac_pb2.JwtHmacKey( version=0, algorithm=jwt_hmac_pb2.HS256, key_value=key_value) return tink_pb2.KeyData( type_url='type.googleapis.com/google.crypto.tink.JwtHmacKey', key_material_type=tink_pb2.KeyData.SYMMETRIC, value=jwt_hmac_key.SerializeToString())
def test_new_key_data(self): key_manager = self.hybrid_decrypt_key_manager() key_data = tink_pb2.KeyData() key_data.ParseFromString( key_manager.new_key_data( hybrid_key_templates.ECIES_P256_HKDF_HMAC_SHA256_AES128_GCM. SerializeToString())) self.assertEqual(key_data.type_url, key_manager.key_type()) self.assertEqual(key_data.key_material_type, tink_pb2.KeyData.ASYMMETRIC_PRIVATE) key = ecies_aead_hkdf_pb2.EciesAeadHkdfPrivateKey() key.ParseFromString(key_data.value) self.assertLen(key.key_value, 32) self.assertEqual(key.public_key.params.kem_params.curve_type, common_pb2.NIST_P256)
def create_fixed_jwt_hmac() -> jwt.JwtMac: # test example in https://tools.ietf.org/html/rfc7515#appendix-A.1.1 key_encoded = (b'AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_' b'T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow') padded_key_encoded = key_encoded + b'=' * (-len(key_encoded) % 4) key_value = base64.urlsafe_b64decode(padded_key_encoded) jwt_hmac_key = jwt_hmac_pb2.JwtHmacKey(version=0, hash_type=common_pb2.SHA256, key_value=key_value) key_data = tink_pb2.KeyData( type_url='type.googleapis.com/google.crypto.tink.JwtHmacKey', key_material_type=tink_pb2.KeyData.SYMMETRIC, value=jwt_hmac_key.SerializeToString()) key_manager = _jwt_hmac_key_manager.MacCcToPyJwtMacKeyManager() return key_manager.primitive(key_data)
def test_new_key_data_sign(self): key_template = self.new_ecdsa_key_template( common_pb2.SHA256, common_pb2.NIST_P256, ecdsa_pb2.DER) key_data = tink_pb2.KeyData() key_data.ParseFromString(self.key_manager_sign.new_key_data(key_template)) self.assertEqual(key_data.type_url, self.key_manager_sign.key_type()) key = ecdsa_pb2.EcdsaPrivateKey() key.ParseFromString(key_data.value) public_key = key.public_key self.assertEqual(key.version, 0) self.assertEqual(public_key.version, 0) self.assertEqual(public_key.params.hash_type, common_pb2.SHA256) self.assertEqual(public_key.params.curve, common_pb2.NIST_P256) self.assertEqual(public_key.params.encoding, ecdsa_pb2.DER) self.assertLen(key.key_value, 32)
def public_key_data( self, private_key_data: tink_pb2.KeyData) -> tink_pb2.KeyData: return tink_pb2.KeyData(type_url='public_' + private_key_data.type_url)
def new_key_data(self, key_template: tink_pb2.KeyTemplate) -> tink_pb2.KeyData: return tink_pb2.KeyData()
def new_key_data(self, key_template: tink_pb2.KeyTemplate) -> tink_pb2.KeyData: return tink_pb2.KeyData(type_url=key_template.type_url)
def test_primitive_ok(self): self.reg.register_key_manager( DummyKeyManager('dummy_type_url', aead.Aead)) primitive = self.reg.primitive( tink_pb2.KeyData(type_url='dummy_type_url'), aead.Aead) self.assertIsInstance(primitive, helper.FakeAead)
def deserialize_key_data(serialized_proto): """Convert serialized KeyData proto to native Python proto.""" key_data = tink_pb2.KeyData() key_data.ParseFromString(serialized_proto) return key_data