From 5fbeb3e29b6440a799d9320e871a1d4d509130b8 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Fri, 6 Jan 2017 12:55:05 +0000 Subject: Enable exporting inbound group session keys A pair of functions which allow you to export the megolm keys for an inbound group session, so that an application can save/restore them. --- python/olm/__main__.py | 30 ++++++++++++++++++++++++++++++ python/olm/inbound_group_session.py | 19 ++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) (limited to 'python') diff --git a/python/olm/__main__.py b/python/olm/__main__.py index eb76301..f195591 100755 --- a/python/olm/__main__.py +++ b/python/olm/__main__.py @@ -277,6 +277,27 @@ def build_arg_parser(): type=argparse.FileType('wb'), nargs='?', default=sys.stdout) group_decrypt.set_defaults(func=do_group_decrypt) + + + export_inbound_group = commands.add_parser( + "export_inbound_group", + help="Export the keys for an inbound group session", + ) + export_inbound_group.add_argument( + "session_file", help="Local inbound group session file", + ) + export_inbound_group.add_argument( + "export_file", help="File to export to (default stdout)", + type=argparse.FileType('w'), nargs='?', + default=sys.stdout, + ) + export_inbound_group.add_argument( + "--message_index", + help="Index to export session at. Defaults to the earliest known index", + type=int, + ) + export_inbound_group.set_defaults(func=do_export_inbound_group) + return parser def do_outbound_group(args): @@ -333,6 +354,15 @@ def do_group_decrypt(args): f.write(session.pickle(args.key)) args.plaintext_file.write(plaintext) +def do_export_inbound_group(args): + session = InboundGroupSession() + session.unpickle(args.key, read_base64_file(args.session_file)) + index = args.message_index + if index is None: + # default to first known index + index = session.first_known_index() + args.export_file.write(session.export_session(index)) + if __name__ == '__main__': parser = build_arg_parser() args = parser.parse_args() diff --git a/python/olm/inbound_group_session.py b/python/olm/inbound_group_session.py index 27a569c..67906b2 100644 --- a/python/olm/inbound_group_session.py +++ b/python/olm/inbound_group_session.py @@ -49,6 +49,13 @@ inbound_group_session_function( inbound_group_session_function(lib.olm_inbound_group_session_id_length) inbound_group_session_function(lib.olm_inbound_group_session_id, c_void_p, c_size_t) +lib.olm_inbound_group_session_first_known_index.argtypes = (c_void_p,) +lib.olm_inbound_group_session_first_known_index.restypes = c_uint32 + +inbound_group_session_function(lib.olm_export_inbound_group_session_length) +inbound_group_session_function(lib.olm_export_inbound_group_session, c_void_p, c_size_t, c_uint32) + + class InboundGroupSession(object): def __init__(self): self.buf = create_string_buffer(lib.olm_inbound_group_session_size()) @@ -95,5 +102,15 @@ class InboundGroupSession(object): def session_id(self): id_length = lib.olm_inbound_group_session_id_length(self.ptr) id_buffer = create_string_buffer(id_length) - lib.olm_inbound_group_session_id(self.ptr, id_buffer, id_length); + lib.olm_inbound_group_session_id(self.ptr, id_buffer, id_length) return id_buffer.raw + + def first_known_index(self): + return lib.olm_inbound_group_session_first_known_index(self.ptr) + + def export_session(self, message_index): + length = lib.olm_export_inbound_group_session_length(self.ptr) + buffer = create_string_buffer(length) + lib.olm_export_inbound_group_session(self.ptr, buffer, length, + message_index) + return buffer.raw -- cgit v1.2.3 From a2f0c93a93f6914291954b08a7518b4f17561c11 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Fri, 6 Jan 2017 17:40:39 +0000 Subject: Implement importing group session data olm_import_inbound_group_session, which reads the format written by olm_export_inbound_group_session to initialise a group session. --- python/.gitignore | 1 + python/olm/__main__.py | 26 ++++++++++++++++++++++++++ python/olm/inbound_group_session.py | 10 ++++++++++ python/test_olm.sh | 13 +++++++++---- 4 files changed, 46 insertions(+), 4 deletions(-) (limited to 'python') diff --git a/python/.gitignore b/python/.gitignore index b8ca4f7..a3d197d 100644 --- a/python/.gitignore +++ b/python/.gitignore @@ -2,3 +2,4 @@ /*.account /*.session /*.group_session +/group_message diff --git a/python/olm/__main__.py b/python/olm/__main__.py index f195591..5f78f76 100755 --- a/python/olm/__main__.py +++ b/python/olm/__main__.py @@ -268,6 +268,19 @@ def build_arg_parser(): default=sys.stdin) inbound_group.set_defaults(func=do_inbound_group) + import_inbound_group = commands.add_parser( + "import_inbound_group", + help="Create an inbound group session based an exported inbound group" + ) + import_inbound_group.add_argument("session_file", help="Local inbound group session file") + import_inbound_group.add_argument( + "export_file", + help="File to read credentials from (default stdin)", + type=argparse.FileType('r'), nargs='?', + default=sys.stdin, + ) + import_inbound_group.set_defaults(func=do_import_inbound_group) + group_decrypt = commands.add_parser("group_decrypt", help="Decrypt a group message") group_decrypt.add_argument("session_file", help="Local inbound group session file") group_decrypt.add_argument("message_file", help="Message file (default stdin)", @@ -345,6 +358,19 @@ def do_inbound_group(args): with open(args.session_file, "wb") as f: f.write(session.pickle(args.key)) +def do_import_inbound_group(args): + if os.path.exists(args.session_file): + sys.stderr.write("Session %r file already exists\n" % ( + args.session_file, + )) + sys.exit(1) + data = args.export_file.read().translate(None, "\r\n") + + session = InboundGroupSession() + session.import_session(data) + with open(args.session_file, "wb") as f: + f.write(session.pickle(args.key)) + def do_group_decrypt(args): session = InboundGroupSession() session.unpickle(args.key, read_base64_file(args.session_file)) diff --git a/python/olm/inbound_group_session.py b/python/olm/inbound_group_session.py index 67906b2..4390b34 100644 --- a/python/olm/inbound_group_session.py +++ b/python/olm/inbound_group_session.py @@ -36,6 +36,10 @@ inbound_group_session_function( lib.olm_init_inbound_group_session, c_void_p, c_size_t ) +inbound_group_session_function( + lib.olm_import_inbound_group_session, c_void_p, c_size_t +) + inbound_group_session_function( lib.olm_group_decrypt_max_plaintext_length, c_void_p, c_size_t ) @@ -83,6 +87,12 @@ class InboundGroupSession(object): self.ptr, key_buffer, len(session_key) ) + def import_session(self, session_key): + key_buffer = create_string_buffer(session_key) + lib.olm_import_inbound_group_session( + self.ptr, key_buffer, len(session_key) + ) + def decrypt(self, message): message_buffer = create_string_buffer(message) max_plaintext_length = lib.olm_group_decrypt_max_plaintext_length( diff --git a/python/test_olm.sh b/python/test_olm.sh index 989e166..7c90daf 100755 --- a/python/test_olm.sh +++ b/python/test_olm.sh @@ -10,10 +10,11 @@ ALICE_GROUP_SESSION=alice.group_session BOB_ACCOUNT=bob.account BOB_SESSION=bob.session BOB_GROUP_SESSION=bob.group_session +CHARLIE_GROUP_SESSION=charlie.group_session -rm $ALICE_ACCOUNT $BOB_ACCOUNT -rm $ALICE_SESSION $BOB_SESSION -rm $ALICE_GROUP_SESSION $BOB_GROUP_SESSION +rm -f $ALICE_ACCOUNT $BOB_ACCOUNT +rm -f $ALICE_SESSION $BOB_SESSION +rm -f $ALICE_GROUP_SESSION $BOB_GROUP_SESSION $CHARLIE_GROUP_SESSION $OLM create_account $ALICE_ACCOUNT $OLM create_account $BOB_ACCOUNT @@ -31,4 +32,8 @@ echo "Hello world" | $OLM encrypt $ALICE_SESSION - - | $OLM inbound $BOB_ACCOUNT $OLM outbound_group $ALICE_GROUP_SESSION $OLM group_credentials $ALICE_GROUP_SESSION | $OLM inbound_group $BOB_GROUP_SESSION -echo "Hello group" | $OLM group_encrypt $ALICE_GROUP_SESSION - - | $OLM group_decrypt $BOB_GROUP_SESSION +echo "Hello group" | $OLM group_encrypt $ALICE_GROUP_SESSION - group_message +$OLM group_decrypt $BOB_GROUP_SESSION group_message + +$OLM export_inbound_group $BOB_GROUP_SESSION | $OLM import_inbound_group $CHARLIE_GROUP_SESSION +$OLM group_decrypt $CHARLIE_GROUP_SESSION group_message -- cgit v1.2.3