Skip to content
Snippets Groups Projects
Commit 5ad92910 authored by Mark Haines's avatar Mark Haines
Browse files

Version the pickled objects and check for errors when unpickling them

parent b6e248c9
No related branches found
No related tags found
No related merge requests found
......@@ -27,6 +27,8 @@ enum struct ErrorCode {
BAD_MESSAGE_KEY_ID = 6, /*!< The message references an unknown key id */
INVALID_BASE64 = 7, /*!< The input base64 was invalid */
BAD_ACCOUNT_KEY = 8, /*!< The supplied account key is invalid */
UNKNOWN_PICKLE_VERSION = 9, /*!< The pickled object is too new */
CORRUPTED_PICKLE = 10, /*!< The pickled object couldn't be decoded */
};
} // namespace olm
......
......@@ -360,11 +360,16 @@ static std::uint8_t const * unpickle(
} // namespace olm
namespace {
static const std::uint32_t ACCOUNT_PICKLE_VERSION = 1;
}
std::size_t olm::pickle_length(
olm::Account const & value
) {
std::size_t length = 0;
length += olm::pickle_length(ACCOUNT_PICKLE_VERSION);
length += olm::pickle_length(value.identity_keys);
length += olm::pickle_length(value.one_time_keys);
length += olm::pickle_length(value.next_one_time_key_id);
......@@ -376,6 +381,7 @@ std::uint8_t * olm::pickle(
std::uint8_t * pos,
olm::Account const & value
) {
pos = olm::pickle(pos, ACCOUNT_PICKLE_VERSION);
pos = olm::pickle(pos, value.identity_keys);
pos = olm::pickle(pos, value.one_time_keys);
pos = olm::pickle(pos, value.next_one_time_key_id);
......@@ -387,6 +393,12 @@ std::uint8_t const * olm::unpickle(
std::uint8_t const * pos, std::uint8_t const * end,
olm::Account & value
) {
uint32_t pickle_version;
pos = olm::unpickle(pos, end, pickle_version);
if (pickle_version != ACCOUNT_PICKLE_VERSION) {
value.last_error = olm::ErrorCode::UNKNOWN_PICKLE_VERSION;
return end;
}
pos = olm::unpickle(pos, end, value.identity_keys);
pos = olm::unpickle(pos, end, value.one_time_keys);
pos = olm::unpickle(pos, end, value.next_one_time_key_id);
......
......@@ -151,7 +151,7 @@ std::size_t b64_input(
return raw_length;
}
const char * errors[9] {
const char * errors[11] {
"SUCCESS",
"NOT_ENOUGH_RANDOM",
"OUTPUT_BUFFER_TOO_SMALL",
......@@ -161,6 +161,8 @@ const char * errors[9] {
"BAD_MESSAGE_KEY_ID",
"INVALID_BASE64",
"BAD_ACCOUNT_KEY",
"UNKNOWN_PICKLE_VERSION",
"CORRUPTED_PICKLE",
};
} // namespace
......@@ -282,7 +284,16 @@ size_t olm_unpickle_account(
return std::size_t(-1);
}
std::uint8_t * const end = pos + raw_length;
unpickle(pos, end, object);
/* On success unpickle will return (pos + raw_length). If unpickling
* terminates too soon then it will return a pointer before
* (pos + raw_length). On error unpickle will return (pos + raw_length + 1).
*/
if (end != unpickle(pos, end + 1, object)) {
if (object.last_error == olm::ErrorCode::SUCCESS) {
object.last_error = olm::ErrorCode::CORRUPTED_PICKLE;
}
return std::size_t(-1);
}
return pickled_length;
}
......@@ -300,8 +311,18 @@ size_t olm_unpickle_session(
if (raw_length == std::size_t(-1)) {
return std::size_t(-1);
}
std::uint8_t * const end = pos + raw_length;
unpickle(pos, end, object);
std::uint8_t * const end = pos + raw_length + 1;
/* On success unpickle will return (pos + raw_length). If unpickling
* terminates too soon then it will return a pointer before
* (pos + raw_length). On error unpickle will return (pos + raw_length + 1).
*/
if (end != unpickle(pos, end + 1, object)) {
if (object.last_error == olm::ErrorCode::SUCCESS) {
object.last_error = olm::ErrorCode::CORRUPTED_PICKLE;
}
return std::size_t(-1);
}
return pickled_length;
}
......
......@@ -353,11 +353,15 @@ std::size_t olm::Session::decrypt(
return result;
}
namespace {
static const std::uint32_t SESSION_PICKLE_VERSION = 1;
}
std::size_t olm::pickle_length(
Session const & value
) {
std::size_t length = 0;
length += olm::pickle_length(SESSION_PICKLE_VERSION);
length += olm::pickle_length(value.received_message);
length += olm::pickle_length(value.alice_identity_key);
length += olm::pickle_length(value.alice_base_key);
......@@ -371,6 +375,7 @@ std::uint8_t * olm::pickle(
std::uint8_t * pos,
Session const & value
) {
pos = olm::pickle(pos, SESSION_PICKLE_VERSION);
pos = olm::pickle(pos, value.received_message);
pos = olm::pickle(pos, value.alice_identity_key);
pos = olm::pickle(pos, value.alice_base_key);
......@@ -384,6 +389,12 @@ std::uint8_t const * olm::unpickle(
std::uint8_t const * pos, std::uint8_t const * end,
Session & value
) {
uint32_t pickle_version;
pos = olm::unpickle(pos, end, pickle_version);
if (pickle_version != SESSION_PICKLE_VERSION) {
value.last_error = olm::ErrorCode::UNKNOWN_PICKLE_VERSION;
return end;
}
pos = olm::unpickle(pos, end, value.received_message);
pos = olm::unpickle(pos, end, value.alice_identity_key);
pos = olm::unpickle(pos, end, value.alice_base_key);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment