Add method getting a session id. Update the python and javascript bindings

This commit is contained in:
Mark Haines 2015-07-16 11:45:20 +01:00
parent 89d9b972a6
commit 3468886e27
7 changed files with 172 additions and 3 deletions

View file

@ -257,6 +257,19 @@ size_t olm_create_inbound_session_from(
void * one_time_key_message, size_t message_length 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 /** 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 * if multiple messages are sent to this account before this account sends a
* message in reply. Returns olm_error() on failure. If the base64 * message in reply. Returns olm_error() on failure. If the base64

View file

@ -54,6 +54,12 @@ struct Session {
std::uint8_t const * one_time_key_message, std::size_t message_length 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( bool matches_inbound_session(
Curve25519PublicKey const * their_identity_key, Curve25519PublicKey const * their_identity_key,
std::uint8_t const * one_time_key_message, std::size_t message_length std::uint8_t const * one_time_key_message, std::size_t message_length

View file

@ -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( Session.prototype['matches_inbound'] = restore_stack(function(
account, one_time_key_message account, one_time_key_message
) { ) {
@ -232,6 +255,20 @@ Session.prototype['matches_inbound'] = restore_stack(function(
) ? true : false; ) ? 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( Session.prototype['encrypt'] = restore_stack(function(
plaintext plaintext
) { ) {

View file

@ -185,7 +185,20 @@ session_function(
c_void_p, # Account c_void_p, # Account
c_void_p, c_size_t, # Pre Key Message 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, 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_message_type)
session_function(lib.olm_encrypt_random_length) session_function(lib.olm_encrypt_random_length)
session_function(lib.olm_encrypt_message_length, c_size_t) session_function(lib.olm_encrypt_message_length, c_size_t)
@ -250,6 +263,22 @@ class Session(object):
one_time_key_message_buffer, len(one_time_key_message) 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): def matches_inbound(self, one_time_key_message):
one_time_key_message_buffer = create_string_buffer(one_time_key_message) one_time_key_message_buffer = create_string_buffer(one_time_key_message)
return bool(lib.olm_matches_inbound_session( return bool(lib.olm_matches_inbound_session(
@ -257,6 +286,15 @@ class Session(object):
one_time_key_message_buffer, len(one_time_key_message) 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): def encrypt(self, plaintext):
r_length = lib.olm_encrypt_random_length(self.ptr) r_length = lib.olm_encrypt_random_length(self.ptr)
random = read_random(r_length) random = read_random(r_length)
@ -421,7 +459,7 @@ if __name__ == '__main__':
def do_inbound(args): def do_inbound(args):
if os.path.exists(args.session_file): if os.path.exists(args.session_file):
sys.stderr.write("Session %r file already exists" % ( sys.stderr.write("Session %r file already exists" % (
args.account_file, args.session_file,
)) ))
sys.exit(1) sys.exit(1)
account = Account() account = Account()
@ -443,6 +481,17 @@ if __name__ == '__main__':
inbound.set_defaults(func=do_inbound) 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 = commands.add_parser("encrypt", help="Encrypt a message")
encrypt.add_argument("session_file", help="Local session file") encrypt.add_argument("session_file", help="Local session file")
encrypt.add_argument("plaintext_file", help="Plaintext", default="-") encrypt.add_argument("plaintext_file", help="Plaintext", default="-")

View file

@ -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( size_t olm_matches_inbound_session(
OlmSession * session, OlmSession * session,
void * one_time_key_message, size_t message_length void * one_time_key_message, size_t message_length
@ -649,12 +676,15 @@ size_t olm_encrypt(
olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
return std::size_t(-1); return std::size_t(-1);
} }
from_c(session)->encrypt( std::size_t result = from_c(session)->encrypt(
from_c(plaintext), plaintext_length, from_c(plaintext), plaintext_length,
from_c(random), random_length, from_c(random), random_length,
b64_output_pos(from_c(message), raw_length), raw_length b64_output_pos(from_c(message), raw_length), raw_length
); );
olm::unset(random, random_length); olm::unset(random, random_length);
if (result == std::size_t(-1)) {
return result;
}
return b64_output(from_c(message), raw_length); return b64_output(from_c(message), raw_length);
} }

View file

@ -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( bool olm::Session::matches_inbound_session(
olm::Curve25519PublicKey const * their_identity_key, olm::Curve25519PublicKey const * their_identity_key,
std::uint8_t const * one_time_key_message, std::size_t message_length std::uint8_t const * one_time_key_message, std::size_t message_length

View file

@ -216,6 +216,19 @@ assert_equals(std::size_t(-1), ::olm_decrypt(
plaintext_2, sizeof(plaintext_2) 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 */ { /** More messages test */