kasten/kasten/generator/pack.py

61 lines
1.6 KiB
Python
Raw Normal View History

2020-04-11 07:48:28 +00:00
"""
0: type: str: 4bytesmax
1: enc-mode: int: 0, 1, 2 (0=plaintext, 1=asymmetic, 2=symmetric).
2. Timestamp: int
encrypted with specified mode:
3. signer: bytes (max 256bits)
4. signature: bytes (max 256bits)
5. app_metadata: JSON
\n
data: bytes
"""
2020-04-14 09:33:17 +00:00
from math import floor
from time import time
2020-04-11 07:48:28 +00:00
from msgpack import packb
2020-04-14 09:33:17 +00:00
from kasten import exceptions
from kasten.types import KastenPacked
2020-04-11 07:48:28 +00:00
def pack(data: bytes, data_type: 'KastenDataType',
enc_mode: 'KastenEncryptionModeID',
signer: bytes = None, signature: bytes = None,
2020-04-14 09:33:17 +00:00
app_metadata: 'KastenSerializeableDict' = None,
timestamp: int = None
) -> KastenPacked:
2020-04-11 07:48:28 +00:00
# Ensure data type does not exceed 4 characters
if not data_type or len(data_type) > 4:
raise exceptions.InvalidKastenTypeLength
2020-04-13 00:53:57 +00:00
# Ensure encryption mode is in [0, 100)
try:
enc_mode = int(enc_mode)
except (TypeError, ValueError):
raise exceptions.InvalidEncryptionMode
if not enc_mode >= 0 or enc_mode >= 100:
raise exceptions.InvalidEncryptionMode
2020-04-14 09:33:17 +00:00
2020-04-11 07:48:28 +00:00
try:
data = data.encode('utf8')
except AttributeError:
pass
2020-04-14 09:33:17 +00:00
if timestamp is None:
timestamp = floor(time())
2020-04-16 07:07:05 +00:00
timestamp = int(timestamp)
2020-04-11 07:48:28 +00:00
2020-04-14 09:33:17 +00:00
kasten_header = [data_type, enc_mode, timestamp]
2020-04-11 07:48:28 +00:00
if signer:
if signature is None:
raise ValueError("Signer specified without signature")
kasten_header.extend((signer, signature))
if app_metadata is not None:
kasten_header.append(app_metadata)
2020-04-16 07:07:05 +00:00
kasten_header = packb(kasten_header) + b'\n'
print(kasten_header + data)
2020-04-11 07:48:28 +00:00
return kasten_header + data