diff options
Diffstat (limited to 'src/session.cpp')
-rw-r--r-- | src/session.cpp | 173 |
1 files changed, 96 insertions, 77 deletions
diff --git a/src/session.cpp b/src/session.cpp index 71c80e4..f1bc5a7 100644 --- a/src/session.cpp +++ b/src/session.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. @@ -13,8 +13,8 @@ * limitations under the License. */ #include "olm/session.hh" -#include "olm/cipher.hh" -#include "olm/crypto.hh" +#include "olm/cipher.h" +#include "olm/crypto.h" #include "olm/account.hh" #include "olm/memory.hh" #include "olm/message.hh" @@ -30,64 +30,64 @@ static const std::uint8_t ROOT_KDF_INFO[] = "OLM_ROOT"; static const std::uint8_t RATCHET_KDF_INFO[] = "OLM_RATCHET"; static const std::uint8_t CIPHER_KDF_INFO[] = "OLM_KEYS"; -static const olm::CipherAesSha256 OLM_CIPHER( - CIPHER_KDF_INFO, sizeof(CIPHER_KDF_INFO) -1 -); - static const olm::KdfInfo OLM_KDF_INFO = { ROOT_KDF_INFO, sizeof(ROOT_KDF_INFO) - 1, RATCHET_KDF_INFO, sizeof(RATCHET_KDF_INFO) - 1 }; +static const struct _olm_cipher_aes_sha_256 OLM_CIPHER = + OLM_CIPHER_INIT_AES_SHA_256(CIPHER_KDF_INFO); + } // namespace olm::Session::Session( -) : ratchet(OLM_KDF_INFO, OLM_CIPHER), - last_error(olm::ErrorCode::SUCCESS), +) : ratchet(OLM_KDF_INFO, OLM_CIPHER_BASE(&OLM_CIPHER)), + last_error(OlmErrorCode::OLM_SUCCESS), received_message(false) { } std::size_t olm::Session::new_outbound_session_random_length() { - return olm::KEY_LENGTH * 2; + return CURVE25519_RANDOM_LENGTH * 2; } std::size_t olm::Session::new_outbound_session( olm::Account const & local_account, - olm::Curve25519PublicKey const & identity_key, - olm::Curve25519PublicKey const & one_time_key, + _olm_curve25519_public_key const & identity_key, + _olm_curve25519_public_key const & one_time_key, std::uint8_t const * random, std::size_t random_length ) { if (random_length < new_outbound_session_random_length()) { - last_error = olm::ErrorCode::NOT_ENOUGH_RANDOM; + last_error = OlmErrorCode::OLM_NOT_ENOUGH_RANDOM; return std::size_t(-1); } - olm::Curve25519KeyPair base_key; - olm::curve25519_generate_key(random, base_key); + _olm_curve25519_key_pair base_key; + _olm_crypto_curve25519_generate_key(random, &base_key); - olm::Curve25519KeyPair ratchet_key; - olm::curve25519_generate_key(random + olm::KEY_LENGTH, ratchet_key); + _olm_curve25519_key_pair ratchet_key; + _olm_crypto_curve25519_generate_key(random + CURVE25519_RANDOM_LENGTH, &ratchet_key); - olm::Curve25519KeyPair const & alice_identity_key_pair = ( + _olm_curve25519_key_pair const & alice_identity_key_pair = ( local_account.identity_keys.curve25519_key ); received_message = false; - alice_identity_key = alice_identity_key_pair; - alice_base_key = base_key; + alice_identity_key = alice_identity_key_pair.public_key; + alice_base_key = base_key.public_key; bob_one_time_key = one_time_key; - std::uint8_t secret[3 * olm::KEY_LENGTH]; + // Calculate the shared secret S via triple DH + std::uint8_t secret[3 * CURVE25519_SHARED_SECRET_LENGTH]; std::uint8_t * pos = secret; - olm::curve25519_shared_secret(alice_identity_key_pair, one_time_key, pos); - pos += olm::KEY_LENGTH; - olm::curve25519_shared_secret(base_key, identity_key, pos); - pos += olm::KEY_LENGTH; - olm::curve25519_shared_secret(base_key, one_time_key, pos); + _olm_crypto_curve25519_shared_secret(&alice_identity_key_pair, &one_time_key, pos); + pos += CURVE25519_SHARED_SECRET_LENGTH; + _olm_crypto_curve25519_shared_secret(&base_key, &identity_key, pos); + pos += CURVE25519_SHARED_SECRET_LENGTH; + _olm_crypto_curve25519_shared_secret(&base_key, &one_time_key, pos); ratchet.initialise_as_alice(secret, sizeof(secret), ratchet_key); @@ -106,13 +106,13 @@ static bool check_message_fields( bool ok = true; ok = ok && (have_their_identity_key || reader.identity_key); if (reader.identity_key) { - ok = ok && reader.identity_key_length == olm::KEY_LENGTH; + ok = ok && reader.identity_key_length == CURVE25519_KEY_LENGTH; } ok = ok && reader.message; ok = ok && reader.base_key; - ok = ok && reader.base_key_length == olm::KEY_LENGTH; + ok = ok && reader.base_key_length == CURVE25519_KEY_LENGTH; ok = ok && reader.one_time_key; - ok = ok && reader.one_time_key_length == olm::KEY_LENGTH; + ok = ok && reader.one_time_key_length == CURVE25519_KEY_LENGTH; return ok; } @@ -121,43 +121,44 @@ static bool check_message_fields( std::size_t olm::Session::new_inbound_session( olm::Account & local_account, - olm::Curve25519PublicKey const * their_identity_key, + _olm_curve25519_public_key const * their_identity_key, std::uint8_t const * one_time_key_message, std::size_t message_length ) { olm::PreKeyMessageReader reader; decode_one_time_key_message(reader, one_time_key_message, message_length); if (!check_message_fields(reader, their_identity_key)) { - last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT; + last_error = OlmErrorCode::OLM_BAD_MESSAGE_FORMAT; return std::size_t(-1); } if (reader.identity_key && their_identity_key) { bool same = 0 == std::memcmp( - their_identity_key->public_key, reader.identity_key, olm::KEY_LENGTH + their_identity_key->public_key, reader.identity_key, CURVE25519_KEY_LENGTH ); if (!same) { - last_error = olm::ErrorCode::BAD_MESSAGE_KEY_ID; + last_error = OlmErrorCode::OLM_BAD_MESSAGE_KEY_ID; return std::size_t(-1); } } + olm::load_array(alice_identity_key.public_key, reader.identity_key); + olm::load_array(alice_base_key.public_key, reader.base_key); + olm::load_array(bob_one_time_key.public_key, reader.one_time_key); + olm::MessageReader message_reader; decode_message( message_reader, reader.message, reader.message_length, - ratchet.ratchet_cipher.mac_length() + ratchet.ratchet_cipher->ops->mac_length(ratchet.ratchet_cipher) ); if (!message_reader.ratchet_key - || message_reader.ratchet_key_length != olm::KEY_LENGTH) { - last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT; + || message_reader.ratchet_key_length != CURVE25519_KEY_LENGTH) { + last_error = OlmErrorCode::OLM_BAD_MESSAGE_FORMAT; return std::size_t(-1); } - olm::load_array(alice_identity_key.public_key, reader.identity_key); - olm::load_array(alice_base_key.public_key, reader.base_key); - olm::load_array(bob_one_time_key.public_key, reader.one_time_key); - olm::Curve25519PublicKey ratchet_key; + _olm_curve25519_public_key ratchet_key; olm::load_array(ratchet_key.public_key, message_reader.ratchet_key); olm::OneTimeKey const * our_one_time_key = local_account.lookup_key( @@ -165,32 +166,34 @@ std::size_t olm::Session::new_inbound_session( ); if (!our_one_time_key) { - last_error = olm::ErrorCode::BAD_MESSAGE_KEY_ID; + last_error = OlmErrorCode::OLM_BAD_MESSAGE_KEY_ID; return std::size_t(-1); } - olm::Curve25519KeyPair const & bob_identity_key = ( + _olm_curve25519_key_pair const & bob_identity_key = ( local_account.identity_keys.curve25519_key ); - olm::Curve25519KeyPair const & bob_one_time_key = our_one_time_key->key; + _olm_curve25519_key_pair const & bob_one_time_key = our_one_time_key->key; - std::uint8_t secret[olm::KEY_LENGTH * 3]; + // Calculate the shared secret S via triple DH + std::uint8_t secret[CURVE25519_SHARED_SECRET_LENGTH * 3]; std::uint8_t * pos = secret; - olm::curve25519_shared_secret(bob_one_time_key, alice_identity_key, pos); - pos += olm::KEY_LENGTH; - olm::curve25519_shared_secret(bob_identity_key, alice_base_key, pos); - pos += olm::KEY_LENGTH; - olm::curve25519_shared_secret(bob_one_time_key, alice_base_key, pos); + _olm_crypto_curve25519_shared_secret(&bob_one_time_key, &alice_identity_key, pos); + pos += CURVE25519_SHARED_SECRET_LENGTH; + _olm_crypto_curve25519_shared_secret(&bob_identity_key, &alice_base_key, pos); + pos += CURVE25519_SHARED_SECRET_LENGTH; + _olm_crypto_curve25519_shared_secret(&bob_one_time_key, &alice_base_key, pos); ratchet.initialise_as_bob(secret, sizeof(secret), ratchet_key); olm::unset(secret); + return std::size_t(0); } std::size_t olm::Session::session_id_length() { - return olm::SHA256_OUTPUT_LENGTH; + return SHA256_OUTPUT_LENGTH; } @@ -198,21 +201,21 @@ std::size_t olm::Session::session_id( std::uint8_t * id, std::size_t id_length ) { if (id_length < session_id_length()) { - last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL; return std::size_t(-1); } - std::uint8_t tmp[olm::KEY_LENGTH * 3]; + std::uint8_t tmp[CURVE25519_KEY_LENGTH * 3]; std::uint8_t * pos = tmp; pos = olm::store_array(pos, alice_identity_key.public_key); pos = olm::store_array(pos, alice_base_key.public_key); pos = olm::store_array(pos, bob_one_time_key.public_key); - olm::sha256(tmp, sizeof(tmp), id); + _olm_crypto_sha256(tmp, sizeof(tmp), id); return session_id_length(); } bool olm::Session::matches_inbound_session( - olm::Curve25519PublicKey const * their_identity_key, + _olm_curve25519_public_key const * their_identity_key, std::uint8_t const * one_time_key_message, std::size_t message_length ) { olm::PreKeyMessageReader reader; @@ -225,20 +228,20 @@ bool olm::Session::matches_inbound_session( bool same = true; if (reader.identity_key) { same = same && 0 == std::memcmp( - reader.identity_key, alice_identity_key.public_key, olm::KEY_LENGTH + reader.identity_key, alice_identity_key.public_key, CURVE25519_KEY_LENGTH ); } if (their_identity_key) { same = same && 0 == std::memcmp( their_identity_key->public_key, alice_identity_key.public_key, - olm::KEY_LENGTH + CURVE25519_KEY_LENGTH ); } same = same && 0 == std::memcmp( - reader.base_key, alice_base_key.public_key, olm::KEY_LENGTH + reader.base_key, alice_base_key.public_key, CURVE25519_KEY_LENGTH ); same = same && 0 == std::memcmp( - reader.one_time_key, bob_one_time_key.public_key, olm::KEY_LENGTH + reader.one_time_key, bob_one_time_key.public_key, CURVE25519_KEY_LENGTH ); return same; } @@ -265,9 +268,9 @@ std::size_t olm::Session::encrypt_message_length( } return encode_one_time_key_message_length( - olm::KEY_LENGTH, - olm::KEY_LENGTH, - olm::KEY_LENGTH, + CURVE25519_KEY_LENGTH, + CURVE25519_KEY_LENGTH, + CURVE25519_KEY_LENGTH, message_length ); } @@ -284,7 +287,7 @@ std::size_t olm::Session::encrypt( std::uint8_t * message, std::size_t message_length ) { if (message_length < encrypt_message_length(plaintext_length)) { - last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL; return std::size_t(-1); } std::uint8_t * message_body; @@ -299,9 +302,9 @@ std::size_t olm::Session::encrypt( encode_one_time_key_message( writer, PROTOCOL_VERSION, - olm::KEY_LENGTH, - olm::KEY_LENGTH, - olm::KEY_LENGTH, + CURVE25519_KEY_LENGTH, + CURVE25519_KEY_LENGTH, + CURVE25519_KEY_LENGTH, message_body_length, message ); @@ -319,8 +322,10 @@ std::size_t olm::Session::encrypt( if (result == std::size_t(-1)) { last_error = ratchet.last_error; - ratchet.last_error = olm::ErrorCode::SUCCESS; + ratchet.last_error = OlmErrorCode::OLM_SUCCESS; + return result; } + return result; } @@ -338,7 +343,7 @@ std::size_t olm::Session::decrypt_max_plaintext_length( olm::PreKeyMessageReader reader; decode_one_time_key_message(reader, message, message_length); if (!reader.message) { - last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT; + last_error = OlmErrorCode::OLM_BAD_MESSAGE_FORMAT; return std::size_t(-1); } message_body = reader.message; @@ -351,7 +356,7 @@ std::size_t olm::Session::decrypt_max_plaintext_length( if (result == std::size_t(-1)) { last_error = ratchet.last_error; - ratchet.last_error = olm::ErrorCode::SUCCESS; + ratchet.last_error = OlmErrorCode::OLM_SUCCESS; } return result; } @@ -371,7 +376,7 @@ std::size_t olm::Session::decrypt( olm::PreKeyMessageReader reader; decode_one_time_key_message(reader, message, message_length); if (!reader.message) { - last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT; + last_error = OlmErrorCode::OLM_BAD_MESSAGE_FORMAT; return std::size_t(-1); } message_body = reader.message; @@ -384,14 +389,17 @@ std::size_t olm::Session::decrypt( if (result == std::size_t(-1)) { last_error = ratchet.last_error; - ratchet.last_error = olm::ErrorCode::SUCCESS; - } else { - received_message = true; + ratchet.last_error = OlmErrorCode::OLM_SUCCESS; + return result; } + + received_message = true; return result; } namespace { +// the master branch writes pickle version 1; the logging_enabled branch writes +// 0x80000001. static const std::uint32_t SESSION_PICKLE_VERSION = 1; } @@ -429,15 +437,26 @@ std::uint8_t const * olm::unpickle( ) { 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; + + bool includes_chain_index; + switch (pickle_version) { + case 1: + includes_chain_index = false; + break; + + case 0x80000001UL: + includes_chain_index = true; + break; + + default: + value.last_error = OlmErrorCode::OLM_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); pos = olm::unpickle(pos, end, value.bob_one_time_key); - pos = olm::unpickle(pos, end, value.ratchet); + pos = olm::unpickle(pos, end, value.ratchet, includes_chain_index); return pos; } - |