diff options
Diffstat (limited to 'src/message.cpp')
-rw-r--r-- | src/message.cpp | 79 |
1 files changed, 76 insertions, 3 deletions
diff --git a/src/message.cpp b/src/message.cpp index 05f707f..05fe2c7 100644 --- a/src/message.cpp +++ b/src/message.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015 OpenMarket Ltd +/* Copyright 2015-2016 OpenMarket Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,6 +14,8 @@ */ #include "olm/message.hh" +#include "olm/memory.hh" + namespace { template<typename T> @@ -131,7 +133,7 @@ static std::uint8_t const * decode( std::uint8_t const * len_start = pos; pos = varint_skip(pos, end); std::size_t len = varint_decode<std::size_t>(len_start, pos); - if (len > end - pos) return end; + if (len > std::size_t(end - pos)) return end; value = pos; value_length = len; pos += len; @@ -152,7 +154,7 @@ static std::uint8_t const * skip_unknown( std::uint8_t const * len_start = pos; pos = varint_skip(pos, end); std::size_t len = varint_decode<std::size_t>(len_start, pos); - if (len > end - pos) return end; + if (len > std::size_t(end - pos)) return end; pos += len; } else { return end; @@ -323,3 +325,74 @@ void olm::decode_one_time_key_message( unknown = pos; } } + + + +static const std::uint8_t GROUP_MESSAGE_INDEX_TAG = 010; +static const std::uint8_t GROUP_CIPHERTEXT_TAG = 022; + +size_t _olm_encode_group_message_length( + uint32_t message_index, + size_t ciphertext_length, + size_t mac_length, + size_t signature_length +) { + size_t length = VERSION_LENGTH; + length += 1 + varint_length(message_index); + length += 1 + varstring_length(ciphertext_length); + length += mac_length; + length += signature_length; + return length; +} + + +size_t _olm_encode_group_message( + uint8_t version, + uint32_t message_index, + size_t ciphertext_length, + uint8_t *output, + uint8_t **ciphertext_ptr +) { + std::uint8_t * pos = output; + + *(pos++) = version; + pos = encode(pos, GROUP_MESSAGE_INDEX_TAG, message_index); + pos = encode(pos, GROUP_CIPHERTEXT_TAG, *ciphertext_ptr, ciphertext_length); + return pos-output; +} + +void _olm_decode_group_message( + const uint8_t *input, size_t input_length, + size_t mac_length, size_t signature_length, + struct _OlmDecodeGroupMessageResults *results +) { + std::uint8_t const * pos = input; + std::size_t trailer_length = mac_length + signature_length; + std::uint8_t const * end = input + input_length - trailer_length; + std::uint8_t const * unknown = nullptr; + + bool has_message_index = false; + results->message_index = 0; + results->ciphertext = nullptr; + results->ciphertext_length = 0; + + if (input_length < trailer_length) return; + results->version = *(pos++); + + while (pos != end) { + pos = decode( + pos, end, GROUP_MESSAGE_INDEX_TAG, + results->message_index, has_message_index + ); + pos = decode( + pos, end, GROUP_CIPHERTEXT_TAG, + results->ciphertext, results->ciphertext_length + ); + if (unknown == pos) { + pos = skip_unknown(pos, end); + } + unknown = pos; + } + + results->has_message_index = (int)has_message_index; +} |