Output simpler JSON for the account keys, don't sign the JSON but instead provide a olm_account_sign method so that the user of the library can sign the JSON themselves

logging_enabled
Mark Haines 2015-07-10 11:57:53 +01:00
parent 373acefde7
commit b6e248c9a5
8 changed files with 194 additions and 227 deletions

View File

@ -56,57 +56,45 @@ struct Account {
);
/** Number of bytes needed to output the identity keys for this account */
std::size_t get_identity_json_length(
std::size_t user_id_length,
std::size_t device_id_length,
std::uint64_t valid_after_ts,
std::uint64_t valid_until_ts
);
std::size_t get_identity_json_length();
/** Output the identity keys for this account as JSON in the following
* format:
*
* {"algorithms":
* ["m.olm.curve25519-aes-sha256"
* ]
* ,"device_id":"<device identifier>"
* ,"keys":
* {"curve25519:<key id>":"<base64 characters>"
* ,"ed25519:<key id>":"<base64 characters>"
* }
* ,"user_id":"<user identifier>"
* ,"valid_after_ts":<digits>
* ,"valid_until_ts":<digits>
* ,"signatures":
* {"<user identifier>/<device identifier>":
* {"ed25519:<key id>":"<base64 characters>"
* }
* }
* {"curve25519":"<43 base64 characters>"
* ,"ed25519":"<43 base64 characters>"
* }
*
* The user_id and device_id must not contain 0x00-0x1F, '\"' or '\\'.
* The JSON up to but not including the "signatures" key will be signed
* using the account's ed25519 key. That signature is then included under
* the "signatures" key.
*
* Returns the size of the JSON written or std::size_t(-1) on error.
* If the buffer is too small last_error will be OUTPUT_BUFFER_TOO_SMALL. */
std::size_t get_identity_json(
std::uint8_t const * user_id, std::size_t user_id_length,
std::uint8_t const * device_id, std::size_t device_id_length,
std::uint64_t valid_after_ts,
std::uint64_t valid_until_ts,
std::uint8_t * identity_json, std::size_t identity_json_length
);
/**
* The length of an ed25519 signature in bytes.
*/
std::size_t signature_length();
/**
* Signs a message with the ed25519 key for this account.
*/
std::size_t sign(
std::uint8_t const * message, std::size_t message_length,
std::uint8_t * signature, std::size_t signature_length
);
/** Number of bytes needed to output the one time keys for this account */
std::size_t get_one_time_keys_json_length();
/** Output the one time keys that haven't been published yet as JSON:
*
* {"curve25519:<key id>":"<base64 characters>"
* ,"curve25519:<key_id>":"<base64 characters>"
* {"curve25519":
* ["<6 byte key id>":"<43 base64 characters>"
* ,"<6 byte key id>":"<43 base64 characters>"
* ...
* ]
* }
*
* Returns the size of the JSON written or std::size_t(-1) on error.

View File

@ -132,11 +132,7 @@ size_t olm_create_account(
/** The size of the output buffer needed to hold the identity keys */
size_t olm_account_identity_keys_length(
OlmAccount * account,
size_t user_id_length,
size_t device_id_length,
uint64_t valid_after_ts,
uint64_t valid_until_ts
OlmAccount * account
);
/** Writes the public parts of the identity keys for the account into the
@ -145,13 +141,24 @@ size_t olm_account_identity_keys_length(
* "OUTPUT_BUFFER_TOO_SMALL". */
size_t olm_account_identity_keys(
OlmAccount * account,
void const * user_id, size_t user_id_length,
void const * device_id, size_t device_id_length,
uint64_t valid_after_ts,
uint64_t valid_until_ts,
void * identity_keys, size_t identity_key_length
);
/** The length of an ed25519 signature encoded as base64. */
size_t olm_account_signature_length(
OlmAccount * account
);
/** Signs a message with the ed25519 key for this account. Returns olm_error()
* on failure. If the signature buffer was too small then
* olm_account_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */
size_t olm_account_sign(
OlmAccount * account,
void const * message, size_t message_length,
void * signature, size_t signature_length
);
/** The size of the output buffer needed to hold the one time keys */
size_t olm_account_one_time_keys_length(
OlmAccount * account

View File

@ -19,8 +19,8 @@ document.addEventListener("DOMContentLoaded", function (event) {
return {start:start, done:done};
}
var alice = new Olm.Account();
var bob = new Olm.Account();
window.alice = new Olm.Account();
window.bob = new Olm.Account();
var a_session = new Olm.Session();
var b_session = new Olm.Session();
var message_1;
@ -32,19 +32,12 @@ document.addEventListener("DOMContentLoaded", function (event) {
bob.generate_one_time_keys(1);
}]);
tasks.push(["alice", "Create outbound session", function() {
var bobs_id_keys = JSON.parse(bob.identity_keys("bob", "bob_device", 0, 0));
var bobs_id_key;
for (key in bobs_id_keys.keys) {
if (key.startsWith("curve25519:")) {
bobs_id_key = bobs_id_keys.keys[key];
}
}
var bobs_id_keys = JSON.parse(bob.identity_keys());
var bobs_id_key = bobs_id_keys.curve25519;
var bobs_ot_keys = JSON.parse(bob.one_time_keys());
var bobs_ot_key;
for (key in bobs_ot_keys) {
if (key.startsWith("curve25519:")) {
bobs_ot_key = bobs_ot_keys[key];
}
for (key in bobs_ot_keys.curve25519) {
bobs_ot_key = bobs_ot_keys.curve25519[key];
}
a_session.create_outbound(alice, bobs_id_key, bobs_ot_key);
}]);
@ -104,7 +97,7 @@ document.addEventListener("DOMContentLoaded", function (event) {
task[2]();
p.done();
window.setTimeout(do_tasks, 50, next);
}, 0)
}, 50)
} else {
next();
}

