aboutsummaryrefslogtreecommitdiff
path: root/src/session.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/session.cpp')
-rw-r--r--src/session.cpp173
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;
}
-