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