in src/services/clients/standalone_key_management.py [0:0]
def sign(self, key_id: str, message: Union[str, bytes], algorithm: str,
encoding='utf-8') -> Optional[bytes]:
"""
Mandates signature production computed using a private-key, retrieved
from a manager store, and an algorithm string, segments of which,
split by `_`, explicitly state:
- key-type standard`:`standard-data-label
- signature-scheme standard
- hashing mode`:`standard-data-label
Note: standard-data-label is meant to provide stateless
configuration of standards, denoting labels, which are supported
i.e. key data - ECC:p521.
:parameter key_id: str
:parameter message: Union[str, bytes]
:parameter algorithm: str
:parameter encoding: str
:return: Union[bytes, Type[None]]
"""
is_bytes = isinstance(message, bytes)
message = message if is_bytes else bytes(message, encoding)
_LOG.debug(f'Going to split \'{algorithm}\' algorithm into standards.')
alg: Optional[Dict[str, str]] = self.dissect_alg(alg=algorithm)
if not algorithm:
return
# Retrieve type and standard data of a key, hash and signature scheme.
key_type, key_std, hash_type, hash_std, sig_scheme = map(
alg.get, (
KEY_TYPE_ATTR, KEY_STD_ATTR, HASH_TYPE_ATTR, HASH_STD_ATTR,
SIG_SCHEME_ATTR
)
)
_LOG.debug(f'Checking \'{algorithm}\' signature protocol support.')
if key_type not in self._key_construction_map():
_LOG.warning(f'\'{key_type}\' construction is not supported')
return None
if not self.is_signature_scheme_accessible(
sig_scheme=sig_scheme, key_type=key_type, key_std=key_std,
hash_type=hash_type, hash_std=hash_std
):
_LOG.warning(
f'\'{algorithm}\' signature-protocol is not supported.'
)
return None
_LOG.debug(f'Going to retrieve raw \'{key_id}\' key data.')
key_data: dict = self.get_key_data(key_id=key_id)
if not key_data:
return None
key = self.get_key(
key_type=key_type, key_std=key_std, key_data=key_data
)
if not key:
return None
hash_obj = self._get_hash_client(
message=message, hash_type=hash_type, hash_std=hash_std,
**(key_data.get(hash_type) or {})
)
if not hash_obj:
return None
signer = self._get_signature_client(
key=key, sig_scheme=sig_scheme, **(key_data.get(sig_scheme) or {})
)
if not signer:
return None
return signer.sign(hash_obj)