# Copyright 2019 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """This module defines the basic types and abstract classes in Tink.""" import abc from typing import Any, Generic, Type, TypeVar from tink.proto import tink_pb2 from tink.core import _tink_error P = TypeVar('P') class KeyManager(Generic[P], metaclass=abc.ABCMeta): """Generates keys and provides primitives for the keys. A KeyManager "understands" keys of a specific key types: it can generate keys of a supported type and create primitives for supported keys. A key type is identified by the global name of the protocol buffer that holds the corresponding key material, and is given by type_url-field of KeyData-protocol buffer. """ @abc.abstractmethod def primitive_class(self) -> Type[P]: """The class of the primitive it uses. Used for internal management.""" raise NotImplementedError() @abc.abstractmethod def primitive(self, key_data: tink_pb2.KeyData) -> P: """Constructs an primitive for the given key. Args: key_data: KeyData protocol buffer Returns: A primitive, for example an instance of Aead or Mac. Raises: tink.TinkError if getting the primitive fails. """ raise NotImplementedError() @abc.abstractmethod def key_type(self) -> str: """Returns the type_url identifying the key type handled by this manager.""" raise NotImplementedError() @abc.abstractmethod def new_key_data(self, key_template: tink_pb2.KeyTemplate) -> tink_pb2.KeyData: """Generates a new random key, based on the specified key_template. Args: key_template: KeyTemplate protocol buffer Returns: A KeyData protocol buffer that contains the key. Raises: tink.TinkError if the key generation fails. """ raise NotImplementedError() def does_support(self, type_url: str) -> bool: return self.key_type() == type_url class PrivateKeyManager(KeyManager[P]): """Generates keys and provides primitives for the keys.""" @abc.abstractmethod def public_key_data( self, private_key_data: tink_pb2.KeyData) -> tink_pb2.KeyData: """Generates a new random key, based on the specified key_template. Args: private_key_data: KeyData protocol buffer Returns: A KeyData protocol buffer that contains the public key. Raises: tink.TinkError if the key generation fails. """ raise NotImplementedError() class KeyManagerCcToPyWrapper(KeyManager[P]): """Transforms C++ KeyManager into a Python KeyManager.""" def __init__(self, cc_key_manager: Any, # A pybinded CcKeyManager
instance primitive_class: Type[P], primitive_py_wrapper: Type[P]): self._cc_key_manager = cc_key_manager self._primitive_class = primitive_class self._primitive_py_wrapper = primitive_py_wrapper def primitive_class(self) -> Type[P]: return self._primitive_class @_tink_error.use_tink_errors def primitive(self, key_data: tink_pb2.KeyData) -> P: return self._primitive_py_wrapper( self._cc_key_manager.primitive(key_data.SerializeToString())) def key_type(self) -> str: return self._cc_key_manager.key_type() @_tink_error.use_tink_errors def new_key_data(self, key_template: tink_pb2.KeyTemplate) -> tink_pb2.KeyData: return tink_pb2.KeyData.FromString( self._cc_key_manager.new_key_data(key_template.SerializeToString())) class PrivateKeyManagerCcToPyWrapper(PrivateKeyManager[P]): """Transforms C++ KeyManager into a Python KeyManager.""" def __init__(self, cc_key_manager: Any, # A pybinded CcKeyManager
instance primitive_class: Type[P], primitive_py_wrapper: Type[P]): self._cc_key_manager = cc_key_manager self._primitive_class = primitive_class self._primitive_py_wrapper = primitive_py_wrapper def primitive_class(self) -> Type[P]: return self._primitive_class @_tink_error.use_tink_errors def primitive(self, key_data: tink_pb2.KeyData) -> P: return self._primitive_py_wrapper( self._cc_key_manager.primitive(key_data.SerializeToString())) def key_type(self) -> str: return self._cc_key_manager.key_type() @_tink_error.use_tink_errors def new_key_data(self, key_template: tink_pb2.KeyTemplate) -> tink_pb2.KeyData: return tink_pb2.KeyData.FromString( self._cc_key_manager.new_key_data(key_template.SerializeToString())) @_tink_error.use_tink_errors def public_key_data(self, key_data: tink_pb2.KeyData) -> tink_pb2.KeyData: return tink_pb2.KeyData.FromString( self._cc_key_manager.public_key_data(key_data.SerializeToString()))