Implement the session key exchange
This commit is contained in:
parent
08a7e44a96
commit
6ecea67718
10 changed files with 369 additions and 25 deletions
|
@ -2,6 +2,8 @@
|
||||||
#define AXOLOTL_ACCOUNT_HH_
|
#define AXOLOTL_ACCOUNT_HH_
|
||||||
|
|
||||||
#include "axolotl/list.hh"
|
#include "axolotl/list.hh"
|
||||||
|
#include "axolotl/crypto.hh"
|
||||||
|
#include "axolotl/error.hh"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
@ -25,16 +27,21 @@ struct Account {
|
||||||
LocalKey identity_key;
|
LocalKey identity_key;
|
||||||
LocalKey last_resort_one_time_key;
|
LocalKey last_resort_one_time_key;
|
||||||
List<LocalKey, MAX_ONE_TIME_KEYS> one_time_keys;
|
List<LocalKey, MAX_ONE_TIME_KEYS> one_time_keys;
|
||||||
|
ErrorCode last_error;
|
||||||
|
|
||||||
/** Number of random bytes needed to create a new account */
|
/** Number of random bytes needed to create a new account */
|
||||||
std::size_t new_account_random_length();
|
std::size_t new_account_random_length();
|
||||||
|
|
||||||
/** Create a new account. Returns NOT_ENOUGH_RANDOM if the number of random
|
/** Create a new account. Returns NOT_ENOUGH_RANDOM if the number of random
|
||||||
* bytes is too small. */
|
* bytes is too small. */
|
||||||
ErrorCode new_account(
|
std::size_t new_account(
|
||||||
uint8_t const * random, std::size_t random_length
|
uint8_t const * random, std::size_t random_length
|
||||||
);
|
);
|
||||||
|
|
||||||
|
LocalKey const * lookup_key(
|
||||||
|
std::uint32_t id
|
||||||
|
);
|
||||||
|
|
||||||
/** The number of bytes needed to persist this account. */
|
/** The number of bytes needed to persist this account. */
|
||||||
std::size_t pickle_length();
|
std::size_t pickle_length();
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
#ifndef AXOLOTL_CRYPTO_HH_
|
||||||
|
#define AXOLOTL_CRYPTO_HH_
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
|
@ -141,3 +144,5 @@ void hkdf_sha256(
|
||||||
);
|
);
|
||||||
|
|
||||||
} // namespace axolotl
|
} // namespace axolotl
|
||||||
|
|
||||||
|
#endif /* AXOLOTL_CRYPTO_HH_ */
|
||||||
|
|
|
@ -10,6 +10,7 @@ enum struct ErrorCode {
|
||||||
BAD_MESSAGE_VERSION = 3, /*!< The message version is unsupported */
|
BAD_MESSAGE_VERSION = 3, /*!< The message version is unsupported */
|
||||||
BAD_MESSAGE_FORMAT = 4, /*!< The message couldn't be decoded */
|
BAD_MESSAGE_FORMAT = 4, /*!< The message couldn't be decoded */
|
||||||
BAD_MESSAGE_MAC = 5, /*!< The message couldn't be decrypted */
|
BAD_MESSAGE_MAC = 5, /*!< The message couldn't be decrypted */
|
||||||
|
BAD_MESSAGE_KEY_ID = 6, /*!< The message references an unknown key id */
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace axolotl
|
} // namespace axolotl
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
#ifndef AXOLOTL_LIST_HH_
|
||||||
|
#define AXOLOTL_LIST_HH_
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
namespace axolotl {
|
namespace axolotl {
|
||||||
|
@ -112,3 +115,5 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace axolotl
|
} // namespace axolotl
|
||||||
|
|
||||||
|
#endif /* AXOLOTL_LIST_HH_ */
|
||||||
|
|
|
@ -88,6 +88,7 @@ struct PreKeyMessageReader {
|
||||||
std::uint8_t const * message; std::size_t message_length;
|
std::uint8_t const * message; std::size_t message_length;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The length of the buffer needed to hold a message.
|
* The length of the buffer needed to hold a message.
|
||||||
*/
|
*/
|
||||||
|
@ -99,6 +100,7 @@ std::size_t encode_one_time_key_message_length(
|
||||||
std::size_t message_length
|
std::size_t message_length
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the message headers into the output buffer.
|
* Writes the message headers into the output buffer.
|
||||||
* Populates the writer struct with pointers into the output buffer.
|
* Populates the writer struct with pointers into the output buffer.
|
||||||
|
|
|
@ -5,14 +5,13 @@
|
||||||
|
|
||||||
namespace axolotl {
|
namespace axolotl {
|
||||||
|
|
||||||
|
class Account;
|
||||||
|
|
||||||
struct RemoteKey {
|
struct RemoteKey {
|
||||||
std::uint32_t id;
|
std::uint32_t id;
|
||||||
Curve25519PublicKey key;
|
Curve25519PublicKey key;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RemoteKeys {
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
enum struct MessageType {
|
enum struct MessageType {
|
||||||
PRE_KEY_MESSAGE = 0,
|
PRE_KEY_MESSAGE = 0,
|
||||||
|
@ -21,28 +20,34 @@ enum struct MessageType {
|
||||||
|
|
||||||
|
|
||||||
struct Session {
|
struct Session {
|
||||||
bool received_message;
|
|
||||||
RemoteKey alice_identity_key;
|
Session();
|
||||||
RemoteKey alice_base_key;
|
|
||||||
RemoteKey bob_identity_key;
|
|
||||||
RemoteKey bob_one_time_key;
|
|
||||||
Ratchet ratchet;
|
Ratchet ratchet;
|
||||||
|
ErrorCode last_error;
|
||||||
|
|
||||||
void initialise_outbound_session_random_length();
|
bool received_message;
|
||||||
|
|
||||||
void initialise_outbound_session(
|
RemoteKey alice_identity_key;
|
||||||
|
Curve25519PublicKey alice_base_key;
|
||||||
|
std::uint32_t bob_one_time_key_id;
|
||||||
|
|
||||||
|
|
||||||
|
std::size_t new_outbound_session_random_length();
|
||||||
|
|
||||||
|
std::size_t new_outbound_session(
|
||||||
Account const & local_account,
|
Account const & local_account,
|
||||||
RemoteKey const & identity_key,
|
Curve25519PublicKey const & identity_key,
|
||||||
RemoteKey const & one_time_key,
|
RemoteKey const & one_time_key,
|
||||||
std::uint8_t const * random, std::size_t random_length
|
std::uint8_t const * random, std::size_t random_length
|
||||||
);
|
);
|
||||||
|
|
||||||
void initialise_inbound_session(
|
std::size_t new_inbound_session(
|
||||||
Account & local_account,
|
Account & local_account,
|
||||||
std::uint8_t const * one_time_key_message, std::size_t message_length
|
std::uint8_t const * one_time_key_message, std::size_t message_length
|
||||||
);
|
);
|
||||||
|
|
||||||
void matches_inbound_session(
|
bool matches_inbound_session(
|
||||||
std::uint8_t const * one_time_key_message, std::size_t message_length
|
std::uint8_t const * one_time_key_message, std::size_t message_length
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ static void derive_keys(
|
||||||
std::uint8_t derived_secrets[80];
|
std::uint8_t derived_secrets[80];
|
||||||
axolotl::hkdf_sha256(
|
axolotl::hkdf_sha256(
|
||||||
key, key_length,
|
key, key_length,
|
||||||
NULL, 0,
|
nullptr, 0,
|
||||||
kdf_info, kdf_info_length,
|
kdf_info, kdf_info_length,
|
||||||
derived_secrets, sizeof(derived_secrets)
|
derived_secrets, sizeof(derived_secrets)
|
||||||
);
|
);
|
||||||
|
|
|
@ -198,15 +198,15 @@ void axolotl::decode_message(
|
||||||
) {
|
) {
|
||||||
std::uint8_t const * pos = input;
|
std::uint8_t const * pos = input;
|
||||||
std::uint8_t const * end = input + input_length - mac_length;
|
std::uint8_t const * end = input + input_length - mac_length;
|
||||||
std::uint8_t const * unknown = NULL;
|
std::uint8_t const * unknown = nullptr;
|
||||||
|
|
||||||
if (pos == end) return;
|
if (pos == end) return;
|
||||||
reader.version = *(pos++);
|
reader.version = *(pos++);
|
||||||
reader.input = input;
|
reader.input = input;
|
||||||
reader.input_length = input_length;
|
reader.input_length = input_length;
|
||||||
reader.has_counter = false;
|
reader.has_counter = false;
|
||||||
reader.ratchet_key = NULL;
|
reader.ratchet_key = nullptr;
|
||||||
reader.ciphertext = NULL;
|
reader.ciphertext = nullptr;
|
||||||
|
|
||||||
while (pos != end) {
|
while (pos != end) {
|
||||||
pos = decode(
|
pos = decode(
|
||||||
|
@ -283,15 +283,15 @@ void axolotl::decode_one_time_key_message(
|
||||||
) {
|
) {
|
||||||
std::uint8_t const * pos = input;
|
std::uint8_t const * pos = input;
|
||||||
std::uint8_t const * end = input + input_length;
|
std::uint8_t const * end = input + input_length;
|
||||||
std::uint8_t const * unknown = NULL;
|
std::uint8_t const * unknown = nullptr;
|
||||||
|
|
||||||
if (pos == end) return;
|
if (pos == end) return;
|
||||||
reader.version = *(pos++);
|
reader.version = *(pos++);
|
||||||
reader.has_registration_id = false;
|
reader.has_registration_id = false;
|
||||||
reader.has_one_time_key_id = false;
|
reader.has_one_time_key_id = false;
|
||||||
reader.identity_key = NULL;
|
reader.identity_key = nullptr;
|
||||||
reader.base_key = NULL;
|
reader.base_key = nullptr;
|
||||||
reader.message = NULL;
|
reader.message = nullptr;
|
||||||
|
|
||||||
while (pos != end) {
|
while (pos != end) {
|
||||||
pos = decode(
|
pos = decode(
|
||||||
|
|
|
@ -184,7 +184,7 @@ void axolotl::Ratchet::initialise_as_bob(
|
||||||
std::uint8_t derived_secrets[64];
|
std::uint8_t derived_secrets[64];
|
||||||
axolotl::hkdf_sha256(
|
axolotl::hkdf_sha256(
|
||||||
shared_secret, shared_secret_length,
|
shared_secret, shared_secret_length,
|
||||||
NULL, 0,
|
nullptr, 0,
|
||||||
kdf_info.root_info, kdf_info.root_info_length,
|
kdf_info.root_info, kdf_info.root_info_length,
|
||||||
derived_secrets, sizeof(derived_secrets)
|
derived_secrets, sizeof(derived_secrets)
|
||||||
);
|
);
|
||||||
|
@ -203,7 +203,7 @@ void axolotl::Ratchet::initialise_as_alice(
|
||||||
std::uint8_t derived_secrets[64];
|
std::uint8_t derived_secrets[64];
|
||||||
axolotl::hkdf_sha256(
|
axolotl::hkdf_sha256(
|
||||||
shared_secret, shared_secret_length,
|
shared_secret, shared_secret_length,
|
||||||
NULL, 0,
|
nullptr, 0,
|
||||||
kdf_info.root_info, kdf_info.root_info_length,
|
kdf_info.root_info, kdf_info.root_info_length,
|
||||||
derived_secrets, sizeof(derived_secrets)
|
derived_secrets, sizeof(derived_secrets)
|
||||||
);
|
);
|
||||||
|
@ -477,7 +477,7 @@ std::size_t axolotl::Ratchet::decrypt(
|
||||||
return std::size_t(-1);
|
return std::size_t(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReceiverChain * chain = NULL;
|
ReceiverChain * chain = nullptr;
|
||||||
for (axolotl::ReceiverChain & receiver_chain : receiver_chains) {
|
for (axolotl::ReceiverChain & receiver_chain : receiver_chains) {
|
||||||
if (0 == std::memcmp(
|
if (0 == std::memcmp(
|
||||||
receiver_chain.ratchet_key.public_key, reader.ratchet_key,
|
receiver_chain.ratchet_key.public_key, reader.ratchet_key,
|
||||||
|
|
319
src/session.cpp
Normal file
319
src/session.cpp
Normal file
|
@ -0,0 +1,319 @@
|
||||||
|
#include "axolotl/session.hh"
|
||||||
|
#include "axolotl/cipher.hh"
|
||||||
|
#include "axolotl/crypto.hh"
|
||||||
|
#include "axolotl/account.hh"
|
||||||
|
#include "axolotl/memory.hh"
|
||||||
|
#include "axolotl/message.hh"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
static const std::size_t KEY_LENGTH = 32;
|
||||||
|
static const std::uint8_t PROTOCOL_VERSION = 0x3;
|
||||||
|
|
||||||
|
static const std::uint8_t ROOT_KDF_INFO[] = "AXOLOTL_ROOT";
|
||||||
|
static const std::uint8_t RATCHET_KDF_INFO[] = "AXOLOTL_RATCHET";
|
||||||
|
static const std::uint8_t CIPHER_KDF_INFO[] = "AXOLOTL_KEYS";
|
||||||
|
|
||||||
|
static const axolotl::CipherAesSha256 AXOLOTL_CIPHER(
|
||||||
|
CIPHER_KDF_INFO, sizeof(CIPHER_KDF_INFO) -1
|
||||||
|
);
|
||||||
|
|
||||||
|
static const axolotl::KdfInfo AXOLOTL_KDF_INFO = {
|
||||||
|
ROOT_KDF_INFO, sizeof(ROOT_KDF_INFO) - 1,
|
||||||
|
RATCHET_KDF_INFO, sizeof(RATCHET_KDF_INFO) - 1
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
axolotl::Session::Session(
|
||||||
|
) : ratchet(AXOLOTL_KDF_INFO, AXOLOTL_CIPHER),
|
||||||
|
last_error(axolotl::ErrorCode::SUCCESS),
|
||||||
|
received_message(false),
|
||||||
|
bob_one_time_key_id(0) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::size_t axolotl::Session::new_outbound_session_random_length() {
|
||||||
|
return KEY_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::size_t axolotl::Session::new_outbound_session(
|
||||||
|
axolotl::Account const & local_account,
|
||||||
|
axolotl::Curve25519PublicKey const & identity_key,
|
||||||
|
axolotl::RemoteKey const & one_time_key,
|
||||||
|
std::uint8_t const * random, std::size_t random_length
|
||||||
|
) {
|
||||||
|
if (random_length < new_outbound_session_random_length()) {
|
||||||
|
last_error = axolotl::ErrorCode::NOT_ENOUGH_RANDOM;
|
||||||
|
return std::size_t(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Curve25519KeyPair base_key;
|
||||||
|
axolotl::generate_key(random, base_key);
|
||||||
|
|
||||||
|
received_message = false;
|
||||||
|
alice_identity_key.id = local_account.identity_key.id;
|
||||||
|
alice_identity_key.key = local_account.identity_key.key;
|
||||||
|
alice_base_key = base_key;
|
||||||
|
bob_one_time_key_id = one_time_key.id;
|
||||||
|
|
||||||
|
std::uint8_t shared_secret[160];
|
||||||
|
std::memset(shared_secret, 0xFF, 32);
|
||||||
|
|
||||||
|
axolotl::curve25519_shared_secret(
|
||||||
|
);
|
||||||
|
axolotl::curve25519_shared_secret(
|
||||||
|
base_key, identity_key, shared_secret + 64
|
||||||
|
);
|
||||||
|
axolotl::curve25519_shared_secret(
|
||||||
|
);
|
||||||
|
axolotl::curve25519_shared_secret(
|
||||||
|
base_key, one_time_key.key, shared_secret + 128
|
||||||
|
);
|
||||||
|
|
||||||
|
axolotl::unset(base_key);
|
||||||
|
axolotl::unset(shared_secret);
|
||||||
|
|
||||||
|
return std::size_t(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
bool check_message_fields(
|
||||||
|
axolotl::PreKeyMessageReader & reader
|
||||||
|
) {
|
||||||
|
bool ok = true;
|
||||||
|
ok = ok && reader.identity_key;
|
||||||
|
ok = ok && reader.identity_key_length == KEY_LENGTH;
|
||||||
|
ok = ok && reader.message;
|
||||||
|
ok = ok && reader.base_key;
|
||||||
|
ok = ok && reader.base_key_length == KEY_LENGTH;
|
||||||
|
ok = ok && reader.has_one_time_key_id;
|
||||||
|
ok = ok && reader.has_registration_id;
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
std::size_t axolotl::Session::new_inbound_session(
|
||||||
|
axolotl::Account & local_account,
|
||||||
|
std::uint8_t const * one_time_key_message, std::size_t message_length
|
||||||
|
) {
|
||||||
|
axolotl::PreKeyMessageReader reader;
|
||||||
|
decode_one_time_key_message(reader, one_time_key_message, message_length);
|
||||||
|
|
||||||
|
if (!check_message_fields(reader)) {
|
||||||
|
last_error = axolotl::ErrorCode::BAD_MESSAGE_FORMAT;
|
||||||
|
return std::size_t(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
alice_identity_key.id = reader.registration_id;
|
||||||
|
std::memcpy(alice_identity_key.key.public_key, reader.identity_key, 32);
|
||||||
|
std::memcpy(alice_base_key.public_key, reader.base_key, 32);
|
||||||
|
bob_one_time_key_id = reader.one_time_key_id;
|
||||||
|
|
||||||
|
|
||||||
|
axolotl::LocalKey const * bob_one_time_key = local_account.lookup_key(
|
||||||
|
bob_one_time_key_id
|
||||||
|
);
|
||||||
|
|
||||||
|
last_error = axolotl::ErrorCode::BAD_MESSAGE_KEY_ID;
|
||||||
|
return std::size_t(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint8_t shared_secret[160];
|
||||||
|
std::memset(shared_secret, 0xFF, 32);
|
||||||
|
|
||||||
|
axolotl::curve25519_shared_secret(
|
||||||
|
);
|
||||||
|
axolotl::curve25519_shared_secret(
|
||||||
|
local_account.identity_key.key, alice_base_key, shared_secret + 64
|
||||||
|
);
|
||||||
|
axolotl::curve25519_shared_secret(
|
||||||
|
);
|
||||||
|
axolotl::curve25519_shared_secret(
|
||||||
|
bob_one_time_key->key, alice_base_key, shared_secret + 128
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
return std::size_t(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool axolotl::Session::matches_inbound_session(
|
||||||
|
std::uint8_t const * one_time_key_message, std::size_t message_length
|
||||||
|
) {
|
||||||
|
axolotl::PreKeyMessageReader reader;
|
||||||
|
decode_one_time_key_message(reader, one_time_key_message, message_length);
|
||||||
|
|
||||||
|
if (!check_message_fields(reader)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool same = true;
|
||||||
|
same = same && 0 == std::memcmp(
|
||||||
|
reader.identity_key, alice_identity_key.key.public_key, KEY_LENGTH
|
||||||
|
);
|
||||||
|
same = same && 0 == std::memcmp(
|
||||||
|
reader.base_key, alice_base_key.public_key, KEY_LENGTH
|
||||||
|
);
|
||||||
|
same = same && reader.one_time_key_id == bob_one_time_key_id;
|
||||||
|
same = same && reader.registration_id == alice_identity_key.id;
|
||||||
|
return same;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
axolotl::MessageType axolotl::Session::encrypt_message_type() {
|
||||||
|
if (received_message) {
|
||||||
|
return axolotl::MessageType::MESSAGE;
|
||||||
|
} else {
|
||||||
|
return axolotl::MessageType::PRE_KEY_MESSAGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::size_t axolotl::Session::encrypt_message_length(
|
||||||
|
std::size_t plaintext_length
|
||||||
|
) {
|
||||||
|
std::size_t message_length = ratchet.encrypt_output_length(
|
||||||
|
plaintext_length
|
||||||
|
);
|
||||||
|
|
||||||
|
if (received_message) {
|
||||||
|
return message_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return encode_one_time_key_message_length(
|
||||||
|
alice_identity_key.id,
|
||||||
|
bob_one_time_key_id,
|
||||||
|
KEY_LENGTH,
|
||||||
|
KEY_LENGTH,
|
||||||
|
message_length
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::size_t axolotl::Session::encrypt_random_length() {
|
||||||
|
return ratchet.encrypt_random_length();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::size_t axolotl::Session::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
|
||||||
|
) {
|
||||||
|
if (message_length < encrypt_message_length(plaintext_length)) {
|
||||||
|
last_error = axolotl::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
|
||||||
|
return std::size_t(-1);
|
||||||
|
}
|
||||||
|
std::uint8_t * message_body;
|
||||||
|
std::size_t message_body_length = ratchet.encrypt_output_length(
|
||||||
|
plaintext_length
|
||||||
|
);
|
||||||
|
|
||||||
|
if (received_message) {
|
||||||
|
message_body = message;
|
||||||
|
} else {
|
||||||
|
axolotl::PreKeyMessageWriter writer;
|
||||||
|
encode_one_time_key_message(
|
||||||
|
writer,
|
||||||
|
PROTOCOL_VERSION,
|
||||||
|
alice_identity_key.id,
|
||||||
|
bob_one_time_key_id,
|
||||||
|
KEY_LENGTH,
|
||||||
|
KEY_LENGTH,
|
||||||
|
message_body_length,
|
||||||
|
message
|
||||||
|
);
|
||||||
|
std::memcpy(
|
||||||
|
writer.identity_key, alice_identity_key.key.public_key, KEY_LENGTH
|
||||||
|
);
|
||||||
|
std::memcpy(
|
||||||
|
writer.base_key, alice_base_key.public_key, KEY_LENGTH
|
||||||
|
);
|
||||||
|
message_body = writer.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t result = ratchet.encrypt(
|
||||||
|
plaintext, plaintext_length,
|
||||||
|
random, random_length,
|
||||||
|
message_body, message_body_length
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result == std::size_t(-1)) {
|
||||||
|
last_error = ratchet.last_error;
|
||||||
|
ratchet.last_error = axolotl::ErrorCode::SUCCESS;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::size_t axolotl::Session::decrypt_max_plaintext_length(
|
||||||
|
MessageType message_type,
|
||||||
|
std::uint8_t const * message, std::size_t message_length
|
||||||
|
) {
|
||||||
|
std::uint8_t const * message_body;
|
||||||
|
std::size_t message_body_length;
|
||||||
|
if (message_type == axolotl::MessageType::MESSAGE) {
|
||||||
|
message_body = message;
|
||||||
|
message_body_length = message_length;
|
||||||
|
} else {
|
||||||
|
axolotl::PreKeyMessageReader reader;
|
||||||
|
decode_one_time_key_message(reader, message, message_length);
|
||||||
|
if (!reader.message) {
|
||||||
|
last_error = axolotl::ErrorCode::BAD_MESSAGE_FORMAT;
|
||||||
|
return std::size_t(-1);
|
||||||
|
}
|
||||||
|
message_body = reader.message;
|
||||||
|
message_body_length = reader.message_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t result = ratchet.decrypt_max_plaintext_length(
|
||||||
|
message_body, message_body_length
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result == std::size_t(-1)) {
|
||||||
|
last_error = ratchet.last_error;
|
||||||
|
ratchet.last_error = axolotl::ErrorCode::SUCCESS;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::size_t axolotl::Session::decrypt(
|
||||||
|
axolotl::MessageType message_type,
|
||||||
|
std::uint8_t const * message, std::size_t message_length,
|
||||||
|
std::uint8_t * plaintext, std::size_t max_plaintext_length
|
||||||
|
) {
|
||||||
|
std::uint8_t const * message_body;
|
||||||
|
std::size_t message_body_length;
|
||||||
|
if (message_type == axolotl::MessageType::MESSAGE) {
|
||||||
|
message_body = message;
|
||||||
|
message_body_length = message_length;
|
||||||
|
} else {
|
||||||
|
axolotl::PreKeyMessageReader reader;
|
||||||
|
decode_one_time_key_message(reader, message, message_length);
|
||||||
|
if (!reader.message) {
|
||||||
|
last_error = axolotl::ErrorCode::BAD_MESSAGE_FORMAT;
|
||||||
|
return std::size_t(-1);
|
||||||
|
}
|
||||||
|
message_body = reader.message;
|
||||||
|
message_body_length = reader.message_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t result = ratchet.decrypt(
|
||||||
|
message_body, message_body_length, plaintext, max_plaintext_length
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result == std::size_t(-1)) {
|
||||||
|
last_error = ratchet.last_error;
|
||||||
|
ratchet.last_error = axolotl::ErrorCode::SUCCESS;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
Loading…
Reference in a new issue