diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/account.cpp | 154 | ||||
-rw-r--r-- | src/olm.cpp | 53 |
2 files changed, 92 insertions, 115 deletions
diff --git a/src/account.cpp b/src/account.cpp index 6a76583..796b06e 100644 --- a/src/account.cpp +++ b/src/account.cpp @@ -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; } diff --git a/src/olm.cpp b/src/olm.cpp index 6450999..efb1dfe 100644 --- a/src/olm.cpp +++ b/src/olm.cpp @@ -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 -) { - return from_c(account)->get_identity_json_length( - user_id_length, - device_id_length, - valid_after_ts, - valid_until_ts - ); + OlmAccount * account +) { + 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); |