aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/olm/olm.hh13
-rw-r--r--include/olm/session.hh6
-rw-r--r--javascript/olm_post.js37
-rwxr-xr-xpython/olm.py53
-rw-r--r--src/olm.cpp32
-rw-r--r--src/session.cpp21
-rw-r--r--tests/test_olm.cpp13
7 files changed, 172 insertions, 3 deletions
diff --git a/include/olm/olm.hh b/include/olm/olm.hh
index f08fb9f..a5a50de 100644
--- a/include/olm/olm.hh
+++ b/include/olm/olm.hh
@@ -257,6 +257,19 @@ size_t olm_create_inbound_session_from(
void * one_time_key_message, size_t message_length
);
+/** The length of the buffer needed to return the id for this session. */
+size_t olm_session_id_length(
+ OlmSession * session
+);
+
+/** An identifier for this session. Will be the same for both ends of the
+ * conversation. If the id buffer is too small then olm_session_last_error()
+ * will be "OUTPUT_BUFFER_TOO_SMALL". */
+size_t olm_session_id(
+ OlmSession * session,
+ void * id, size_t id_length
+);
+
/** Checks if the PRE_KEY message is for this in-bound session. This can happen
* if multiple messages are sent to this account before this account sends a
* message in reply. Returns olm_error() on failure. If the base64
diff --git a/include/olm/session.hh b/include/olm/session.hh
index b70ce6a..993a8da 100644
--- a/include/olm/session.hh
+++ b/include/olm/session.hh
@@ -54,6 +54,12 @@ struct Session {
std::uint8_t const * one_time_key_message, std::size_t message_length
);
+ std::size_t session_id_length();
+
+ std::size_t session_id(
+ std::uint8_t * id, std::size_t id_length
+ );
+
bool matches_inbound_session(
Curve25519PublicKey const * their_identity_key,
std::uint8_t const * one_time_key_message, std::size_t message_length
diff --git a/javascript/olm_post.js b/javascript/olm_post.js
index 60876b1..94d3e82 100644
--- a/javascript/olm_post.js
+++ b/javascript/olm_post.js
@@ -222,6 +222,29 @@ Session.prototype['create_inbound'] = restore_stack(function(
);
});
+Session.prototype['create_inbound_from'] = restore_stack(function(
+ account, identity_key, one_time_key_message
+) {
+ var identity_key_array = array_from_string(identity_key);
+ var identity_key_buffer = stack(identity_key_array);
+ var message_array = array_from_string(one_time_key_message);
+ var message_buffer = stack(message_array);
+ session_method(Module['_olm_create_inbound_session_from'])(
+ this.ptr, account.ptr,
+ identity_key_buffer, identity_key_array.length,
+ message_buffer, message_array.length
+ );
+});
+
+Session.prototype['session_id'] = restore_stack(function() {
+ var id_length = session_method(Module['_olm_session_id_length'])(this.ptr);
+ var id_buffer = stack(id_length);
+ session_method(Module['_olm_session_id'])(
+ this.ptr, id_buffer, id_length
+ );
+ return Pointer_stringify(id_buffer, id_length);
+});
+
Session.prototype['matches_inbound'] = restore_stack(function(
account, one_time_key_message
) {
@@ -232,6 +255,20 @@ Session.prototype['matches_inbound'] = restore_stack(function(
) ? true : false;
});
+Session.prototype['matches_inbound_from'] = restore_stack(function(
+ account, identity_key, one_time_key_message
+) {
+ var identity_key_array = array_from_string(identity_key);
+ var identity_key_buffer = stack(identity_key_array);
+ var message_array = array_from_string(one_time_key_message);
+ var message_buffer = stack(message_array);
+ return session_method(Module['_olm_matches_inbound_session_from'])(
+ this.ptr, account.ptr,
+ identity_key_buffer, identity_key_array.length,
+ message_buffer, message_array.length
+ ) ? true : false;
+});
+
Session.prototype['encrypt'] = restore_stack(function(
plaintext
) {
diff --git a/python/olm.py b/python/olm.py
index 8d484fc..4bd85f0 100755
--- a/python/olm.py
+++ b/python/olm.py
@@ -185,7 +185,20 @@ session_function(
c_void_p, # Account
c_void_p, c_size_t, # Pre Key Message
)
+session_function(
+ lib.olm_create_inbound_session_from,
+ c_void_p, # Account
+ c_void_p, c_size_t, # Identity Key
+ c_void_p, c_size_t, # Pre Key Message
+)
+session_function(lib.olm_session_id_length)
+session_function(lib.olm_session_id, c_void_p, c_size_t)
session_function(lib.olm_matches_inbound_session, c_void_p, c_size_t)
+session_function(
+ lib.olm_matches_inbound_session_from,
+ c_void_p, c_size_t, # Identity Key
+ c_void_p, c_size_t, # Pre Key Message
+)
session_function(lib.olm_encrypt_message_type)
session_function(lib.olm_encrypt_random_length)
session_function(lib.olm_encrypt_message_length, c_size_t)
@@ -204,7 +217,7 @@ session_function(
lib.olm_decrypt,
c_size_t, # Message Type
c_void_p, c_size_t, # Message
- c_void_p, c_size_t, # Plaintext
+ c_void_p, c_size_t, # Plaintext
)
class Session(object):
@@ -250,6 +263,22 @@ class Session(object):
one_time_key_message_buffer, len(one_time_key_message)
)
+ def create_inbound_from(self, account, identity_key, one_time_key_message):
+ identity_key_buffer = create_string_buffer(identity_key)
+ one_time_key_message_buffer = create_string_buffer(one_time_key_message)
+ lib.olm_create_inbound_session_from(
+ self.ptr,
+ account.ptr,
+ identity_key_buffer, len(identity_key),
+ one_time_key_message_buffer, len(one_time_key_message)
+ )
+
+ def session_id(self):
+ id_length = lib.olm_session_id_length(self.ptr)
+ id_buffer = create_string_buffer(id_length)
+ lib.olm_session_id(self.ptr, id_buffer, id_length);
+ return id_buffer.raw
+
def matches_inbound(self, one_time_key_message):
one_time_key_message_buffer = create_string_buffer(one_time_key_message)
return bool(lib.olm_matches_inbound_session(
@@ -257,6 +286,15 @@ class Session(object):
one_time_key_message_buffer, len(one_time_key_message)
))
+ def matches_inbound_from(self, identity_key, one_time_key_message):
+ identity_key_buffer = create_string_buffer(identity_key)
+ one_time_key_message_buffer = create_string_buffer(one_time_key_message)
+ return bool(lib.olm_matches_inbound_session(
+ self.ptr,
+ identity_key_buffer, len(identity_key),
+ one_time_key_message_buffer, len(one_time_key_message)
+ ))
+
def encrypt(self, plaintext):
r_length = lib.olm_encrypt_random_length(self.ptr)
random = read_random(r_length)
@@ -421,7 +459,7 @@ if __name__ == '__main__':
def do_inbound(args):
if os.path.exists(args.session_file):
sys.stderr.write("Session %r file already exists" % (
- args.account_file,
+ args.session_file,
))
sys.exit(1)
account = Account()
@@ -443,6 +481,17 @@ if __name__ == '__main__':
inbound.set_defaults(func=do_inbound)
+ session_id = commands.add_parser("session_id", help="Session ID")
+ session_id.add_argument("session_file", help="Local session file")
+
+ def do_session_id(args):
+ session = Session()
+ with open(args.session_file, "rb") as f:
+ session.unpickle(args.key, f.read())
+ sys.stdout.write(session.session_id() + "\n")
+
+ session_id.set_defaults(func=do_session_id)
+
encrypt = commands.add_parser("encrypt", help="Encrypt a message")
encrypt.add_argument("session_file", help="Local session file")
encrypt.add_argument("plaintext_file", help="Plaintext", default="-")
diff --git a/src/olm.cpp b/src/olm.cpp
index 17461fe..cb4291e 100644
--- a/src/olm.cpp
+++ b/src/olm.cpp
@@ -552,6 +552,33 @@ size_t olm_create_inbound_session_from(
}
+size_t olm_session_id_length(
+ OlmSession * session
+) {
+ return b64_output_length(from_c(session)->session_id_length());
+}
+
+
+size_t olm_session_id(
+ OlmSession * session,
+ void * id, size_t id_length
+) {
+ std::size_t raw_length = from_c(session)->session_id_length();
+ if (id_length < b64_output_length(raw_length)) {
+ from_c(session)->last_error =
+ olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
+ return std::size_t(-1);
+ }
+ std::size_t result = from_c(session)->session_id(
+ b64_output_pos(from_c(id), raw_length), raw_length
+ );
+ if (result == std::size_t(-1)) {
+ return result;
+ }
+ return b64_output(from_c(id), raw_length);
+}
+
+
size_t olm_matches_inbound_session(
OlmSession * session,
void * one_time_key_message, size_t message_length
@@ -649,12 +676,15 @@ size_t olm_encrypt(
olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
return std::size_t(-1);
}
- from_c(session)->encrypt(
+ std::size_t result = from_c(session)->encrypt(
from_c(plaintext), plaintext_length,
from_c(random), random_length,
b64_output_pos(from_c(message), raw_length), raw_length
);
olm::unset(random, random_length);
+ if (result == std::size_t(-1)) {
+ return result;
+ }
return b64_output(from_c(message), raw_length);
}
diff --git a/src/session.cpp b/src/session.cpp
index 0249e6c..b17a059 100644
--- a/src/session.cpp
+++ b/src/session.cpp
@@ -189,6 +189,27 @@ std::size_t olm::Session::new_inbound_session(
}
+std::size_t olm::Session::session_id_length() {
+ return 32;
+}
+
+
+std::size_t olm::Session::session_id(
+ std::uint8_t * id, std::size_t id_length
+) {
+ if (id_length < session_id_length()) {
+ last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
+ return std::size_t(-1);
+ }
+ std::uint8_t tmp[96];
+ std::memcpy(tmp, alice_identity_key.public_key, 32);
+ std::memcpy(tmp + 32, alice_base_key.public_key, 32);
+ std::memcpy(tmp + 64, bob_one_time_key.public_key, 32);
+ olm::sha256(tmp, sizeof(tmp), id);
+ return session_id_length();
+}
+
+
bool olm::Session::matches_inbound_session(
olm::Curve25519PublicKey const * their_identity_key,
std::uint8_t const * one_time_key_message, std::size_t message_length
diff --git a/tests/test_olm.cpp b/tests/test_olm.cpp
index 551b3cd..fbc14cf 100644
--- a/tests/test_olm.cpp
+++ b/tests/test_olm.cpp
@@ -216,6 +216,19 @@ assert_equals(std::size_t(-1), ::olm_decrypt(
plaintext_2, sizeof(plaintext_2)
));
+std::uint8_t a_session_id[::olm_session_id_length(a_session)];
+assert_not_equals(std::size_t(-1), ::olm_session_id(
+ a_session, a_session_id, sizeof(a_session_id)
+));
+
+std::uint8_t b_session_id[::olm_session_id_length(b_session)];
+assert_not_equals(std::size_t(-1), ::olm_session_id(
+ b_session, b_session_id, sizeof(b_session_id)
+));
+
+assert_equals(sizeof(a_session_id), sizeof(b_session_id));
+assert_equals(a_session_id, b_session_id, sizeof(b_session_id));
+
}
{ /** More messages test */