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

This commit is contained in:
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 */ /** Number of bytes needed to output the identity keys for this account */
std::size_t get_identity_json_length( 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
);
/** Output the identity keys for this account as JSON in the following /** Output the identity keys for this account as JSON in the following
* format: * format:
* *
* {"algorithms": * {"curve25519":"<43 base64 characters>"
* ["m.olm.curve25519-aes-sha256" * ,"ed25519":"<43 base64 characters>"
* ]
* ,"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>"
* }
* }
* } * }
* *
* 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. * 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. */ * If the buffer is too small last_error will be OUTPUT_BUFFER_TOO_SMALL. */
std::size_t get_identity_json( 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 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 */ /** Number of bytes needed to output the one time keys for this account */
std::size_t get_one_time_keys_json_length(); std::size_t get_one_time_keys_json_length();
/** Output the one time keys that haven't been published yet as JSON: /** Output the one time keys that haven't been published yet as JSON:
* *
* {"curve25519:<key id>":"<base64 characters>" * {"curve25519":
* ,"curve25519:<key_id>":"<base64 characters>" * ["<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. * 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 */ /** The size of the output buffer needed to hold the identity keys */
size_t olm_account_identity_keys_length( size_t olm_account_identity_keys_length(
OlmAccount * account, OlmAccount * account
size_t user_id_length,
size_t device_id_length,
uint64_t valid_after_ts,
uint64_t valid_until_ts
); );
/** Writes the public parts of the identity keys for the account into the /** 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". */ * "OUTPUT_BUFFER_TOO_SMALL". */
size_t olm_account_identity_keys( size_t olm_account_identity_keys(
OlmAccount * account, 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 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 */ /** The size of the output buffer needed to hold the one time keys */
size_t olm_account_one_time_keys_length( size_t olm_account_one_time_keys_length(
OlmAccount * account OlmAccount * account

View file

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

View file

@ -63,32 +63,32 @@ Account.prototype['create'] = restore_stack(function() {
); );
}); });
Account.prototype['identity_keys'] = 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);
var keys_length = account_method( var keys_length = account_method(
Module['_olm_account_identity_keys_length'] Module['_olm_account_identity_keys_length']
)( )(this.ptr);
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);
var keys = stack(keys_length); var keys = stack(keys_length);
account_method(Module['_olm_account_identity_keys'])( account_method(Module['_olm_account_identity_keys'])(
this.ptr, this.ptr, keys, keys_length
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
); );
return Pointer_stringify(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() { Account.prototype['one_time_keys'] = restore_stack(function() {
var keys_length = account_method( var keys_length = account_method(
Module['_olm_account_one_time_keys_length'] 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_random_length)
account_function(lib.olm_create_account, c_void_p, c_size_t) account_function(lib.olm_create_account, c_void_p, c_size_t)
account_function( account_function(lib.olm_account_identity_keys_length)
lib.olm_account_identity_keys_length, account_function(lib.olm_account_identity_keys, c_void_p, c_size_t)
c_size_t, c_size_t, c_uint64, c_uint64 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_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_one_time_keys_length) 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_one_time_keys, c_void_p, c_size_t)
account_function(lib.olm_account_mark_keys_as_published) account_function(lib.olm_account_mark_keys_as_published)
@ -66,7 +61,7 @@ account_function(
c_size_t c_size_t
) )
account_function( account_function(
lib.olm_account_generate_one_time_keys lib.olm_account_generate_one_time_keys,
c_size_t, c_size_t,
c_void_p, 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) self.ptr, key_buffer, len(key), pickle_buffer, len(pickle)
) )
def identity_keys(self, user_id, device_id, valid_after, valid_until): def identity_keys(self):
out_length = lib.olm_account_identity_keys_length( out_length = lib.olm_account_identity_keys_length(self.ptr)
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)
out_buffer = create_string_buffer(out_length) out_buffer = create_string_buffer(out_length)
lib.olm_account_identity_keys( lib.olm_account_identity_keys(
self.ptr, self.ptr,
user_id_buffer, len(user_id),
device_id_buffer, len(device_id),
valid_after, valid_until,
out_buffer, out_length out_buffer, out_length
) )
return json.loads(out_buffer.raw) 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): def one_time_keys(self):
out_length = lib.olm_account_one_time_keys_length(self.ptr) out_length = lib.olm_account_one_time_keys_length(self.ptr)
out_buffer = create_string_buffer(out_length) out_buffer = create_string_buffer(out_length)
@ -128,7 +125,6 @@ class Account(object):
def mark_keys_as_published(self): def mark_keys_as_published(self):
lib.olm_account_mark_keys_as_published(self.ptr) lib.olm_account_mark_keys_as_published(self.ptr)
def max_number_of_one_time_keys(self): def max_number_of_one_time_keys(self):
return lib.olm_account_max_number_of_one_time_keys(self.ptr) 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) create_account.set_defaults(func=do_create_account)
keys = commands.add_parser("keys", help="List public keys for an 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") keys.add_argument("account_file", help="Local account file")
def do_keys(args): def do_keys(args):
@ -337,10 +329,7 @@ if __name__ == '__main__':
with open(args.account_file, "rb") as f: with open(args.account_file, "rb") as f:
account.unpickle(args.key, f.read()) account.unpickle(args.key, f.read())
result1 = { result1 = {
"device_keys": account.identity_keys( "account_keys": account.identity_keys(),
args.user_id, args.device_id,
args.valid_after, args.valid_until,
),
"one_time_keys": account.one_time_keys(), "one_time_keys": account.one_time_keys(),
} }
try: try:
@ -350,6 +339,23 @@ if __name__ == '__main__':
keys.set_defaults(func=do_keys) 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 = commands.add_parser("outbound", help="Create an outbound session")
outbound.add_argument("account_file", help="Local account file") outbound.add_argument("account_file", help="Local account file")
outbound.add_argument("session_file", help="Local session file") outbound.add_argument("session_file", help="Local session file")