View File

@ -63,32 +63,32 @@ Account.prototype['create'] = restore_stack(function() {
);
});
Account.prototype['identity_keys'] = restore_stack(function(
user_id, device_id, valid_after, valid_until
) {
var user_id_array = array_from_string(user_id);
var device_id_array = array_from_string(device_id);
Account.prototype['identity_keys'] = restore_stack(function() {
var keys_length = account_method(
Module['_olm_account_identity_keys_length']
)(
this.ptr, user_id_array.length, device_id_array.length,
valid_after, valid_after / Math.pow(2, 32),
valid_until, valid_until / Math.pow(2, 32)
);
var user_id_buffer = stack(user_id_array);
var device_id_buffer = stack(device_id_array);
)(this.ptr);
var keys = stack(keys_length);
account_method(Module['_olm_account_identity_keys'])(
this.ptr,
user_id_buffer, user_id_array.length,
device_id_buffer, device_id_array.length,
valid_after, valid_after / Math.pow(2, 32),
valid_until, valid_until / Math.pow(2, 32),
keys, keys_length
this.ptr, keys, keys_length
);
return Pointer_stringify(keys, keys_length);
});
Account.prototype['sign'] = restore_stack(function(message) {
var signature_length = account_method(
Module['_olm_account_signature_length']
)(this.ptr);
var message_array = array_from_string(message);
var message_buffer = stack(message_array);
var signature_buffer = stack(signature_length);
account_method(Module['_olm_account_sign'])(
this.ptr,
message_buffer, message_array.length,
signature_buffer, signature_length
);
return Pointer_stringify(signature_buffer, signature_length);
});
Account.prototype['one_time_keys'] = restore_stack(function() {
var keys_length = account_method(
Module['_olm_account_one_time_keys_length']

62
olm.py
View File

@ -48,15 +48,10 @@ account_function(
)
account_function(lib.olm_create_account_random_length)
account_function(lib.olm_create_account, c_void_p, c_size_t)
account_function(
lib.olm_account_identity_keys_length,
c_size_t, c_size_t, c_uint64, c_uint64
)
account_function(
lib.olm_account_identity_keys,
c_void_p, c_size_t, c_void_p, c_size_t, c_uint64, c_uint64,
c_void_p, c_size_t
)
account_function(lib.olm_account_identity_keys_length)
account_function(lib.olm_account_identity_keys, c_void_p, c_size_t)
account_function(lib.olm_account_signature_length)
account_function(lib.olm_account_sign, c_void_p, c_size_t, c_void_p, c_size_t)
account_function(lib.olm_account_one_time_keys_length)
account_function(lib.olm_account_one_time_keys, c_void_p, c_size_t)
account_function(lib.olm_account_mark_keys_as_published)
@ -66,7 +61,7 @@ account_function(
c_size_t
)
account_function(
lib.olm_account_generate_one_time_keys
lib.olm_account_generate_one_time_keys,
c_size_t,
c_void_p, c_size_t
)
@ -103,22 +98,24 @@ class Account(object):
self.ptr, key_buffer, len(key), pickle_buffer, len(pickle)
)
def identity_keys(self, user_id, device_id, valid_after, valid_until):
out_length = lib.olm_account_identity_keys_length(
self.ptr, len(user_id), len(device_id), valid_after, valid_until
)
user_id_buffer = create_string_buffer(user_id)
device_id_buffer = create_string_buffer(device_id)
def identity_keys(self):
out_length = lib.olm_account_identity_keys_length(self.ptr)
out_buffer = create_string_buffer(out_length)
lib.olm_account_identity_keys(
self.ptr,
user_id_buffer, len(user_id),
device_id_buffer, len(device_id),
valid_after, valid_until,
out_buffer, out_length
)
return json.loads(out_buffer.raw)
def sign(self, message):
out_length = lib.olm_account_signature_length(self.ptr)
message_buffer = create_string_buffer(message)
out_buffer = create_string_buffer(out_length)
lib.olm_account_sign(
self.ptr, message_buffer, len(message), out_buffer, out_length
)
return out_buffer.raw
def one_time_keys(self):
out_length = lib.olm_account_one_time_keys_length(self.ptr)
out_buffer = create_string_buffer(out_length)
@ -128,7 +125,6 @@ class Account(object):
def mark_keys_as_published(self):
lib.olm_account_mark_keys_as_published(self.ptr)
def max_number_of_one_time_keys(self):
return lib.olm_account_max_number_of_one_time_keys(self.ptr)
@ -326,10 +322,6 @@ if __name__ == '__main__':
create_account.set_defaults(func=do_create_account)
keys = commands.add_parser("keys", help="List public keys for an account")
keys.add_argument("--user-id", default="@user:example.com")
keys.add_argument("--device-id", default="default_device_id")
keys.add_argument("--valid-after", default=0, type=int)
keys.add_argument("--valid-until", default=0, type=int)
keys.add_argument("account_file", help="Local account file")
def do_keys(args):
@ -337,10 +329,7 @@ if __name__ == '__main__':
with open(args.account_file, "rb") as f:
account.unpickle(args.key, f.read())
result1 = {
"device_keys": account.identity_keys(
args.user_id, args.device_id,
args.valid_after, args.valid_until,
),
"account_keys": account.identity_keys(),
"one_time_keys": account.one_time_keys(),
}
try:
@ -350,6 +339,23 @@ if __name__ == '__main__':
keys.set_defaults(func=do_keys)
sign = commands.add_parser("sign", help="Sign a message")
sign.add_argument("account_file", help="Local account file")
sign.add_argument("message_file", help="Message to sign")
sign.add_argument("signature_file", help="Signature to output")
def do_sign(args):
account = Account()
with open(args.account_file, "rb") as f:
account.unpickle(args.key, f.read())
with open_in(args.message_file) as f:
message = f.read()
signature = account.sign(message)
with open_out(args.signature_file) as f:
f.write(signature)
sign.set_defaults(func=do_sign)
outbound = commands.add_parser("outbound", help="Create an outbound session")
outbound.add_argument("account_file", help="Local account file")
outbound.add_argument("session_file", help="Local session file")

View File

@ -69,22 +69,12 @@ std::size_t olm::Account::new_account(
namespace {
static const uint8_t IDENTITY_JSON_PART_0[] =
"{\"algorithms\":"
"[\"m.olm.curve25519-aes-sha256\""
"],\"device_id\":\"";
static const uint8_t IDENTITY_JSON_PART_1[] = "\",\"keys\":{\"curve25519:";
static const uint8_t IDENTITY_JSON_PART_2[] = "\":\"";
static const uint8_t IDENTITY_JSON_PART_3[] = "\",\"ed25519:";
static const uint8_t IDENTITY_JSON_PART_4[] = "\":\"";
static const uint8_t IDENTITY_JSON_PART_5[] = "\"},\"user_id\":\"";
static const uint8_t IDENTITY_JSON_PART_6[] = "\",\"valid_after_ts\":";
static const uint8_t IDENTITY_JSON_PART_7[] = ",\"valid_until_ts\":";
static const uint8_t IDENTITY_JSON_PART_8[] = ",\"signatures\":{\"";
static const uint8_t IDENTITY_JSON_PART_9[] = "/";
static const uint8_t IDENTITY_JSON_PART_A[] = "\":{\"ed25519:";
static const uint8_t IDENTITY_JSON_PART_B[] = "\":\"";
static const uint8_t IDENTITY_JSON_PART_C[] = "\"}}}";
namespace {
uint8_t KEY_JSON_ED25519[] = "\"ed25519\":";
uint8_t KEY_JSON_CURVE25519[] = "\"curve25519\":";
}
std::size_t count_digits(
std::uint64_t value
@ -130,104 +120,79 @@ std::uint8_t * write_digits(
}
std::size_t olm::Account::get_identity_json_length(
std::size_t user_id_length,
std::size_t device_id_length,
std::uint64_t valid_after_ts,
std::uint64_t valid_until_ts
) {
std::size_t olm::Account::get_identity_json_length() {
std::size_t length = 0;
length += sizeof(IDENTITY_JSON_PART_0) - 1;
length += device_id_length;
length += sizeof(IDENTITY_JSON_PART_1) - 1;
length += olm::encode_base64_length(3);
length += sizeof(IDENTITY_JSON_PART_2) - 1;
length += 1; /* { */
length += sizeof(KEY_JSON_CURVE25519) - 1;
length += 1; /* " */
length += olm::encode_base64_length(
sizeof(identity_keys.curve25519_key.public_key)
);
length += sizeof(IDENTITY_JSON_PART_3) - 1;
length += olm::encode_base64_length(3);
length += sizeof(IDENTITY_JSON_PART_4) - 1;
length += 2; /* ", */
length += sizeof(KEY_JSON_ED25519) - 1;
length += 1; /* " */
length += olm::encode_base64_length(
sizeof(identity_keys.ed25519_key.public_key)
);
length += sizeof(IDENTITY_JSON_PART_5) - 1;
length += user_id_length;
length += sizeof(IDENTITY_JSON_PART_6) - 1;
length += count_digits(valid_after_ts);
length += sizeof(IDENTITY_JSON_PART_7) - 1;
length += count_digits(valid_until_ts);
length += sizeof(IDENTITY_JSON_PART_8) - 1;
length += user_id_length;
length += sizeof(IDENTITY_JSON_PART_9) - 1;
length += device_id_length;
length += sizeof(IDENTITY_JSON_PART_A) - 1;
length += olm::encode_base64_length(3);
length += sizeof(IDENTITY_JSON_PART_B) - 1;
length += olm::encode_base64_length(64);
length += sizeof(IDENTITY_JSON_PART_C) - 1;
length += 2; /* "} */
return length;
}
std::size_t olm::Account::get_identity_json(
std::uint8_t const * user_id, std::size_t user_id_length,
std::uint8_t const * device_id, std::size_t device_id_length,
std::uint64_t valid_after_ts,
std::uint64_t valid_until_ts,
std::uint8_t * identity_json, std::size_t identity_json_length
) {
std::uint8_t * pos = identity_json;
std::uint8_t signature[64];
size_t expected_length = get_identity_json_length(
user_id_length, device_id_length, valid_after_ts, valid_until_ts
);
size_t expected_length = get_identity_json_length();
if (identity_json_length < expected_length) {
last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
return std::size_t(-1);
}
pos = write_string(pos, IDENTITY_JSON_PART_0);
pos = write_string(pos, device_id, device_id_length);
pos = write_string(pos, IDENTITY_JSON_PART_1);
pos = encode_base64(identity_keys.curve25519_key.public_key, 3, pos);
pos = write_string(pos, IDENTITY_JSON_PART_2);
pos = encode_base64(identity_keys.curve25519_key.public_key, 32, pos);
pos = write_string(pos, IDENTITY_JSON_PART_3);
pos = encode_base64(identity_keys.ed25519_key.public_key, 3, pos);
pos = write_string(pos, IDENTITY_JSON_PART_4);
pos = encode_base64(identity_keys.ed25519_key.public_key, 32, pos);
pos = write_string(pos, IDENTITY_JSON_PART_5);
pos = write_string(pos, user_id, user_id_length);
pos = write_string(pos, IDENTITY_JSON_PART_6);
pos = write_digits(pos, valid_after_ts);
pos = write_string(pos, IDENTITY_JSON_PART_7);
pos = write_digits(pos, valid_until_ts);
*pos = '}';
// Sign the JSON up to written up to this point.
ed25519_sign(
identity_keys.ed25519_key,
identity_json, 1 + pos - identity_json,
signature
*(pos++) = '{';
pos = write_string(pos, KEY_JSON_CURVE25519);
*(pos++) = '\"';
pos = olm::encode_base64(
identity_keys.curve25519_key.public_key,
sizeof(identity_keys.curve25519_key.public_key),
pos
);
// Append the signature to the end of the JSON.
pos = write_string(pos, IDENTITY_JSON_PART_8);
pos = write_string(pos, user_id, user_id_length);
pos = write_string(pos, IDENTITY_JSON_PART_9);
pos = write_string(pos, device_id, device_id_length);
pos = write_string(pos, IDENTITY_JSON_PART_A);
pos = encode_base64(identity_keys.ed25519_key.public_key, 3, pos);
pos = write_string(pos, IDENTITY_JSON_PART_B);
pos = encode_base64(signature, 64, pos);
pos = write_string(pos, IDENTITY_JSON_PART_C);
*(pos++) = '\"'; *(pos++) = ',';
pos = write_string(pos, KEY_JSON_ED25519);
*(pos++) = '\"';
pos = olm::encode_base64(
identity_keys.ed25519_key.public_key,
sizeof(identity_keys.ed25519_key.public_key),
pos
);
*(pos++) = '\"'; *(pos++) = '}';
return pos - identity_json;
}
namespace {
uint8_t ONE_TIME_KEY_JSON_ALG[] = "curve25519";
std::size_t olm::Account::signature_length(
) {
return 64;
}
std::size_t olm::Account::sign(
std::uint8_t const * message, std::size_t message_length,
std::uint8_t * signature, std::size_t signature_length
) {
if (signature_length < this->signature_length()) {
last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
return std::size_t(-1);
}
olm::ed25519_sign(
identity_keys.ed25519_key, message, message_length, signature
);
return this->signature_length();
}
std::size_t olm::Account::get_one_time_keys_json_length(
) {
std::size_t length = 0;
@ -236,18 +201,18 @@ std::size_t olm::Account::get_one_time_keys_json_length(
continue;
}
length += 2; /* {" */
length += sizeof(ONE_TIME_KEY_JSON_ALG) - 1;
length += 1; /* : */
length += olm::encode_base64_length(olm::pickle_length(key.id));
length += 3; /* ":" */
length += olm::encode_base64_length(sizeof(key.key.public_key));
length += 1; /* " */
}
if (length) {
return length + 1; /* } */
} else {
return 2; /* {} */
if (length == 0) {
/* The list was empty. Add a byte for the opening '{' */
length = 1;
}
length += 3; /* }{} */
length += sizeof(KEY_JSON_CURVE25519) - 1;
return length;
}
@ -259,6 +224,8 @@ std::size_t olm::Account::get_one_time_keys_json(
last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
return std::size_t(-1);
}
*(pos++) = '{';
pos = write_string(pos, KEY_JSON_CURVE25519);
std::uint8_t sep = '{';
for (auto const & key : one_time_keys) {
if (key.published) {
@ -266,8 +233,6 @@ std::size_t olm::Account::get_one_time_keys_json(
}
*(pos++) = sep;
*(pos++) = '\"';
pos = write_string(pos, ONE_TIME_KEY_JSON_ALG);
*(pos++) = ':';
std::uint8_t key_id[olm::pickle_length(key.id)];
olm::pickle(key_id, key.id);
pos = olm::encode_base64(key_id, sizeof(key_id), pos);
@ -282,6 +247,7 @@ std::size_t olm::Account::get_one_time_keys_json(
*(pos++) = sep;
}
*(pos++) = '}';
*(pos++) = '}';
return pos - one_time_json;
}

View File

@ -320,39 +320,50 @@ size_t olm_create_account(
return from_c(account)->new_account(from_c(random), random_length);
}
size_t olm_account_identity_keys_length(
OlmAccount * account,
size_t user_id_length,
size_t device_id_length,
uint64_t valid_after_ts,
uint64_t valid_until_ts
OlmAccount * account
) {
return from_c(account)->get_identity_json_length(
user_id_length,
device_id_length,
valid_after_ts,
valid_until_ts
);
return from_c(account)->get_identity_json_length();
}
size_t olm_account_identity_keys(
OlmAccount * account,
void const * user_id, size_t user_id_length,
void const * device_id, size_t device_id_length,
uint64_t valid_after_ts,
uint64_t valid_until_ts,
void * identity_keys, size_t identity_key_length
) {
return from_c(account)->get_identity_json(
from_c(user_id), user_id_length,
from_c(device_id), device_id_length,
valid_after_ts,
valid_until_ts,
from_c(identity_keys), identity_key_length
);
}
size_t olm_account_signature_length(
OlmAccount * account
) {
return b64_output_length(from_c(account)->signature_length());
}
size_t olm_account_sign(
OlmAccount * account,
void const * message, size_t message_length,
void * signature, size_t signature_length
) {
std::size_t raw_length = from_c(account)->signature_length();
if (signature_length < b64_output_length(raw_length)) {
from_c(account)->last_error =
olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
return std::size_t(-1);
}
from_c(account)->sign(
from_c(message), message_length,
b64_output_pos(from_c(signature), raw_length), raw_length
);
return b64_output(from_c(signature), raw_length);
}
size_t olm_account_one_time_keys_length(
OlmAccount * account
) {
@ -524,7 +535,7 @@ size_t olm_encrypt(
std::size_t raw_length = from_c(session)->encrypt_message_length(
plaintext_length
);
if (message_length < raw_length) {
if (message_length < b64_output_length(raw_length)) {
from_c(session)->last_error =
olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
return std::size_t(-1);

View File

@ -86,11 +86,9 @@ std::uint8_t o_random[::olm_account_generate_one_time_keys_random_length(
mock_random_b(o_random, sizeof(o_random));
::olm_account_generate_one_time_keys(b_account, 42, o_random, sizeof(o_random));
std::uint8_t b_id_keys[::olm_account_identity_keys_length(b_account, 0, 0, 0, 0)];
std::uint8_t b_id_keys[::olm_account_identity_keys_length(b_account)];
std::uint8_t b_ot_keys[::olm_account_one_time_keys_length(b_account)];
::olm_account_identity_keys(
b_account, nullptr, 0, nullptr, 0, 0, 0, b_id_keys, sizeof(b_id_keys)
);
::olm_account_identity_keys(b_account, b_id_keys, sizeof(b_id_keys));
::olm_account_one_time_keys(b_account, b_ot_keys, sizeof(b_ot_keys));
std::uint8_t a_session_buffer[::olm_session_size()];
@ -99,8 +97,8 @@ std::uint8_t a_rand[::olm_create_outbound_session_random_length(a_session)];
mock_random_a(a_rand, sizeof(a_rand));
assert_not_equals(std::size_t(-1), ::olm_create_outbound_session(
a_session, a_account,
b_id_keys + 88, 43,
b_ot_keys + 22, 43,
b_id_keys + 15, 43,
b_ot_keys + 25, 43,
a_rand, sizeof(a_rand)
));
@ -195,11 +193,9 @@ std::uint8_t o_random[::olm_account_generate_one_time_keys_random_length(
mock_random_b(o_random, sizeof(o_random));
::olm_account_generate_one_time_keys(b_account, 42, o_random, sizeof(o_random));
std::uint8_t b_id_keys[::olm_account_identity_keys_length(b_account, 0, 0, 0, 0)];
std::uint8_t b_id_keys[::olm_account_identity_keys_length(b_account)];
std::uint8_t b_ot_keys[::olm_account_one_time_keys_length(b_account)];
::olm_account_identity_keys(
b_account, nullptr, 0, nullptr, 0, 0, 0, b_id_keys, sizeof(b_id_keys)
);
::olm_account_identity_keys(b_account, b_id_keys, sizeof(b_id_keys));
::olm_account_one_time_keys(b_account, b_ot_keys, sizeof(b_ot_keys));
std::uint8_t a_session_buffer[::olm_session_size()];
@ -208,8 +204,8 @@ std::uint8_t a_rand[::olm_create_outbound_session_random_length(a_session)];
mock_random_a(a_rand, sizeof(a_rand));
assert_not_equals(std::size_t(-1), ::olm_create_outbound_session(
a_session, a_account,
b_id_keys + 88, 43,
b_ot_keys + 22, 43,
b_id_keys + 15, 43,
b_ot_keys + 25, 43,
a_rand, sizeof(a_rand)
));