diff --git a/CHANGELOG.md b/CHANGELOG.md index ac9e5a7..641c31e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ This project uses Semantic Versioning + +## 1.0.0 + ++ Serialize all official header keys, always (breaks header order of prev versions) + + ## 0.1.0 + Added custom args support to kasten auto check diff --git a/kasten/generator/pack.py b/kasten/generator/pack.py index 5572565..c837166 100644 --- a/kasten/generator/pack.py +++ b/kasten/generator/pack.py @@ -45,18 +45,34 @@ along with this program. If not, see . """ -def pack(data: bytes, data_type: '', +def pack(data: bytes, data_type: str, enc_mode: 'KastenEncryptionModeID', signer: bytes = None, signature: bytes = None, app_metadata: 'KastenSerializeableDict' = None, timestamp: int = None - ) -> KastenPacked: + ) -> KastenPacked: """Create KastenPacked bytes sequence but do not ID or run through generator""" + + # Final data will be: + # msgpack.packb([data_type, enc_mode, timestamp, (signer, signature), {app_metadata}]) \ + # + b'\n' + data # Ensure data type does not exceed 4 characters if not data_type or len(data_type) > 4: raise exceptions.InvalidKastenTypeLength + try: + data_type = data_type.decode('utf8') + except AttributeError: + pass + + if signer: + if signature is None: + raise ValueError("Signer specified without signature") + else: + signer = b'' + signature = b'' + # Ensure encryption mode is in [0, 100) try: enc_mode = int(enc_mode) @@ -74,12 +90,8 @@ def pack(data: bytes, data_type: '', timestamp = int(timestamp) kasten_header = [data_type, enc_mode, timestamp] - 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) + kasten_header.append((signer, signature)) + kasten_header.append(app_metadata) kasten_header = packb(kasten_header) + b'\n' return kasten_header + data diff --git a/kasten/main.py b/kasten/main.py index 80c931f..450da10 100644 --- a/kasten/main.py +++ b/kasten/main.py @@ -58,9 +58,13 @@ class Kasten: ret = func() except IndexError: return None + except TypeError: + return None return ret return pack.pack(self.data, self.get_data_type(), self.get_encryption_mode(), + signer=_get_or_none(self.get_signer), + signature=_get_or_none(self.get_signature), app_metadata=_get_or_none(self.get_metadata), timestamp=self.get_timestamp()) @@ -70,4 +74,8 @@ class Kasten: def get_timestamp(self): return self.header[2] - def get_metadata(self): return self.header[3] + def get_signer(self): return self.header[3][0] + + def get_signature(self): return self.header[3][1] + + def get_metadata(self): return self.header[4] diff --git a/setup.py b/setup.py index 4c120a1..8157183 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ with open(path.join(this_directory, 'README.md'), encoding='utf-8') as f: long_description = f.read() setup(name='kasten', - version='0.2.0', + version='1.0.0', description='Efficient, secure data serialization format with extensibility.', author='Kevin Froman', author_email='beardog@mailbox.org', diff --git a/tests/test_generator_base.py b/tests/test_generator_base.py index da2bbbd..59130c0 100644 --- a/tests/test_generator_base.py +++ b/tests/test_generator_base.py @@ -7,14 +7,23 @@ from kasten.generator import KastenBaseGenerator class TestBaseGenerator(unittest.TestCase): def test_base_generator(self): - k = b'\x93\xa3txt\x01\xce^\x97\xe3\xdc\ntest' - invalid = b'\x93\xa3txt\x01\xce^\x97\xe3\xdc\ntes2' - K = KastenBaseGenerator.generate(k) - h = sha3_384(k).digest() - self.assertTrue(len(K.get_packed()) > 0) - KastenBaseGenerator.validate_id(h, k) - self.assertRaises(exceptions.InvalidID, KastenBaseGenerator.validate_id, h, invalid) - self.assertEqual(K.get_packed(), k) + + k = b'\x95\xa3tst\x00\x00\xc0\xc0\ntest data' + invalid = b'\x95\xa3tst\x00\x00\xc0\xc0\ntest datb' + + correct_K = KastenBaseGenerator.generate(k) + hash_test = sha3_384(k).digest() + + self.assertTrue(len(correct_K.get_packed()) > 0) + + # k = b'\x93\xa3txt\x01\xce^\x97\xe3\xdc\ntest' + # invalid = b'\x93\xa3txt\x01\xce^\x97\xe3\xdc\ntes2' + # K = KastenBaseGenerator.generate(k) + # h = sha3_384(k).digest() + # self.assertTrue(len(K.get_packed()) > 0) + # KastenBaseGenerator.validate_id(h, k) + # self.assertRaises(exceptions.InvalidID, KastenBaseGenerator.validate_id, h, invalid) + # self.assertEqual(K.get_packed(), k) unittest.main() diff --git a/tests/test_kasten_with_base_generator.py b/tests/test_kasten_with_base_generator.py index 04e244b..5dae9d4 100644 --- a/tests/test_kasten_with_base_generator.py +++ b/tests/test_kasten_with_base_generator.py @@ -8,11 +8,11 @@ from kasten.generator import KastenBaseGenerator, pack class TestKastenBaseGenerator(unittest.TestCase): def test_kasten(self): - k = b'\x93\xa3txt\x01\xce^\x97\xe3\xdc\ntest' + k = b'\x95\xa3tst\x00\x00\x92\xc4\x00\xc4\x00\xc0\ntest data' K = Kasten(sha3_384(k).digest(), k, KastenBaseGenerator) def test_kasten_invalid(self): - k = b'\x93\xa3txt\x01\xce^\x97\xe3\xdc\ntest' + k = b'\x95\xa3tst\x00\x00\x92\xc4\x00\xc4\x00\xc0\ntest data' self.assertRaises( exceptions.InvalidID, Kasten, sha3_384(k + b'invalid').digest(), k, KastenBaseGenerator) diff --git a/tests/test_mimc_generator.py b/tests/test_mimc_generator.py index 64b216c..a8c0c78 100644 --- a/tests/test_mimc_generator.py +++ b/tests/test_mimc_generator.py @@ -9,8 +9,8 @@ from kasten import Kasten class TestMimcGenerator(unittest.TestCase): def test_mimc_generator(self): - k = b'\x93\xa3txt\x01\xce^\x97\xe3\xdc\ntest' - invalid = b'\x93\xa3txt\x01\xce^\x97\xe3\xdc\ntes2' + k = b'\x95\xa3tst\x00\x00\x92\xc4\x00\xc4\x00\xc0\ntest data' + invalid = b'\x95\xa3tst\x00\x00\x92\xc4\x00\xc4\x00\xc0\ntest dat2' K = KastenMimcGenerator.generate(k) #h = sha3_384(k).digest() h = mimcvdf.vdf_create(k, 5000, dec=True) @@ -20,8 +20,8 @@ class TestMimcGenerator(unittest.TestCase): self.assertEqual(K.get_packed(), k) def test_mimc_generator_wrong_rounds(self): - k = b'\x93\xa3txt\x01\xce^\x97\xe3\xdc\ntest' - invalid = b'\x93\xa3txt\x01\xce^\x97\xe3\xdc\ntes2' + k = b'\x95\xa3tst\x00\x00\x92\xc4\x00\xc4\x00\xc0\ntest data' + invalid = b'\x95\xa3tst\x00\x00\xc0\xc0\ntest dat2' K = KastenMimcGenerator.generate(k) #h = sha3_384(k).digest() h = mimcvdf.vdf_create(k, 1000, dec=True) @@ -31,7 +31,7 @@ class TestMimcGenerator(unittest.TestCase): self.assertEqual(K.get_packed(), k) def test_mimc_generator_kasten_auto_validate(self): - k = b'\x93\xa3txt\x01\xce^\x97\xe3\xdc\ntest' + k = b'\x95\xa3tst\x00\x00\x92\xc4\x00\xc4\x00\xc0\ntest data' K = KastenMimcGenerator.generate(k, 1000) Kasten(int.from_bytes(K.id, byteorder="big"), K.get_packed(), KastenMimcGenerator, *[1000]) diff --git a/tests/test_pack.py b/tests/test_pack.py index 9e186aa..10d72ab 100644 --- a/tests/test_pack.py +++ b/tests/test_pack.py @@ -19,7 +19,7 @@ class TestPack(unittest.TestCase): self.assertEqual(unpacked[0], 'bin') self.assertEqual(unpacked[1], 0) self.assertAlmostEqual(unpacked[2], t) - self.assertEqual(len(unpacked), 3) + self.assertEqual(len(unpacked), 5) def test_unsigned_with_meta(self): data = os.urandom(10) @@ -30,8 +30,8 @@ class TestPack(unittest.TestCase): self.assertEqual(unpacked[0], 'bin') self.assertEqual(unpacked[1], 0) self.assertAlmostEqual(unpacked[2], t) - self.assertEqual(unpacked[3], {"meme": "doge"}) - self.assertEqual(len(unpacked), 4) + self.assertEqual(unpacked[4], {"meme": "doge"}) + self.assertEqual(len(unpacked), 5) def test_linebreak_data(self): data = os.urandom(10) + b'\n'