aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile10
-rw-r--r--include/olm/account.hh4
-rw-r--r--include/olm/base64.h77
-rw-r--r--include/olm/cipher.h138
-rw-r--r--include/olm/cipher.hh132
-rw-r--r--include/olm/crypto.h65
-rw-r--r--include/olm/crypto.hh37
-rw-r--r--include/olm/error.h40
-rw-r--r--include/olm/error.hh36
-rw-r--r--include/olm/memory.h41
-rw-r--r--include/olm/olm.h423
-rw-r--r--include/olm/olm.hh424
-rw-r--r--include/olm/pickle.h50
-rw-r--r--include/olm/ratchet.hh12
-rw-r--r--include/olm/session.hh2
-rw-r--r--include/olm/utility.hh4
-rw-r--r--python/.gitignore3
-rwxr-xr-xpython/olm.py542
-rw-r--r--python/olm/__init__.py2
-rwxr-xr-xpython/olm/__main__.py210
-rw-r--r--python/olm/_base.py19
-rw-r--r--python/olm/account.py121
-rw-r--r--python/olm/session.py192
-rwxr-xr-xpython/test_olm.sh2
-rw-r--r--src/account.cpp14
-rw-r--r--src/base64.cpp33
-rw-r--r--src/cipher.cpp89
-rw-r--r--src/crypto.cpp22
-rw-r--r--src/memory.cpp6
-rw-r--r--src/message.cpp4
-rw-r--r--src/olm.cpp83
-rw-r--r--src/pickle.cpp35
-rw-r--r--src/ratchet.cpp60
-rw-r--r--src/session.cpp45
-rw-r--r--src/utility.cpp14
-rw-r--r--tests/test_base64.cpp38
-rw-r--r--tests/test_crypto.cpp8
-rw-r--r--tests/test_olm.cpp2
-rw-r--r--tests/test_olm_decrypt.cpp4
-rw-r--r--tests/test_olm_sha256.cpp2
-rw-r--r--tests/test_olm_signature.cpp2
-rw-r--r--tests/test_olm_using_malloc.cpp2
-rw-r--r--tests/test_ratchet.cpp11
43 files changed, 1702 insertions, 1358 deletions
diff --git a/Makefile b/Makefile
index 1ea5bb4..8594946 100644
--- a/Makefile
+++ b/Makefile
@@ -15,7 +15,7 @@ JS_TARGET := javascript/olm.js
JS_EXPORTED_FUNCTIONS := javascript/exported_functions.json
-PUBLIC_HEADERS := include/olm/olm.hh
+PUBLIC_HEADERS := include/olm/olm.h
SOURCES := $(wildcard src/*.cpp) $(wildcard src/*.c)
RELEASE_OBJECTS := $(patsubst src/%,$(BUILD_DIR)/release/%,$(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCES))))
@@ -31,9 +31,9 @@ JS_PRE := $(wildcard javascript/*pre.js)
JS_POST := $(wildcard javascript/*post.js)
CPPFLAGS += -Iinclude -Ilib
-CFLAGS += -Wall -std=c89 -fPIC
-CXXFLAGS += -Wall -std=c++11 -fPIC
-LDFLAGS += -Wall
+CFLAGS += -Wall -Werror -std=c89 -fPIC
+CXXFLAGS += -Wall -Werror -std=c++11 -fPIC
+LDFLAGS += -Wall -Werror
EMCCFLAGS = --closure 1 --memory-init-file 0 -s NO_FILESYSTEM=1 -s INVOKE_RUN=0
# NO_BROWSER is kept for compatibility with emscripten 1.35.24, but is no
@@ -63,7 +63,7 @@ $(DEBUG_OBJECTS): CXXFLAGS += $(DEBUG_OPTIMIZE_FLAGS)
$(DEBUG_TARGET): LDFLAGS += $(DEBUG_OPTIMIZE_FLAGS)
$(TEST_BINARIES): CPPFLAGS += -Itests/include
-$(TEST_BINARIES): LDFLAGS += $(TEST_OPTIMIZE_FLAGS) -L$(BUILD_DIR)
+$(TEST_BINARIES): LDFLAGS += $(DEBUG_OPTIMIZE_FLAGS) -L$(BUILD_DIR)
$(FUZZER_OBJECTS): CFLAGS += $(FUZZER_OPTIMIZE_FLAGS)
$(FUZZER_OBJECTS): CXXFLAGS += $(FUZZER_OPTIMIZE_FLAGS)
diff --git a/include/olm/account.hh b/include/olm/account.hh
index 209139a..6ea0d19 100644
--- a/include/olm/account.hh
+++ b/include/olm/account.hh
@@ -17,7 +17,7 @@
#include "olm/list.hh"
#include "olm/crypto.hh"
-#include "olm/error.hh"
+#include "olm/error.h"
#include <cstdint>
@@ -44,7 +44,7 @@ struct Account {
IdentityKeys identity_keys;
List<OneTimeKey, MAX_ONE_TIME_KEYS> one_time_keys;
std::uint32_t next_one_time_key_id;
- ErrorCode last_error;
+ OlmErrorCode last_error;
/** Number of random bytes needed to create a new account */
std::size_t new_account_random_length();
diff --git a/include/olm/base64.h b/include/olm/base64.h
new file mode 100644
index 0000000..80384a8
--- /dev/null
+++ b/include/olm/base64.h
@@ -0,0 +1,77 @@
+/* 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* C bindings for base64 functions */
+
+
+#ifndef OLM_BASE64_H_
+#define OLM_BASE64_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * The number of bytes of unpadded base64 needed to encode a length of input.
+ */
+size_t _olm_encode_base64_length(
+ size_t input_length
+);
+
+/**
+ * Encode the raw input as unpadded base64.
+ * Writes encode_base64_length(input_length) bytes to the output buffer.
+ * The input can overlap with the last three quarters of the output buffer.
+ * That is, the input pointer may be output + output_length - input_length.
+ *
+ * Returns number of bytes encoded
+ */
+size_t _olm_encode_base64(
+ uint8_t const * input, size_t input_length,
+ uint8_t * output
+);
+
+/**
+ * The number of bytes of raw data a length of unpadded base64 will encode to.
+ * Returns size_t(-1) if the length is not a valid length for base64.
+ */
+size_t _olm_decode_base64_length(
+ size_t input_length
+);
+
+/**
+ * Decodes the unpadded base64 input to raw bytes.
+ * Writes decode_base64_length(input_length) bytes to the output buffer.
+ * The output can overlap with the first three quarters of the input buffer.
+ * That is, the input pointers and output pointer may be the same.
+ *
+ * Returns number of bytes decoded
+ */
+size_t _olm_decode_base64(
+ uint8_t const * input, size_t input_length,
+ uint8_t * output
+);
+
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+
+#endif /* OLM_BASE64_H_ */
diff --git a/include/olm/cipher.h b/include/olm/cipher.h
new file mode 100644
index 0000000..b26f8ba
--- /dev/null
+++ b/include/olm/cipher.h
@@ -0,0 +1,138 @@
+/* Copyright 2015 OpenMarket Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OLM_CIPHER_H_
+#define OLM_CIPHER_H_
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct _olm_cipher;
+
+struct _olm_cipher_ops {
+ /**
+ * Returns the length of the message authentication code that will be
+ * appended to the output.
+ */
+ size_t (*mac_length)(const struct _olm_cipher *cipher);
+
+ /**
+ * Returns the length of cipher-text for a given length of plain-text.
+ */
+ size_t (*encrypt_ciphertext_length)(
+ const struct _olm_cipher *cipher,
+ size_t plaintext_length
+ );
+
+ /*
+ * Encrypts the plain-text into the output buffer and authenticates the
+ * contents of the output buffer covering both cipher-text and any other
+ * associated data in the output buffer.
+ *
+ * |---------------------------------------output_length-->|
+ * output |--ciphertext_length-->| |---mac_length-->|
+ * ciphertext
+ *
+ * The plain-text pointers and cipher-text pointers may be the same.
+ *
+ * Returns size_t(-1) if the length of the cipher-text or the output
+ * buffer is too small. Otherwise returns the length of the output buffer.
+ */
+ size_t (*encrypt)(
+ const struct _olm_cipher *cipher,
+ uint8_t const * key, size_t key_length,
+ uint8_t const * plaintext, size_t plaintext_length,
+ uint8_t * ciphertext, size_t ciphertext_length,
+ uint8_t * output, size_t output_length
+ );
+
+ /**
+ * Returns the maximum length of plain-text that a given length of
+ * cipher-text can contain.
+ */
+ size_t (*decrypt_max_plaintext_length)(
+ const struct _olm_cipher *cipher,
+ size_t ciphertext_length
+ );
+
+ /**
+ * Authenticates the input and decrypts the cipher-text into the plain-text
+ * buffer.
+ *
+ * |----------------------------------------input_length-->|
+ * input |--ciphertext_length-->| |---mac_length-->|
+ * ciphertext
+ *
+ * The plain-text pointers and cipher-text pointers may be the same.
+ *
+ * Returns size_t(-1) if the length of the plain-text buffer is too
+ * small or if the authentication check fails. Otherwise returns the length
+ * of the plain text.
+ */
+ size_t (*decrypt)(
+ const struct _olm_cipher *cipher,
+ uint8_t const * key, size_t key_length,
+ uint8_t const * input, size_t input_length,
+ uint8_t const * ciphertext, size_t ciphertext_length,
+ uint8_t * plaintext, size_t max_plaintext_length
+ );
+};
+
+struct _olm_cipher {
+ const struct _olm_cipher_ops *ops;
+ /* cipher-specific fields follow */
+};
+
+struct _olm_cipher_aes_sha_256 {
+ struct _olm_cipher base_cipher;
+
+ /** context string for the HKDF used for deriving the AES256 key, HMAC key,
+ * and AES IV, from the key material passed to encrypt/decrypt.
+ */
+ uint8_t const * kdf_info;
+
+ /** length of context string kdf_info */
+ size_t kdf_info_length;
+};
+
+extern const struct _olm_cipher_ops _olm_cipher_aes_sha_256_ops;
+
+/**
+ * get an initializer for an instance of struct _olm_cipher_aes_sha_256.
+ *
+ * To use it, declare:
+ *
+ * struct _olm_cipher_aes_sha_256 MY_CIPHER =
+ * OLM_CIPHER_INIT_AES_SHA_256("MY_KDF");
+ * struct _olm_cipher *cipher = OLM_CIPHER_BASE(&MY_CIPHER);
+ */
+#define OLM_CIPHER_INIT_AES_SHA_256(KDF_INFO) { \
+ .base_cipher = { &_olm_cipher_aes_sha_256_ops },\
+ .kdf_info = (uint8_t *)(KDF_INFO), \
+ .kdf_info_length = sizeof(KDF_INFO) - 1 \
+}
+#define OLM_CIPHER_BASE(CIPHER) \
+ (&((CIPHER)->base_cipher))
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* OLM_CIPHER_H_ */
diff --git a/include/olm/cipher.hh b/include/olm/cipher.hh
deleted file mode 100644
index c561972..0000000
--- a/include/olm/cipher.hh
+++ /dev/null
@@ -1,132 +0,0 @@
-/* Copyright 2015 OpenMarket Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef OLM_CIPHER_HH_
-#define OLM_CIPHER_HH_
-
-#include <cstdint>
-#include <cstddef>
-
-namespace olm {
-
-class Cipher {
-public:
- virtual ~Cipher();
-
- /**
- * Returns the length of the message authentication code that will be
- * appended to the output.
- */
- virtual std::size_t mac_length() const = 0;
-
- /**
- * Returns the length of cipher-text for a given length of plain-text.
- */
- virtual std::size_t encrypt_ciphertext_length(
- std::size_t plaintext_length
- ) const = 0;
-
- /*
- * Encrypts the plain-text into the output buffer and authenticates the
- * contents of the output buffer covering both cipher-text and any other
- * associated data in the output buffer.
- *
- * |---------------------------------------output_length-->|
- * output |--ciphertext_length-->| |---mac_length-->|
- * ciphertext
- *
- * The plain-text pointers and cipher-text pointers may be the same.
- *
- * Returns std::size_t(-1) if the length of the cipher-text or the output
- * buffer is too small. Otherwise returns the length of the output buffer.
- */
- virtual std::size_t encrypt(
- std::uint8_t const * key, std::size_t key_length,
- std::uint8_t const * plaintext, std::size_t plaintext_length,
- std::uint8_t * ciphertext, std::size_t ciphertext_length,
- std::uint8_t * output, std::size_t output_length
- ) const = 0;
-
- /**
- * Returns the maximum length of plain-text that a given length of
- * cipher-text can contain.
- */
- virtual std::size_t decrypt_max_plaintext_length(
- std::size_t ciphertext_length
- ) const = 0;
-
- /**
- * Authenticates the input and decrypts the cipher-text into the plain-text
- * buffer.
- *
- * |----------------------------------------input_length-->|
- * input |--ciphertext_length-->| |---mac_length-->|
- * ciphertext
- *
- * The plain-text pointers and cipher-text pointers may be the same.
- *
- * Returns std::size_t(-1) if the length of the plain-text buffer is too
- * small or if the authentication check fails. Otherwise returns the length
- * of the plain text.
- */
- virtual std::size_t decrypt(
- std::uint8_t const * key, std::size_t key_length,
- std::uint8_t const * input, std::size_t input_length,
- std::uint8_t const * ciphertext, std::size_t ciphertext_length,
- std::uint8_t * plaintext, std::size_t max_plaintext_length
- ) const = 0;
-};
-
-
-class CipherAesSha256 : public Cipher {
-public:
- CipherAesSha256(
- std::uint8_t const * kdf_info, std::size_t kdf_info_length
- );
-
- virtual std::size_t mac_length() const;
-
- virtual std::size_t encrypt_ciphertext_length(
- std::size_t plaintext_length
- ) const;
-
- virtual std::size_t encrypt(
- std::uint8_t const * key, std::size_t key_length,
- std::uint8_t const * plaintext, std::size_t plaintext_length,
- std::uint8_t * ciphertext, std::size_t ciphertext_length,
- std::uint8_t * output, std::size_t output_length
- ) const;
-
- virtual std::size_t decrypt_max_plaintext_length(
- std::size_t ciphertext_length
- ) const;
-
- virtual std::size_t decrypt(
- std::uint8_t const * key, std::size_t key_length,
- std::uint8_t const * input, std::size_t input_length,
- std::uint8_t const * ciphertext, std::size_t ciphertext_length,
- std::uint8_t * plaintext, std::size_t max_plaintext_length
- ) const;
-
-private:
- std::uint8_t const * kdf_info;
- std::size_t kdf_info_length;
-};
-
-
-} // namespace
-
-
-#endif /* OLM_CIPHER_HH_ */
diff --git a/include/olm/crypto.h b/include/olm/crypto.h
new file mode 100644
index 0000000..31b9b60
--- /dev/null
+++ b/include/olm/crypto.h
@@ -0,0 +1,65 @@
+/* Copyright 2015 OpenMarket Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* C-compatible crpyto utility functions. At some point all of crypto.hh will
+ * move here.
+ */
+
+#ifndef OLM_CRYPTO_H_
+#define OLM_CRYPTO_H_
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const size_t SHA256_OUTPUT_LENGTH = 32;
+
+/** Computes SHA-256 of the input. The output buffer must be a least 32
+ * bytes long. */
+void _olm_crypto_sha256(
+ uint8_t const * input, size_t input_length,
+ uint8_t * output
+);
+
+/** HMAC: Keyed-Hashing for Message Authentication
+ * http://tools.ietf.org/html/rfc2104
+ * Computes HMAC-SHA-256 of the input for the key. The output buffer must
+ * be at least 32 bytes long. */
+void _olm_crypto_hmac_sha256(
+ uint8_t const * key, size_t key_length,
+ uint8_t const * input, size_t input_length,
+ uint8_t * output
+);
+
+
+/** HMAC-based Key Derivation Function (HKDF)
+ * https://tools.ietf.org/html/rfc5869
+ * Derives key material from the input bytes. */
+void _olm_crypto_hkdf_sha256(
+ uint8_t const * input, size_t input_length,
+ uint8_t const * info, size_t info_length,
+ uint8_t const * salt, size_t salt_length,
+ uint8_t * output, size_t output_length
+);
+
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* OLM_CRYPTO_H_ */
diff --git a/include/olm/crypto.hh b/include/olm/crypto.hh
index 7a05f8d..64e8f7d 100644
--- a/include/olm/crypto.hh
+++ b/include/olm/crypto.hh
@@ -18,6 +18,11 @@
#include <cstdint>
#include <cstddef>
+// eventually all of this needs to move into crypto.h, and everything should
+// use that. For now, include crypto.h here.
+
+#include "olm/crypto.h"
+
namespace olm {
static const std::size_t KEY_LENGTH = 32;
@@ -142,38 +147,6 @@ std::size_t aes_decrypt_cbc(
);
-/** Computes SHA-256 of the input. The output buffer must be a least 32
- * bytes long. */
-void sha256(
- std::uint8_t const * input, std::size_t input_length,
- std::uint8_t * output
-);
-
-
-const std::size_t SHA256_OUTPUT_LENGTH = 32;
-
-
-/** HMAC: Keyed-Hashing for Message Authentication
- * http://tools.ietf.org/html/rfc2104
- * Computes HMAC-SHA-256 of the input for the key. The output buffer must
- * be at least 32 bytes long. */
-void hmac_sha256(
- std::uint8_t const * key, std::size_t key_length,
- std::uint8_t const * input, std::size_t input_length,
- std::uint8_t * output
-);
-
-
-/** HMAC-based Key Derivation Function (HKDF)
- * https://tools.ietf.org/html/rfc5869
- * Derives key material from the input bytes. */
-void hkdf_sha256(
- std::uint8_t const * input, std::size_t input_length,
- std::uint8_t const * info, std::size_t info_length,
- std::uint8_t const * salt, std::size_t salt_length,
- std::uint8_t * output, std::size_t output_length
-);
-
} // namespace olm
#endif /* OLM_CRYPTO_HH_ */
diff --git a/include/olm/error.h b/include/olm/error.h
new file mode 100644
index 0000000..a4f373e
--- /dev/null
+++ b/include/olm/error.h
@@ -0,0 +1,40 @@
+/* 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef OLM_ERROR_H_
+#define OLM_ERROR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum OlmErrorCode {
+ OLM_SUCCESS = 0, /*!< There wasn't an error */
+ OLM_NOT_ENOUGH_RANDOM = 1, /*!< Not enough entropy was supplied */
+ OLM_OUTPUT_BUFFER_TOO_SMALL = 2, /*!< Supplied output buffer is too small */
+ OLM_BAD_MESSAGE_VERSION = 3, /*!< The message version is unsupported */
+ OLM_BAD_MESSAGE_FORMAT = 4, /*!< The message couldn't be decoded */
+ OLM_BAD_MESSAGE_MAC = 5, /*!< The message couldn't be decrypted */
+ OLM_BAD_MESSAGE_KEY_ID = 6, /*!< The message references an unknown key id */
+ OLM_INVALID_BASE64 = 7, /*!< The input base64 was invalid */
+ OLM_BAD_ACCOUNT_KEY = 8, /*!< The supplied account key is invalid */
+ OLM_UNKNOWN_PICKLE_VERSION = 9, /*!< The pickled object is too new */
+ OLM_CORRUPTED_PICKLE = 10, /*!< The pickled object couldn't be decoded */
+};
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* OLM_ERROR_H_ */
diff --git a/include/olm/error.hh b/include/olm/error.hh
deleted file mode 100644
index b0d3764..0000000
--- a/include/olm/error.hh
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Copyright 2015 OpenMarket Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef ERROR_HH_
-#define ERROR_HH_
-
-namespace olm {
-
-enum struct ErrorCode {
- SUCCESS = 0, /*!< There wasn't an error */
- NOT_ENOUGH_RANDOM = 1, /*!< Not enough entropy was supplied */
- OUTPUT_BUFFER_TOO_SMALL = 2, /*!< Supplied output buffer is too small */
- BAD_MESSAGE_VERSION = 3, /*!< The message version is unsupported */
- BAD_MESSAGE_FORMAT = 4, /*!< The message couldn't be decoded */
- BAD_MESSAGE_MAC = 5, /*!< The message couldn't be decrypted */
- BAD_MESSAGE_KEY_ID = 6, /*!< The message references an unknown key id */
- INVALID_BASE64 = 7, /*!< The input base64 was invalid */
- BAD_ACCOUNT_KEY = 8, /*!< The supplied account key is invalid */
- UNKNOWN_PICKLE_VERSION = 9, /*!< The pickled object is too new */
- CORRUPTED_PICKLE = 10, /*!< The pickled object couldn't be decoded */
-};
-
-} // namespace olm
-
-#endif /* ERROR_HH_ */
diff --git a/include/olm/memory.h b/include/olm/memory.h
new file mode 100644
index 0000000..cc346d0
--- /dev/null
+++ b/include/olm/memory.h
@@ -0,0 +1,41 @@
+/* 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* C bindings for memory functions */
+
+
+#ifndef OLM_MEMORY_H_
+#define OLM_MEMORY_H_
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Clear the memory held in the buffer. This is more resilient to being
+ * optimised away than memset or bzero.
+ */
+void _olm_unset(
+ void volatile * buffer, size_t buffer_length
+);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+
+#endif /* OLM_MEMORY_H_ */
diff --git a/include/olm/olm.h b/include/olm/olm.h
new file mode 100644
index 0000000..8abac49
--- /dev/null
+++ b/include/olm/olm.h
@@ -0,0 +1,423 @@
+/* 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OLM_H_
+#define OLM_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static const size_t OLM_MESSAGE_TYPE_PRE_KEY = 0;
+static const size_t OLM_MESSAGE_TYPE_MESSAGE = 1;
+
+typedef struct OlmAccount OlmAccount;
+typedef struct OlmSession OlmSession;
+typedef struct OlmUtility OlmUtility;
+
+/** The size of an account object in bytes */
+size_t olm_account_size();
+
+/** The size of a session object in bytes */
+size_t olm_session_size();
+
+/** The size of a utility object in bytes */
+size_t olm_utility_size();
+
+/** Initialise an account object using the supplied memory
+ * The supplied memory must be at least olm_account_size() bytes */
+OlmAccount * olm_account(
+ void * memory
+);
+
+/** Initialise a session object using the supplied memory
+ * The supplied memory must be at least olm_session_size() bytes */
+OlmSession * olm_session(
+ void * memory
+);
+
+/** Initialise a utility object using the supplied memory
+ * The supplied memory must be at least olm_utility_size() bytes */
+OlmUtility * olm_utility(
+ void * memory
+);
+
+/** The value that olm will return from a function if there was an error */
+size_t olm_error();
+
+/** A null terminated string describing the most recent error to happen to an
+ * account */
+const char * olm_account_last_error(
+ OlmAccount * account
+);
+
+/** A null terminated string describing the most recent error to happen to a
+ * session */
+const char * olm_session_last_error(
+ OlmSession * session
+);
+
+/** A null terminated string describing the most recent error to happen to a
+ * utility */
+const char * olm_utility_last_error(
+ OlmUtility * utility
+);
+
+/** Clears the memory used to back this account */
+size_t olm_clear_account(
+ OlmAccount * account
+);
+
+/** Clears the memory used to back this session */
+size_t olm_clear_session(
+ OlmSession * session
+);
+
+/** Clears the memory used to back this utility */
+size_t olm_clear_utility(
+ OlmUtility * utility
+);
+
+/** Returns the number of bytes needed to store an account */
+size_t olm_pickle_account_length(
+ OlmAccount * account
+);
+
+/** Returns the number of bytes needed to store a session */
+size_t olm_pickle_session_length(
+ OlmSession * session
+);
+
+/** Stores an account as a base64 string. Encrypts the account using the
+ * supplied key. Returns the length of the pickled account on success.
+ * Returns olm_error() on failure. If the pickle output buffer
+ * is smaller than olm_pickle_account_length() then
+ * olm_account_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */
+size_t olm_pickle_account(
+ OlmAccount * account,
+ void const * key, size_t key_length,
+ void * pickled, size_t pickled_length
+);
+
+/** Stores a session as a base64 string. Encrypts the session using the
+ * supplied key. Returns the length of the pickled session on success.
+ * Returns olm_error() on failure. If the pickle output buffer
+ * is smaller than olm_pickle_session_length() then
+ * olm_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */
+size_t olm_pickle_session(
+ OlmSession * session,
+ void const * key, size_t key_length,
+ void * pickled, size_t pickled_length
+);
+
+/** Loads an account from a pickled base64 string. Decrypts the account using
+ * the supplied key. Returns olm_error() on failure. If the key doesn't
+ * match the one used to encrypt the account then olm_account_last_error()
+ * will be "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then
+ * olm_account_last_error() will be "INVALID_BASE64". The input pickled
+ * buffer is destroyed */
+size_t olm_unpickle_account(
+ OlmAccount * account,
+ void const * key, size_t key_length,
+ void * pickled, size_t pickled_length
+);
+
+/** Loads a session from a pickled base64 string. Decrypts the session using
+ * the supplied key. Returns olm_error() on failure. If the key doesn't
+ * match the one used to encrypt the account then olm_session_last_error()
+ * will be "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then
+ * olm_session_last_error() will be "INVALID_BASE64". The input pickled
+ * buffer is destroyed */
+size_t olm_unpickle_session(
+ OlmSession * session,
+ void const * key, size_t key_length,
+ void * pickled, size_t pickled_length
+);
+
+/** The number of random bytes needed to create an account.*/
+size_t olm_create_account_random_length(
+ OlmAccount * account
+);
+
+/** Creates a new account. Returns olm_error() on failure. If weren't
+ * enough random bytes then olm_account_last_error() will be
+ * "NOT_ENOUGH_RANDOM" */
+size_t olm_create_account(
+ OlmAccount * account,
+ void * random, size_t random_length
+);
+
+/** The size of the output buffer needed to hold the identity keys */
+size_t olm_account_identity_keys_length(
+ OlmAccount * account
+);
+
+/** Writes the public parts of the identity keys for the account into the
+ * identity_keys output buffer. Returns olm_error() on failure. If the
+ * identity_keys buffer was too small then olm_account_last_error() will be
+ * "OUTPUT_BUFFER_TOO_SMALL". */
+size_t olm_account_identity_keys(
+ OlmAccount * account,
+ void * identity_keys, size_t identity_key_length
+);
+
+
+/** The length of an ed25519 signature encoded as base64. */
+size_t olm_account_signature_length(
+ OlmAccount * account
+);
+
+/** Signs a message with the ed25519 key for this account. Returns olm_error()
+ * on failure. If the signature buffer was too small then
+ * olm_account_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */
+size_t olm_account_sign(
+ OlmAccount * account,
+ void const * message, size_t message_length,
+ void * signature, size_t signature_length
+);
+
+/** The size of the output buffer needed to hold the one time keys */
+size_t olm_account_one_time_keys_length(
+ OlmAccount * account
+);
+
+/** Writes the public parts of the unpublished one time keys for the account
+ * into the one_time_keys output buffer. Returns olm_error() on failure.
+ * If the one_time_keys buffer was too small then olm_account_last_error()
+ * will be "OUTPUT_BUFFER_TOO_SMALL". */
+size_t olm_account_one_time_keys(
+ OlmAccount * account,
+ void * one_time_keys, size_t one_time_keys_length
+);
+
+/** Marks the current set of one time keys as being published. */
+size_t olm_account_mark_keys_as_published(
+ OlmAccount * account
+);
+
+/** The largest number of one time keys this account can store. */
+size_t olm_account_max_number_of_one_time_keys(
+ OlmAccount * account
+);
+
+/** The number of random bytes needed to generate a given number of new one
+ * time keys. */
+size_t olm_account_generate_one_time_keys_random_length(
+ OlmAccount * account,
+ size_t number_of_keys
+);
+
+/** Generates a number of new one time keys. If the total number of keys stored
+ * by this account exceeds max_number_of_one_time_keys() then the old keys are
+ * discarded. Returns olm_error() on error. If the number of random bytes is
+ * too small then olm_account_last_error() will be "NOT_ENOUGH_RANDOM". */
+size_t olm_account_generate_one_time_keys(
+ OlmAccount * account,
+ size_t number_of_keys,
+ void * random, size_t random_length
+);
+
+/** The number of random bytes needed to create an outbound session */
+size_t olm_create_outbound_session_random_length(
+ OlmSession * session
+);
+
+/** Creates a new out-bound session for sending messages to a given identity_key
+ * and one_time_key. Returns olm_error() on failure. If the keys couldn't be
+ * decoded as base64 then olm_session_last_error() will be "INVALID_BASE64"
+ * If there weren't enough random bytes then olm_session_last_error() will
+ * be "NOT_ENOUGH_RANDOM". */
+size_t olm_create_outbound_session(
+ OlmSession * session,
+ OlmAccount * account,
+ void const * their_identity_key, size_t their_identity_key_length,
+ void const * their_one_time_key, size_t their_one_time_key_length,
+ void * random, size_t random_length
+);
+
+/** Create a new in-bound session for sending/receiving messages from an
+ * incoming PRE_KEY message. Returns olm_error() on failure. If the base64
+ * couldn't be decoded then olm_session_last_error will be "INVALID_BASE64".
+ * If the message was for an unsupported protocol version then
+ * olm_session_last_error() will be "BAD_MESSAGE_VERSION". If the message
+ * couldn't be decoded then then olm_session_last_error() will be
+ * "BAD_MESSAGE_FORMAT". If the message refers to an unknown one time
+ * key then olm_session_last_error() will be "BAD_MESSAGE_KEY_ID". */
+size_t olm_create_inbound_session(
+ OlmSession * session,
+ OlmAccount * account,
+ void * one_time_key_message, size_t message_length
+);
+
+/** Create a new in-bound session for sending/receiving messages from an
+ * incoming PRE_KEY message. Returns olm_error() on failure. If the base64
+ * couldn't be decoded then olm_session_last_error will be "INVALID_BASE64".
+ * If the message was for an unsupported protocol version then
+ * olm_session_last_error() will be "BAD_MESSAGE_VERSION". If the message
+ * couldn't be decoded then then olm_session_last_error() will be
+ * "BAD_MESSAGE_FORMAT". If the message refers to an unknown one time
+ * key then olm_session_last_error() will be "BAD_MESSAGE_KEY_ID". */
+size_t olm_create_inbound_session_from(
+ OlmSession * session,
+ OlmAccount * account,
+ void const * their_identity_key, size_t their_identity_key_length,
+ void * one_time_key_message, size_t message_length
+);
+
+/** The length of the buffer needed to return the id for this session. */
+size_t olm_session_id_length(
+ OlmSession * session
+);
+
+/** An identifier for this session. Will be the same for both ends of the
+ * conversation. If the id buffer is too small then olm_session_last_error()
+ * will be "OUTPUT_BUFFER_TOO_SMALL". */
+size_t olm_session_id(
+ OlmSession * session,
+ void * id, size_t id_length
+);
+
+/** Checks if the PRE_KEY message is for this in-bound session. This can happen
+ * if multiple messages are sent to this account before this account sends a
+ * message in reply. Returns olm_error() on failure. If the base64
+ * couldn't be decoded then olm_session_last_error will be "INVALID_BASE64".
+ * If the message was for an unsupported protocol version then
+ * olm_session_last_error() will be "BAD_MESSAGE_VERSION". If the message
+ * couldn't be decoded then then olm_session_last_error() will be
+ * "BAD_MESSAGE_FORMAT". */
+size_t olm_matches_inbound_session(
+ OlmSession * session,
+ void * one_time_key_message, size_t message_length
+);
+
+/** Checks if the PRE_KEY message is for this in-bound session. This can happen
+ * if multiple messages are sent to this account before this account sends a
+ * message in reply. Returns olm_error() on failure. If the base64
+ * couldn't be decoded then olm_session_last_error will be "INVALID_BASE64".
+ * If the message was for an unsupported protocol version then
+ * olm_session_last_error() will be "BAD_MESSAGE_VERSION". If the message
+ * couldn't be decoded then then olm_session_last_error() will be
+ * "BAD_MESSAGE_FORMAT". */
+size_t olm_matches_inbound_session_from(
+ OlmSession * session,
+ void const * their_identity_key, size_t their_identity_key_length,
+ void * one_time_key_message, size_t message_length
+);
+
+/** Removes the one time keys that the session used from the account. Returns
+ * olm_error() on failure. If the account doesn't have any matching one time
+ * keys then olm_account_last_error() will be "BAD_MESSAGE_KEY_ID". */
+size_t olm_remove_one_time_keys(
+ OlmAccount * account,
+ OlmSession * session
+);
+
+/** The type of the next message that olm_encrypt() will return. Returns
+ * OLM_MESSAGE_TYPE_PRE_KEY if the message will be a PRE_KEY message.
+ * Returns OLM_MESSAGE_TYPE_MESSAGE if the message will be a normal message.
+ * Returns olm_error on failure. */
+size_t olm_encrypt_message_type(
+ OlmSession * session
+);
+
+/** The number of random bytes needed to encrypt the next message. */
+size_t olm_encrypt_random_length(
+ OlmSession * session
+);
+
+/** The size of the next message in bytes for the given number of plain-text
+ * bytes. */
+size_t olm_encrypt_message_length(
+ OlmSession * session,
+ size_t plaintext_length
+);
+
+/** Encrypts a message using the session. Returns the length of the message in
+ * bytes on success. Writes the message as base64 into the message buffer.
+ * Returns olm_error() on failure. If the message buffer is too small then
+ * olm_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". If there
+ * weren't enough random bytes then olm_session_last_error() will be
+ * "NOT_ENOUGH_RANDOM". */
+size_t olm_encrypt(
+ OlmSession * session,
+ void const * plaintext, size_t plaintext_length,
+ void * random, size_t random_length,
+ void * message, size_t message_length
+);
+
+/** The maximum number of bytes of plain-text a given message could decode to.
+ * The actual size could be different due to padding. The input message buffer
+ * is destroyed. Returns olm_error() on failure. If the message base64
+ * couldn't be decoded then olm_session_last_error() will be
+ * "INVALID_BASE64". If the message is for an unsupported version of the
+ * protocol then olm_session_last_error() will be "BAD_MESSAGE_VERSION".
+ * If the message couldn't be decoded then olm_session_last_error() will be
+ * "BAD_MESSAGE_FORMAT". */
+size_t olm_decrypt_max_plaintext_length(
+ OlmSession * session,
+ size_t message_type,
+ void * message, size_t message_length
+);
+
+/** Decrypts a message using the session. The input message buffer is destroyed.
+ * Returns the length of the plain-text on success. Returns olm_error() on
+ * failure. If the plain-text buffer is smaller than
+ * olm_decrypt_max_plaintext_length() then olm_session_last_error()
+ * will be "OUTPUT_BUFFER_TOO_SMALL". If the base64 couldn't be decoded then
+ * olm_session_last_error() will be "INVALID_BASE64". If the message is for
+ * an unsupported version of the protocol then olm_session_last_error() will
+ * be "BAD_MESSAGE_VERSION". If the message couldn't be decoded then
+ * olm_session_last_error() will be BAD_MESSAGE_FORMAT".
+ * If the MAC on the message was invalid then olm_session_last_error() will
+ * be "BAD_MESSAGE_MAC". */
+size_t olm_decrypt(
+ OlmSession * session,
+ size_t message_type,
+ void * message, size_t message_length,
+ void * plaintext, size_t max_plaintext_length
+);
+
+/** The length of the buffer needed to hold the SHA-256 hash. */
+size_t olm_sha256_length(
+ OlmUtility * utility
+);
+
+/** Calculates the SHA-256 hash of the input and encodes it as base64. If the
+ * output buffer is smaller than olm_sha256_length() then
+ * olm_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". */
+size_t olm_sha256(
+ OlmUtility * utility,
+ void const * input, size_t input_length,
+ void * output, size_t output_length
+);
+
+/** Verify an ed25519 signature. If the key was too small then
+ * olm_session_last_error will be "INVALID_BASE64". If the signature was invalid
+ * then olm_session_last_error() will be "BAD_MESSAGE_MAC". */
+size_t olm_ed25519_verify(
+ OlmUtility * utility,
+ void const * key, size_t key_length,
+ void const * message, size_t message_length,
+ void * signature, size_t signature_length
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OLM_HH_ */
diff --git a/include/olm/olm.hh b/include/olm/olm.hh
index 51d5c04..5ca59c3 100644
--- a/include/olm/olm.hh
+++ b/include/olm/olm.hh
@@ -1,422 +1,4 @@
-/* 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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+/* this file exists only for compatibility with existing applications.
+ * You should use "#include <olm/olm.h>" instead.
*/
-#ifndef OLM_HH_
-#define OLM_HH_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-static const size_t OLM_MESSAGE_TYPE_PRE_KEY = 0;
-static const size_t OLM_MESSAGE_TYPE_MESSAGE = 1;
-
-typedef struct OlmAccount OlmAccount;
-typedef struct OlmSession OlmSession;
-typedef struct OlmUtility OlmUtility;
-
-/** The size of an account object in bytes */
-size_t olm_account_size();
-
-/** The size of a session object in bytes */
-size_t olm_session_size();
-
-/** The size of a utility object in bytes */
-size_t olm_utility_size();
-
-/** Initialise an account object using the supplied memory
- * The supplied memory must be at least olm_account_size() bytes */
-OlmAccount * olm_account(
- void * memory
-);
-
-/** Initialise a session object using the supplied memory
- * The supplied memory must be at least olm_session_size() bytes */
-OlmSession * olm_session(
- void * memory
-);
-
-/** Initialise a utility object using the supplied memory
- * The supplied memory must be at least olm_utility_size() bytes */
-OlmUtility * olm_utility(
- void * memory
-);
-
-/** The value that olm will return from a function if there was an error */
-size_t olm_error();
-
-/** A null terminated string describing the most recent error to happen to an
- * account */
-const char * olm_account_last_error(
- OlmAccount * account
-);
-
-/** A null terminated string describing the most recent error to happen to a
- * session */
-const char * olm_session_last_error(
- OlmSession * session
-);
-
-/** A null terminated string describing the most recent error to happen to a
- * utility */
-const char * olm_utility_last_error(
- OlmUtility * utility
-);
-
-/** Clears the memory used to back this account */
-size_t olm_clear_account(
- OlmAccount * account
-);
-
-/** Clears the memory used to back this session */
-size_t olm_clear_session(
- OlmSession * session
-);
-
-/** Clears the memory used to back this utility */
-size_t olm_clear_utility(
- OlmUtility * utility
-);
-
-/** Returns the number of bytes needed to store an account */
-size_t olm_pickle_account_length(
- OlmAccount * account
-);
-
-/** Returns the number of bytes needed to store a session */
-size_t olm_pickle_session_length(
- OlmSession * session
-);
-
-/** Stores an account as a base64 string. Encrypts the account using the
- * supplied key. Returns the length of the pickled account on success.
- * Returns olm_error() on failure. If the pickle output buffer
- * is smaller than olm_pickle_account_length() then
- * olm_account_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */
-size_t olm_pickle_account(
- OlmAccount * account,
- void const * key, size_t key_length,
- void * pickled, size_t pickled_length
-);
-
-/** Stores a session as a base64 string. Encrypts the session using the
- * supplied key. Returns the length of the pickled session on success.
- * Returns olm_error() on failure. If the pickle output buffer
- * is smaller than olm_pickle_session_length() then
- * olm_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */
-size_t olm_pickle_session(
- OlmSession * session,
- void const * key, size_t key_length,
- void * pickled, size_t pickled_length
-);
-
-/** Loads an account from a pickled base64 string. Decrypts the account using
- * the supplied key. Returns olm_error() on failure. If the key doesn't
- * match the one used to encrypt the account then olm_account_last_error()
- * will be "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then
- * olm_account_last_error() will be "INVALID_BASE64". The input pickled
- * buffer is destroyed */
-size_t olm_unpickle_account(
- OlmAccount * account,
- void const * key, size_t key_length,
- void * pickled, size_t pickled_length
-);
-
-/** Loads a session from a pickled base64 string. Decrypts the session using
- * the supplied key. Returns olm_error() on failure. If the key doesn't
- * match the one used to encrypt the account then olm_session_last_error()
- * will be "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then
- * olm_session_last_error() will be "INVALID_BASE64". The input pickled
- * buffer is destroyed */
-size_t olm_unpickle_session(
- OlmSession * session,
- void const * key, size_t key_length,
- void * pickled, size_t pickled_length
-);
-
-/** The number of random bytes needed to create an account.*/
-size_t olm_create_account_random_length(
- OlmAccount * account
-);
-
-/** Creates a new account. Returns olm_error() on failure. If weren't
- * enough random bytes then olm_account_last_error() will be
- * "NOT_ENOUGH_RANDOM" */
-size_t olm_create_account(
- OlmAccount * account,
- void * random, size_t random_length
-);
-
-/** The size of the output buffer needed to hold the identity keys */
-size_t olm_account_identity_keys_length(
- OlmAccount * account
-);
-
-/** Writes the public parts of the identity keys for the account into the
- * identity_keys output buffer. Returns olm_error() on failure. If the
- * identity_keys buffer was too small then olm_account_last_error() will be
- * "OUTPUT_BUFFER_TOO_SMALL". */
-size_t olm_account_identity_keys(
- OlmAccount * account,
- void * identity_keys, size_t identity_key_length
-);
-
-
-/** The length of an ed25519 signature encoded as base64. */
-size_t olm_account_signature_length(
- OlmAccount * account
-);
-
-/** Signs a message with the ed25519 key for this account. Returns olm_error()
- * on failure. If the signature buffer was too small then
- * olm_account_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */
-size_t olm_account_sign(
- OlmAccount * account,
- void const * message, size_t message_length,
- void * signature, size_t signature_length
-);
-
-/** The size of the output buffer needed to hold the one time keys */
-size_t olm_account_one_time_keys_length(
- OlmAccount * account
-);
-
-/** Writes the public parts of the unpublished one time keys for the account
- * into the one_time_keys output buffer. Returns olm_error() on failure.
- * If the one_time_keys buffer was too small then olm_account_last_error()
- * will be "OUTPUT_BUFFER_TOO_SMALL". */
-size_t olm_account_one_time_keys(
- OlmAccount * account,
- void * one_time_keys, size_t one_time_keys_length
-);
-
-/** Marks the current set of one time keys as being published. */
-size_t olm_account_mark_keys_as_published(
- OlmAccount * account
-);
-
-/** The largest number of one time keys this account can store. */
-size_t olm_account_max_number_of_one_time_keys(
- OlmAccount * account
-);
-
-/** The number of random bytes needed to generate a given number of new one
- * time keys. */
-size_t olm_account_generate_one_time_keys_random_length(
- OlmAccount * account,
- size_t number_of_keys
-);
-
-/** Generates a number of new one time keys. If the total number of keys stored
- * by this account exceeds max_number_of_one_time_keys() then the old keys are
- * discarded. Returns olm_error() on error. If the number of random bytes is
- * too small then olm_account_last_error() will be "NOT_ENOUGH_RANDOM". */
-size_t olm_account_generate_one_time_keys(
- OlmAccount * account,
- size_t number_of_keys,
- void * random, size_t random_length
-);
-
-/** The number of random bytes needed to create an outbound session */
-size_t olm_create_outbound_session_random_length(
- OlmSession * session
-);
-
-/** Creates a new out-bound session for sending messages to a given identity_key
- * and one_time_key. Returns olm_error() on failure. If the keys couldn't be
- * decoded as base64 then olm_session_last_error() will be "INVALID_BASE64"
- * If there weren't enough random bytes then olm_session_last_error() will
- * be "NOT_ENOUGH_RANDOM". */
-size_t olm_create_outbound_session(
- OlmSession * session,
- OlmAccount * account,
- void const * their_identity_key, size_t their_identity_key_length,
- void const * their_one_time_key, size_t their_one_time_key_length,
- void * random, size_t random_length
-);
-
-/** Create a new in-bound session for sending/receiving messages from an
- * incoming PRE_KEY message. Returns olm_error() on failure. If the base64
- * couldn't be decoded then olm_session_last_error will be "INVALID_BASE64".
- * If the message was for an unsupported protocol version then
- * olm_session_last_error() will be "BAD_MESSAGE_VERSION". If the message
- * couldn't be decoded then then olm_session_last_error() will be
- * "BAD_MESSAGE_FORMAT". If the message refers to an unknown one time
- * key then olm_session_last_error() will be "BAD_MESSAGE_KEY_ID". */
-size_t olm_create_inbound_session(
- OlmSession * session,
- OlmAccount * account,
- void * one_time_key_message, size_t message_length
-);
-
-/** Create a new in-bound session for sending/receiving messages from an
- * incoming PRE_KEY message. Returns olm_error() on failure. If the base64
- * couldn't be decoded then olm_session_last_error will be "INVALID_BASE64".
- * If the message was for an unsupported protocol version then
- * olm_session_last_error() will be "BAD_MESSAGE_VERSION". If the message
- * couldn't be decoded then then olm_session_last_error() will be
- * "BAD_MESSAGE_FORMAT". If the message refers to an unknown one time
- * key then olm_session_last_error() will be "BAD_MESSAGE_KEY_ID". */
-size_t olm_create_inbound_session_from(
- OlmSession * session,
- OlmAccount * account,
- void const * their_identity_key, size_t their_identity_key_length,
- void * one_time_key_message, size_t message_length
-);
-
-/** The length of the buffer needed to return the id for this session. */
-size_t olm_session_id_length(
- OlmSession * session
-);
-
-/** An identifier for this session. Will be the same for both ends of the
- * conversation. If the id buffer is too small then olm_session_last_error()
- * will be "OUTPUT_BUFFER_TOO_SMALL". */
-size_t olm_session_id(
- OlmSession * session,
- void * id, size_t id_length
-);
-
-/** Checks if the PRE_KEY message is for this in-bound session. This can happen
- * if multiple messages are sent to this account before this account sends a
- * message in reply. Returns olm_error() on failure. If the base64
- * couldn't be decoded then olm_session_last_error will be "INVALID_BASE64".
- * If the message was for an unsupported protocol version then
- * olm_session_last_error() will be "BAD_MESSAGE_VERSION". If the message
- * couldn't be decoded then then olm_session_last_error() will be
- * "BAD_MESSAGE_FORMAT". */
-size_t olm_matches_inbound_session(
- OlmSession * session,
- void * one_time_key_message, size_t message_length
-);
-
-/** Checks if the PRE_KEY message is for this in-bound session. This can happen
- * if multiple messages are sent to this account before this account sends a
- * message in reply. Returns olm_error() on failure. If the base64
- * couldn't be decoded then olm_session_last_error will be "INVALID_BASE64".
- * If the message was for an unsupported protocol version then
- * olm_session_last_error() will be "BAD_MESSAGE_VERSION". If the message
- * couldn't be decoded then then olm_session_last_error() will be
- * "BAD_MESSAGE_FORMAT". */
-size_t olm_matches_inbound_session_from(
- OlmSession * session,
- void const * their_identity_key, size_t their_identity_key_length,
- void * one_time_key_message, size_t message_length
-);
-
-/** Removes the one time keys that the session used from the account. Returns
- * olm_error() on failure. If the account doesn't have any matching one time
- * keys then olm_account_last_error() will be "BAD_MESSAGE_KEY_ID". */
-size_t olm_remove_one_time_keys(
- OlmAccount * account,
- OlmSession * session
-);
-
-/** The type of the next message that olm_encrypt() will return. Returns
- * OLM_MESSAGE_TYPE_PRE_KEY if the message will be a PRE_KEY message.
- * Returns OLM_MESSAGE_TYPE_MESSAGE if the message will be a normal message.
- * Returns olm_error on failure. */
-size_t olm_encrypt_message_type(
- OlmSession * session
-);
-
-/** The number of random bytes needed to encrypt the next message. */
-size_t olm_encrypt_random_length(
- OlmSession * session
-);
-
-/** The size of the next message in bytes for the given number of plain-text
- * bytes. */
-size_t olm_encrypt_message_length(
- OlmSession * session,
- size_t plaintext_length
-);
-
-/** Encrypts a message using the session. Returns the length of the message in
- * bytes on success. Writes the message as base64 into the message buffer.
- * Returns olm_error() on failure. If the message buffer is too small then
- * olm_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". If there
- * weren't enough random bytes then olm_session_last_error() will be
- * "NOT_ENOUGH_RANDOM". */
-size_t olm_encrypt(
- OlmSession * session,
- void const * plaintext, size_t plaintext_length,
- void * random, size_t random_length,
- void * message, size_t message_length
-);
-
-/** The maximum number of bytes of plain-text a given message could decode to.
- * The actual size could be different due to padding. The input message buffer
- * is destroyed. Returns olm_error() on failure. If the message base64
- * couldn't be decoded then olm_session_last_error() will be
- * "INVALID_BASE64". If the message is for an unsupported version of the
- * protocol then olm_session_last_error() will be "BAD_MESSAGE_VERSION".
- * If the message couldn't be decoded then olm_session_last_error() will be
- * "BAD_MESSAGE_FORMAT". */
-size_t olm_decrypt_max_plaintext_length(
- OlmSession * session,
- size_t message_type,
- void * message, size_t message_length
-);
-
-/** Decrypts a message using the session. The input message buffer is destroyed.
- * Returns the length of the plain-text on success. Returns olm_error() on
- * failure. If the plain-text buffer is smaller than
- * olm_decrypt_max_plaintext_length() then olm_session_last_error()
- * will be "OUTPUT_BUFFER_TOO_SMALL". If the base64 couldn't be decoded then
- * olm_session_last_error() will be "INVALID_BASE64". If the message is for
- * an unsupported version of the protocol then olm_session_last_error() will
- * be "BAD_MESSAGE_VERSION". If the message couldn't be decoded then
- * olm_session_last_error() will be BAD_MESSAGE_FORMAT".
- * If the MAC on the message was invalid then olm_session_last_error() will
- * be "BAD_MESSAGE_MAC". */
-size_t olm_decrypt(
- OlmSession * session,
- size_t message_type,
- void * message, size_t message_length,
- void * plaintext, size_t max_plaintext_length
-);
-
-/** The length of the buffer needed to hold the SHA-256 hash. */
-size_t olm_sha256_length(
- OlmUtility * utility
-);
-
-/** Calculates the SHA-256 hash of the input and encodes it as base64. If the
- * output buffer is smaller than olm_sha256_length() then
- * olm_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". */
-size_t olm_sha256(
- OlmUtility * utility,
- void const * input, size_t input_length,
- void * output, size_t output_length
-);
-
-/** Verify an ed25519 signature. If the key was too small then
- * olm_session_last_error will be "INVALID_BASE64". If the signature was invalid
- * then olm_session_last_error() will be "BAD_MESSAGE_MAC". */
-size_t olm_ed25519_verify(
- OlmUtility * utility,
- void const * key, size_t key_length,
- void const * message, size_t message_length,
- void * signature, size_t signature_length
-);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* OLM_HH_ */
+#include "olm/olm.h"
diff --git a/include/olm/pickle.h b/include/olm/pickle.h
new file mode 100644
index 0000000..c1e8192
--- /dev/null
+++ b/include/olm/pickle.h
@@ -0,0 +1,50 @@
+/* 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef OLM_PICKLE_H_
+#define OLM_PICKLE_H_
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define _olm_pickle_uint32_length(value) 4
+uint8_t * _olm_pickle_uint32(uint8_t * pos, uint32_t value);
+uint8_t const * _olm_unpickle_uint32(
+ uint8_t const * pos, uint8_t const * end,
+ uint32_t *value
+);
+
+
+#define _olm_pickle_bool_length(value) 1
+uint8_t * _olm_pickle_bool(uint8_t * pos, int value);
+uint8_t const * _olm_unpickle_bool(
+ uint8_t const * pos, uint8_t const * end,
+ int *value
+);
+
+#define _olm_pickle_bytes_length(bytes, bytes_length) (bytes_length)
+uint8_t * _olm_pickle_bytes(uint8_t * pos, uint8_t const * bytes,
+ size_t bytes_length);
+uint8_t const * _olm_unpickle_bytes(uint8_t const * pos, uint8_t const * end,
+ uint8_t * bytes, size_t bytes_length);
+
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* OLM_PICKLE_H */
diff --git a/include/olm/ratchet.hh b/include/olm/ratchet.hh
index 071e349..acb5608 100644
--- a/include/olm/ratchet.hh
+++ b/include/olm/ratchet.hh
@@ -15,11 +15,11 @@
#include "olm/crypto.hh"
#include "olm/list.hh"
-#include "olm/error.hh"
+#include "olm/error.h"
-namespace olm {
+struct _olm_cipher;
-class Cipher;
+namespace olm {
typedef std::uint8_t SharedKey[olm::KEY_LENGTH];
@@ -69,17 +69,17 @@ struct Ratchet {
Ratchet(
KdfInfo const & kdf_info,
- Cipher const & ratchet_cipher
+ _olm_cipher const *ratchet_cipher
);
/** A some strings identifying the application to feed into the KDF. */
KdfInfo const & kdf_info;
/** The AEAD cipher to use for encrypting messages. */
- Cipher const & ratchet_cipher;
+ _olm_cipher const *ratchet_cipher;
/** The last error that happened encrypting or decrypting a message. */
- ErrorCode last_error;
+ OlmErrorCode last_error;
/**
* A count of the number of times the root key has been advanced; this is
diff --git a/include/olm/session.hh b/include/olm/session.hh
index 829f271..5b91cb1 100644
--- a/include/olm/session.hh
+++ b/include/olm/session.hh
@@ -31,7 +31,7 @@ struct Session {
Session();
Ratchet ratchet;
- ErrorCode last_error;
+ OlmErrorCode last_error;
bool received_message;
diff --git a/include/olm/utility.hh b/include/olm/utility.hh
index 1e77675..1339fe5 100644
--- a/include/olm/utility.hh
+++ b/include/olm/utility.hh
@@ -16,7 +16,7 @@
#ifndef UTILITY_HH_
#define UTILITY_HH_
-#include "olm/error.hh"
+#include "olm/error.h"
#include <cstddef>
#include <cstdint>
@@ -29,7 +29,7 @@ struct Utility {
Utility();
- ErrorCode last_error;
+ OlmErrorCode last_error;
/** The length of a SHA-256 hash in bytes. */
std::size_t sha256_length();
diff --git a/python/.gitignore b/python/.gitignore
new file mode 100644
index 0000000..4e9d33a
--- /dev/null
+++ b/python/.gitignore
@@ -0,0 +1,3 @@
+*.pyc
+/*.account
+/*.session
diff --git a/python/olm.py b/python/olm.py
deleted file mode 100755
index b048844..0000000
--- a/python/olm.py
+++ /dev/null
@@ -1,542 +0,0 @@
-#! /usr/bin/env python
-from ctypes import *
-import json
-import os
-
-lib = cdll.LoadLibrary(os.path.join(
- os.path.dirname(__file__), "..", "build", "libolm.so")
-)
-
-
-lib.olm_error.argtypes = []
-lib.olm_error.restypes = c_size_t
-
-ERR = lib.olm_error()
-
-class OlmError(Exception):
- pass
-
-
-lib.olm_account_size.argtypes = []
-lib.olm_account_size.restype = c_size_t
-
-lib.olm_account.argtypes = [c_void_p]
-lib.olm_account.restype = c_void_p
-
-lib.olm_account_last_error.argtypes = [c_void_p]
-lib.olm_account_last_error.restype = c_char_p
-
-def account_errcheck(res, func, args):
- if res == ERR:
- raise OlmError("%s: %s" % (
- func.__name__, lib.olm_account_last_error(args[0])
- ))
- return res
-
-
-def account_function(func, *types):
- func.argtypes = (c_void_p,) + types
- func.restypes = c_size_t
- func.errcheck = account_errcheck
-
-
-account_function(
- lib.olm_pickle_account, c_void_p, c_size_t, c_void_p, c_size_t
-)
-account_function(
- lib.olm_unpickle_account, c_void_p, c_size_t, c_void_p, c_size_t
-)
-account_function(lib.olm_create_account_random_length)
-account_function(lib.olm_create_account, c_void_p, c_size_t)
-account_function(lib.olm_account_identity_keys_length)
-account_function(lib.olm_account_identity_keys, c_void_p, c_size_t)
-account_function(lib.olm_account_signature_length)
-account_function(lib.olm_account_sign, c_void_p, c_size_t, c_void_p, c_size_t)
-account_function(lib.olm_account_one_time_keys_length)
-account_function(lib.olm_account_one_time_keys, c_void_p, c_size_t)
-account_function(lib.olm_account_mark_keys_as_published)
-account_function(lib.olm_account_max_number_of_one_time_keys)
-account_function(
- lib.olm_account_generate_one_time_keys_random_length,
- c_size_t
-)
-account_function(
- lib.olm_account_generate_one_time_keys,
- c_size_t,
- c_void_p, c_size_t
-)
-
-
-def read_random(n):
- with open("/dev/urandom", "rb") as f:
- return f.read(n)
-
-class Account(object):
- def __init__(self):
- self.buf = create_string_buffer(lib.olm_account_size())
- self.ptr = lib.olm_account(self.buf)
-
- def create(self):
- random_length = lib.olm_create_account_random_length(self.ptr)
- random = read_random(random_length)
- random_buffer = create_string_buffer(random)
- lib.olm_create_account(self.ptr, random_buffer, random_length)
-
- def pickle(self, key):
- key_buffer = create_string_buffer(key)
- pickle_length = lib.olm_pickle_account_length(self.ptr)
- pickle_buffer = create_string_buffer(pickle_length)
- lib.olm_pickle_account(
- self.ptr, key_buffer, len(key), pickle_buffer, pickle_length
- )
- return pickle_buffer.raw
-
- def unpickle(self, key, pickle):
- key_buffer = create_string_buffer(key)
- pickle_buffer = create_string_buffer(pickle)
- lib.olm_unpickle_account(
- self.ptr, key_buffer, len(key), pickle_buffer, len(pickle)
- )
-
- def identity_keys(self):
- out_length = lib.olm_account_identity_keys_length(self.ptr)
- out_buffer = create_string_buffer(out_length)
- lib.olm_account_identity_keys(
- self.ptr,
- out_buffer, out_length
- )
- return json.loads(out_buffer.raw)
-
- def sign(self, message):
- out_length = lib.olm_account_signature_length(self.ptr)
- message_buffer = create_string_buffer(message)
- out_buffer = create_string_buffer(out_length)
- lib.olm_account_sign(
- self.ptr, message_buffer, len(message), out_buffer, out_length
- )
- return out_buffer.raw
-
- def one_time_keys(self):
- out_length = lib.olm_account_one_time_keys_length(self.ptr)
- out_buffer = create_string_buffer(out_length)
- lib.olm_account_one_time_keys(self.ptr, out_buffer, out_length)
- return json.loads(out_buffer.raw)
-
- def mark_keys_as_published(self):
- lib.olm_account_mark_keys_as_published(self.ptr)
-
- def max_number_of_one_time_keys(self):
- return lib.olm_account_max_number_of_one_time_keys(self.ptr)
-
- def generate_one_time_keys(self, count):
- random_length = lib.olm_account_generate_one_time_keys_random_length(
- self.ptr, count
- )
- random = read_random(random_length)
- random_buffer = create_string_buffer(random)
- lib.olm_account_generate_one_time_keys(
- self.ptr, count, random_buffer, random_length
- )
-
- def clear(self):
- pass
-
-
-lib.olm_session_size.argtypes = []
-lib.olm_session_size.restype = c_size_t
-
-lib.olm_session.argtypes = [c_void_p]
-lib.olm_session.restype = c_void_p
-
-lib.olm_session_last_error.argtypes = [c_void_p]
-lib.olm_session_last_error.restype = c_char_p
-
-
-def session_errcheck(res, func, args):
- if res == ERR:
- raise OlmError("%s: %s" % (
- func.__name__, lib.olm_session_last_error(args[0])
- ))
- return res
-
-
-def session_function(func, *types):
- func.argtypes = (c_void_p,) + types
- func.restypes = c_size_t
- func.errcheck = session_errcheck
-
-session_function(lib.olm_session_last_error)
-session_function(
- lib.olm_pickle_session, c_void_p, c_size_t, c_void_p, c_size_t
-)
-session_function(
- lib.olm_unpickle_session, c_void_p, c_size_t, c_void_p, c_size_t
-)
-session_function(lib.olm_create_outbound_session_random_length)
-session_function(
- lib.olm_create_outbound_session,
- c_void_p, # Account
- c_void_p, c_size_t, # Identity Key
- c_void_p, c_size_t, # One Time Key
- c_void_p, c_size_t, # Random
-)
-session_function(
- lib.olm_create_inbound_session,
- c_void_p, # Account
- c_void_p, c_size_t, # Pre Key Message
-)
-session_function(
- lib.olm_create_inbound_session_from,
- c_void_p, # Account
- c_void_p, c_size_t, # Identity Key
- c_void_p, c_size_t, # Pre Key Message
-)
-session_function(lib.olm_session_id_length)
-session_function(lib.olm_session_id, c_void_p, c_size_t)
-session_function(lib.olm_matches_inbound_session, c_void_p, c_size_t)
-session_function(
- lib.olm_matches_inbound_session_from,
- c_void_p, c_size_t, # Identity Key
- c_void_p, c_size_t, # Pre Key Message
-)
-session_function(lib.olm_encrypt_message_type)
-session_function(lib.olm_encrypt_random_length)
-session_function(lib.olm_encrypt_message_length, c_size_t)
-session_function(
- lib.olm_encrypt,
- c_void_p, c_size_t, # Plaintext
- c_void_p, c_size_t, # Random
- c_void_p, c_size_t, # Message
-);
-session_function(
- lib.olm_decrypt_max_plaintext_length,
- c_size_t, # Message Type
- c_void_p, c_size_t, # Message
-)
-session_function(
- lib.olm_decrypt,
- c_size_t, # Message Type
- c_void_p, c_size_t, # Message
- c_void_p, c_size_t, # Plaintext
-)
-
-class Session(object):
- def __init__(self):
- self.buf = create_string_buffer(lib.olm_session_size())
- self.ptr = lib.olm_session(self.buf)
-
- def pickle(self, key):
- key_buffer = create_string_buffer(key)
- pickle_length = lib.olm_pickle_session_length(self.ptr)
- pickle_buffer = create_string_buffer(pickle_length)
- lib.olm_pickle_session(
- self.ptr, key_buffer, len(key), pickle_buffer, pickle_length
- )
- return pickle_buffer.raw
-
- def unpickle(self, key, pickle):
- key_buffer = create_string_buffer(key)
- pickle_buffer = create_string_buffer(pickle)
- lib.olm_unpickle_session(
- self.ptr, key_buffer, len(key), pickle_buffer, len(pickle)
- )
-
- def create_outbound(self, account, identity_key, one_time_key):
- r_length = lib.olm_create_outbound_session_random_length(self.ptr)
- random = read_random(r_length)
- random_buffer = create_string_buffer(random)
- identity_key_buffer = create_string_buffer(identity_key)
- one_time_key_buffer = create_string_buffer(one_time_key)
- lib.olm_create_outbound_session(
- self.ptr,
- account.ptr,
- identity_key_buffer, len(identity_key),
- one_time_key_buffer, len(one_time_key),
- random_buffer, r_length
- )
-
- def create_inbound(self, account, one_time_key_message):
- one_time_key_message_buffer = create_string_buffer(one_time_key_message)
- lib.olm_create_inbound_session(
- self.ptr,
- account.ptr,
- one_time_key_message_buffer, len(one_time_key_message)
- )
-
- def create_inbound_from(self, account, identity_key, one_time_key_message):
- identity_key_buffer = create_string_buffer(identity_key)
- one_time_key_message_buffer = create_string_buffer(one_time_key_message)
- lib.olm_create_inbound_session_from(
- self.ptr,
- account.ptr,
- identity_key_buffer, len(identity_key),
- one_time_key_message_buffer, len(one_time_key_message)
- )
-
- def session_id(self):
- id_length = lib.olm_session_id_length(self.ptr)
- id_buffer = create_string_buffer(id_length)
- lib.olm_session_id(self.ptr, id_buffer, id_length);
- return id_buffer.raw
-
- def matches_inbound(self, one_time_key_message):
- one_time_key_message_buffer = create_string_buffer(one_time_key_message)
- return bool(lib.olm_matches_inbound_session(
- self.ptr,
- one_time_key_message_buffer, len(one_time_key_message)
- ))
-
- def matches_inbound_from(self, identity_key, one_time_key_message):
- identity_key_buffer = create_string_buffer(identity_key)
- one_time_key_message_buffer = create_string_buffer(one_time_key_message)
- return bool(lib.olm_matches_inbound_session(
- self.ptr,
- identity_key_buffer, len(identity_key),
- one_time_key_message_buffer, len(one_time_key_message)
- ))
-
- def encrypt(self, plaintext):
- r_length = lib.olm_encrypt_random_length(self.ptr)
- random = read_random(r_length)
- random_buffer = create_string_buffer(random)
-
- message_type = lib.olm_encrypt_message_type(self.ptr)
- message_length = lib.olm_encrypt_message_length(
- self.ptr, len(plaintext)
- )
- message_buffer = create_string_buffer(message_length)
-
- plaintext_buffer = create_string_buffer(plaintext)
-
- lib.olm_encrypt(
- self.ptr,
- plaintext_buffer, len(plaintext),
- random_buffer, r_length,
- message_buffer, message_length,
- )
- return message_type, message_buffer.raw
-
- def decrypt(self, message_type, message):
- message_buffer = create_string_buffer(message)
- max_plaintext_length = lib.olm_decrypt_max_plaintext_length(
- self.ptr, message_type, message_buffer, len(message)
- )
- plaintext_buffer = create_string_buffer(max_plaintext_length)
- message_buffer = create_string_buffer(message)
- plaintext_length = lib.olm_decrypt(
- self.ptr, message_type, message_buffer, len(message),
- plaintext_buffer, max_plaintext_length
- )
- return plaintext_buffer.raw[:plaintext_length]
-
- def clear(self):
- pass
-
-
-if __name__ == '__main__':
- import argparse
- import sys
- import os
- import yaml
-
- parser = argparse.ArgumentParser()
- parser.add_argument("--key", help="Account encryption key", default="")
- commands = parser.add_subparsers()
-
- create_account = commands.add_parser("create_account", help="Create a new account")
- create_account.add_argument("account_file", help="Local account file")
-
- def do_create_account(args):
- if os.path.exists(args.account_file):
- sys.stderr.write("Account %r file already exists" % (
- args.account_file,
- ))
- sys.exit(1)
- account = Account()
- account.create()
- with open(args.account_file, "wb") as f:
- f.write(account.pickle(args.key))
-
- create_account.set_defaults(func=do_create_account)
-
- keys = commands.add_parser("keys", help="List public keys for an account")
- keys.add_argument("account_file", help="Local account file")
- keys.add_argument("--json", action="store_true", help="Output as JSON")
-
- def do_keys(args):
- account = Account()
- with open(args.account_file, "rb") as f:
- account.unpickle(args.key, f.read())
- result = {
- "account_keys": account.identity_keys(),
- "one_time_keys": account.one_time_keys(),
- }
- try:
- if args.json:
- json.dump(result, sys.stdout, indent=4)
- else:
- yaml.safe_dump(result, sys.stdout, default_flow_style=False)
- except:
- pass
-
- keys.set_defaults(func=do_keys)
-
- sign = commands.add_parser("sign", help="Sign a message")
- sign.add_argument("account_file", help="Local account file")
- sign.add_argument("message_file", help="Message to sign")
- sign.add_argument("signature_file", help="Signature to output")
-
- def do_sign(args):
- account = Account()
- with open(args.account_file, "rb") as f:
- account.unpickle(args.key, f.read())
- with open_in(args.message_file) as f:
- message = f.read()
- signature = account.sign(message)
- with open_out(args.signature_file) as f:
- f.write(signature)
-
- sign.set_defaults(func=do_sign)
-
-
- generate_keys = commands.add_parser("generate_keys", help="Generate one time keys")
- generate_keys.add_argument("account_file", help="Local account file")
- generate_keys.add_argument("count", type=int, help="Number of keys to generate")
-
- def do_generate_keys(args):
- account = Account()
- with open(args.account_file, "rb") as f:
- account.unpickle(args.key, f.read())
- account.generate_one_time_keys(args.count)
- with open(args.account_file, "wb") as f:
- f.write(account.pickle(args.key))
-
- generate_keys.set_defaults(func=do_generate_keys)
-
-
- outbound = commands.add_parser("outbound", help="Create an outbound session")
- outbound.add_argument("account_file", help="Local account file")
- outbound.add_argument("session_file", help="Local session file")
- outbound.add_argument("identity_key", help="Remote identity key")
- outbound.add_argument("one_time_key", help="Remote one time key")
-
- def do_outbound(args):
- if os.path.exists(args.session_file):
- sys.stderr.write("Session %r file already exists" % (
- args.session_file,
- ))
- sys.exit(1)
- account = Account()
- with open(args.account_file, "rb") as f:
- account.unpickle(args.key, f.read())
- session = Session()
- session.create_outbound(
- account, args.identity_key, args.one_time_key
- )
- with open(args.session_file, "wb") as f:
- f.write(session.pickle(args.key))
-
- outbound.set_defaults(func=do_outbound)
-
- def open_in(path):
- if path == "-":
- return sys.stdin
- else:
- return open(path, "rb")
-
- def open_out(path):
- if path == "-":
- return sys.stdout
- else:
- return open(path, "wb")
-
- inbound = commands.add_parser("inbound", help="Create an inbound session")
- inbound.add_argument("account_file", help="Local account file")
- inbound.add_argument("session_file", help="Local session file")
- inbound.add_argument("message_file", help="Message", default="-")
- inbound.add_argument("plaintext_file", help="Plaintext", default="-")
-
- def do_inbound(args):
- if os.path.exists(args.session_file):
- sys.stderr.write("Session %r file already exists" % (
- args.session_file,
- ))
- sys.exit(1)
- account = Account()
- with open(args.account_file, "rb") as f:
- account.unpickle(args.key, f.read())
- with open_in(args.message_file) as f:
- message_type = f.read(8)
- message = f.read()
- if message_type != "PRE_KEY ":
- sys.stderr.write("Expecting a PRE_KEY message")
- sys.exit(1)
- session = Session()
- session.create_inbound(account, message)
- plaintext = session.decrypt(0, message)
- with open(args.session_file, "wb") as f:
- f.write(session.pickle(args.key))
- with open_out(args.plaintext_file) as f:
- f.write(plaintext)
-
- inbound.set_defaults(func=do_inbound)
-
- session_id = commands.add_parser("session_id", help="Session ID")
- session_id.add_argument("session_file", help="Local session file")
-
- def do_session_id(args):
- session = Session()
- with open(args.session_file, "rb") as f:
- session.unpickle(args.key, f.read())
- sys.stdout.write(session.session_id() + "\n")
-
- session_id.set_defaults(func=do_session_id)
-
- encrypt = commands.add_parser("encrypt", help="Encrypt a message")
- encrypt.add_argument("session_file", help="Local session file")
- encrypt.add_argument("plaintext_file", help="Plaintext", default="-")
- encrypt.add_argument("message_file", help="Message", default="-")
-
- def do_encrypt(args):
- session = Session()
- with open(args.session_file, "rb") as f:
- session.unpickle(args.key, f.read())
- with open_in(args.plaintext_file) as f:
- plaintext = f.read()
- message_type, message = session.encrypt(plaintext)
- with open(args.session_file, "wb") as f:
- f.write(session.pickle(args.key))
- with open_out(args.message_file) as f:
- f.write(["PRE_KEY ", "MESSAGE "][message_type])
- f.write(message)
-
- encrypt.set_defaults(func=do_encrypt)
-
- decrypt = commands.add_parser("decrypt", help="Decrypt a message")
- decrypt.add_argument("session_file", help="Local session file")
- decrypt.add_argument("message_file", help="Message", default="-")
- decrypt.add_argument("plaintext_file", help="Plaintext", default="-")
-
- def do_decrypt(args):
- session = Session()
- with open(args.session_file, "rb") as f:
- session.unpickle(args.key, f.read())
- with open_in(args.message_file) as f:
- message_type = f.read(8)
- message = f.read()
- if message_type not in {"PRE_KEY ", "MESSAGE "}:
- sys.stderr.write("Expecting a PRE_KEY or MESSAGE message")
- sys.exit(1)
- message_type = 1 if message_type == "MESSAGE " else 0
- plaintext = session.decrypt(message_type, message)
- with open(args.session_file, "wb") as f:
- f.write(session.pickle(args.key))
- with open_out(args.plaintext_file) as f:
- f.write(plaintext)
-
- decrypt.set_defaults(func=do_decrypt)
-
- args = parser.parse_args()
- args.func(args)
-
-
diff --git a/python/olm/__init__.py b/python/olm/__init__.py
new file mode 100644
index 0000000..5520132
--- /dev/null
+++ b/python/olm/__init__.py
@@ -0,0 +1,2 @@
+from .account import Account
+from .session import Session
diff --git a/python/olm/__main__.py b/python/olm/__main__.py
new file mode 100755
index 0000000..d2b0d38
--- /dev/null
+++ b/python/olm/__main__.py
@@ -0,0 +1,210 @@
+#! /usr/bin/env python
+
+import argparse
+import json
+import os
+import sys
+import yaml
+
+from . import *
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--key", help="Account encryption key", default="")
+ commands = parser.add_subparsers()
+
+ create_account = commands.add_parser("create_account", help="Create a new account")
+ create_account.add_argument("account_file", help="Local account file")
+
+ def do_create_account(args):
+ if os.path.exists(args.account_file):
+ sys.stderr.write("Account %r file already exists" % (
+ args.account_file,
+ ))
+ sys.exit(1)
+ account = Account()
+ account.create()
+ with open(args.account_file, "wb") as f:
+ f.write(account.pickle(args.key))
+
+ create_account.set_defaults(func=do_create_account)
+
+ keys = commands.add_parser("keys", help="List public keys for an account")
+ keys.add_argument("account_file", help="Local account file")
+ keys.add_argument("--json", action="store_true", help="Output as JSON")
+
+ def do_keys(args):
+ account = Account()
+ with open(args.account_file, "rb") as f:
+ account.unpickle(args.key, f.read())
+ result = {
+ "account_keys": account.identity_keys(),
+ "one_time_keys": account.one_time_keys(),
+ }
+ try:
+ if args.json:
+ json.dump(result, sys.stdout, indent=4)
+ else:
+ yaml.safe_dump(result, sys.stdout, default_flow_style=False)
+ except:
+ pass
+
+ keys.set_defaults(func=do_keys)
+
+ sign = commands.add_parser("sign", help="Sign a message")
+ sign.add_argument("account_file", help="Local account file")
+ sign.add_argument("message_file", help="Message to sign")
+ sign.add_argument("signature_file", help="Signature to output")
+
+ def do_sign(args):
+ account = Account()
+ with open(args.account_file, "rb") as f:
+ account.unpickle(args.key, f.read())
+ with open_in(args.message_file) as f:
+ message = f.read()
+ signature = account.sign(message)
+ with open_out(args.signature_file) as f:
+ f.write(signature)
+
+ sign.set_defaults(func=do_sign)
+
+
+ generate_keys = commands.add_parser("generate_keys", help="Generate one time keys")
+ generate_keys.add_argument("account_file", help="Local account file")
+ generate_keys.add_argument("count", type=int, help="Number of keys to generate")
+
+ def do_generate_keys(args):
+ account = Account()
+ with open(args.account_file, "rb") as f:
+ account.unpickle(args.key, f.read())
+ account.generate_one_time_keys(args.count)
+ with open(args.account_file, "wb") as f:
+ f.write(account.pickle(args.key))
+
+ generate_keys.set_defaults(func=do_generate_keys)
+
+
+ outbound = commands.add_parser("outbound", help="Create an outbound session")
+ outbound.add_argument("account_file", help="Local account file")
+ outbound.add_argument("session_file", help="Local session file")
+ outbound.add_argument("identity_key", help="Remote identity key")
+ outbound.add_argument("one_time_key", help="Remote one time key")
+
+ def do_outbound(args):
+ if os.path.exists(args.session_file):
+ sys.stderr.write("Session %r file already exists" % (
+ args.session_file,
+ ))
+ sys.exit(1)
+ account = Account()
+ with open(args.account_file, "rb") as f:
+ account.unpickle(args.key, f.read())
+ session = Session()
+ session.create_outbound(
+ account, args.identity_key, args.one_time_key
+ )
+ with open(args.session_file, "wb") as f:
+ f.write(session.pickle(args.key))
+
+ outbound.set_defaults(func=do_outbound)
+
+ def open_in(path):
+ if path == "-":
+ return sys.stdin
+ else:
+ return open(path, "rb")
+
+ def open_out(path):
+ if path == "-":
+ return sys.stdout
+ else:
+ return open(path, "wb")
+
+ inbound = commands.add_parser("inbound", help="Create an inbound session")
+ inbound.add_argument("account_file", help="Local account file")
+ inbound.add_argument("session_file", help="Local session file")
+ inbound.add_argument("message_file", help="Message", default="-")
+ inbound.add_argument("plaintext_file", help="Plaintext", default="-")
+
+ def do_inbound(args):
+ if os.path.exists(args.session_file):
+ sys.stderr.write("Session %r file already exists" % (
+ args.session_file,
+ ))
+ sys.exit(1)
+ account = Account()
+ with open(args.account_file, "rb") as f:
+ account.unpickle(args.key, f.read())
+ with open_in(args.message_file) as f:
+ message_type = f.read(8)
+ message = f.read()
+ if message_type != "PRE_KEY ":
+ sys.stderr.write("Expecting a PRE_KEY message")
+ sys.exit(1)
+ session = Session()
+ session.create_inbound(account, message)
+ plaintext = session.decrypt(0, message)
+ with open(args.session_file, "wb") as f:
+ f.write(session.pickle(args.key))
+ with open_out(args.plaintext_file) as f:
+ f.write(plaintext)
+
+ inbound.set_defaults(func=do_inbound)
+
+ session_id = commands.add_parser("session_id", help="Session ID")
+ session_id.add_argument("session_file", help="Local session file")
+
+ def do_session_id(args):
+ session = Session()
+ with open(args.session_file, "rb") as f:
+ session.unpickle(args.key, f.read())
+ sys.stdout.write(session.session_id() + "\n")
+
+ session_id.set_defaults(func=do_session_id)
+
+ encrypt = commands.add_parser("encrypt", help="Encrypt a message")
+ encrypt.add_argument("session_file", help="Local session file")
+ encrypt.add_argument("plaintext_file", help="Plaintext", default="-")
+ encrypt.add_argument("message_file", help="Message", default="-")
+
+ def do_encrypt(args):
+ session = Session()
+ with open(args.session_file, "rb") as f:
+ session.unpickle(args.key, f.read())
+ with open_in(args.plaintext_file) as f:
+ plaintext = f.read()
+ message_type, message = session.encrypt(plaintext)
+ with open(args.session_file, "wb") as f:
+ f.write(session.pickle(args.key))
+ with open_out(args.message_file) as f:
+ f.write(["PRE_KEY ", "MESSAGE "][message_type])
+ f.write(message)
+
+ encrypt.set_defaults(func=do_encrypt)
+
+ decrypt = commands.add_parser("decrypt", help="Decrypt a message")
+ decrypt.add_argument("session_file", help="Local session file")
+ decrypt.add_argument("message_file", help="Message", default="-")
+ decrypt.add_argument("plaintext_file", help="Plaintext", default="-")
+
+ def do_decrypt(args):
+ session = Session()
+ with open(args.session_file, "rb") as f:
+ session.unpickle(args.key, f.read())
+ with open_in(args.message_file) as f:
+ message_type = f.read(8)
+ message = f.read()
+ if message_type not in {"PRE_KEY ", "MESSAGE "}:
+ sys.stderr.write("Expecting a PRE_KEY or MESSAGE message")
+ sys.exit(1)
+ message_type = 1 if message_type == "MESSAGE " else 0
+ plaintext = session.decrypt(message_type, message)
+ with open(args.session_file, "wb") as f:
+ f.write(session.pickle(args.key))
+ with open_out(args.plaintext_file) as f:
+ f.write(plaintext)
+
+ decrypt.set_defaults(func=do_decrypt)
+
+ args = parser.parse_args()
+ args.func(args)
diff --git a/python/olm/_base.py b/python/olm/_base.py
new file mode 100644
index 0000000..8238957
--- /dev/null
+++ b/python/olm/_base.py
@@ -0,0 +1,19 @@
+import os.path
+
+from ctypes import *
+
+def read_random(n):
+ with open("/dev/urandom", "rb") as f:
+ return f.read(n)
+
+lib = cdll.LoadLibrary(os.path.join(
+ os.path.dirname(__file__), "..", "..", "build", "libolm.so")
+)
+
+lib.olm_error.argtypes = []
+lib.olm_error.restypes = c_size_t
+
+ERR = lib.olm_error()
+
+class OlmError(Exception):
+ pass
diff --git a/python/olm/account.py b/python/olm/account.py
new file mode 100644
index 0000000..7673329
--- /dev/null
+++ b/python/olm/account.py
@@ -0,0 +1,121 @@
+import json
+
+from ._base import *
+
+lib.olm_account_size.argtypes = []
+lib.olm_account_size.restype = c_size_t
+
+lib.olm_account.argtypes = [c_void_p]
+lib.olm_account.restype = c_void_p
+
+lib.olm_account_last_error.argtypes = [c_void_p]
+lib.olm_account_last_error.restype = c_char_p
+
+def account_errcheck(res, func, args):
+ if res == ERR:
+ raise OlmError("%s: %s" % (
+ func.__name__, lib.olm_account_last_error(args[0])
+ ))
+ return res
+
+
+def account_function(func, *types):
+ func.argtypes = (c_void_p,) + types
+ func.restypes = c_size_t
+ func.errcheck = account_errcheck
+
+
+account_function(
+ lib.olm_pickle_account, c_void_p, c_size_t, c_void_p, c_size_t
+)
+account_function(
+ lib.olm_unpickle_account, c_void_p, c_size_t, c_void_p, c_size_t
+)
+account_function(lib.olm_create_account_random_length)
+account_function(lib.olm_create_account, c_void_p, c_size_t)
+account_function(lib.olm_account_identity_keys_length)
+account_function(lib.olm_account_identity_keys, c_void_p, c_size_t)
+account_function(lib.olm_account_signature_length)
+account_function(lib.olm_account_sign, c_void_p, c_size_t, c_void_p, c_size_t)
+account_function(lib.olm_account_one_time_keys_length)
+account_function(lib.olm_account_one_time_keys, c_void_p, c_size_t)
+account_function(lib.olm_account_mark_keys_as_published)
+account_function(lib.olm_account_max_number_of_one_time_keys)
+account_function(
+ lib.olm_account_generate_one_time_keys_random_length,
+ c_size_t
+)
+account_function(
+ lib.olm_account_generate_one_time_keys,
+ c_size_t,
+ c_void_p, c_size_t
+)
+class Account(object):
+ def __init__(self):
+ self.buf = create_string_buffer(lib.olm_account_size())
+ self.ptr = lib.olm_account(self.buf)
+
+ def create(self):
+ random_length = lib.olm_create_account_random_length(self.ptr)
+ random = read_random(random_length)
+ random_buffer = create_string_buffer(random)
+ lib.olm_create_account(self.ptr, random_buffer, random_length)
+
+ def pickle(self, key):
+ key_buffer = create_string_buffer(key)
+ pickle_length = lib.olm_pickle_account_length(self.ptr)
+ pickle_buffer = create_string_buffer(pickle_length)
+ lib.olm_pickle_account(
+ self.ptr, key_buffer, len(key), pickle_buffer, pickle_length
+ )
+ return pickle_buffer.raw
+
+ def unpickle(self, key, pickle):
+ key_buffer = create_string_buffer(key)
+ pickle_buffer = create_string_buffer(pickle)
+ lib.olm_unpickle_account(
+ self.ptr, key_buffer, len(key), pickle_buffer, len(pickle)
+ )
+
+ def identity_keys(self):
+ out_length = lib.olm_account_identity_keys_length(self.ptr)
+ out_buffer = create_string_buffer(out_length)
+ lib.olm_account_identity_keys(
+ self.ptr,
+ out_buffer, out_length
+ )
+ return json.loads(out_buffer.raw)
+
+ def sign(self, message):
+ out_length = lib.olm_account_signature_length(self.ptr)
+ message_buffer = create_string_buffer(message)
+ out_buffer = create_string_buffer(out_length)
+ lib.olm_account_sign(
+ self.ptr, message_buffer, len(message), out_buffer, out_length
+ )
+ return out_buffer.raw
+
+ def one_time_keys(self):
+ out_length = lib.olm_account_one_time_keys_length(self.ptr)
+ out_buffer = create_string_buffer(out_length)
+ lib.olm_account_one_time_keys(self.ptr, out_buffer, out_length)
+ return json.loads(out_buffer.raw)
+
+ def mark_keys_as_published(self):
+ lib.olm_account_mark_keys_as_published(self.ptr)
+
+ def max_number_of_one_time_keys(self):
+ return lib.olm_account_max_number_of_one_time_keys(self.ptr)
+
+ def generate_one_time_keys(self, count):
+ random_length = lib.olm_account_generate_one_time_keys_random_length(
+ self.ptr, count
+ )
+ random = read_random(random_length)
+ random_buffer = create_string_buffer(random)
+ lib.olm_account_generate_one_time_keys(
+ self.ptr, count, random_buffer, random_length
+ )
+
+ def clear(self):
+ pass
diff --git a/python/olm/session.py b/python/olm/session.py
new file mode 100644
index 0000000..308f220
--- /dev/null
+++ b/python/olm/session.py
@@ -0,0 +1,192 @@
+from ._base import *
+
+
+lib.olm_session_size.argtypes = []
+lib.olm_session_size.restype = c_size_t
+
+lib.olm_session.argtypes = [c_void_p]
+lib.olm_session.restype = c_void_p
+
+lib.olm_session_last_error.argtypes = [c_void_p]
+lib.olm_session_last_error.restype = c_char_p
+
+
+def session_errcheck(res, func, args):
+ if res == ERR:
+ raise OlmError("%s: %s" % (
+ func.__name__, lib.olm_session_last_error(args[0])
+ ))
+ return res
+
+
+def session_function(func, *types):
+ func.argtypes = (c_void_p,) + types
+ func.restypes = c_size_t
+ func.errcheck = session_errcheck
+
+session_function(lib.olm_session_last_error)
+session_function(
+ lib.olm_pickle_session, c_void_p, c_size_t, c_void_p, c_size_t
+)
+session_function(
+ lib.olm_unpickle_session, c_void_p, c_size_t, c_void_p, c_size_t
+)
+session_function(lib.olm_create_outbound_session_random_length)
+session_function(
+ lib.olm_create_outbound_session,
+ c_void_p, # Account
+ c_void_p, c_size_t, # Identity Key
+ c_void_p, c_size_t, # One Time Key
+ c_void_p, c_size_t, # Random
+)
+session_function(
+ lib.olm_create_inbound_session,
+ c_void_p, # Account
+ c_void_p, c_size_t, # Pre Key Message
+)
+session_function(
+ lib.olm_create_inbound_session_from,
+ c_void_p, # Account
+ c_void_p, c_size_t, # Identity Key
+ c_void_p, c_size_t, # Pre Key Message
+)
+session_function(lib.olm_session_id_length)
+session_function(lib.olm_session_id, c_void_p, c_size_t)
+session_function(lib.olm_matches_inbound_session, c_void_p, c_size_t)
+session_function(
+ lib.olm_matches_inbound_session_from,
+ c_void_p, c_size_t, # Identity Key
+ c_void_p, c_size_t, # Pre Key Message
+)
+session_function(lib.olm_encrypt_message_type)
+session_function(lib.olm_encrypt_random_length)
+session_function(lib.olm_encrypt_message_length, c_size_t)
+session_function(
+ lib.olm_encrypt,
+ c_void_p, c_size_t, # Plaintext
+ c_void_p, c_size_t, # Random
+ c_void_p, c_size_t, # Message
+);
+session_function(
+ lib.olm_decrypt_max_plaintext_length,
+ c_size_t, # Message Type
+ c_void_p, c_size_t, # Message
+)
+session_function(
+ lib.olm_decrypt,
+ c_size_t, # Message Type
+ c_void_p, c_size_t, # Message
+ c_void_p, c_size_t, # Plaintext
+)
+
+class Session(object):
+ def __init__(self):
+ self.buf = create_string_buffer(lib.olm_session_size())
+ self.ptr = lib.olm_session(self.buf)
+
+ def pickle(self, key):
+ key_buffer = create_string_buffer(key)
+ pickle_length = lib.olm_pickle_session_length(self.ptr)
+ pickle_buffer = create_string_buffer(pickle_length)
+ lib.olm_pickle_session(
+ self.ptr, key_buffer, len(key), pickle_buffer, pickle_length
+ )
+ return pickle_buffer.raw
+
+ def unpickle(self, key, pickle):
+ key_buffer = create_string_buffer(key)
+ pickle_buffer = create_string_buffer(pickle)
+ lib.olm_unpickle_session(
+ self.ptr, key_buffer, len(key), pickle_buffer, len(pickle)
+ )
+
+ def create_outbound(self, account, identity_key, one_time_key):
+ r_length = lib.olm_create_outbound_session_random_length(self.ptr)
+ random = read_random(r_length)
+ random_buffer = create_string_buffer(random)
+ identity_key_buffer = create_string_buffer(identity_key)
+ one_time_key_buffer = create_string_buffer(one_time_key)
+ lib.olm_create_outbound_session(
+ self.ptr,
+ account.ptr,
+ identity_key_buffer, len(identity_key),
+ one_time_key_buffer, len(one_time_key),
+ random_buffer, r_length
+ )
+
+ def create_inbound(self, account, one_time_key_message):
+ one_time_key_message_buffer = create_string_buffer(one_time_key_message)
+ lib.olm_create_inbound_session(
+ self.ptr,
+ account.ptr,
+ one_time_key_message_buffer, len(one_time_key_message)
+ )
+
+ def create_inbound_from(self, account, identity_key, one_time_key_message):
+ identity_key_buffer = create_string_buffer(identity_key)
+ one_time_key_message_buffer = create_string_buffer(one_time_key_message)
+ lib.olm_create_inbound_session_from(
+ self.ptr,
+ account.ptr,
+ identity_key_buffer, len(identity_key),
+ one_time_key_message_buffer, len(one_time_key_message)
+ )
+
+ def session_id(self):
+ id_length = lib.olm_session_id_length(self.ptr)
+ id_buffer = create_string_buffer(id_length)
+ lib.olm_session_id(self.ptr, id_buffer, id_length);
+ return id_buffer.raw
+
+ def matches_inbound(self, one_time_key_message):
+ one_time_key_message_buffer = create_string_buffer(one_time_key_message)
+ return bool(lib.olm_matches_inbound_session(
+ self.ptr,
+ one_time_key_message_buffer, len(one_time_key_message)
+ ))
+
+ def matches_inbound_from(self, identity_key, one_time_key_message):
+ identity_key_buffer = create_string_buffer(identity_key)
+ one_time_key_message_buffer = create_string_buffer(one_time_key_message)
+ return bool(lib.olm_matches_inbound_session(
+ self.ptr,
+ identity_key_buffer, len(identity_key),
+ one_time_key_message_buffer, len(one_time_key_message)
+ ))
+
+ def encrypt(self, plaintext):
+ r_length = lib.olm_encrypt_random_length(self.ptr)
+ random = read_random(r_length)
+ random_buffer = create_string_buffer(random)
+
+ message_type = lib.olm_encrypt_message_type(self.ptr)
+ message_length = lib.olm_encrypt_message_length(
+ self.ptr, len(plaintext)
+ )
+ message_buffer = create_string_buffer(message_length)
+
+ plaintext_buffer = create_string_buffer(plaintext)
+
+ lib.olm_encrypt(
+ self.ptr,
+ plaintext_buffer, len(plaintext),
+ random_buffer, r_length,
+ message_buffer, message_length,
+ )
+ return message_type, message_buffer.raw
+
+ def decrypt(self, message_type, message):
+ message_buffer = create_string_buffer(message)
+ max_plaintext_length = lib.olm_decrypt_max_plaintext_length(
+ self.ptr, message_type, message_buffer, len(message)
+ )
+ plaintext_buffer = create_string_buffer(max_plaintext_length)
+ message_buffer = create_string_buffer(message)
+ plaintext_length = lib.olm_decrypt(
+ self.ptr, message_type, message_buffer, len(message),
+ plaintext_buffer, max_plaintext_length
+ )
+ return plaintext_buffer.raw[:plaintext_length]
+
+ def clear(self):
+ pass
diff --git a/python/test_olm.sh b/python/test_olm.sh
index 78cd3c2..b575cbf 100755
--- a/python/test_olm.sh
+++ b/python/test_olm.sh
@@ -1,6 +1,6 @@
#! /bin/bash
-OLM="$(dirname $0)/olm.py"
+OLM="python -m olm"
ALICE_ACCOUNT=alice.account
ALICE_SESSION=alice.session
diff --git a/src/account.cpp b/src/account.cpp
index e5cbfab..c8e6e40 100644
--- a/src/account.cpp
+++ b/src/account.cpp
@@ -19,7 +19,7 @@
olm::Account::Account(
) : next_one_time_key_id(0),
- last_error(olm::ErrorCode::SUCCESS) {
+ last_error(OlmErrorCode::OLM_SUCCESS) {
}
@@ -56,7 +56,7 @@ std::size_t olm::Account::new_account(
uint8_t const * random, std::size_t random_length
) {
if (random_length < new_account_random_length()) {
- last_error = olm::ErrorCode::NOT_ENOUGH_RANDOM;
+ last_error = OlmErrorCode::OLM_NOT_ENOUGH_RANDOM;
return std::size_t(-1);
}
@@ -110,7 +110,7 @@ std::size_t olm::Account::get_identity_json(
size_t expected_length = get_identity_json_length();
if (identity_json_length < expected_length) {
- last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
+ last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL;
return std::size_t(-1);
}
@@ -146,7 +146,7 @@ std::size_t olm::Account::sign(
std::uint8_t * signature, std::size_t signature_length
) {
if (signature_length < this->signature_length()) {
- last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
+ last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL;
return std::size_t(-1);
}
olm::ed25519_sign(
@@ -185,7 +185,7 @@ std::size_t olm::Account::get_one_time_keys_json(
) {
std::uint8_t * pos = one_time_json;
if (one_time_json_length < get_one_time_keys_json_length()) {
- last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
+ last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL;
return std::size_t(-1);
}
*(pos++) = '{';
@@ -246,7 +246,7 @@ std::size_t olm::Account::generate_one_time_keys(
std::uint8_t const * random, std::size_t random_length
) {
if (random_length < generate_one_time_keys_random_length(number_of_keys)) {
- last_error = olm::ErrorCode::NOT_ENOUGH_RANDOM;
+ last_error = OlmErrorCode::OLM_NOT_ENOUGH_RANDOM;
return std::size_t(-1);
}
for (unsigned i = 0; i < number_of_keys; ++i) {
@@ -361,7 +361,7 @@ std::uint8_t const * olm::unpickle(
uint32_t pickle_version;
pos = olm::unpickle(pos, end, pickle_version);
if (pickle_version != ACCOUNT_PICKLE_VERSION) {
- value.last_error = olm::ErrorCode::UNKNOWN_PICKLE_VERSION;
+ value.last_error = OlmErrorCode::OLM_UNKNOWN_PICKLE_VERSION;
return end;
}
pos = olm::unpickle(pos, end, value.identity_keys);
diff --git a/src/base64.cpp b/src/base64.cpp
index 66f512b..bbfb210 100644
--- a/src/base64.cpp
+++ b/src/base64.cpp
@@ -12,9 +12,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include "olm/base64.h"
#include "olm/base64.hh"
-
namespace {
static const std::uint8_t ENCODE_BASE64[64] = {
@@ -134,3 +134,34 @@ std::uint8_t const * olm::decode_base64(
}
return input + input_length;
}
+
+
+// implementations of base64.h
+
+size_t _olm_encode_base64_length(
+ size_t input_length
+) {
+ return olm::encode_base64_length(input_length);
+}
+
+size_t _olm_encode_base64(
+ uint8_t const * input, size_t input_length,
+ uint8_t * output
+) {
+ uint8_t * r = olm::encode_base64(input, input_length, output);
+ return r - output;
+}
+
+size_t _olm_decode_base64_length(
+ size_t input_length
+) {
+ return olm::decode_base64_length(input_length);
+}
+
+size_t _olm_decode_base64(
+ uint8_t const * input, size_t input_length,
+ uint8_t * output
+) {
+ olm::decode_base64(input, input_length, output);
+ return olm::decode_base64_length(input_length);
+}
diff --git a/src/cipher.cpp b/src/cipher.cpp
index 7bb11b8..8c3de92 100644
--- a/src/cipher.cpp
+++ b/src/cipher.cpp
@@ -12,15 +12,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "olm/cipher.hh"
+#include "olm/cipher.h"
#include "olm/crypto.hh"
#include "olm/memory.hh"
#include <cstring>
-olm::Cipher::~Cipher() {
-
-}
-
namespace {
struct DerivedKeys {
@@ -36,7 +32,7 @@ static void derive_keys(
DerivedKeys & keys
) {
std::uint8_t derived_secrets[2 * olm::KEY_LENGTH + olm::IV_LENGTH];
- olm::hkdf_sha256(
+ _olm_crypto_hkdf_sha256(
key, key_length,
nullptr, 0,
kdf_info, kdf_info_length,
@@ -51,47 +47,40 @@ static void derive_keys(
static const std::size_t MAC_LENGTH = 8;
-} // namespace
-
-
-olm::CipherAesSha256::CipherAesSha256(
- std::uint8_t const * kdf_info, std::size_t kdf_info_length
-) : kdf_info(kdf_info), kdf_info_length(kdf_info_length) {
-
-}
-
-
-std::size_t olm::CipherAesSha256::mac_length() const {
+size_t aes_sha_256_cipher_mac_length(const struct _olm_cipher *cipher) {
return MAC_LENGTH;
}
-
-std::size_t olm::CipherAesSha256::encrypt_ciphertext_length(
- std::size_t plaintext_length
-) const {
+size_t aes_sha_256_cipher_encrypt_ciphertext_length(
+ const struct _olm_cipher *cipher, size_t plaintext_length
+) {
return olm::aes_encrypt_cbc_length(plaintext_length);
}
+size_t aes_sha_256_cipher_encrypt(
+ const struct _olm_cipher *cipher,
+ uint8_t const * key, size_t key_length,
+ uint8_t const * plaintext, size_t plaintext_length,
+ uint8_t * ciphertext, size_t ciphertext_length,
+ uint8_t * output, size_t output_length
+) {
+ auto *c = reinterpret_cast<const _olm_cipher_aes_sha_256 *>(cipher);
-std::size_t olm::CipherAesSha256::encrypt(
- std::uint8_t const * key, std::size_t key_length,
- std::uint8_t const * plaintext, std::size_t plaintext_length,
- std::uint8_t * ciphertext, std::size_t ciphertext_length,
- std::uint8_t * output, std::size_t output_length
-) const {
- if (encrypt_ciphertext_length(plaintext_length) < ciphertext_length) {
+ if (aes_sha_256_cipher_encrypt_ciphertext_length(cipher, plaintext_length)
+ < ciphertext_length) {
return std::size_t(-1);
}
+
struct DerivedKeys keys;
- std::uint8_t mac[olm::SHA256_OUTPUT_LENGTH];
+ std::uint8_t mac[SHA256_OUTPUT_LENGTH];
- derive_keys(kdf_info, kdf_info_length, key, key_length, keys);
+ derive_keys(c->kdf_info, c->kdf_info_length, key, key_length, keys);
olm::aes_encrypt_cbc(
keys.aes_key, keys.aes_iv, plaintext, plaintext_length, ciphertext
);
- olm::hmac_sha256(
+ _olm_crypto_hmac_sha256(
keys.mac_key, olm::KEY_LENGTH, output, output_length - MAC_LENGTH, mac
);
@@ -102,24 +91,28 @@ std::size_t olm::CipherAesSha256::encrypt(
}
-std::size_t olm::CipherAesSha256::decrypt_max_plaintext_length(
- std::size_t ciphertext_length
-) const {
+size_t aes_sha_256_cipher_decrypt_max_plaintext_length(
+ const struct _olm_cipher *cipher,
+ size_t ciphertext_length
+) {
return ciphertext_length;
}
-std::size_t olm::CipherAesSha256::decrypt(
- std::uint8_t const * key, std::size_t key_length,
- std::uint8_t const * input, std::size_t input_length,
- std::uint8_t const * ciphertext, std::size_t ciphertext_length,
- std::uint8_t * plaintext, std::size_t max_plaintext_length
-) const {
+size_t aes_sha_256_cipher_decrypt(
+ const struct _olm_cipher *cipher,
+ uint8_t const * key, size_t key_length,
+ uint8_t const * input, size_t input_length,
+ uint8_t const * ciphertext, size_t ciphertext_length,
+ uint8_t * plaintext, size_t max_plaintext_length
+) {
+ auto *c = reinterpret_cast<const _olm_cipher_aes_sha_256 *>(cipher);
+
DerivedKeys keys;
- std::uint8_t mac[olm::SHA256_OUTPUT_LENGTH];
+ std::uint8_t mac[SHA256_OUTPUT_LENGTH];
- derive_keys(kdf_info, kdf_info_length, key, key_length, keys);
+ derive_keys(c->kdf_info, c->kdf_info_length, key, key_length, keys);
- olm::hmac_sha256(
+ _olm_crypto_hmac_sha256(
keys.mac_key, olm::KEY_LENGTH, input, input_length - MAC_LENGTH, mac
);
@@ -136,3 +129,13 @@ std::size_t olm::CipherAesSha256::decrypt(
olm::unset(keys);
return plaintext_length;
}
+
+} // namespace
+
+const struct _olm_cipher_ops _olm_cipher_aes_sha_256_ops = {
+ aes_sha_256_cipher_mac_length,
+ aes_sha_256_cipher_encrypt_ciphertext_length,
+ aes_sha_256_cipher_encrypt,
+ aes_sha_256_cipher_decrypt_max_plaintext_length,
+ aes_sha_256_cipher_decrypt,
+};
diff --git a/src/crypto.cpp b/src/crypto.cpp
index ffe2661..4fa92f1 100644
--- a/src/crypto.cpp
+++ b/src/crypto.cpp
@@ -85,7 +85,7 @@ inline static void hmac_sha256_final(
std::uint8_t const * hmac_key,
std::uint8_t * output
) {
- std::uint8_t o_pad[SHA256_BLOCK_LENGTH + olm::SHA256_OUTPUT_LENGTH];
+ std::uint8_t o_pad[SHA256_BLOCK_LENGTH + SHA256_OUTPUT_LENGTH];
std::memcpy(o_pad, hmac_key, SHA256_BLOCK_LENGTH);
for (std::size_t i = 0; i < SHA256_BLOCK_LENGTH; ++i) {
o_pad[i] ^= 0x5C;
@@ -255,7 +255,7 @@ std::size_t olm::aes_decrypt_cbc(
}
-void olm::sha256(
+void _olm_crypto_sha256(
std::uint8_t const * input, std::size_t input_length,
std::uint8_t * output
) {
@@ -267,7 +267,7 @@ void olm::sha256(
}
-void olm::hmac_sha256(
+void _olm_crypto_hmac_sha256(
std::uint8_t const * key, std::size_t key_length,
std::uint8_t const * input, std::size_t input_length,
std::uint8_t * output
@@ -283,7 +283,7 @@ void olm::hmac_sha256(
}
-void olm::hkdf_sha256(
+void _olm_crypto_hkdf_sha256(
std::uint8_t const * input, std::size_t input_length,
std::uint8_t const * salt, std::size_t salt_length,
std::uint8_t const * info, std::size_t info_length,
@@ -291,7 +291,7 @@ void olm::hkdf_sha256(
) {
::SHA256_CTX context;
std::uint8_t hmac_key[SHA256_BLOCK_LENGTH];
- std::uint8_t step_result[olm::SHA256_OUTPUT_LENGTH];
+ std::uint8_t step_result[SHA256_OUTPUT_LENGTH];
std::size_t bytes_remaining = output_length;
std::uint8_t iteration = 1;
if (!salt) {
@@ -303,20 +303,20 @@ void olm::hkdf_sha256(
hmac_sha256_init(&context, hmac_key);
::sha256_update(&context, input, input_length);
hmac_sha256_final(&context, hmac_key, step_result);
- hmac_sha256_key(step_result, olm::SHA256_OUTPUT_LENGTH, hmac_key);
+ hmac_sha256_key(step_result, SHA256_OUTPUT_LENGTH, hmac_key);
/* Expand */
hmac_sha256_init(&context, hmac_key);
::sha256_update(&context, info, info_length);
::sha256_update(&context, &iteration, 1);
hmac_sha256_final(&context, hmac_key, step_result);
- while (bytes_remaining > olm::SHA256_OUTPUT_LENGTH) {
- std::memcpy(output, step_result, olm::SHA256_OUTPUT_LENGTH);
- output += olm::SHA256_OUTPUT_LENGTH;
- bytes_remaining -= olm::SHA256_OUTPUT_LENGTH;
+ while (bytes_remaining > SHA256_OUTPUT_LENGTH) {
+ std::memcpy(output, step_result, SHA256_OUTPUT_LENGTH);
+ output += SHA256_OUTPUT_LENGTH;
+ bytes_remaining -= SHA256_OUTPUT_LENGTH;
iteration ++;
hmac_sha256_init(&context, hmac_key);
- ::sha256_update(&context, step_result, olm::SHA256_OUTPUT_LENGTH);
+ ::sha256_update(&context, step_result, SHA256_OUTPUT_LENGTH);
::sha256_update(&context, info, info_length);
::sha256_update(&context, &iteration, 1);
hmac_sha256_final(&context, hmac_key, step_result);
diff --git a/src/memory.cpp b/src/memory.cpp
index 16a4683..20e0683 100644
--- a/src/memory.cpp
+++ b/src/memory.cpp
@@ -13,7 +13,13 @@
* limitations under the License.
*/
#include "olm/memory.hh"
+#include "olm/memory.h"
+void _olm_unset(
+ void volatile * buffer, size_t buffer_length
+) {
+ olm::unset(buffer, buffer_length);
+}
void olm::unset(
void volatile * buffer, std::size_t buffer_length
diff --git a/src/message.cpp b/src/message.cpp
index 1c93eb8..3be5234 100644
--- a/src/message.cpp
+++ b/src/message.cpp
@@ -133,7 +133,7 @@ static std::uint8_t const * decode(
std::uint8_t const * len_start = pos;
pos = varint_skip(pos, end);
std::size_t len = varint_decode<std::size_t>(len_start, pos);
- if (len + pos > end) return end;
+ if (len > std::size_t(end - pos)) return end;
value = pos;
value_length = len;
pos += len;
@@ -154,7 +154,7 @@ static std::uint8_t const * skip_unknown(
std::uint8_t const * len_start = pos;
pos = varint_skip(pos, end);
std::size_t len = varint_decode<std::size_t>(len_start, pos);
- if (len + pos > end) return end;
+ if (len > std::size_t(end - pos)) return end;
pos += len;
} else {
return end;
diff --git a/src/olm.cpp b/src/olm.cpp
index 63f3d83..fcd033a 100644
--- a/src/olm.cpp
+++ b/src/olm.cpp
@@ -12,12 +12,12 @@
* 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/utility.hh"
#include "olm/base64.hh"
-#include "olm/cipher.hh"
#include "olm/memory.hh"
#include <new>
@@ -57,17 +57,15 @@ 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
-);
+static const struct _olm_cipher_aes_sha_256 PICKLE_CIPHER =
+ OLM_CIPHER_INIT_AES_SHA_256("Pickle");
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();
+ auto *cipher = OLM_CIPHER_BASE(&PICKLE_CIPHER);
+ std::size_t length = cipher->ops->encrypt_ciphertext_length(cipher, raw_length);
+ length += cipher->ops->mac_length(cipher);
return olm::encode_base64_length(length);
}
@@ -76,8 +74,9 @@ 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();
+ auto *cipher = OLM_CIPHER_BASE(&PICKLE_CIPHER);
+ std::size_t length = cipher->ops->encrypt_ciphertext_length(cipher, raw_length);
+ length += cipher->ops->mac_length(cipher);
return output + olm::encode_base64_length(length) - length;
}
@@ -85,13 +84,15 @@ 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
+ auto *cipher = OLM_CIPHER_BASE(&PICKLE_CIPHER);
+ std::size_t ciphertext_length = cipher->ops->encrypt_ciphertext_length(
+ cipher, raw_length
);
- std::size_t length = ciphertext_length + PICKLE_CIPHER.mac_length();
+ std::size_t length = ciphertext_length + cipher->ops->mac_length(cipher);
std::size_t base64_length = olm::encode_base64_length(length);
std::uint8_t * raw_output = output + base64_length - length;
- PICKLE_CIPHER.encrypt(
+ cipher->ops->encrypt(
+ cipher,
key, key_length,
raw_output, raw_length,
raw_output, ciphertext_length,
@@ -104,23 +105,25 @@ std::size_t enc_output(
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
+ OlmErrorCode & 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;
+ last_error = OlmErrorCode::OLM_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(
+ auto *cipher = OLM_CIPHER_BASE(&PICKLE_CIPHER);
+ std::size_t raw_length = enc_length - cipher->ops->mac_length(cipher);
+ std::size_t result = cipher->ops->decrypt(
+ cipher,
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;
+ last_error = OlmErrorCode::OLM_BAD_ACCOUNT_KEY;
}
return result;
}
@@ -150,11 +153,11 @@ 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);
@@ -190,7 +193,7 @@ const char * olm_account_last_error(
OlmAccount * account
) {
unsigned error = unsigned(from_c(account)->last_error);
- if (error < sizeof(ERRORS)) {
+ if (error < (sizeof(ERRORS)/sizeof(ERRORS[0]))) {
return ERRORS[error];
} else {
return "UNKNOWN_ERROR";
@@ -202,7 +205,7 @@ const char * olm_session_last_error(
OlmSession * session
) {
unsigned error = unsigned(from_c(session)->last_error);
- if (error < sizeof(ERRORS)) {
+ if (error < (sizeof(ERRORS)/sizeof(ERRORS[0]))) {
return ERRORS[error];
} else {
return "UNKNOWN_ERROR";
@@ -213,7 +216,7 @@ const char * olm_utility_last_error(
OlmUtility * utility
) {
unsigned error = unsigned(from_c(utility)->last_error);
- if (error < sizeof(ERRORS)) {
+ if (error < (sizeof(ERRORS)/sizeof(ERRORS[0]))) {
return ERRORS[error];
} else {
return "UNKNOWN_ERROR";
@@ -312,7 +315,7 @@ 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;
+ object.last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL;
return size_t(-1);
}
pickle(enc_output_pos(from_c(pickled), raw_length), object);
@@ -328,7 +331,7 @@ 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;
+ object.last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL;
return size_t(-1);
}
pickle(enc_output_pos(from_c(pickled), raw_length), object);
@@ -355,8 +358,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);
}
@@ -384,8 +387,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 +445,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(
@@ -528,7 +531,7 @@ size_t olm_create_outbound_session(
if (olm::decode_base64_length(id_key_length) != olm::KEY_LENGTH
|| olm::decode_base64_length(ot_key_length) != olm::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;
@@ -573,7 +576,7 @@ size_t olm_create_inbound_session_from(
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;
+ from_c(session)->last_error = OlmErrorCode::OLM_INVALID_BASE64;
return std::size_t(-1);
}
olm::Curve25519PublicKey identity_key;
@@ -605,7 +608,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(
@@ -644,7 +647,7 @@ size_t olm_matches_inbound_session_from(
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;
+ from_c(session)->last_error = OlmErrorCode::OLM_INVALID_BASE64;
return std::size_t(-1);
}
olm::Curve25519PublicKey identity_key;
@@ -671,7 +674,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 +715,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 +782,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(
@@ -800,7 +803,7 @@ size_t olm_ed25519_verify(
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;
+ from_c(utility)->last_error = OlmErrorCode::OLM_INVALID_BASE64;
return std::size_t(-1);
}
olm::Ed25519PublicKey verify_key;
diff --git a/src/pickle.cpp b/src/pickle.cpp
index 00f7cd4..fc3e2b4 100644
--- a/src/pickle.cpp
+++ b/src/pickle.cpp
@@ -13,6 +13,7 @@
* limitations under the License.
*/
#include "olm/pickle.hh"
+#include "olm/pickle.h"
std::uint8_t * olm::pickle(
std::uint8_t * pos,
@@ -196,3 +197,37 @@ std::uint8_t const * olm::unpickle(
);
return pos;
}
+
+////// pickle.h implementations
+
+uint8_t * _olm_pickle_uint32(uint8_t * pos, uint32_t value) {
+ return olm::pickle(pos, value);
+}
+
+uint8_t const * _olm_unpickle_uint32(
+ uint8_t const * pos, uint8_t const * end,
+ uint32_t *value
+) {
+ return olm::unpickle(pos, end, *value);
+}
+
+uint8_t * _olm_pickle_bool(uint8_t * pos, int value) {
+ return olm::pickle(pos, (bool)value);
+}
+
+uint8_t const * _olm_unpickle_bool(
+ uint8_t const * pos, uint8_t const * end,
+ int *value
+) {
+ return olm::unpickle(pos, end, *reinterpret_cast<bool *>(value));
+}
+
+uint8_t * _olm_pickle_bytes(uint8_t * pos, uint8_t const * bytes,
+ size_t bytes_length) {
+ return olm::pickle_bytes(pos, bytes, bytes_length);
+}
+
+uint8_t const * _olm_unpickle_bytes(uint8_t const * pos, uint8_t const * end,
+ uint8_t * bytes, size_t bytes_length) {
+ return olm::unpickle_bytes(pos, end, bytes, bytes_length);
+}
diff --git a/src/ratchet.cpp b/src/ratchet.cpp
index b04099f..abcc8a1 100644
--- a/src/ratchet.cpp
+++ b/src/ratchet.cpp
@@ -15,7 +15,7 @@
#include "olm/ratchet.hh"
#include "olm/message.hh"
#include "olm/memory.hh"
-#include "olm/cipher.hh"
+#include "olm/cipher.h"
#include "olm/pickle.hh"
#include <cstring>
@@ -50,7 +50,7 @@ static void create_chain_key(
olm::SharedKey secret;
olm::curve25519_shared_secret(our_key, their_key, secret);
std::uint8_t derived_secrets[2 * olm::KEY_LENGTH];
- olm::hkdf_sha256(
+ _olm_crypto_hkdf_sha256(
secret, sizeof(secret),
root_key, sizeof(root_key),
info.ratchet_info, info.ratchet_info_length,
@@ -70,7 +70,7 @@ static void advance_chain_key(
olm::ChainKey const & chain_key,
olm::ChainKey & new_chain_key
) {
- olm::hmac_sha256(
+ _olm_crypto_hmac_sha256(
chain_key.key, sizeof(chain_key.key),
CHAIN_KEY_SEED, sizeof(CHAIN_KEY_SEED),
new_chain_key.key
@@ -84,7 +84,7 @@ static void create_message_keys(
olm::ChainKey const & chain_key,
olm::KdfInfo const & info,
olm::MessageKey & message_key) {
- olm::hmac_sha256(
+ _olm_crypto_hmac_sha256(
chain_key.key, sizeof(chain_key.key),
MESSAGE_KEY_SEED, sizeof(MESSAGE_KEY_SEED),
message_key.key
@@ -94,12 +94,13 @@ static void create_message_keys(
static std::size_t verify_mac_and_decrypt(
- olm::Cipher const & cipher,
+ _olm_cipher const *cipher,
olm::MessageKey const & message_key,
olm::MessageReader const & reader,
std::uint8_t * plaintext, std::size_t max_plaintext_length
) {
- return cipher.decrypt(
+ return cipher->ops->decrypt(
+ cipher,
message_key.key, sizeof(message_key.key),
reader.input, reader.input_length,
reader.ciphertext, reader.ciphertext_length,
@@ -183,10 +184,10 @@ static std::size_t verify_mac_and_decrypt_for_new_chain(
olm::Ratchet::Ratchet(
olm::KdfInfo const & kdf_info,
- Cipher const & ratchet_cipher
+ _olm_cipher const * ratchet_cipher
) : kdf_info(kdf_info),
ratchet_cipher(ratchet_cipher),
- last_error(olm::ErrorCode::SUCCESS) {
+ last_error(OlmErrorCode::OLM_SUCCESS) {
}
@@ -195,7 +196,7 @@ void olm::Ratchet::initialise_as_bob(
olm::Curve25519PublicKey const & their_ratchet_key
) {
std::uint8_t derived_secrets[2 * olm::KEY_LENGTH];
- olm::hkdf_sha256(
+ _olm_crypto_hkdf_sha256(
shared_secret, shared_secret_length,
nullptr, 0,
kdf_info.root_info, kdf_info.root_info_length,
@@ -217,7 +218,7 @@ void olm::Ratchet::initialise_as_alice(
olm::Curve25519KeyPair const & our_ratchet_key
) {
std::uint8_t derived_secrets[2 * olm::KEY_LENGTH];
- olm::hkdf_sha256(
+ _olm_crypto_hkdf_sha256(
shared_secret, shared_secret_length,
nullptr, 0,
kdf_info.root_info, kdf_info.root_info_length,
@@ -405,11 +406,12 @@ std::size_t olm::Ratchet::encrypt_output_length(
if (!sender_chain.empty()) {
counter = sender_chain[0].chain_key.index;
}
- std::size_t padded = ratchet_cipher.encrypt_ciphertext_length(
+ std::size_t padded = ratchet_cipher->ops->encrypt_ciphertext_length(
+ ratchet_cipher,
plaintext_length
);
return olm::encode_message_length(
- counter, olm::KEY_LENGTH, padded, ratchet_cipher.mac_length()
+ counter, olm::KEY_LENGTH, padded, ratchet_cipher->ops->mac_length(ratchet_cipher)
);
}
@@ -427,11 +429,11 @@ std::size_t olm::Ratchet::encrypt(
std::size_t output_length = encrypt_output_length(plaintext_length);
if (random_length < encrypt_random_length()) {
- last_error = olm::ErrorCode::NOT_ENOUGH_RANDOM;
+ last_error = OlmErrorCode::OLM_NOT_ENOUGH_RANDOM;
return std::size_t(-1);
}
if (max_output_length < output_length) {
- last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
+ last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL;
return std::size_t(-1);
}
@@ -452,7 +454,8 @@ std::size_t olm::Ratchet::encrypt(
create_message_keys(chain_index, sender_chain[0].chain_key, kdf_info, keys);
advance_chain_key(chain_index, sender_chain[0].chain_key, sender_chain[0].chain_key);
- std::size_t ciphertext_length = ratchet_cipher.encrypt_ciphertext_length(
+ std::size_t ciphertext_length = ratchet_cipher->ops->encrypt_ciphertext_length(
+ ratchet_cipher,
plaintext_length
);
std::uint32_t counter = keys.index;
@@ -467,7 +470,8 @@ std::size_t olm::Ratchet::encrypt(
olm::store_array(writer.ratchet_key, ratchet_key.public_key);
- ratchet_cipher.encrypt(
+ ratchet_cipher->ops->encrypt(
+ ratchet_cipher,
keys.key, sizeof(keys.key),
plaintext, plaintext_length,
writer.ciphertext, ciphertext_length,
@@ -484,15 +488,17 @@ std::size_t olm::Ratchet::decrypt_max_plaintext_length(
) {
olm::MessageReader reader;
olm::decode_message(
- reader, input, input_length, ratchet_cipher.mac_length()
+ reader, input, input_length,
+ ratchet_cipher->ops->mac_length(ratchet_cipher)
);
if (!reader.ciphertext) {
- last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT;
+ last_error = OlmErrorCode::OLM_BAD_MESSAGE_FORMAT;
return std::size_t(-1);
}
- return ratchet_cipher.decrypt_max_plaintext_length(reader.ciphertext_length);
+ return ratchet_cipher->ops->decrypt_max_plaintext_length(
+ ratchet_cipher, reader.ciphertext_length);
}
@@ -502,30 +508,32 @@ std::size_t olm::Ratchet::decrypt(
) {
olm::MessageReader reader;
olm::decode_message(
- reader, input, input_length, ratchet_cipher.mac_length()
+ reader, input, input_length,
+ ratchet_cipher->ops->mac_length(ratchet_cipher)
);
if (reader.version != PROTOCOL_VERSION) {
- last_error = olm::ErrorCode::BAD_MESSAGE_VERSION;
+ last_error = OlmErrorCode::OLM_BAD_MESSAGE_VERSION;
return std::size_t(-1);
}
if (!reader.has_counter || !reader.ratchet_key || !reader.ciphertext) {
- last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT;
+ last_error = OlmErrorCode::OLM_BAD_MESSAGE_FORMAT;
return std::size_t(-1);
}
- std::size_t max_length = ratchet_cipher.decrypt_max_plaintext_length(
+ std::size_t max_length = ratchet_cipher->ops->decrypt_max_plaintext_length(
+ ratchet_cipher,
reader.ciphertext_length
);
if (max_plaintext_length < max_length) {
- last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
+ last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL;
return std::size_t(-1);
}
if (reader.ratchet_key_length != olm::KEY_LENGTH) {
- last_error = olm::ErrorCode::BAD_MESSAGE_FORMAT;
+ last_error = OlmErrorCode::OLM_BAD_MESSAGE_FORMAT;
return std::size_t(-1);
}
@@ -588,7 +596,7 @@ std::size_t olm::Ratchet::decrypt(
}
if (result == std::size_t(-1)) {
- last_error = olm::ErrorCode::BAD_MESSAGE_MAC;
+ last_error = OlmErrorCode::OLM_BAD_MESSAGE_MAC;
return std::size_t(-1);
}
diff --git a/src/session.cpp b/src/session.cpp
index 86ba63b..c148c97 100644
--- a/src/session.cpp
+++ b/src/session.cpp
@@ -13,7 +13,7 @@
* limitations under the License.
*/
#include "olm/session.hh"
-#include "olm/cipher.hh"
+#include "olm/cipher.h"
#include "olm/crypto.hh"
#include "olm/account.hh"
#include "olm/memory.hh"
@@ -30,20 +30,19 @@ 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) {
}
@@ -61,7 +60,7 @@ std::size_t olm::Session::new_outbound_session(
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);
}
@@ -128,7 +127,7 @@ std::size_t olm::Session::new_inbound_session(
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);
}
@@ -137,7 +136,7 @@ std::size_t olm::Session::new_inbound_session(
their_identity_key->public_key, reader.identity_key, olm::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);
}
}
@@ -149,12 +148,12 @@ std::size_t olm::Session::new_inbound_session(
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;
+ last_error = OlmErrorCode::OLM_BAD_MESSAGE_FORMAT;
return std::size_t(-1);
}
@@ -166,7 +165,7 @@ 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);
}
@@ -192,7 +191,7 @@ std::size_t olm::Session::new_inbound_session(
std::size_t olm::Session::session_id_length() {
- return olm::SHA256_OUTPUT_LENGTH;
+ return SHA256_OUTPUT_LENGTH;
}
@@ -200,7 +199,7 @@ 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];
@@ -208,7 +207,7 @@ std::size_t olm::Session::session_id(
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();
}
@@ -286,7 +285,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;
@@ -321,7 +320,7 @@ 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;
}
@@ -342,7 +341,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;
@@ -355,7 +354,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;
}
@@ -375,7 +374,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;
@@ -388,7 +387,7 @@ std::size_t olm::Session::decrypt(
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;
}
@@ -435,7 +434,7 @@ 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;
+ value.last_error = OlmErrorCode::OLM_UNKNOWN_PICKLE_VERSION;
return end;
}
pos = olm::unpickle(pos, end, value.received_message);
diff --git a/src/utility.cpp b/src/utility.cpp
index bc51cff..67029c9 100644
--- a/src/utility.cpp
+++ b/src/utility.cpp
@@ -18,12 +18,12 @@
olm::Utility::Utility(
-) : last_error(olm::ErrorCode::SUCCESS) {
+) : last_error(OlmErrorCode::OLM_SUCCESS) {
}
size_t olm::Utility::sha256_length() {
- return olm::SHA256_OUTPUT_LENGTH;
+ return SHA256_OUTPUT_LENGTH;
}
@@ -32,11 +32,11 @@ size_t olm::Utility::sha256(
std::uint8_t * output, std::size_t output_length
) {
if (output_length < sha256_length()) {
- last_error = olm::ErrorCode::OUTPUT_BUFFER_TOO_SMALL;
+ last_error = OlmErrorCode::OLM_OUTPUT_BUFFER_TOO_SMALL;
return std::size_t(-1);
}
- olm::sha256(input, input_length, output);
- return olm::SHA256_OUTPUT_LENGTH;
+ _olm_crypto_sha256(input, input_length, output);
+ return SHA256_OUTPUT_LENGTH;
}
@@ -46,11 +46,11 @@ size_t olm::Utility::ed25519_verify(
std::uint8_t const * signature, std::size_t signature_length
) {
if (signature_length < olm::SIGNATURE_LENGTH) {
- last_error = olm::ErrorCode::BAD_MESSAGE_MAC;
+ last_error = OlmErrorCode::OLM_BAD_MESSAGE_MAC;
return std::size_t(-1);
}
if (!olm::ed25519_verify(key, message, message_length, signature)) {
- last_error = olm::ErrorCode::BAD_MESSAGE_MAC;
+ last_error = OlmErrorCode::OLM_BAD_MESSAGE_MAC;
return std::size_t(-1);
}
return std::size_t(0);
diff --git a/tests/test_base64.cpp b/tests/test_base64.cpp
index 5bae2f9..c95e3c9 100644
--- a/tests/test_base64.cpp
+++ b/tests/test_base64.cpp
@@ -1,10 +1,11 @@
#include "olm/base64.hh"
+#include "olm/base64.h"
#include "unittest.hh"
int main() {
{ /* Base64 encode test */
-TestCase test_case("Base64 encode test");
+TestCase test_case("Base64 C++ binding encode test");
std::uint8_t input[] = "Hello World";
std::uint8_t expected_output[] = "SGVsbG8gV29ybGQ";
@@ -18,8 +19,24 @@ olm::encode_base64(input, input_length, output);
assert_equals(expected_output, output, output_length);
}
+{
+TestCase test_case("Base64 C binding encode test");
+
+std::uint8_t input[] = "Hello World";
+std::uint8_t expected_output[] = "SGVsbG8gV29ybGQ";
+std::size_t input_length = sizeof(input) - 1;
+
+std::size_t output_length = ::_olm_encode_base64_length(input_length);
+assert_equals(std::size_t(15), output_length);
+
+std::uint8_t output[output_length];
+output_length = ::_olm_encode_base64(input, input_length, output);
+assert_equals(std::size_t(15), output_length);
+assert_equals(expected_output, output, output_length);
+}
+
{ /* Base64 decode test */
-TestCase test_case("Base64 decode test");
+TestCase test_case("Base64 C++ binding decode test");
std::uint8_t input[] = "SGVsbG8gV29ybGQ";
std::uint8_t expected_output[] = "Hello World";
@@ -33,4 +50,21 @@ olm::decode_base64(input, input_length, output);
assert_equals(expected_output, output, output_length);
}
+{
+TestCase test_case("Base64 C binding decode test");
+
+std::uint8_t input[] = "SGVsbG8gV29ybGQ";
+std::uint8_t expected_output[] = "Hello World";
+std::size_t input_length = sizeof(input) - 1;
+
+std::size_t output_length = ::_olm_decode_base64_length(input_length);
+assert_equals(std::size_t(11), output_length);
+
+std::uint8_t output[output_length];
+output_length = ::_olm_decode_base64(input, input_length, output);
+assert_equals(std::size_t(11), output_length);
+assert_equals(expected_output, output, output_length);
+}
+
+
}
diff --git a/tests/test_crypto.cpp b/tests/test_crypto.cpp
index 4606c52..1041538 100644
--- a/tests/test_crypto.cpp
+++ b/tests/test_crypto.cpp
@@ -186,7 +186,7 @@ std::uint8_t expected[32] = {
std::uint8_t actual[32];
-olm::sha256(input, sizeof(input), actual);
+_olm_crypto_sha256(input, sizeof(input), actual);
assert_equals(expected, actual, 32);
@@ -207,7 +207,7 @@ std::uint8_t expected[32] = {
std::uint8_t actual[32];
-olm::hmac_sha256(input, sizeof(input), input, sizeof(input), actual);
+_olm_crypto_hmac_sha256(input, sizeof(input), input, sizeof(input), actual);
assert_equals(expected, actual, 32);
@@ -242,7 +242,7 @@ std::uint8_t hmac_expected_output[32] = {
std::uint8_t hmac_actual_output[32] = {};
-olm::hmac_sha256(
+_olm_crypto_hmac_sha256(
salt, sizeof(salt),
input, sizeof(input),
hmac_actual_output
@@ -261,7 +261,7 @@ std::uint8_t hkdf_expected_output[42] = {
std::uint8_t hkdf_actual_output[42] = {};
-olm::hkdf_sha256(
+_olm_crypto_hkdf_sha256(
input, sizeof(input),
salt, sizeof(salt),
info, sizeof(info),
diff --git a/tests/test_olm.cpp b/tests/test_olm.cpp
index fbc14cf..de7e236 100644
--- a/tests/test_olm.cpp
+++ b/tests/test_olm.cpp
@@ -1,4 +1,4 @@
-#include "olm/olm.hh"
+#include "olm/olm.h"
#include "unittest.hh"
#include <cstddef>
diff --git a/tests/test_olm_decrypt.cpp b/tests/test_olm_decrypt.cpp
index 2a2db98..95cb18e 100644
--- a/tests/test_olm_decrypt.cpp
+++ b/tests/test_olm_decrypt.cpp
@@ -1,4 +1,4 @@
-#include "olm/olm.hh"
+#include "olm/olm.h"
#include "unittest.hh"
const char * test_cases[] = {
@@ -67,7 +67,7 @@ int main() {
{
TestCase my_test("Olm decrypt test");
-for (int i = 0; i < sizeof(test_cases)/ sizeof(const char *); ++i) {
+for (unsigned int i = 0; i < sizeof(test_cases)/ sizeof(const char *); ++i) {
decrypt_case(0, test_cases[i]);
}
diff --git a/tests/test_olm_sha256.cpp b/tests/test_olm_sha256.cpp
index fe5bf42..c6d0242 100644
--- a/tests/test_olm_sha256.cpp
+++ b/tests/test_olm_sha256.cpp
@@ -1,4 +1,4 @@
-#include "olm/olm.hh"
+#include "olm/olm.h"
#include "unittest.hh"
int main() {
diff --git a/tests/test_olm_signature.cpp b/tests/test_olm_signature.cpp
index a7cce63..d7259de 100644
--- a/tests/test_olm_signature.cpp
+++ b/tests/test_olm_signature.cpp
@@ -1,4 +1,4 @@
-#include "olm/olm.hh"
+#include "olm/olm.h"
#include "unittest.hh"
#include <cstddef>
diff --git a/tests/test_olm_using_malloc.cpp b/tests/test_olm_using_malloc.cpp
index 84fbbd7..fff3ea2 100644
--- a/tests/test_olm_using_malloc.cpp
+++ b/tests/test_olm_using_malloc.cpp
@@ -1,4 +1,4 @@
-#include "olm/olm.hh"
+#include "olm/olm.h"
#include "unittest.hh"
#include <cstddef>
diff --git a/tests/test_ratchet.cpp b/tests/test_ratchet.cpp
index cbb3c52..2f8412e 100644
--- a/tests/test_ratchet.cpp
+++ b/tests/test_ratchet.cpp
@@ -13,7 +13,7 @@
* limitations under the License.
*/
#include "olm/ratchet.hh"
-#include "olm/cipher.hh"
+#include "olm/cipher.h"
#include "unittest.hh"
@@ -28,9 +28,8 @@ olm::KdfInfo kdf_info = {
ratchet_info, sizeof(ratchet_info) - 1
};
-olm::CipherAesSha256 cipher(
- message_info, sizeof(message_info) - 1
-);
+_olm_cipher_aes_sha_256 cipher0 = OLM_CIPHER_INIT_AES_SHA_256(message_info);
+_olm_cipher *cipher = OLM_CIPHER_BASE(&cipher0);
std::uint8_t random_bytes[] = "0123456789ABDEF0123456789ABCDEF";
olm::Curve25519KeyPair alice_key;
@@ -195,7 +194,7 @@ std::uint8_t random[] = "This is a random 32 byte string";
for (unsigned i = 0; i < 8; ++i) {
{
std::uint8_t msg[alice.encrypt_output_length(sizeof(plaintext))];
- std::uint8_t encrypt_length = alice.encrypt(
+ alice.encrypt(
plaintext, 15, random, 32, msg, sizeof(msg)
);
std::uint8_t output[bob.decrypt_max_plaintext_length(msg, sizeof(msg))];
@@ -206,7 +205,7 @@ for (unsigned i = 0; i < 8; ++i) {
random[31]++;
{
std::uint8_t msg[bob.encrypt_output_length(sizeof(plaintext))];
- std::uint8_t encrypt_length = bob.encrypt(
+ bob.encrypt(
plaintext, 15, random, 32, msg, sizeof(msg)
);
std::uint8_t output[alice.decrypt_max_plaintext_length(msg, sizeof(msg))];