From 39ad75314b9e28053f568ed6a4109f5d3a9468fe Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 18 May 2016 17:23:09 +0100 Subject: Implement decrypting inbound group messages Includes creation of inbound sessions, etc --- include/olm/error.h | 3 + include/olm/inbound_group_session.h | 153 ++++++++++++++++++++++++++++++++++++ include/olm/message.h | 24 ++++++ include/olm/olm.h | 1 + 4 files changed, 181 insertions(+) create mode 100644 include/olm/inbound_group_session.h (limited to 'include') diff --git a/include/olm/error.h b/include/olm/error.h index 87e019a..3f74992 100644 --- a/include/olm/error.h +++ b/include/olm/error.h @@ -32,6 +32,9 @@ enum OlmErrorCode { OLM_UNKNOWN_PICKLE_VERSION = 9, /*!< The pickled object is too new */ OLM_CORRUPTED_PICKLE = 10, /*!< The pickled object couldn't be decoded */ + OLM_BAD_RATCHET_KEY = 11, + OLM_BAD_CHAIN_INDEX = 12, + /* remember to update the list of string constants in error.c when updating * this list. */ }; diff --git a/include/olm/inbound_group_session.h b/include/olm/inbound_group_session.h new file mode 100644 index 0000000..4cf4ac4 --- /dev/null +++ b/include/olm/inbound_group_session.h @@ -0,0 +1,153 @@ +/* Copyright 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OLM_INBOUND_GROUP_SESSION_H_ +#define OLM_INBOUND_GROUP_SESSION_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct OlmInboundGroupSession OlmInboundGroupSession; + +/** get the size of an inbound group session, in bytes. */ +size_t olm_inbound_group_session_size(); + +/** + * Initialise an inbound group session object using the supplied memory + * The supplied memory should be at least olm_inbound_group_session_size() + * bytes. + */ +OlmInboundGroupSession * olm_inbound_group_session( + void *memory +); + +/** + * A null terminated string describing the most recent error to happen to a + * group session */ +const char *olm_inbound_group_session_last_error( + const OlmInboundGroupSession *session +); + +/** Clears the memory used to back this group session */ +size_t olm_clear_inbound_group_session( + OlmInboundGroupSession *session +); + +/** Returns the number of bytes needed to store an inbound group session */ +size_t olm_pickle_inbound_group_session_length( + const OlmInboundGroupSession *session +); + +/** + * Stores a group session as a base64 string. Encrypts the session using the + * supplied key. Returns the length of the session on success. + * + * Returns olm_error() on failure. If the pickle output buffer + * is smaller than olm_pickle_inbound_group_session_length() then + * olm_inbound_group_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" + */ +size_t olm_pickle_inbound_group_session( + OlmInboundGroupSession *session, + void const * key, size_t key_length, + void * pickled, size_t pickled_length +); + +/** + * Loads a group session from a pickled base64 string. Decrypts the session + * using the supplied key. + * + * Returns olm_error() on failure. If the key doesn't match the one used to + * encrypt the account then olm_inbound_group_session_last_error() will be + * "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then + * olm_inbound_group_session_last_error() will be "INVALID_BASE64". The input + * pickled buffer is destroyed + */ +size_t olm_unpickle_inbound_group_session( + OlmInboundGroupSession *session, + void const * key, size_t key_length, + void * pickled, size_t pickled_length +); + + +/** + * Start a new inbound group session, based on the parameters supplied. + * + * Returns olm_error() on failure. On failure last_error will be set with an + * error code. The last_error will be: + * + * * OLM_INVALID_BASE64 if the session_key is not valid base64 + * * OLM_BAD_RATCHET_KEY if the session_key is invalid + */ +size_t olm_init_inbound_group_session( + OlmInboundGroupSession *session, + uint32_t message_index, + + /* base64-encoded key */ + uint8_t const * session_key, size_t session_key_length +); + +/** + * Get an upper bound on the number of bytes of plain-text the decrypt method + * will write for a given input message length. The actual size could be + * different due to padding. + * + * The input message buffer is destroyed. + * + * Returns olm_error() on failure. + */ +size_t olm_group_decrypt_max_plaintext_length( + OlmInboundGroupSession *session, + uint8_t * message, size_t message_length +); + +/** + * Decrypt a message. + * + * The input message buffer is destroyed. + * + * Returns the length of the decrypted plain-text, or olm_error() on failure. + * + * On failure last_error will be set with an error code. The last_error will + * be: + * * OLM_OUTPUT_BUFFER_TOO_SMALL if the plain-text buffer is too small + * * OLM_INVALID_BASE64 if the message is not valid base-64 + * * OLM_BAD_MESSAGE_VERSION if the message was encrypted with an unsupported + * version of the protocol + * * OLM_BAD_MESSAGE_FORMAT if the message headers could not be decoded + * * OLM_BAD_MESSAGE_MAC if the message could not be verified + * * OLM_BAD_CHAIN_INDEX if we do not have a ratchet key corresponding to the + * message's index (ie, it was sent before the ratchet key was shared with + * us) + */ +size_t olm_group_decrypt( + OlmInboundGroupSession *session, + + /* input; note that it will be overwritten with the base64-decoded + message. */ + uint8_t * message, size_t message_length, + + /* output */ + uint8_t * plaintext, size_t max_plaintext_length +); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif /* OLM_INBOUND_GROUP_SESSION_H_ */ diff --git a/include/olm/message.h b/include/olm/message.h index 05fb56c..bd7aec3 100644 --- a/include/olm/message.h +++ b/include/olm/message.h @@ -65,6 +65,30 @@ void _olm_encode_group_message( ); +struct _OlmDecodeGroupMessageResults { + uint8_t version; + const uint8_t *session_id; + size_t session_id_length; + uint32_t chain_index; + int has_chain_index; + const uint8_t *ciphertext; + size_t ciphertext_length; +}; + + +/** + * Reads the message headers from the input buffer. + */ +void _olm_decode_group_message( + const uint8_t *input, size_t input_length, + size_t mac_length, + + /* output structure: updated with results */ + struct _OlmDecodeGroupMessageResults *results +); + + + #ifdef __cplusplus } // extern "C" #endif diff --git a/include/olm/olm.h b/include/olm/olm.h index 00e1f63..dbaf71e 100644 --- a/include/olm/olm.h +++ b/include/olm/olm.h @@ -19,6 +19,7 @@ #include #include +#include "olm/inbound_group_session.h" #include "olm/outbound_group_session.h" #ifdef __cplusplus -- cgit v1.2.3