View file

@ -69,22 +69,12 @@ std::size_t olm::Account::new_account(
namespace { namespace {
static const uint8_t IDENTITY_JSON_PART_0[] =
"{\"algorithms\":" namespace {
"[\"m.olm.curve25519-aes-sha256\"" uint8_t KEY_JSON_ED25519[] = "\"ed25519\":";
"],\"device_id\":\""; uint8_t KEY_JSON_CURVE25519[] = "\"curve25519\":";
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[] = "\"}}}";
std::size_t count_digits( std::size_t count_digits(
std::uint64_t value 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 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 length = 0; std::size_t length = 0;
length += sizeof(IDENTITY_JSON_PART_0) - 1; length += 1; /* { */
length += device_id_length; length += sizeof(KEY_JSON_CURVE25519) - 1;
length += sizeof(IDENTITY_JSON_PART_1) - 1; length += 1; /* " */
length += olm::encode_base64_length(3);
length += sizeof(IDENTITY_JSON_PART_2) - 1;
length += olm::encode_base64_length( length += olm::encode_base64_length(
sizeof(identity_keys.curve25519_key.public_key) sizeof(identity_keys.curve25519_key.public_key)
); );
length += sizeof(IDENTITY_JSON_PART_3) - 1; length += 2; /* ", */
length += olm::encode_base64_length(3); length += sizeof(KEY_JSON_ED25519) - 1;
length += sizeof(IDENTITY_JSON_PART_4) - 1; length += 1; /* " */
length += olm::encode_base64_length( length += olm::encode_base64_length(
sizeof(identity_keys.ed25519_key.public_key) sizeof(identity_keys.ed25519_key.public_key)
); );
length += sizeof(IDENTITY_JSON_PART_5) - 1; length += 2; /* "} */
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;
return length; return length;
} }
std::size_t olm::Account::get_identity_json( 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 * identity_json, std::size_t identity_json_length
) { ) {
std::uint8_t * pos = identity_json; std::uint8_t * pos = identity_json;
std::uint8_t signature[64]; std::uint8_t signature[64];
size_t expected_length = get_identity_json_length( size_t expected_length = get_identity_json_length();
user_id_length, device_id_length, valid_after_ts, valid_until_ts
);
if (identity_json_length < expected_length) { if (identity_json_length < expected_length) {
last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
return std::size_t(-1); return std::size_t(-1);
} }
pos = write_string(pos, IDENTITY_JSON_PART_0); *(pos++) = '{';
pos = write_string(pos, device_id, device_id_length); pos = write_string(pos, KEY_JSON_CURVE25519);
pos = write_string(pos, IDENTITY_JSON_PART_1); *(pos++) = '\"';
pos = encode_base64(identity_keys.curve25519_key.public_key, 3, pos); pos = olm::encode_base64(
pos = write_string(pos, IDENTITY_JSON_PART_2); identity_keys.curve25519_key.public_key,
pos = encode_base64(identity_keys.curve25519_key.public_key, 32, pos); sizeof(identity_keys.curve25519_key.public_key),
pos = write_string(pos, IDENTITY_JSON_PART_3); pos
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
); );
// Append the signature to the end of the JSON. *(pos++) = '\"'; *(pos++) = ',';
pos = write_string(pos, IDENTITY_JSON_PART_8); pos = write_string(pos, KEY_JSON_ED25519);
pos = write_string(pos, user_id, user_id_length); *(pos++) = '\"';
pos = write_string(pos, IDENTITY_JSON_PART_9); pos = olm::encode_base64(
pos = write_string(pos, device_id, device_id_length); identity_keys.ed25519_key.public_key,
pos = write_string(pos, IDENTITY_JSON_PART_A); sizeof(identity_keys.ed25519_key.public_key),
pos = encode_base64(identity_keys.ed25519_key.public_key, 3, pos); pos
pos = write_string(pos, IDENTITY_JSON_PART_B); );
pos = encode_base64(signature, 64, pos); *(pos++) = '\"'; *(pos++) = '}';
pos = write_string(pos, IDENTITY_JSON_PART_C);
return pos - identity_json; 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 olm::Account::get_one_time_keys_json_length(
) { ) {
std::size_t length = 0; std::size_t length = 0;
@ -236,18 +201,18 @@ std::size_t olm::Account::get_one_time_keys_json_length(
continue; continue;
} }
length += 2; /* {" */ length += 2; /* {" */
length += sizeof(ONE_TIME_KEY_JSON_ALG) - 1;
length += 1; /* : */
length += olm::encode_base64_length(olm::pickle_length(key.id)); length += olm::encode_base64_length(olm::pickle_length(key.id));
length += 3; /* ":" */ length += 3; /* ":" */
length += olm::encode_base64_length(sizeof(key.key.public_key)); length += olm::encode_base64_length(sizeof(key.key.public_key));
length += 1; /* " */ length += 1; /* " */
} }
if (length) { if (length == 0) {
return length + 1; /* } */ /* The list was empty. Add a byte for the opening '{' */
} else { length = 1;
return 2; /* {} */
} }
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; last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
return std::size_t(-1); return std::size_t(-1);
} }
*(pos++) = '{';
pos = write_string(pos, KEY_JSON_CURVE25519);
std::uint8_t sep = '{'; std::uint8_t sep = '{';
for (auto const & key : one_time_keys) { for (auto const & key : one_time_keys) {
if (key.published) { if (key.published) {
@ -266,8 +233,6 @@ std::size_t olm::Account::get_one_time_keys_json(
} }
*(pos++) = sep; *(pos++) = sep;
*(pos++) = '\"'; *(pos++) = '\"';
pos = write_string(pos, ONE_TIME_KEY_JSON_ALG);
*(pos++) = ':';
std::uint8_t key_id[olm::pickle_length(key.id)]; std::uint8_t key_id[olm::pickle_length(key.id)];
olm::pickle(key_id, key.id); olm::pickle(key_id, key.id);
pos = olm::encode_base64(key_id, sizeof(key_id), pos); 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++) = sep;
} }
*(pos++) = '}'; *(pos++) = '}';
*(pos++) = '}';
return pos - one_time_json; 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); return from_c(account)->new_account(from_c(random), random_length);
} }
size_t olm_account_identity_keys_length( size_t olm_account_identity_keys_length(
OlmAccount * account, OlmAccount * account
size_t user_id_length,
size_t device_id_length,
uint64_t valid_after_ts,
uint64_t valid_until_ts
) { ) {
return from_c(account)->get_identity_json_length( return from_c(account)->get_identity_json_length();
user_id_length,
device_id_length,
valid_after_ts,
valid_until_ts
);
} }
size_t olm_account_identity_keys( size_t olm_account_identity_keys(
OlmAccount * account, 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 void * identity_keys, size_t identity_key_length
) { ) {
return from_c(account)->get_identity_json( 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 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( size_t olm_account_one_time_keys_length(
OlmAccount * account OlmAccount * account
) { ) {
@ -524,7 +535,7 @@ size_t olm_encrypt(
std::size_t raw_length = from_c(session)->encrypt_message_length( std::size_t raw_length = from_c(session)->encrypt_message_length(
plaintext_length plaintext_length
); );
if (message_length < raw_length) { if (message_length < b64_output_length(raw_length)) {
from_c(session)->last_error = from_c(session)->last_error =
olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
return std::size_t(-1); 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)); mock_random_b(o_random, sizeof(o_random));
::olm_account_generate_one_time_keys(b_account, 42, 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)]; std::uint8_t b_ot_keys[::olm_account_one_time_keys_length(b_account)];
::olm_account_identity_keys( ::olm_account_identity_keys(b_account, b_id_keys, sizeof(b_id_keys));
b_account, nullptr, 0, nullptr, 0, 0, 0, b_id_keys, sizeof(b_id_keys)
);
::olm_account_one_time_keys(b_account, b_ot_keys, sizeof(b_ot_keys)); ::olm_account_one_time_keys(b_account, b_ot_keys, sizeof(b_ot_keys));
std::uint8_t a_session_buffer[::olm_session_size()]; 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)); mock_random_a(a_rand, sizeof(a_rand));
assert_not_equals(std::size_t(-1), ::olm_create_outbound_session( assert_not_equals(std::size_t(-1), ::olm_create_outbound_session(
a_session, a_account, a_session, a_account,
b_id_keys + 88, 43, b_id_keys + 15, 43,
b_ot_keys + 22, 43, b_ot_keys + 25, 43,
a_rand, sizeof(a_rand) 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)); mock_random_b(o_random, sizeof(o_random));
::olm_account_generate_one_time_keys(b_account, 42, 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)]; std::uint8_t b_ot_keys[::olm_account_one_time_keys_length(b_account)];
::olm_account_identity_keys( ::olm_account_identity_keys(b_account, b_id_keys, sizeof(b_id_keys));
b_account, nullptr, 0, nullptr, 0, 0, 0, b_id_keys, sizeof(b_id_keys)
);
::olm_account_one_time_keys(b_account, b_ot_keys, sizeof(b_ot_keys)); ::olm_account_one_time_keys(b_account, b_ot_keys, sizeof(b_ot_keys));
std::uint8_t a_session_buffer[::olm_session_size()]; 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)); mock_random_a(a_rand, sizeof(a_rand));
assert_not_equals(std::size_t(-1), ::olm_create_outbound_session( assert_not_equals(std::size_t(-1), ::olm_create_outbound_session(
a_session, a_account, a_session, a_account,
b_id_keys + 88, 43, b_id_keys + 15, 43,
b_ot_keys + 22, 43, b_ot_keys + 25, 43,
a_rand, sizeof(a_rand) a_rand, sizeof(a_rand)
)); ));