blob: c069d864d7651e333364cec3e44a215571e6be3a [file] [log] [blame]
# 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."""
from __future__ import absolute_import
from __future__ import division
from __future__ import google_type_annotations
from __future__ import print_function
import abc
from typing import Any, Generic, Text, Type, TypeVar
from tink.proto import tink_pb2
from tink.python.core import tink_error
P = TypeVar('P')
class KeyManager(Generic[P]):
"""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.
"""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def primitive_class(self) -> Type[P]:
"""The class of the primitive it uses. Used for internal management."""
pass
@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.
"""
pass
@abc.abstractmethod
def key_type(self) -> Text:
"""Returns the type_url identifying the key type handled by this manager."""
pass
@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.
"""
pass
def does_support(self, type_url: Text) -> 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.
"""
pass
class KeyManagerCcToPyWrapper(KeyManager[P]):
"""Transforms cliffed C++ KeyManager into a Python KeyManager."""
def __init__(self,
cc_key_manager: Any, # A cliffed CcKeyManager<P> 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))
def key_type(self) -> Text:
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 self._cc_key_manager.new_key_data(key_template)
class PrivateKeyManagerCcToPyWrapper(PrivateKeyManager[P]):
"""Transforms cliffed C++ KeyManager into a Python KeyManager."""
def __init__(self,
cc_key_manager: Any, # A cliffed CcKeyManager<P> 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))
def key_type(self) -> Text:
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 self._cc_key_manager.new_key_data(key_template)
@tink_error.use_tink_errors
def public_key_data(self, key_data: tink_pb2.KeyData) -> tink_pb2.KeyData:
return self._cc_key_manager.public_key_data(key_data)