From 793b9b910a8f3c010a55433188e4b63414cbb314 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Thu, 11 Jun 2015 18:03:22 +0100 Subject: [PATCH] Start writing the interfaces for session and the account objects --- include/axolotl/account.hh | 57 ++++++++++++++++++++++++++++ include/axolotl/error.hh | 17 +++++++++ include/axolotl/ratchet.hh | 15 ++------ include/axolotl/session.hh | 78 ++++++++++++++++++++++++++++++++++++++ src/ratchet.cpp | 8 ++-- 5 files changed, 159 insertions(+), 16 deletions(-) create mode 100644 include/axolotl/account.hh create mode 100644 include/axolotl/error.hh create mode 100644 include/axolotl/session.hh diff --git a/include/axolotl/account.hh b/include/axolotl/account.hh new file mode 100644 index 0000000..5edb799 --- /dev/null +++ b/include/axolotl/account.hh @@ -0,0 +1,57 @@ +#ifndef AXOLOTL_ACCOUNT_HH_ +#define AXOLOTL_ACCOUNT_HH_ + +#include "axolotl/list.hh" + +#include + +namespace axolotl { + + +struct LocalKey { + std::uint32_t id; + Curve25519KeyPair key; +}; + + +struct SignedKey : LocalKey { + std::uint8_t signature[64]; +}; + + +static std::size_t const MAX_ONE_TIME_KEYS = 100; + +struct Account { + LocalKey identity_key; + LocalKey last_resort_one_time_key; + List one_time_keys; + + /** Number of random bytes needed to create a new account */ + std::size_t new_account_random_length(); + + /** Create a new account. Returns NOT_ENOUGH_RANDOM if the number of random + * bytes is too small. */ + ErrorCode new_account( + uint8_t const * random, std::size_t random_length + ); + + /** The number of bytes needed to persist this account. */ + std::size_t pickle_length(); + + /** Persists an account as a sequence of bytes + * Returns the number of output bytes used. */ + std::size_t pickle( + std::uint8_t * output, std::size_t output_length + ); + + /** Loads an account from a sequence of bytes. + * Returns 0 on success, or std::size_t(-1) on failure. */ + std::size_t unpickle( + std::uint8_t * input, std::size_t input_length + ); +}; + + +} // namespace axolotl + +#endif /* AXOLOTL_ACCOUNT_HH_ */ diff --git a/include/axolotl/error.hh b/include/axolotl/error.hh new file mode 100644 index 0000000..712b9eb --- /dev/null +++ b/include/axolotl/error.hh @@ -0,0 +1,17 @@ +#ifndef ERROR_HH_ +#define ERROR_HH_ + +namespace axolotl { + +enum struct ErrorCode { + SUCCESS = 0, /*!< There wasn't an error */ + NOT_ENOUGH_RANDOM = 1, /*!< Not enough entropy was supplied */ + OUTPUT_BUFFER_TOO_SMALL = 2, /*!< Supplied output buffer is too small */ + BAD_MESSAGE_VERSION = 3, /*!< The message version is unsupported */ + BAD_MESSAGE_FORMAT = 4, /*!< The message couldn't be decoded */ + BAD_MESSAGE_MAC = 5, /*!< The message couldn't be decrypted */ +}; + +} // namespace axolotl + +#endif /* ERROR_HH_ */ diff --git a/include/axolotl/ratchet.hh b/include/axolotl/ratchet.hh index d5053b2..f7d30d0 100644 --- a/include/axolotl/ratchet.hh +++ b/include/axolotl/ratchet.hh @@ -15,6 +15,7 @@ #include "axolotl/crypto.hh" #include "axolotl/list.hh" +#include "axolotl/error.hh" namespace axolotl { @@ -53,16 +54,6 @@ struct SkippedMessageKey { }; -enum struct ErrorCode { - SUCCESS = 0, /*!< There wasn't an error */ - NOT_ENOUGH_RANDOM = 1, /*!< Not enough entropy was supplied */ - OUTPUT_BUFFER_TOO_SMALL = 2, /*!< Supplied output buffer is too small */ - BAD_MESSAGE_VERSION = 3, /*!< The message version is unsupported */ - BAD_MESSAGE_FORMAT = 4, /*!< The message couldn't be decoded */ - BAD_MESSAGE_MAC = 5, /*!< The message couldn't be decrypted */ -}; - - static std::size_t const MAX_RECEIVER_CHAINS = 5; static std::size_t const MAX_SKIPPED_MESSAGE_KEYS = 40; @@ -124,12 +115,12 @@ struct Ratchet { ); /** The number of bytes needed to persist the current session. */ - std::size_t pickle_max_output_length(); + std::size_t pickle_length(); /** Persists a session as a sequence of bytes * Returns the number of output bytes used. */ std::size_t pickle( - std::uint8_t * output, std::size_t max_output_length + std::uint8_t * output, std::size_t output_length ); /** Loads a session from a sequence of bytes. diff --git a/include/axolotl/session.hh b/include/axolotl/session.hh new file mode 100644 index 0000000..c69699d --- /dev/null +++ b/include/axolotl/session.hh @@ -0,0 +1,78 @@ +#ifndef AXOLOTL_SESSION_HH_ +#define AXOLOTL_SESSION_HH_ + +#include "axolotl/ratchet.hh" + +namespace axolotl { + +struct RemoteKey { + std::uint32_t id; + Curve25519PublicKey key; +}; + +struct RemoteKeys { +}; + + +enum struct MessageType { + PRE_KEY_MESSAGE = 0, + MESSAGE = 1, +}; + + +struct Session { + bool received_message; + RemoteKey alice_identity_key; + RemoteKey alice_base_key; + RemoteKey bob_identity_key; + RemoteKey bob_one_time_key; + Ratchet ratchet; + + void initialise_outbound_session_random_length(); + + void initialise_outbound_session( + Account const & local_account, + RemoteKey const & identity_key, + RemoteKey const & one_time_key, + std::uint8_t const * random, std::size_t random_length + ); + + void initialise_inbound_session( + Account & local_account, + std::uint8_t const * one_time_key_message, std::size_t message_length + ); + + void matches_inbound_session( + std::uint8_t const * one_time_key_message, std::size_t message_length + ); + + MessageType encrypt_message_type(); + + std::size_t encrypt_message_length( + std::size_t plaintext_length + ); + + std::size_t encrypt_random_length(); + + std::size_t encrypt( + std::uint8_t const * plaintext, std::size_t plaintext_length, + std::uint8_t const * random, std::size_t random_length, + std::uint8_t * message, std::size_t message_length + ); + + std::size_t decrypt_max_plaintext_length( + MessageType message_type, + std::uint8_t const * message, std::size_t message_length + ); + + std::size_t decrypt( + MessageType message_type, + std::uint8_t const * message, std::size_t message_length, + std::uint8_t * plaintext, std::size_t max_plaintext_length + ); +}; + + +} // namespace axolotl + +#endif /* AXOLOTL_SESSION_HH_ */ diff --git a/src/ratchet.cpp b/src/ratchet.cpp index bdd0ba3..5097643 100644 --- a/src/ratchet.cpp +++ b/src/ratchet.cpp @@ -215,11 +215,11 @@ void axolotl::Ratchet::initialise_as_alice( } -std::size_t axolotl::Ratchet::pickle_max_output_length() { +std::size_t axolotl::Ratchet::pickle_length() { std::size_t counter_length = 4; std::size_t send_chain_length = counter_length + 64 + 32; std::size_t recv_chain_length = counter_length + 32 + 32; - std::size_t skip_key_length = counter_length + 32 + 32 + 32 + 16; + std::size_t skip_key_length = counter_length + 32 + 32; std::size_t pickle_length = 3 * counter_length + 32; pickle_length += sender_chain.size() * send_chain_length; pickle_length += receiver_chains.size() * recv_chain_length; @@ -265,10 +265,10 @@ std::uint8_t * unpickle_bytes( std::size_t axolotl::Ratchet::pickle( - std::uint8_t * output, std::size_t max_output_length + std::uint8_t * output, std::size_t output_length ) { std::uint8_t * pos = output; - if (max_output_length < pickle_max_output_length()) { + if (output_length < pickle_length()) { last_error = axolotl::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; return std::size_t(-1); }