diff options
Diffstat (limited to 'src/olm.cpp')
-rw-r--r-- | src/olm.cpp | 201 |
1 files changed, 59 insertions, 142 deletions
diff --git a/src/olm.cpp b/src/olm.cpp index 63f3d83..d3af19c 100644 --- a/src/olm.cpp +++ b/src/olm.cpp @@ -12,12 +12,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "olm/olm.hh" +#include "olm/olm.h" #include "olm/session.hh" #include "olm/account.hh" +#include "olm/cipher.h" +#include "olm/pickle_encoding.h" #include "olm/utility.hh" #include "olm/base64.hh" -#include "olm/cipher.hh" #include "olm/memory.hh" #include <new> @@ -57,75 +58,6 @@ static std::uint8_t const * from_c(void const * bytes) { return reinterpret_cast<std::uint8_t const *>(bytes); } -static const std::uint8_t CIPHER_KDF_INFO[] = "Pickle"; - -static const olm::CipherAesSha256 PICKLE_CIPHER( - CIPHER_KDF_INFO, sizeof(CIPHER_KDF_INFO) -1 -); - -std::size_t enc_output_length( - size_t raw_length -) { - std::size_t length = PICKLE_CIPHER.encrypt_ciphertext_length(raw_length); - length += PICKLE_CIPHER.mac_length(); - return olm::encode_base64_length(length); -} - - -std::uint8_t * enc_output_pos( - std::uint8_t * output, - size_t raw_length -) { - std::size_t length = PICKLE_CIPHER.encrypt_ciphertext_length(raw_length); - length += PICKLE_CIPHER.mac_length(); - return output + olm::encode_base64_length(length) - length; -} - -std::size_t enc_output( - std::uint8_t const * key, std::size_t key_length, - std::uint8_t * output, size_t raw_length -) { - std::size_t ciphertext_length = PICKLE_CIPHER.encrypt_ciphertext_length( - raw_length - ); - std::size_t length = ciphertext_length + PICKLE_CIPHER.mac_length(); - std::size_t base64_length = olm::encode_base64_length(length); - std::uint8_t * raw_output = output + base64_length - length; - PICKLE_CIPHER.encrypt( - key, key_length, - raw_output, raw_length, - raw_output, ciphertext_length, - raw_output, length - ); - olm::encode_base64(raw_output, length, output); - return raw_length; -} - -std::size_t enc_input( - std::uint8_t const * key, std::size_t key_length, - std::uint8_t * input, size_t b64_length, - olm::ErrorCode & last_error -) { - std::size_t enc_length = olm::decode_base64_length(b64_length); - if (enc_length == std::size_t(-1)) { - last_error = olm::ErrorCode::INVALID_BASE64; - return std::size_t(-1); - } - olm::decode_base64(input, b64_length, input); - std::size_t raw_length = enc_length - PICKLE_CIPHER.mac_length(); - std::size_t result = PICKLE_CIPHER.decrypt( - key, key_length, - input, enc_length, - input, raw_length, - input, raw_length - ); - if (result == std::size_t(-1)) { - last_error = olm::ErrorCode::BAD_ACCOUNT_KEY; - } - return result; -} - - std::size_t b64_output_length( size_t raw_length ) { @@ -150,36 +82,27 @@ std::size_t b64_output( std::size_t b64_input( std::uint8_t * input, size_t b64_length, - olm::ErrorCode & last_error + OlmErrorCode & last_error ) { std::size_t raw_length = olm::decode_base64_length(b64_length); if (raw_length == std::size_t(-1)) { - last_error = olm::ErrorCode::INVALID_BASE64; + last_error = OlmErrorCode::OLM_INVALID_BASE64; return std::size_t(-1); } olm::decode_base64(input, b64_length, input); return raw_length; } -static const char * ERRORS[11] { - "SUCCESS", - "NOT_ENOUGH_RANDOM", - "OUTPUT_BUFFER_TOO_SMALL", - "BAD_MESSAGE_VERSION", - "BAD_MESSAGE_FORMAT", - "BAD_MESSAGE_MAC", - "BAD_MESSAGE_KEY_ID", - "INVALID_BASE64", - "BAD_ACCOUNT_KEY", - "UNKNOWN_PICKLE_VERSION", - "CORRUPTED_PICKLE", -}; - } // namespace extern "C" { +void olm_get_library_version(uint8_t *major, uint8_t *minor, uint8_t *patch) { + if (major != NULL) *major = OLMLIB_VERSION_MAJOR; + if (minor != NULL) *minor = OLMLIB_VERSION_MINOR; + if (patch != NULL) *patch = OLMLIB_VERSION_PATCH; +} size_t olm_error() { return std::size_t(-1); @@ -189,35 +112,23 @@ size_t olm_error() { const char * olm_account_last_error( OlmAccount * account ) { - unsigned error = unsigned(from_c(account)->last_error); - if (error < sizeof(ERRORS)) { - return ERRORS[error]; - } else { - return "UNKNOWN_ERROR"; - } + auto error = from_c(account)->last_error; + return _olm_error_to_string(error); } const char * olm_session_last_error( OlmSession * session ) { - unsigned error = unsigned(from_c(session)->last_error); - if (error < sizeof(ERRORS)) { - return ERRORS[error]; - } else { - return "UNKNOWN_ERROR"; - } + auto error = from_c(session)->last_error; + return _olm_error_to_string(error); } const char * olm_utility_last_error( OlmUtility * utility ) { - unsigned error = unsigned(from_c(utility)->last_error); - if (error < sizeof(ERRORS)) { - return ERRORS[error]; - } else { - return "UNKNOWN_ERROR"; - } + auto error = from_c(utility)->last_error; + return _olm_error_to_string(error); } size_t olm_account_size() { @@ -293,14 +204,14 @@ size_t olm_clear_utility( size_t olm_pickle_account_length( OlmAccount * account ) { - return enc_output_length(pickle_length(*from_c(account))); + return _olm_enc_output_length(pickle_length(*from_c(account))); } size_t olm_pickle_session_length( OlmSession * session ) { - return enc_output_length(pickle_length(*from_c(session))); + return _olm_enc_output_length(pickle_length(*from_c(session))); } @@ -311,12 +222,12 @@ size_t olm_pickle_account( ) { olm::Account & object = *from_c(account); std::size_t raw_length = pickle_length(object); - if (pickled_length < enc_output_length(raw_length)) { - object.last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + if (pickled_length < _olm_enc_output_length(raw_length)) { + object.last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL; return size_t(-1); } - pickle(enc_output_pos(from_c(pickled), raw_length), object); - return enc_output(from_c(key), key_length, from_c(pickled), raw_length); + pickle(_olm_enc_output_pos(from_c(pickled), raw_length), object); + return _olm_enc_output(from_c(key), key_length, from_c(pickled), raw_length); } @@ -327,12 +238,12 @@ size_t olm_pickle_session( ) { olm::Session & object = *from_c(session); std::size_t raw_length = pickle_length(object); - if (pickled_length < enc_output_length(raw_length)) { - object.last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + if (pickled_length < _olm_enc_output_length(raw_length)) { + object.last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL; return size_t(-1); } - pickle(enc_output_pos(from_c(pickled), raw_length), object); - return enc_output(from_c(key), key_length, from_c(pickled), raw_length); + pickle(_olm_enc_output_pos(from_c(pickled), raw_length), object); + return _olm_enc_output(from_c(key), key_length, from_c(pickled), raw_length); } @@ -343,8 +254,8 @@ size_t olm_unpickle_account( ) { olm::Account & object = *from_c(account); std::uint8_t * const pos = from_c(pickled); - std::size_t raw_length = enc_input( - from_c(key), key_length, pos, pickled_length, object.last_error + std::size_t raw_length = _olm_enc_input( + from_c(key), key_length, pos, pickled_length, &object.last_error ); if (raw_length == std::size_t(-1)) { return std::size_t(-1); @@ -355,8 +266,8 @@ size_t olm_unpickle_account( * (pos + raw_length). On error unpickle will return (pos + raw_length + 1). */ if (end != unpickle(pos, end + 1, object)) { - if (object.last_error == olm::ErrorCode::SUCCESS) { - object.last_error = olm::ErrorCode::CORRUPTED_PICKLE; + if (object.last_error == OlmErrorCode::OLM_SUCCESS) { + object.last_error = OlmErrorCode::OLM_CORRUPTED_PICKLE; } return std::size_t(-1); } @@ -371,8 +282,8 @@ size_t olm_unpickle_session( ) { olm::Session & object = *from_c(session); std::uint8_t * const pos = from_c(pickled); - std::size_t raw_length = enc_input( - from_c(key), key_length, pos, pickled_length, object.last_error + std::size_t raw_length = _olm_enc_input( + from_c(key), key_length, pos, pickled_length, &object.last_error ); if (raw_length == std::size_t(-1)) { return std::size_t(-1); @@ -384,8 +295,8 @@ size_t olm_unpickle_session( * (pos + raw_length). On error unpickle will return (pos + raw_length + 1). */ if (end != unpickle(pos, end + 1, object)) { - if (object.last_error == olm::ErrorCode::SUCCESS) { - object.last_error = olm::ErrorCode::CORRUPTED_PICKLE; + if (object.last_error == OlmErrorCode::OLM_SUCCESS) { + object.last_error = OlmErrorCode::OLM_CORRUPTED_PICKLE; } return std::size_t(-1); } @@ -442,7 +353,7 @@ size_t olm_account_sign( std::size_t raw_length = from_c(account)->signature_length(); if (signature_length < b64_output_length(raw_length)) { from_c(account)->last_error = - olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL; return std::size_t(-1); } from_c(account)->sign( @@ -525,14 +436,14 @@ size_t olm_create_outbound_session( std::size_t id_key_length = their_identity_key_length; std::size_t ot_key_length = their_one_time_key_length; - if (olm::decode_base64_length(id_key_length) != olm::KEY_LENGTH - || olm::decode_base64_length(ot_key_length) != olm::KEY_LENGTH + if (olm::decode_base64_length(id_key_length) != CURVE25519_KEY_LENGTH + || olm::decode_base64_length(ot_key_length) != CURVE25519_KEY_LENGTH ) { - from_c(session)->last_error = olm::ErrorCode::INVALID_BASE64; + from_c(session)->last_error = OlmErrorCode::OLM_INVALID_BASE64; return std::size_t(-1); } - olm::Curve25519PublicKey identity_key; - olm::Curve25519PublicKey one_time_key; + _olm_curve25519_public_key identity_key; + _olm_curve25519_public_key one_time_key; olm::decode_base64(id_key, id_key_length, identity_key.public_key); olm::decode_base64(ot_key, ot_key_length, one_time_key.public_key); @@ -572,11 +483,11 @@ size_t olm_create_inbound_session_from( std::uint8_t const * id_key = from_c(their_identity_key); std::size_t id_key_length = their_identity_key_length; - if (olm::decode_base64_length(id_key_length) != olm::KEY_LENGTH) { - from_c(session)->last_error = olm::ErrorCode::INVALID_BASE64; + if (olm::decode_base64_length(id_key_length) != CURVE25519_KEY_LENGTH) { + from_c(session)->last_error = OlmErrorCode::OLM_INVALID_BASE64; return std::size_t(-1); } - olm::Curve25519PublicKey identity_key; + _olm_curve25519_public_key identity_key; olm::decode_base64(id_key, id_key_length, identity_key.public_key); std::size_t raw_length = b64_input( @@ -605,7 +516,7 @@ size_t olm_session_id( std::size_t raw_length = from_c(session)->session_id_length(); if (id_length < b64_output_length(raw_length)) { from_c(session)->last_error = - olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL; return std::size_t(-1); } std::size_t result = from_c(session)->session_id( @@ -618,6 +529,12 @@ size_t olm_session_id( } +int olm_session_has_received_message( + OlmSession * session +) { + return from_c(session)->received_message; +} + size_t olm_matches_inbound_session( OlmSession * session, void * one_time_key_message, size_t message_length @@ -643,11 +560,11 @@ size_t olm_matches_inbound_session_from( std::uint8_t const * id_key = from_c(their_identity_key); std::size_t id_key_length = their_identity_key_length; - if (olm::decode_base64_length(id_key_length) != olm::KEY_LENGTH) { - from_c(session)->last_error = olm::ErrorCode::INVALID_BASE64; + if (olm::decode_base64_length(id_key_length) != CURVE25519_KEY_LENGTH) { + from_c(session)->last_error = OlmErrorCode::OLM_INVALID_BASE64; return std::size_t(-1); } - olm::Curve25519PublicKey identity_key; + _olm_curve25519_public_key identity_key; olm::decode_base64(id_key, id_key_length, identity_key.public_key); std::size_t raw_length = b64_input( @@ -671,7 +588,7 @@ size_t olm_remove_one_time_keys( from_c(session)->bob_one_time_key ); if (result == std::size_t(-1)) { - from_c(account)->last_error = olm::ErrorCode::BAD_MESSAGE_KEY_ID; + from_c(account)->last_error = OlmErrorCode::OLM_BAD_MESSAGE_KEY_ID; } return result; } @@ -712,7 +629,7 @@ size_t olm_encrypt( ); if (message_length < b64_output_length(raw_length)) { from_c(session)->last_error = - olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL; return std::size_t(-1); } std::size_t result = from_c(session)->encrypt( @@ -779,7 +696,7 @@ size_t olm_sha256( std::size_t raw_length = from_c(utility)->sha256_length(); if (output_length < b64_output_length(raw_length)) { from_c(utility)->last_error = - olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL; + OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL; return std::size_t(-1); } std::size_t result = from_c(utility)->sha256( @@ -799,11 +716,11 @@ size_t olm_ed25519_verify( void const * message, size_t message_length, void * signature, size_t signature_length ) { - if (olm::decode_base64_length(key_length) != olm::KEY_LENGTH) { - from_c(utility)->last_error = olm::ErrorCode::INVALID_BASE64; + if (olm::decode_base64_length(key_length) != CURVE25519_KEY_LENGTH) { + from_c(utility)->last_error = OlmErrorCode::OLM_INVALID_BASE64; return std::size_t(-1); } - olm::Ed25519PublicKey verify_key; + _olm_ed25519_public_key verify_key; olm::decode_base64(from_c(key), key_length, verify_key.public_key); std::size_t raw_signature_length = b64_input( from_c(signature), signature_length, from_c(utility)->last_error |